finder: don't do own item-id calcluation
[git-cheetah/kirill.git] / finder / menu.c
blobbddf26d340d7d090874c3ac69e1f290cde313ad2
1 /* menu.c
3 * Implementation of a finder menu plugin for git-cheetah
5 * This implements the cheetah interface to create menu entries.
7 * Copyright (C) Heiko Voigt, 2009
9 * inspired by an example from Brent Simmons
10 * brent@ranchero.com, http://macte.ch/kmyXM
15 /* implements platform dependent functions declared by cheetah */
16 #include "../common/git-compat-util.h"
17 #include "../common/strbuf.h"
18 #include "../common/exec.h"
19 #include "../common/menuengine.h"
20 #include "../common/cheetahmenu.h"
21 #include "../common/debug.h"
22 #include "plugin.h"
23 #include "util.h"
24 #include "menu.h"
26 BOOL build_item(struct git_data *me, const struct menu_item *item,
27 void *platform)
29 struct osx_menu_data *osx_data = platform;
30 AERecord menu_entry = { typeNull, NULL };
31 BOOL status = TRUE;
32 char *item_name = strdup(item->string);
33 char shortcut_key;
35 if (!platform)
36 return TRUE;
38 shortcut_key = parse_and_remove_shortcuts(item_name);
40 debug_git("Adding entry: %s", item_name);
42 if (AECreateList(NULL, 0, true, &menu_entry) != noErr)
43 return FALSE;
45 if (AEPutKeyPtr(&menu_entry, keyAEName, typeCString, item_name,
46 strlen(item_name) + 1) != noErr)
48 status = FALSE;
49 goto add_menu_entry_cleanup;
52 if (AEPutKeyPtr(&menu_entry, keyContextualMenuCommandID, typeSInt32,
53 &next_active_item,
54 sizeof(next_active_item)) != noErr)
56 status = FALSE;
57 goto add_menu_entry_cleanup;
60 /* insert menu item at the end of the menu */
61 if (AEPutDesc(osx_data->menu, 0, &menu_entry) != noErr)
63 status = FALSE;
64 goto add_menu_entry_cleanup;
67 add_menu_entry_cleanup:
68 AEDisposeDesc(&menu_entry);
69 free(item_name);
70 return status;
73 BOOL build_separator(struct git_data *me, const struct menu_item *item,
74 void *platform)
76 return TRUE;
79 /* osx does not need to reset anything */
80 void reset_platform(void *platform)
84 void *start_submenu(struct git_data *me, const struct menu_item *item,
85 void *platform)
87 /* not implemented, yet */
88 return NULL;
91 void end_submenu(void *parent, void *submenu)
95 OSStatus query_context_menu(void *_me, const AEDescList *selection,
96 AEDescList *menu)
98 struct plugin_data *me = _me;
99 struct osx_menu_data osx_data = { menu, selection, noErr };
101 /* currently this fails when multiple files/directories are
102 * selected
104 * TODO: add support to handle selection of multiple items
105 * e.g. selection_to_path could be called more often until no
106 * item is left
108 if (!selection_to_path(me->git_data.name, MAX_PATH, selection))
109 return noErr;
111 debug_git("Selected: %s", me->git_data.name);
113 build_cheetah_menu(&me->git_data, &osx_data);
115 return osx_data.status;
118 struct menu_argv_data {
119 char *apple_script;
120 const char **argv;
123 static void free_platform_argv(void *data)
125 struct menu_argv_data *my_data = data;
127 free(my_data->argv);
128 free(my_data->apple_script);
129 free(my_data);
132 const char **menu_get_platform_argv(menu_commands cmd, const void *data,
133 free_func_t *free_argv, void **argv_data)
135 struct menu_argv_data *my_data;
136 int script_len;
137 const char *wd;
138 char *apple_script;
139 const char **argv = NULL;
140 const char *bash_argv[] = { "osascript", "-e",
141 "tell application \"Terminal\"", "-e",
142 NULL, "-e", "end tell", NULL };
144 *argv_data = NULL;
145 *free_argv = NULL;
147 switch(cmd)
149 case MENU_BASH:
150 wd = (const char *) data;
152 my_data = xmalloc(sizeof(struct menu_argv_data));
153 apple_script = xmalloc((MAX_PATH+32) * sizeof(char));
154 argv = xmalloc(sizeof(bash_argv));
156 bash_argv[4] = apple_script;
157 my_data->apple_script = apple_script;
158 my_data->argv = argv;
160 memcpy(argv, bash_argv, sizeof(bash_argv));
162 script_len = snprintf(apple_script, MAX_PATH+32,
163 "do script \"cd %s\"", wd);
164 if (script_len >= (MAX_PATH+32))
165 argv = NULL;
167 *argv_data = my_data;
168 *free_argv = free_platform_argv;
170 break;
172 default:
173 return NULL;
176 return argv;
179 /* this is called by the finder after clicking on some item from us */
180 OSStatus invoke_command(void *_me, AEDesc *selection,
181 SInt32 id)
183 struct plugin_data *me = _me;
184 char path[MAX_PATH];
185 if (!selection_to_path(path, MAX_PATH, selection))
186 return noErr;
188 debug_git("invoke_command: %s, id: %i", path, id);
189 handle_menu_item(&me->git_data, id);
191 return noErr;
194 /* this is called after display of the menu to give the plugin a chance
195 * to cleanup anything needed during display phase
197 void cleanup_context_menu(void *_me) {
198 /* we do not need to cleanup anything */