As Johannes Schindelin suggested, it verifies that the selected item is
a valid Git repository and adds different menu items accordingly.
This version is for preview purposes only. It implements the suggestion
in a way that the text of the item is context-sensitive, but the action
is always the same.
TODO: think about moving env_for_git() and exec_with_status() to
systeminfo. It does not really belong there, but even less so to menu.
TODO: decide on a structure and actions of added menu items.
---
ext.c | 4 +++
menu.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
2 files changed, 89 insertions(+), 10 deletions(-)
diff --git a/ext.c b/ext.c
index 593d4e4..8579386 100644
--- a/ext.c
+++ b/ext.c
@@ -57,6 +57,10 @@ inline STDMETHODIMP initialize_git_data(struct
git_data *this_,
UINT count;
HRESULT result = S_OK;
+ // store the folder, if provided
+ if (folder)
+ SHGetPathFromIDList(folder, this_->name);
+
if (!data)
return S_OK;
diff --git a/menu.c b/menu.c
index f3e876c..7f034db 100644
--- a/menu.c
+++ b/menu.c
@@ -1,12 +1,13 @@
#include <shlobj.h>
-#include <stdarg.h>
-#include <tchar.h>
#include <stdio.h>
#include "menu.h"
#include "ext.h"
#include "debug.h"
#include "systeminfo.h"
+#define LONGEST_MENU_ITEM 40
+#define MAX_PROCESSING_TIME (60 * 1000)
+
/*
* Modifies a copy of the environment, to include Git in PATH
*/
@@ -58,6 +59,46 @@ static void *env_for_git()
return environment;
}
+static int exec_with_status(char *cmd, const char *wd)
+{
+ STARTUPINFO si = { sizeof(si) };
+ PROCESS_INFORMATION pi;
+ DWORD status = -1;
+
+ si.dwFlags = STARTF_USESHOWWINDOW;
+ si.wShowWindow = SW_HIDE;
+
+ if (CreateProcess(NULL, cmd,
+ NULL, NULL, FALSE, 0,
+ env_for_git(), wd, &si, &pi)) {
+
+ if (WAIT_OBJECT_0 == WaitForSingleObject(pi.hProcess,
+ MAX_PROCESSING_TIME)) {
+
+ if (! GetExitCodeProcess(pi.hProcess, &status)) {
+ debug_git("[ERROR] GetExitCode failed (%d); "
+ "wd: %s; cmd: %s",
+ GetLastError(), wd, cmd);
+ }
+
+ } else {
+ debug_git("[ERROR] process timed out; "
+ "wd: %s; cmd: %s",
+ wd, cmd);
+ }
+
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+
+ } else {
+ debug_git("[ERROR] Could not create git process (%d); "
+ "wd: %s; cmd: %s",
+ GetLastError(), wd, cmd);
+ }
+
+ return status;
+}
+
/*
* These are the functions for handling the context menu.
*/
@@ -67,16 +108,52 @@ static STDMETHODIMP query_context_menu(void *p, HMENU menu,
{
struct git_menu *this_menu = p;
struct git_data *this_ = this_menu->git_data;
+ char *wd;
+ BOOL bDirSelected = TRUE;
+
+ UINT original_first = first_command;
+ char menu_item[LONGEST_MENU_ITEM];
+
+ int status;
if (flags & CMF_DEFAULTONLY)
return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 0);
+ // figure out the directory
+ wd = strdup(this_->name);
+ if (! (FILE_ATTRIBUTE_DIRECTORY & GetFileAttributes(wd))) {
+ char *c = strrchr(wd, '\\');
+ *c = 0;
+ bDirSelected = FALSE;
+ }
+
+ status = exec_with_status ("git.exe rev-parse --show-cdup", wd);
+ free (wd);
+
+ if (-1 == status)
+ return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 0);
+
+ /* TODO: the following big, ugly code needs to be something like
+ build_menu_items()
+ It's left as is to signify the preview nature of the patch
+ */
+ if (0 != status) { // this is not a repository
+ if (bDirSelected)
+ strcpy(menu_item, "&Git Clone Here");
+ else
+ strcpy(menu_item, "&Git Init Here");
+ } else
+ strcpy(menu_item, "&Git");
+
InsertMenu(menu, index, MF_SEPARATOR | MF_BYPOSITION,
- first_command, "");
+ first_command++, "");
InsertMenu(menu, index+1, MF_STRING | MF_BYPOSITION,
- first_command+1, _T("&Git Gui"));
+ first_command++, menu_item);
- return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 2);
+ /* TODO: when the above block is fixed, we'll just have
+ return MAKE_RESULT(..., build_menu_items()); */
+ return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL,
+ first_command - original_first);
}
/*
@@ -147,13 +224,11 @@ static STDMETHODIMP invoke_command(void *p,
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
- TCHAR command[1024];
+ char command[1024];
const char *wd;
DWORD dwAttr, fa;
- wsprintf(command, TEXT("wish.exe \"%s/bin/git-gui\""),
- msys_path());
-
+ sprintf(command, "wish.exe \"%s/bin/git-gui\"", msys_path());
wd = this_->name;
if (wd == NULL || strlen(wd) == 0)
@@ -202,7 +277,7 @@ static STDMETHODIMP get_command_string(void *p, UINT id,
if (flags & GCS_HELPTEXT) {
- LPCTSTR text = _T("Launch the GIT Gui in the local or chosen
directory.");
+ char *text = "Launch the GIT Gui in the local or chosen
directory.";
size_t len = strlen(text) + 1;
LPWSTR tw = malloc(len*sizeof(wchar_t));
// need to convert terminating NULL as well
--
1.5.4.rc0.929.g50e2