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
, 'cmcd', typeSInt32
, &osx_data
->item_id
,
61 sizeof(osx_data
->item_id
)) != noErr
)
64 goto add_menu_entry_cleanup
;
67 /* insert menu item at the end of the menu */
68 if (AEPutDesc(osx_data
->menu
, 0, &menu_entry
) != noErr
)
71 goto add_menu_entry_cleanup
;
74 /* this needs to be uniqe for each item */
77 add_menu_entry_cleanup
:
78 AEDisposeDesc(&menu_entry
);
83 BOOL
build_separator(struct git_data
*me
, const struct menu_item
*item
,
86 struct osx_menu_data
*osx_data
= platform
;
91 /* osx does not need to reset anything */
92 void reset_platform(void *platform
)
96 void *start_submenu(struct git_data
*me
, const struct menu_item
*item
,
99 /* not implemented, yet */
103 void end_submenu(void *parent
, void *submenu
)
107 OSStatus
query_context_menu(void *_me
, const AEDescList
*selection
,
110 struct plugin_data
*me
= _me
;
111 struct osx_menu_data osx_data
= { menu
, selection
, noErr
, 0 };
113 /* currently this fails when multiple files/directories are
116 * TODO: add support to handle selection of multiple items
117 * e.g. selection_to_path could be called more often until no
120 if (!selection_to_path(me
->git_data
.name
, MAX_PATH
, selection
))
123 debug_git("Selected: %s", me
->git_data
.name
);
125 build_cheetah_menu(&me
->git_data
, &osx_data
);
127 return osx_data
.status
;
130 struct menu_argv_data
{
135 static void free_platform_argv(void *data
)
137 struct menu_argv_data
*my_data
= data
;
140 free(my_data
->apple_script
);
144 const char **menu_get_platform_argv(menu_commands cmd
, const void *data
,
145 free_func_t
*free_argv
, void **argv_data
)
147 struct menu_argv_data
*my_data
;
151 const char **argv
= NULL
;
152 const char *bash_argv
[] = { "osascript", "-e",
153 "tell application \"Terminal\"", "-e",
154 NULL
, "-e", "end tell", NULL
};
162 wd
= (const char *) data
;
164 my_data
= xmalloc(sizeof(struct menu_argv_data
));
165 apple_script
= xmalloc((MAX_PATH
+32) * sizeof(char));
166 argv
= xmalloc(sizeof(bash_argv
));
168 bash_argv
[4] = apple_script
;
169 my_data
->apple_script
= apple_script
;
170 my_data
->argv
= argv
;
172 memcpy(argv
, bash_argv
, sizeof(bash_argv
));
174 script_len
= snprintf(apple_script
, MAX_PATH
+32,
175 "do script \"cd %s\"", wd
);
176 if (script_len
>= (MAX_PATH
+32))
179 *argv_data
= my_data
;
180 *free_argv
= free_platform_argv
;
191 /* this is called by the finder after clicking on some item from us */
192 OSStatus
invoke_command(void *_me
, AEDesc
*selection
,
195 struct plugin_data
*me
= _me
;
197 if (!selection_to_path(path
, MAX_PATH
, selection
))
200 debug_git("invoke_command: %s, id: %i", path
, id
);
201 handle_menu_item(&me
->git_data
, id
);
206 /* this is called after display of the menu to give the plugin a chance
207 * to cleanup anything needed during display phase
209 void cleanup_context_menu(void *_me
) {
210 /* we do not need to cleanup anything */