Add git version defines
[git-cheetah/kirill.git] / common / cheetahmenu.c
blobbea8f3cfbb3719c683d40cbcf8346b6357f786d7
2 #include "cache.h"
3 #include "exec.h"
4 #include "menuengine.h"
5 #include "cheetahmenu.h"
6 #include "debug.h"
7 #include "systeminfo.h"
9 char *wd_from_path(const char *path, BOOL *is_path_dir)
11 BOOL directory = TRUE;
12 char *cheetah_wd = strdup(path);
13 if (!is_directory(cheetah_wd)) {
14 char *c = strrchr(cheetah_wd, PATH_SEPERATOR);
15 if (c) /* sanity check in case it's a weird directory */
16 *c = 0;
18 directory = FALSE;
21 if (is_path_dir)
22 *is_path_dir = directory;
24 return cheetah_wd;
28 * Cheetah-specific menu
31 static int menu_gui(struct git_data *this_, UINT id)
33 char *wd = wd_from_path(this_->name, NULL);
34 const char **argv;
36 free_func_t argv_free;
37 void *argv_data;
39 const char *generic_argv[] = { "git", "gui", NULL };
41 argv = menu_get_platform_argv(MENU_GUI, NULL,
42 &argv_free, &argv_data);
44 if (!argv)
45 argv = generic_argv;
47 exec_program_v(wd, NULL, NULL, HIDDENMODE, argv);
49 if (argv_free)
50 argv_free(argv_data);
51 free(wd);
53 return 0;
56 static int menu_init(struct git_data *this_, UINT id)
58 char *wd = wd_from_path(this_->name, NULL);
59 const char **argv;
61 free_func_t argv_free;
62 void *argv_data;
64 const char *generic_argv[] = { "git", "init", NULL };
66 argv = menu_get_platform_argv(MENU_INIT, NULL,
67 &argv_free, &argv_data);
68 if (!argv)
69 argv = generic_argv;
71 exec_program_v(wd, NULL, NULL, HIDDENMODE | WAITMODE, argv);
73 if (argv_free)
74 argv_free(argv_data);
75 free(wd);
77 return 1;
80 static int menu_history(struct git_data *this_, unsigned int id)
82 BOOL is_directory;
83 char *wd = wd_from_path(this_->name, &is_directory);
84 char *name = "";
85 const char **argv;
87 free_func_t argv_free;
88 void *argv_data;
90 const char *generic_argv[] = { "gitk", "HEAD", "--",
91 NULL, NULL };
93 if (!is_directory)
94 name = this_->name + strlen(wd) + 1;
95 generic_argv[3] = name;
97 argv = menu_get_platform_argv(MENU_HISTORY, name,
98 &argv_free, &argv_data);
99 if (!argv)
100 argv = generic_argv;
102 exec_program_v(wd, NULL, NULL, HIDDENMODE, argv);
104 if (argv_free)
105 argv_free(argv_data);
106 free(wd);
108 return 0;
111 static int menu_bash(struct git_data *this_, UINT id)
113 char *wd = wd_from_path(this_->name, NULL);
114 const char **argv;
116 free_func_t argv_free;
117 void *argv_data;
119 argv = menu_get_platform_argv(MENU_BASH, wd,
120 &argv_free, &argv_data);
121 /* There is no generic implementation for this item */
122 if (!argv) {
123 debug_git("Error: Got no platform terminal for bash");
124 return 0;
127 exec_program_v(wd, NULL, NULL, NORMALMODE, argv);
129 if (argv_free)
130 argv_free(argv_data);
131 free(wd);
133 return 0;
136 static int menu_blame(struct git_data *this_, UINT id)
138 BOOL is_directory;
139 char *wd = wd_from_path(this_->name, &is_directory);
140 char *name = "";
141 const char **argv;
143 free_func_t argv_free = NULL;
144 void *argv_data;
146 const char *generic_argv[] = { "git", "gui", "blame",
147 NULL, NULL };
149 if (!is_directory) {
150 name = this_->name + strlen(wd) + 1;
151 generic_argv[3] = name;
153 argv = menu_get_platform_argv(MENU_BLAME, name,
154 &argv_free, &argv_data);
155 if (!argv)
156 argv = generic_argv;
158 exec_program_v(wd, NULL, NULL, HIDDENMODE, argv);
161 if (argv_free)
162 argv_free(argv_data);
163 free(wd);
165 return 0;
168 static int menu_citool(struct git_data *this_, UINT id)
170 char *wd = wd_from_path(this_->name, NULL);
171 const char **argv;
173 free_func_t argv_free;
174 void *argv_data;
176 const char *generic_argv[] = { "git", "citool", NULL };
178 argv = menu_get_platform_argv(MENU_CITOOL, NULL,
179 &argv_free, &argv_data);
180 if (!argv)
181 argv = generic_argv;
183 exec_program_v(wd, NULL, NULL, HIDDENMODE, argv);
185 if (argv_free)
186 argv_free(argv_data);
187 free(wd);
189 return 0;
192 static int menu_addall(struct git_data *this_, UINT id)
194 char *wd = wd_from_path(this_->name, NULL);
195 const char **argv;
197 free_func_t argv_free;
198 void *argv_data;
200 const char *generic_argv[] = { "git", "add", "--all", NULL };
202 argv = menu_get_platform_argv(MENU_ADDALL, NULL,
203 &argv_free, &argv_data);
204 if (!argv)
205 argv = generic_argv;
207 exec_program_v(wd, NULL, NULL, HIDDENMODE, argv);
209 if (argv_free)
210 argv_free(argv_data);
211 free(wd);
213 return 0;
216 static int menu_branch(struct git_data *this_, UINT id)
218 int status;
219 char *wd = wd_from_path(this_->name, NULL);
220 struct strbuf err;
221 const char *menu_item_text;
222 const char **argv;
224 free_func_t argv_free;
225 void *argv_data;
227 const char *generic_argv[] = { "git", "checkout", NULL, NULL };
229 menu_item_text = get_menu_item_text(id);
230 generic_argv[2] = menu_item_text;
232 argv = menu_get_platform_argv(MENU_BRANCH, menu_item_text,
233 &argv_free, &argv_data);
234 if (!argv)
235 argv = generic_argv;
237 strbuf_init(&err, 0);
239 status = exec_program_v(wd, NULL, &err, HIDDENMODE | WAITMODE, argv);
241 /* if nothing, terribly wrong happened, show the confirmation */
242 if (-1 != status)
243 /* strangely enough even success message is on stderr */
244 debug_git_mbox(err.buf);
246 if (argv_free)
247 argv_free(argv_data);
248 free(wd);
250 return 1;
253 static BOOL build_branch_menu(struct git_data *data,
254 const struct menu_item *item,
255 void *platform)
257 void *submenu;
259 int status;
260 char *wd = wd_from_path(data->name, NULL);
262 struct strbuf output;
263 struct strbuf **lines, **it;
264 strbuf_init(&output, 0);
266 status = exec_program(wd, &output, NULL, WAITMODE,
267 "git", "branch", NULL);
268 free(wd);
269 if (status)
270 return FALSE;
272 submenu = start_submenu(data, item, platform);
274 lines = strbuf_split(&output, '\n');
275 for (it = lines; *it; it++) {
276 struct menu_item item = {
277 MENU_ITEM_CLEANUP, 0,
278 NULL, NULL,
279 NULL, menu_branch
282 strbuf_rtrim(*it);
283 item.string = strdup((*it)->buf + 2);
284 item.helptext = strdup((*it)->buf + 2);
285 item.flags = '*' == (*it)->buf[0] ?
286 MI_CHECKED | MI_DISABLED : 0;
287 if (build_item(data, &item, submenu))
288 append_active_menu(&item);
289 else
291 * if the platform failed to create an item
292 * there is no point to try other items
294 break;
297 end_submenu(platform, submenu);
299 /* technically, there is nothing to track for the menu engine */
300 return FALSE;
303 UINT cheetah_menu_mask(struct git_data *this_)
305 BOOL is_directory;
306 char *wd = wd_from_path(this_->name, &is_directory);
307 UINT selection = is_directory ? MENU_ITEM_DIR : MENU_ITEM_FILE;
308 int status;
310 struct strbuf output;
311 char *eol;
312 strbuf_init(&output, 0);
314 status = exec_program(wd, &output, NULL, WAITMODE,
315 "git", "rev-parse", "--show-prefix", NULL);
316 eol = strchr(output.buf, '\n');
317 if (eol)
318 *eol = 0;
320 if (status < 0) /* something went terribly wrong */
321 selection = MENU_ITEM_LAST;
322 else if (status)
323 selection |= MENU_ITEM_NOREPO;
324 else {
325 char head_path[MAX_PATH] = "HEAD";
326 if (!is_directory)
327 sprintf(head_path, "HEAD:%s%s",
328 output.buf,
329 this_->name + strlen(wd) + 1);
331 status = exec_program(wd, NULL, NULL, WAITMODE,
332 "git", "rev-parse", "--verify", head_path, NULL);
333 if (status < 0) /* something went terribly wrong */
334 selection = MENU_ITEM_LAST;
335 else
336 selection |= MENU_ITEM_REPO |
337 (status ?
338 MENU_ITEM_NOTRACK : MENU_ITEM_TRACK);
341 strbuf_release(&output);
342 free(wd);
343 return selection;
346 const struct menu_item cheetah_menu[] = {
347 { MENU_ITEM_ALWAYS, 0, NULL, NULL, build_separator, NULL },
349 { MENU_ITEM_REPO, 0, "Git &Add all files now",
350 "Add all files from this folder now",
351 build_item, menu_addall },
352 { MENU_ITEM_REPO, 0, "Git &Commit Tool",
353 "Launch the GIT commit tool in the local or chosen directory.",
354 build_item, menu_citool },
355 { MENU_ITEM_TRACK, 0, "Git &History",
356 "Show GIT history of the chosen file or directory.",
357 build_item,
358 menu_history },
359 { MENU_ITEM_TRACK | MENU_ITEM_FILE, 0, "Git &Blame",
360 "Start a blame viewer on the specified file.",
361 build_item, menu_blame },
363 { MENU_ITEM_REPO, 0, "Git &Gui",
364 "Launch the GIT Gui in the local or chosen directory.",
365 build_item, menu_gui },
367 { MENU_ITEM_REPO, 0, "Git Bra&nch",
368 "Checkout a branch",
369 build_branch_menu, NULL },
371 { MENU_ITEM_NOREPO, 0, "Git I&nit Here",
372 "Initialize GIT repo in the local directory.",
373 build_item, menu_init },
374 { MENU_ITEM_NOREPO | MENU_ITEM_DIR, 0, "Git &Gui",
375 "Launch the GIT Gui in the local or chosen directory.",
376 build_item, menu_gui },
378 { MENU_ITEM_ALWAYS, 0, "Git Ba&sh",
379 "Start GIT shell in the local or chosen directory",
380 build_item, menu_bash },
381 { MENU_ITEM_ALWAYS, 0, NULL, NULL, build_separator, NULL },
384 void build_cheetah_menu(struct git_data *data, void *platform_data)
386 reset_platform(platform_data);
387 build_menu_items(data, cheetah_menu_mask,
388 cheetah_menu,
389 sizeof(cheetah_menu) / sizeof(cheetah_menu[0]),
390 platform_data);