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
);
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
)
45 if (AEPutKeyPtr(&menu_entry
, keyAEName
, typeCString
, item_name
,
46 strlen(item_name
) + 1) != noErr
)
49 goto add_menu_entry_cleanup
;
52 if (AEPutKeyPtr(&menu_entry
, keyContextualMenuCommandID
, typeSInt32
,
54 sizeof(next_active_item
)) != noErr
)
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
)
64 goto add_menu_entry_cleanup
;
67 add_menu_entry_cleanup
:
68 AEDisposeDesc(&menu_entry
);
73 BOOL
build_separator(struct git_data
*me
, const struct menu_item
*item
,
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
,
87 /* not implemented, yet */
91 void end_submenu(void *parent
, void *submenu
)
95 OSStatus
query_context_menu(void *_me
, const AEDescList
*selection
,
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
104 * TODO: add support to handle selection of multiple items
105 * e.g. selection_to_path could be called more often until no
108 if (!selection_to_path(me
->git_data
.name
, MAX_PATH
, selection
))
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
{
123 static void free_platform_argv(void *data
)
125 struct menu_argv_data
*my_data
= data
;
128 free(my_data
->apple_script
);
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
;
139 const char **argv
= NULL
;
140 const char *bash_argv
[] = { "osascript", "-e",
141 "tell application \"Terminal\"", "-e",
142 NULL
, "-e", "end tell", NULL
};
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))
167 *argv_data
= my_data
;
168 *free_argv
= free_platform_argv
;
179 /* this is called by the finder after clicking on some item from us */
180 OSStatus
invoke_command(void *_me
, AEDesc
*selection
,
183 struct plugin_data
*me
= _me
;
185 if (!selection_to_path(path
, MAX_PATH
, selection
))
188 debug_git("invoke_command: %s, id: %i", path
, id
);
189 handle_menu_item(&me
->git_data
, id
);
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 */