5 #include "menuengine.h"
9 #include "systeminfo.h"
12 #define LONGEST_MENU_ITEM 40
15 * These are the functions for handling the context menu.
18 static STDMETHODIMP
query_context_menu(void *p
, HMENU menu
,
19 UINT index
, UINT first_command
,
20 UINT last_command
, UINT flags
)
22 struct git_menu
*this_menu
= p
;
23 struct git_data
*this_
= this_menu
->git_data
;
25 BOOL bDirSelected
= TRUE
;
27 UINT original_first
= first_command
;
28 char menu_item
[LONGEST_MENU_ITEM
];
32 if (flags
& CMF_DEFAULTONLY
)
33 return MAKE_HRESULT(SEVERITY_SUCCESS
, FACILITY_NULL
, 0);
35 /* figure out the directory */
36 wd
= strdup(this_
->name
);
37 if (!(FILE_ATTRIBUTE_DIRECTORY
& GetFileAttributes(wd
))) {
38 char *c
= strrchr(wd
, '\\');
45 status
= exec_program(wd
, NULL
, NULL
, WAITMODE
,
46 "git", "rev-parse", "--show-cdup", NULL
);
49 /* something really bad happened, could run git */
51 return MAKE_HRESULT(SEVERITY_SUCCESS
, FACILITY_NULL
, 0);
54 * TODO: the following big, ugly code needs to be something like
56 * It's left as is to signify the preview nature of the patch
58 if (status
) { /* this is not a repository */
60 strcpy(menu_item
, "&Git Clone Here");
62 strcpy(menu_item
, "&Git Init Here");
64 strcpy(menu_item
, "&Git");
66 InsertMenu(menu
, index
, MF_SEPARATOR
| MF_BYPOSITION
,
68 InsertMenu(menu
, index
+1, MF_STRING
| MF_BYPOSITION
,
69 first_command
++, menu_item
);
72 * TODO: when the above block is fixed, we'll just have
73 * return MAKE_RESULT(..., build_menu_items());
75 return MAKE_HRESULT(SEVERITY_SUCCESS
, FACILITY_NULL
,
76 first_command
- original_first
);
80 * Perform a couple of transformations, such that a directory
81 * C:\Program Files\Bunch of stuff\in\A dir
83 * /C/Program\ Files/Bunch\ of\ stuff/in/A\ dir
85 * Assumes path is initially a correctly formed Windows-style path.
86 * Returns a new string.
88 static char *convert_directory_format(const char *path
)
95 /* Figure out how much extra space we need to escape spaces */
96 for (i
= 0; i
< MAX_PATH
&& path
[i
] != '\0'; ++i
)
100 converted
= (char *)calloc(size_incr
+ i
+ 1, sizeof(char));
107 for (i
= 0; i
< MAX_PATH
&& path
[i
] != '\0'; ++i
)
126 converted
[1] = converted
[0];
132 static STDMETHODIMP
invoke_command(void *p
,
133 LPCMINVOKECOMMANDINFO info
)
135 struct git_menu
*this_menu
= p
;
136 struct git_data
*this_
= this_menu
->git_data
;
137 int command
= LOWORD(info
->lpVerb
);
139 if (HIWORD(info
->lpVerb
) != 0)
148 if (wd
== NULL
|| strlen(wd
) == 0)
149 wd
= info
->lpDirectory
;
151 dwAttr
= FILE_ATTRIBUTE_DIRECTORY
;
152 fa
= GetFileAttributes(wd
);
154 wd
= info
->lpDirectory
;
156 exec_program(wd
, NULL
, NULL
, NORMALMODE
,
165 static STDMETHODIMP
get_command_string(void *p
, UINT id
,
166 UINT flags
, UINT
*reserved
,
167 LPSTR name
, UINT size
)
170 struct git_menu
*this_menu
= p
;
171 struct git_data
*this_
= this_menu
->git_data
;
177 if (flags
& GCS_HELPTEXT
) {
178 LPCTSTR text
= _T("Launch the GIT Gui in the local or chosen directory.");
179 size_t len
= strlen(text
) + 1;
180 LPWSTR tw
= malloc(len
* sizeof(wchar_t));
181 /* need to convert terminating NULL as well */
182 mbstowcs(tw
, text
, len
);
183 /* use Win32 lstrcpyn to [automatically] avoid buffer overflow */
184 if (flags
& GCS_UNICODE
)
185 lstrcpynW((LPWSTR
)name
, tw
, size
);
187 lstrcpynA(name
, text
, size
);
196 DEFINE_STANDARD_METHODS(git_menu
)
198 struct git_menu_virtual_table git_menu_virtual_table
= {
199 query_interface_git_menu
,