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"
26 BOOL
build_item(struct git_data
*me
, const struct menu_item
*item
,
29 struct osx_menu_data
*osx_data
= platform
;
30 AERecord menu_entry
= { typeNull
, NULL
};
32 char *item_name
= strdup(item
->string
);
34 static int not_shown_offset
= 0;
41 if (not_shown_offset
) {
42 osx_data
->item_id
+= not_shown_offset
;
46 shortcut_key
= parse_and_remove_shortcuts(item_name
);
48 debug_git("Adding entry: %s", item_name
);
50 if (AECreateList(NULL
, 0, true, &menu_entry
) != noErr
)
53 if (AEPutKeyPtr(&menu_entry
, keyAEName
, typeCString
, item_name
,
54 strlen(item_name
) + 1) != noErr
)
57 goto add_menu_entry_cleanup
;
60 if (AEPutKeyPtr(&menu_entry
, keyContextualMenuCommandID
, typeSInt32
,
62 sizeof(osx_data
->item_id
)) != noErr
)
65 goto add_menu_entry_cleanup
;
68 /* insert menu item at the end of the menu */
69 if (AEPutDesc(osx_data
->menu
, 0, &menu_entry
) != noErr
)
72 goto add_menu_entry_cleanup
;
75 /* this needs to be uniqe for each item */
78 add_menu_entry_cleanup
:
79 AEDisposeDesc(&menu_entry
);
84 BOOL
build_separator(struct git_data
*me
, const struct menu_item
*item
,
87 struct osx_menu_data
*osx_data
= platform
;
92 /* osx does not need to reset anything */
93 void reset_platform(void *platform
)
97 void *start_submenu(struct git_data
*me
, const struct menu_item
*item
,
100 /* not implemented, yet */
104 void end_submenu(void *parent
, void *submenu
)
108 OSStatus
query_context_menu(void *_me
, const AEDescList
*selection
,
111 struct plugin_data
*me
= _me
;
112 struct osx_menu_data osx_data
= { menu
, selection
, noErr
, 0 };
114 /* currently this fails when multiple files/directories are
117 * TODO: add support to handle selection of multiple items
118 * e.g. selection_to_path could be called more often until no
121 if (!selection_to_path(me
->git_data
.name
, MAX_PATH
, selection
))
124 debug_git("Selected: %s", me
->git_data
.name
);
126 build_cheetah_menu(&me
->git_data
, &osx_data
);
128 return osx_data
.status
;
131 struct menu_argv_data
{
136 static void free_platform_argv(void *data
)
138 struct menu_argv_data
*my_data
= data
;
141 free(my_data
->apple_script
);
145 const char **menu_get_platform_argv(menu_commands cmd
, const void *data
,
146 free_func_t
*free_argv
, void **argv_data
)
148 struct menu_argv_data
*my_data
;
152 const char **argv
= NULL
;
153 const char *bash_argv
[] = { "osascript", "-e",
154 "tell application \"Terminal\"", "-e",
155 NULL
, "-e", "end tell", NULL
};
163 wd
= (const char *) data
;
165 my_data
= xmalloc(sizeof(struct menu_argv_data
));
166 apple_script
= xmalloc((MAX_PATH
+32) * sizeof(char));
167 argv
= xmalloc(sizeof(bash_argv
));
169 bash_argv
[4] = apple_script
;
170 my_data
->apple_script
= apple_script
;
171 my_data
->argv
= argv
;
173 memcpy(argv
, bash_argv
, sizeof(bash_argv
));
175 script_len
= snprintf(apple_script
, MAX_PATH
+32,
176 "do script \"cd %s\"", wd
);
177 if (script_len
>= (MAX_PATH
+32))
180 *argv_data
= my_data
;
181 *free_argv
= free_platform_argv
;
192 /* this is called by the finder after clicking on some item from us */
193 OSStatus
invoke_command(void *_me
, AEDesc
*selection
,
196 struct plugin_data
*me
= _me
;
198 if (!selection_to_path(path
, MAX_PATH
, selection
))
201 debug_git("invoke_command: %s, id: %i", path
, id
);
202 handle_menu_item(&me
->git_data
, id
);
207 /* this is called after display of the menu to give the plugin a chance
208 * to cleanup anything needed during display phase
210 void cleanup_context_menu(void *_me
) {
211 /* we do not need to cleanup anything */