Do not modify "our" environment, because it's Explorer's one
[git-cheetah/kirill.git] / menu.c
blob43b5061b7b8c986de80712b22193316631fd18de
1 #include <shlobj.h>
2 #include <stdarg.h>
3 #include <tchar.h>
4 #include <stdio.h>
5 #include "menu.h"
6 #include "ext.h"
7 #include "debug.h"
8 #include "systeminfo.h"
9 #include "exec.h"
12 * These are the functions for handling the context menu.
15 static STDMETHODIMP query_context_menu(void *p, HMENU menu,
16 UINT index, UINT first_command,
17 UINT last_command, UINT flags)
19 struct git_menu *this_menu = p;
20 struct git_data *this_ = this_menu->git_data;
22 if (flags & CMF_DEFAULTONLY)
23 return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 0);
25 InsertMenu(menu, index, MF_SEPARATOR | MF_BYPOSITION,
26 first_command, "");
27 InsertMenu(menu, index+1, MF_STRING | MF_BYPOSITION,
28 first_command+1, _T("&Git Gui"));
30 return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 2);
34 * Perform a couple of transformations, such that a directory
35 * C:\Program Files\Bunch of stuff\in\A dir
36 * becomes
37 * /C/Program\ Files/Bunch\ of\ stuff/in/A\ dir
39 * Assumes path is initially a correctly formed Windows-style path.
40 * Returns a new string.
42 static char *convert_directory_format(const char *path)
44 int i;
45 int size_incr = 0;
46 char *converted;
47 char *dst;
49 /* Figure out how much extra space we need to escape spaces */
50 for (i = 0; i < MAX_PATH && path[i] != '\0'; ++i)
51 if (path[i] == ' ')
52 size_incr++;
54 converted = (char *)calloc(size_incr + i + 1, sizeof(char));
55 dst = converted;
57 /* Transform:
58 * " " -> "\ "
59 * "\" -> "/"
61 for (i = 0; i < MAX_PATH && path[i] != '\0'; ++i)
63 switch (path[i])
65 case ' ':
66 *(dst++) = '\\';
67 *(dst++) = ' ';
68 break;
69 case '\\':
70 *(dst++) = '/';
71 break;
72 default:
73 *(dst++) = path[i];
74 break;
77 *dst = '\0';
79 /* X: -> /X */
80 converted[1] = converted[0];
81 converted[0] = '/';
83 return converted;
86 static STDMETHODIMP invoke_command(void *p,
87 LPCMINVOKECOMMANDINFO info)
89 struct git_menu *this_menu = p;
90 struct git_data *this_ = this_menu->git_data;
91 int command = LOWORD(info->lpVerb);
93 if (HIWORD(info->lpVerb) != 0)
94 return E_INVALIDARG;
96 if (command == 1)
98 TCHAR * msysPath = msys_path();
100 if (msysPath)
102 TCHAR command[1024];
103 const char *wd;
104 DWORD dwAttr, fa;
106 wsprintf(command, TEXT("\"%s\\bin\\git.exe\" gui"),
107 msysPath);
110 wd = this_->name;
111 if (wd == NULL || strlen(wd) == 0)
112 wd = info->lpDirectory;
114 dwAttr = FILE_ATTRIBUTE_DIRECTORY;
115 fa = GetFileAttributes(wd);
116 if (! (fa & dwAttr))
117 wd = info->lpDirectory;
119 exec_gui(command, wd);
121 else
122 debug_git("[ERROR] %s/%s:%d Could not find msysPath",
123 __FILE__, __FUNCTION__, __LINE__);
125 return S_OK;
128 return E_INVALIDARG;
131 static STDMETHODIMP get_command_string(void *p, UINT id,
132 UINT flags, UINT *reserved,
133 LPSTR name, UINT size)
136 struct git_menu *this_menu = p;
137 struct git_data *this_ = this_menu->git_data;
139 if (id != 1)
140 return E_INVALIDARG;
143 if (flags & GCS_HELPTEXT) {
144 LPCTSTR text = _T("Launch the GIT Gui in the local or chosen directory.");
145 size_t len = strlen(text) + 1;
146 LPWSTR tw = malloc(len * sizeof(wchar_t));
147 /* need to convert terminating NULL as well */
148 mbstowcs(tw, text, len);
149 /* use Win32 lstrcpyn to [automatically] avoid buffer overflow */
150 if (flags & GCS_UNICODE)
151 lstrcpynW((LPWSTR)name, tw, size);
152 else
153 lstrcpynA(name, text, size);
154 free(tw);
155 return S_OK;
159 return E_INVALIDARG;
162 DEFINE_STANDARD_METHODS(git_menu)
164 struct git_menu_virtual_table git_menu_virtual_table = {
165 query_interface_git_menu,
166 add_ref_git_menu,
167 release_git_menu,
168 query_context_menu,
169 invoke_command,
170 get_command_string