4 #include "menuengine.h"
5 #include "cheetahmenu.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 */
22 *is_path_dir
= directory
;
27 static char *get_git_prefix(const char *wd
, int *out_status
)
31 struct strbuf output
= STRBUF_INIT
;
33 status
= exec_program(wd
, &output
, NULL
, WAITMODE
,
34 "git", "rev-parse", "--show-prefix", NULL
);
38 strbuf_release(&output
);
42 eol
= strchr(output
.buf
, '\n');
46 return strbuf_detach(&output
, NULL
);
50 * Cheetah-specific menu
53 static int menu_gui(struct git_data
*this_
, UINT id
)
55 char *wd
= wd_from_path(this_
->name
, NULL
);
58 free_func_t argv_free
;
61 const char *generic_argv
[] = { "git", "gui", NULL
};
63 argv
= menu_get_platform_argv(MENU_GUI
, NULL
,
64 &argv_free
, &argv_data
);
69 exec_program_v(wd
, NULL
, NULL
, HIDDENMODE
, argv
);
78 static int menu_init(struct git_data
*this_
, UINT id
)
80 char *wd
= wd_from_path(this_
->name
, NULL
);
83 free_func_t argv_free
;
86 const char *generic_argv
[] = { "git", "init", NULL
};
88 argv
= menu_get_platform_argv(MENU_INIT
, NULL
,
89 &argv_free
, &argv_data
);
93 exec_program_v(wd
, NULL
, NULL
, HIDDENMODE
| WAITMODE
, argv
);
102 static int menu_history(struct git_data
*this_
, unsigned int id
)
105 char *wd
= wd_from_path(this_
->name
, &is_directory
);
109 free_func_t argv_free
;
112 const char *generic_argv
[] = { "gitk", "HEAD", "--",
118 name
= this_
->name
+ strlen(wd
) + 1;
120 generic_argv
[3] = name
;
122 argv
= menu_get_platform_argv(MENU_HISTORY
, name
,
123 &argv_free
, &argv_data
);
127 exec_program_v(wd
, NULL
, NULL
, HIDDENMODE
, argv
);
130 argv_free(argv_data
);
136 static int menu_bash(struct git_data
*this_
, UINT id
)
138 char *wd
= wd_from_path(this_
->name
, NULL
);
141 free_func_t argv_free
;
144 argv
= menu_get_platform_argv(MENU_BASH
, wd
,
145 &argv_free
, &argv_data
);
146 /* There is no generic implementation for this item */
148 debug_git("Error: Got no platform terminal for bash");
152 exec_program_v(wd
, NULL
, NULL
, DETACHMODE
, argv
);
155 argv_free(argv_data
);
161 static int menu_blame(struct git_data
*this_
, UINT id
)
164 char *wd
= wd_from_path(this_
->name
, &is_directory
);
168 free_func_t argv_free
= NULL
;
171 const char *generic_argv
[] = { "git", "gui", "blame",
175 name
= this_
->name
+ strlen(wd
) + 1;
176 generic_argv
[3] = name
;
178 argv
= menu_get_platform_argv(MENU_BLAME
, NULL
,
179 &argv_free
, &argv_data
);
183 exec_program_v(wd
, NULL
, NULL
, HIDDENMODE
, argv
);
187 argv_free(argv_data
);
193 static int menu_citool(struct git_data
*this_
, UINT id
)
195 char *wd
= wd_from_path(this_
->name
, NULL
);
198 free_func_t argv_free
;
201 const char *generic_argv
[] = { "git", "citool", NULL
};
203 argv
= menu_get_platform_argv(MENU_CITOOL
, NULL
,
204 &argv_free
, &argv_data
);
208 exec_program_v(wd
, NULL
, NULL
, HIDDENMODE
, argv
);
211 argv_free(argv_data
);
217 static int menu_addall(struct git_data
*this_
, UINT id
)
219 char *wd
= wd_from_path(this_
->name
, NULL
);
222 free_func_t argv_free
;
225 const char *generic_argv
[] = { "git", "add", "--all", NULL
};
227 argv
= menu_get_platform_argv(MENU_ADDALL
, NULL
,
228 &argv_free
, &argv_data
);
232 exec_program_v(wd
, NULL
, NULL
, HIDDENMODE
, argv
);
235 argv_free(argv_data
);
241 static int menu_branch(struct git_data
*this_
, UINT id
)
244 char *wd
= wd_from_path(this_
->name
, NULL
);
246 const char *menu_item_text
;
249 free_func_t argv_free
;
252 const char *generic_argv
[] = { "git", "checkout", NULL
, NULL
};
254 menu_item_text
= get_menu_item_text(id
);
255 generic_argv
[2] = menu_item_text
;
257 argv
= menu_get_platform_argv(MENU_BRANCH
, NULL
,
258 &argv_free
, &argv_data
);
262 strbuf_init(&err
, 0);
264 status
= exec_program_v(wd
, NULL
, &err
, HIDDENMODE
| WAITMODE
, argv
);
266 /* if nothing, terribly wrong happened, show the confirmation */
268 /* strangely enough even success message is on stderr */
269 debug_git_mbox(err
.buf
);
272 argv_free(argv_data
);
278 static BOOL
build_branch_menu(struct git_data
*data
,
279 const struct menu_item
*item
,
285 char *wd
= wd_from_path(data
->name
, NULL
);
287 struct strbuf output
;
288 struct strbuf
**lines
, **it
;
289 strbuf_init(&output
, 0);
291 status
= exec_program(wd
, &output
, NULL
, WAITMODE
,
292 "git", "branch", NULL
);
297 submenu
= start_submenu(data
, item
, platform
);
299 lines
= strbuf_split(&output
, '\n');
300 for (it
= lines
; *it
; it
++) {
301 struct menu_item item
= {
302 MENU_ITEM_CLEANUP
, 0,
308 item
.string
= strdup((*it
)->buf
+ 2);
309 item
.helptext
= strdup((*it
)->buf
+ 2);
310 item
.flags
= '*' == (*it
)->buf
[0] ?
311 MI_CHECKED
| MI_DISABLED
: 0;
312 if (build_item(data
, &item
, submenu
))
313 append_active_menu(&item
);
316 * if the platform failed to create an item
317 * there is no point to try other items
322 end_submenu(platform
, submenu
);
324 /* technically, there is nothing to track for the menu engine */
328 UINT
cheetah_menu_mask(struct git_data
*this_
)
331 char *wd
= wd_from_path(this_
->name
, &is_directory
);
332 UINT selection
= is_directory
? MENU_ITEM_DIR
: MENU_ITEM_FILE
;
334 char *prefix
= get_git_prefix(wd
, &status
);
336 if (status
< 0) /* something went terribly wrong */
337 selection
= MENU_ITEM_LAST
;
339 selection
|= MENU_ITEM_NOREPO
;
341 char head_path
[MAX_PATH
] = "HEAD";
343 sprintf(head_path
, "HEAD:%s%s",
345 this_
->name
+ strlen(wd
) + 1);
347 status
= exec_program(wd
, NULL
, NULL
, WAITMODE
,
348 "git", "rev-parse", "--verify", head_path
, NULL
);
349 if (status
< 0) /* something went terribly wrong */
350 selection
= MENU_ITEM_LAST
;
352 selection
|= MENU_ITEM_REPO
|
354 MENU_ITEM_NOTRACK
: MENU_ITEM_TRACK
);
362 const struct menu_item cheetah_menu
[] = {
363 { MENU_ITEM_ALWAYS
, 0, NULL
, NULL
, build_separator
, NULL
},
365 { MENU_ITEM_REPO
, 0, "Git &Add all files now",
366 "Add all files from this folder now",
367 build_item
, menu_addall
},
368 { MENU_ITEM_REPO
, 0, "Git &Commit Tool",
369 "Launch the GIT commit tool in the local or chosen directory.",
370 build_item
, menu_citool
},
371 { MENU_ITEM_TRACK
, 0, "Git &History",
372 "Show GIT history of the chosen file or directory.",
375 { MENU_ITEM_TRACK
| MENU_ITEM_FILE
, 0, "Git &Blame",
376 "Start a blame viewer on the specified file.",
377 build_item
, menu_blame
},
379 { MENU_ITEM_REPO
, 0, "Git &Gui",
380 "Launch the GIT Gui in the local or chosen directory.",
381 build_item
, menu_gui
},
383 { MENU_ITEM_REPO
, 0, "Git Bra&nch",
385 build_branch_menu
, NULL
},
387 { MENU_ITEM_NOREPO
, 0, "Git I&nit Here",
388 "Initialize GIT repo in the local directory.",
389 build_item
, menu_init
},
390 { MENU_ITEM_NOREPO
| MENU_ITEM_DIR
, 0, "Git &Gui",
391 "Launch the GIT Gui in the local or chosen directory.",
392 build_item
, menu_gui
},
394 { MENU_ITEM_ALWAYS
, 0, "Git Ba&sh",
395 "Start GIT shell in the local or chosen directory",
396 build_item
, menu_bash
},
397 { MENU_ITEM_ALWAYS
, 0, NULL
, NULL
, build_separator
, NULL
},
400 void build_cheetah_menu(struct git_data
*data
, void *platform_data
)
402 reset_platform(platform_data
);
403 build_menu_items(data
, cheetah_menu_mask
,
405 sizeof(cheetah_menu
) / sizeof(cheetah_menu
[0]),