X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=src%2FTortoiseShell%2FContextMenu.cpp;h=953a281f8534505ccc79683e01b27bd84bbc7cd2;hb=8bfa8b3c0e2a04e4e298428189027e0b7f38cdd2;hp=a37baf477585786f5c1fea3050309218d8ccc549;hpb=0720fd3abc8e2ed4e95d1265d9e70c1b6a476de4;p=tortoisegit%2FTortoiseGitJp.git diff --git a/src/TortoiseShell/ContextMenu.cpp b/src/TortoiseShell/ContextMenu.cpp index a37baf4..953a281 100644 --- a/src/TortoiseShell/ContextMenu.cpp +++ b/src/TortoiseShell/ContextMenu.cpp @@ -47,8 +47,9 @@ CShellExt::MenuInfo CShellExt::menuInfo[] = // { ShellMenuCheckout, MENUCHECKOUT, IDI_CHECKOUT, IDS_MENUCHECKOUT, IDS_MENUDESCCHECKOUT, // ITEMIS_FOLDER, ITEMIS_INSVN|ITEMIS_FOLDERINSVN, 0, 0, 0, 0, 0, 0 }, -// { ShellMenuUpdate, MENUUPDATE, IDI_UPDATE, IDS_MENUUPDATE, IDS_MENUDESCUPDATE, -// ITEMIS_INSVN, ITEMIS_ADDED, ITEMIS_FOLDERINSVN, 0, 0, 0, 0, 0 }, +// { ShellMenuUpdate, MENUSUBUPDATE, IDI_UPDATE, IDS_MENUUPDATE, IDS_MENUDESCUPDATE, +// ITEMIS_INSVN, 0, ITEMIS_FOLDERINSVN, 0, 0, 0, 0, 0 }, + { ShellMenuCommit, MENUCOMMIT, IDI_COMMIT, IDS_MENUCOMMIT, IDS_MENUDESCCOMMIT, ITEMIS_INSVN, 0, ITEMIS_FOLDERINSVN, 0, 0, 0, 0, 0 }, @@ -67,25 +68,37 @@ CShellExt::MenuInfo CShellExt::menuInfo[] = { ShellMenuLog, MENULOG, IDI_LOG, IDS_MENULOG, IDS_MENUDESCLOG, ITEMIS_INSVN|ITEMIS_ONLYONE, ITEMIS_ADDED, ITEMIS_FOLDER|ITEMIS_FOLDERINSVN|ITEMIS_ONLYONE, ITEMIS_ADDED, ITEMIS_FOLDERINSVN|ITEMIS_ONLYONE, ITEMIS_ADDED, 0, 0 }, + { ShellMenuRefLog, MENUREFLOG, IDI_LOG, IDS_MENUREFLOG, IDS_MENUDESCREFLOG, + ITEMIS_INSVN|ITEMIS_ONLYONE|ITEMIS_EXTENDED, ITEMIS_ADDED, ITEMIS_FOLDER|ITEMIS_FOLDERINSVN|ITEMIS_ONLYONE|ITEMIS_EXTENDED, ITEMIS_ADDED, ITEMIS_FOLDERINSVN|ITEMIS_ONLYONE|ITEMIS_EXTENDED, ITEMIS_ADDED, 0, 0 }, + // { ShellMenuRepoBrowse, MENUREPOBROWSE, IDI_REPOBROWSE, IDS_MENUREPOBROWSE, IDS_MENUDESCREPOBROWSE, // ITEMIS_ONLYONE, 0, ITEMIS_FOLDERINSVN|ITEMIS_ONLYONE, 0, 0, 0, 0, 0 }, { ShellMenuShowChanged, MENUSHOWCHANGED, IDI_SHOWCHANGED, IDS_MENUSHOWCHANGED, IDS_MENUDESCSHOWCHANGED, ITEMIS_INSVN|ITEMIS_ONLYONE, 0, ITEMIS_FOLDER|ITEMIS_FOLDERINSVN|ITEMIS_ONLYONE, 0, 0, 0, 0, 0}, + { ShellMenuRebase, MENUREBASE, IDI_REBASE, IDS_MENUREBASE, IDS_MENUREBASE, + ITEMIS_INSVN|ITEMIS_ONLYONE, 0, ITEMIS_FOLDER|ITEMIS_FOLDERINSVN|ITEMIS_ONLYONE, 0, 0, 0, 0, 0}, + // { ShellMenuRevisionGraph, MENUREVISIONGRAPH, IDI_REVISIONGRAPH, IDS_MENUREVISIONGRAPH, IDS_MENUDESCREVISIONGRAPH, // ITEMIS_INSVN|ITEMIS_ONLYONE, ITEMIS_ADDED, ITEMIS_FOLDER|ITEMIS_FOLDERINSVN|ITEMIS_ONLYONE, ITEMIS_ADDED, 0, 0, 0, 0}, + { ShellMenuStashSave, MENUSTASHSAVE, IDI_COMMIT, IDS_MENUSTASHSAVE, IDS_MENUSTASHSAVE, + ITEMIS_INSVN, 0, ITEMIS_FOLDERINSVN, 0, 0, 0, 0, 0 }, + { ShellMenuStashApply, MENUSTASHAPPLY, IDI_RELOCATE, IDS_MENUSTASHAPPLY, IDS_MENUSTASHAPPLY, + ITEMIS_INSVN, 0, ITEMIS_FOLDERINSVN, 0, 0, 0, 0, 0 }, + { ShellMenuStashList, MENUSTASHAPPLY, IDI_LOG, IDS_MENUSTASHLIST, IDS_MENUSTASHLIST, + ITEMIS_INSVN|ITEMIS_EXTENDED, 0, ITEMIS_FOLDERINSVN|ITEMIS_EXTENDED, 0, 0, 0, 0, 0 }, + + { ShellSeparator, 0, 0, 0, 0, 0, 0, 0, 0}, { ShellMenuConflictEditor, MENUCONFLICTEDITOR, IDI_CONFLICT, IDS_MENUCONFLICT, IDS_MENUDESCCONFLICT, ITEMIS_INSVN|ITEMIS_CONFLICTED, ITEMIS_FOLDER, 0, 0, 0, 0, 0, 0 }, -// { ShellMenuResolve, MENURESOLVE, IDI_RESOLVE, IDS_MENURESOLVE, IDS_MENUDESCRESOLVE, -// ITEMIS_INSVN|ITEMIS_CONFLICTED, 0, ITEMIS_INSVN|ITEMIS_FOLDER, 0, ITEMIS_FOLDERINSVN, 0, 0, 0 }, + { ShellMenuResolve, MENURESOLVE, IDI_RESOLVE, IDS_MENURESOLVE, IDS_MENUDESCRESOLVE, + ITEMIS_INSVN|ITEMIS_CONFLICTED, 0, ITEMIS_INSVN|ITEMIS_FOLDER, 0, ITEMIS_FOLDERINSVN, 0, 0, 0 }, -// { ShellMenuUpdateExt, MENUUPDATEEXT, IDI_UPDATE, IDS_MENUUPDATEEXT, IDS_MENUDESCUPDATEEXT, -// ITEMIS_INSVN, ITEMIS_ADDED, ITEMIS_FOLDERINSVN, ITEMIS_ADDED, 0, 0, 0, 0 }, { ShellMenuRename, MENURENAME, IDI_RENAME, IDS_MENURENAME, IDS_MENUDESCRENAME, ITEMIS_INSVN|ITEMIS_ONLYONE|ITEMIS_INVERSIONEDFOLDER, 0, 0, 0, 0, 0, 0, 0 }, @@ -127,8 +140,8 @@ CShellExt::MenuInfo CShellExt::menuInfo[] = { ShellMenuMerge, MENUMERGE, IDI_MERGE, IDS_MENUMERGE, IDS_MENUDESCMERGE, ITEMIS_INSVN|ITEMIS_ONLYONE, ITEMIS_ADDED, ITEMIS_FOLDER|ITEMIS_FOLDERINSVN|ITEMIS_ONLYONE, 0, 0, 0, 0, 0 }, - { ShellMenuMergeAll, MENUMERGEALL, IDI_MERGE, IDS_MENUMERGEALL, IDS_MENUDESCMERGEALL, - ITEMIS_INSVN|ITEMIS_ONLYONE|ITEMIS_EXTENDED, ITEMIS_ADDED, ITEMIS_FOLDER|ITEMIS_FOLDERINSVN|ITEMIS_ONLYONE|ITEMIS_EXTENDED, 0, 0, 0, 0, 0 }, +// { ShellMenuMergeAll, MENUMERGEALL, IDI_MERGE, IDS_MENUMERGEALL, IDS_MENUDESCMERGEALL, +// ITEMIS_INSVN|ITEMIS_ONLYONE|ITEMIS_EXTENDED, ITEMIS_ADDED, ITEMIS_FOLDER|ITEMIS_FOLDERINSVN|ITEMIS_ONLYONE|ITEMIS_EXTENDED, 0, 0, 0, 0, 0 }, { ShellMenuBranch, MENUCOPY, IDI_COPY, IDS_MENUBRANCH, IDS_MENUDESCCOPY, ITEMIS_INSVN, 0, ITEMIS_FOLDERINSVN, 0, 0, 0, 0, 0 }, @@ -168,6 +181,19 @@ CShellExt::MenuInfo CShellExt::menuInfo[] = { ShellSeparator, 0, 0, 0, 0, 0, 0, 0, 0}, + { ShellMenuSubAdd, MENUSUBADD, IDI_ADD, IDS_MENUSUBADD, IDS_MENUSUBADD, + ITEMIS_INSVN, 0, ITEMIS_FOLDERINSVN, 0, 0, 0, 0, 0 }, + + { ShellMenuUpdateExt, MENUUPDATEEXT, IDI_UPDATE, IDS_MENUUPDATEEXT, IDS_MENUDESCUPDATEEXT, + ITEMIS_INSVN|ITEMIS_FOLDER|ITEMIS_SUBMODULE, 0, 0, 0, 0, 0, 0, 0 }, + + { ShellMenuSubSync, MENUSUBSYNC, IDI_MENUSYNC, IDS_MENUSUBSYNC, IDS_MENUSUBSYNC, + ITEMIS_INSVN|ITEMIS_FOLDER|ITEMIS_SUBMODULE|ITEMIS_EXTENDED, 0, 0, 0, 0, 0, 0, 0 }, + + + + { ShellSeparator, 0, 0, 0, 0, 0, 0, 0, 0}, + // { ShellMenuCherryPick, MENUCHERRYPICK, IDI_CREATEPATCH, IDS_MENUCHERRYPICK, IDS_MENUDESCCREATEPATCH, // ITEMIS_INSVN, ITEMIS_NORMAL, ITEMIS_FOLDERINSVN, 0, 0, 0, 0, 0 }, @@ -175,17 +201,20 @@ CShellExt::MenuInfo CShellExt::menuInfo[] = ITEMIS_INSVN, ITEMIS_NORMAL, ITEMIS_FOLDERINSVN, 0, 0, 0, 0, 0 }, { ShellMenuImportPatch, MENUIMPORTPATCH, IDI_PATCH, IDS_MENUIMPORTPATCH, IDS_MENUDESCCREATEPATCH, - ITEMIS_INSVN, ITEMIS_NORMAL, ITEMIS_FOLDERINSVN, 0, 0, 0, 0, 0 }, + ITEMIS_INSVN, ITEMIS_NORMAL, ITEMIS_FOLDERINSVN, 0, ITEMIS_PATCHFILE, 0, 0, 0 }, { ShellMenuCreatePatch, MENUCREATEPATCH, IDI_CREATEPATCH, IDS_MENUCREATEPATCH, IDS_MENUDESCCREATEPATCH, - ITEMIS_INSVN, ITEMIS_NORMAL, ITEMIS_FOLDERINSVN, 0, 0, 0, 0, 0 }, + ITEMIS_INSVN|ITEMIS_EXTENDED, ITEMIS_NORMAL, ITEMIS_FOLDERINSVN|ITEMIS_EXTENDED, 0, 0, 0, 0, 0 }, { ShellMenuApplyPatch, MENUAPPLYPATCH, IDI_PATCH, IDS_MENUAPPLYPATCH, IDS_MENUDESCAPPLYPATCH, - ITEMIS_INSVN|ITEMIS_FOLDER|ITEMIS_FOLDERINSVN, ITEMIS_ADDED, ITEMIS_ONLYONE|ITEMIS_PATCHFILE, 0, ITEMIS_FOLDERINSVN, ITEMIS_ADDED, 0, 0 }, + ITEMIS_INSVN|ITEMIS_FOLDER|ITEMIS_FOLDERINSVN|ITEMIS_EXTENDED, ITEMIS_ADDED, ITEMIS_ONLYONE|ITEMIS_PATCHFILE, 0, ITEMIS_FOLDERINSVN|ITEMIS_EXTENDED, ITEMIS_ADDED, 0, 0 }, - { ShellMenuProperties, MENUPROPERTIES, IDI_PROPERTIES, IDS_MENUPROPERTIES, IDS_MENUDESCPROPERTIES, - ITEMIS_INSVN, 0, ITEMIS_FOLDERINSVN, 0, 0, 0, 0, 0 }, + { ShellMenuSendMail, MENUSENDMAIL, IDI_MENUSENDMAIL, IDS_MENUSENDMAIL, IDS_MENUDESSENDMAIL, + ITEMIS_PATCHFILE, 0, 0, 0, 0, 0, 0, 0 }, + +// { ShellMenuProperties, MENUPROPERTIES, IDI_PROPERTIES, IDS_MENUPROPERTIES, IDS_MENUDESCPROPERTIES, +// ITEMIS_INSVN, 0, ITEMIS_FOLDERINSVN, 0, 0, 0, 0, 0 }, { ShellSeparator, 0, 0, 0, 0, 0, 0, 0, 0}, // { ShellMenuClipPaste, MENUCLIPPASTE, IDI_CLIPPASTE, IDS_MENUCLIPPASTE, IDS_MENUDESCCLIPPASTE, @@ -344,6 +373,10 @@ STDMETHODIMP CShellExt::Initialize(LPCITEMIDLIST pIDFolder, { if (askedpath.HasAdminDir()) itemStates |= ITEMIS_INSVN; + if (askedpath.HasSubmodules()) + { + itemStates |= ITEMIS_SUBMODULE; + } } if ((status != git_wc_status_unversioned)&&(status != git_wc_status_ignored)&&(status != git_wc_status_none)) itemStates |= ITEMIS_INSVN; @@ -453,6 +486,10 @@ STDMETHODIMP CShellExt::Initialize(LPCITEMIDLIST pIDFolder, { if (strpath.HasAdminDir()) itemStates |= ITEMIS_INSVN; + if (strpath.HasSubmodules()) + { + itemStates |= ITEMIS_SUBMODULE; + } } if ((status != git_wc_status_unversioned)&&(status != git_wc_status_ignored)&&(status != git_wc_status_none)) itemStates |= ITEMIS_INSVN; @@ -583,6 +620,10 @@ STDMETHODIMP CShellExt::Initialize(LPCITEMIDLIST pIDFolder, { itemStatesFolder |= ITEMIS_FOLDERINSVN; } + if (askedpath.HasSubmodules()) + { + itemStatesFolder |= ITEMIS_SUBMODULE; + } if (status == git_wc_status_ignored) itemStatesFolder |= ITEMIS_IGNORED; itemStatesFolder |= ITEMIS_FOLDER; @@ -590,6 +631,7 @@ STDMETHODIMP CShellExt::Initialize(LPCITEMIDLIST pIDFolder, itemStates |= ITEMIS_ONLYONE; if (m_State != FileStateDropHandler) itemStates |= itemStatesFolder; + } if (files_.size() == 2) @@ -656,7 +698,7 @@ STDMETHODIMP CShellExt::Initialize(LPCITEMIDLIST pIDFolder, void CShellExt::InsertGitMenu(BOOL istop, HMENU menu, UINT pos, UINT_PTR id, UINT stringid, UINT icon, UINT idCmdFirst, GitCommands com, UINT uFlags) { - TCHAR menutextbuffer[255] = {0}; + TCHAR menutextbuffer[512] = {0}; TCHAR verbsbuffer[255] = {0}; MAKESTRING(stringid); @@ -667,27 +709,88 @@ void CShellExt::InsertGitMenu(BOOL istop, HMENU menu, UINT pos, UINT_PTR id, UIN _tcscpy_s(menutextbuffer, 255, _T("Git ")); } _tcscat_s(menutextbuffer, 255, stringtablebuffer); - if ((fullver < 0x500)||(fullver == 0x500 && !uFlags)) +#if 1 + // insert branch name into "Git Commit..." entry, so it looks like "Git Commit "master"..." + // so we have an easy and fast way to check the current branch + // (the other alternative is using a separate disabled menu entry, the code is already done but commented out) + if (com == ShellMenuCommit) + { + // get branch name + CTGitPath path(folder_.empty() ? files_.front().c_str() : folder_.c_str()); + CString sProjectRoot; + CString sBranchName; + + if (path.HasAdminDir(&sProjectRoot) && !g_Git.GetCurrentBranchFromFile(sProjectRoot, sBranchName)) + { + if (sBranchName.GetLength() == 40) + { + // if SHA1 only show 4 first bytes + BOOL bIsSha1 = TRUE; + for (int i=0; i<40; i++) + if ( !iswxdigit(sBranchName[i]) ) + { + bIsSha1 = FALSE; + break; + } + if (bIsSha1) + sBranchName = sBranchName.Left(8) + _T("...."); + } + + // sanity check + if (sBranchName.GetLength() > 64) + sBranchName = sBranchName.Left(64) + _T("..."); + + // scan to before "..." + LPTSTR s = menutextbuffer + _tcslen(menutextbuffer)-1; + if (s > menutextbuffer) + { + while (s > menutextbuffer) + { + if (*s != _T('.')) + { + s++; + break; + } + s--; + } + } + else + { + s = menutextbuffer; + } + + // append branch name and end with ... + _tcscpy(s, _T(" -> \"") + sBranchName + _T("\"...")); + } + } +#endif + if ((fullver < 0x500)||(fullver == 0x500 && !(uFlags&~(CMF_RESERVED|CMF_EXPLORE|CMF_EXTENDEDVERBS)))) { + // on win2k, the context menu does not work properly if we use + // icon bitmaps. At least the menu text is empty in the context menu + // for folder backgrounds (seems like a win2k bug). + // the workaround is to use the check/unchecked bitmaps, which are drawn + // with AND raster op, but it's better than nothing at all InsertMenu(menu, pos, MF_BYPOSITION | MF_STRING , id, menutextbuffer); - if (fullver >= 0x500) + if (icon) { - // on win2k, the context menu does not work properly if we use - // icon bitmaps. At least the menu text is empty in the context menu - // for folder backgrounds (seems like a win2k bug). HBITMAP bmp = IconToBitmap(icon); SetMenuItemBitmaps(menu, pos, MF_BYPOSITION, bmp, bmp); } } else { - MENUITEMINFO menuiteminfo = {0}; + MENUITEMINFO menuiteminfo; + SecureZeroMemory(&menuiteminfo, sizeof(menuiteminfo)); menuiteminfo.cbSize = sizeof(menuiteminfo); - menuiteminfo.fMask = MIIM_FTYPE | MIIM_ID | MIIM_BITMAP | MIIM_STRING; + menuiteminfo.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING; menuiteminfo.fType = MFT_STRING; menuiteminfo.dwTypeData = menutextbuffer; if (icon) + { + menuiteminfo.fMask |= MIIM_BITMAP; menuiteminfo.hbmpItem = (fullver >= 0x600) ? IconToBitmapPARGB32(icon) : HBMMENU_CALLBACK; + } menuiteminfo.wID = id; InsertMenuItem(menu, pos, TRUE, &menuiteminfo); } @@ -1084,9 +1187,75 @@ STDMETHODIMP CShellExt::QueryContextMenu(HMENU hMenu, // insert separator at start InsertMenu(hMenu, indexMenu++, MF_SEPARATOR|MF_BYPOSITION, 0, NULL); idCmd++; bool bShowIcons = !!DWORD(CRegStdWORD(_T("Software\\TortoiseGit\\ShowContextMenuIcons"), TRUE)); - // ?? TortoiseSVN had this as (fullver <= 0x0500) this disabled icons in win2k, but icons work fine in win2k - if (fullver < 0x0500) - bShowIcons = false; + // ?? TSV disabled icons for win2k and earlier, but they work for win2k and should work for win95 and up + /*if (fullver <= 0x500) + bShowIcons = false;*/ + +#if 0 + if (itemStates & (ITEMIS_INSVN|ITEMIS_FOLDERINSVN)) + { + // show current branch name (as a "read-only" menu entry) + + CTGitPath path(folder_.empty() ? files_.front().c_str() : folder_.c_str()); + CString sProjectRoot; + CString sBranchName; + + if (path.HasAdminDir(&sProjectRoot) && !g_Git.GetCurrentBranchFromFile(sProjectRoot, sBranchName)) + { + if (sBranchName.GetLength() == 40) + { + // if SHA1 only show 4 first bytes + BOOL bIsSha1 = TRUE; + for (int i=0; i<40; i++) + if ( !iswxdigit(sBranchName[i]) ) + { + bIsSha1 = FALSE; + break; + } + if (bIsSha1) + sBranchName = sBranchName.Left(8) + _T("...."); + } + + sBranchName = _T('"') + sBranchName + _T('"'); + + const int icon = IDI_COPY; + const int pos = indexMenu++; + const int id = idCmd++; + + if ((fullver < 0x500)||(fullver == 0x500 && !(uFlags&~(CMF_RESERVED|CMF_EXPLORE|CMF_EXTENDEDVERBS)))) + { + InsertMenu(hMenu, pos, MF_DISABLED|MF_GRAYED|MF_BYPOSITION|MF_STRING, id, sBranchName); + HBITMAP bmp = IconToBitmap(icon); + SetMenuItemBitmaps(hMenu, pos, MF_BYPOSITION, bmp, bmp); + } + else + { + MENUITEMINFO menuiteminfo; + SecureZeroMemory(&menuiteminfo, sizeof(menuiteminfo)); + menuiteminfo.cbSize = sizeof(menuiteminfo); + menuiteminfo.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING | MIIM_STATE; + menuiteminfo.fState = MFS_DISABLED; + menuiteminfo.fType = MFT_STRING; + menuiteminfo.dwTypeData = (LPWSTR)sBranchName.GetString(); + if (icon) + { + menuiteminfo.fMask |= MIIM_BITMAP; + menuiteminfo.hbmpItem = (fullver >= 0x600) ? IconToBitmapPARGB32(icon) : HBMMENU_CALLBACK; + + if (menuiteminfo.hbmpItem == HBMMENU_CALLBACK) + { + // WM_DRAWITEM uses myIDMap to get icon, we use the same icon as create branch + myIDMap[id - idCmdFirst] = ShellMenuBranch; + myIDMap[id] = ShellMenuBranch; + } + } + menuiteminfo.wID = id; + InsertMenuItem(hMenu, pos, TRUE, &menuiteminfo); + } + } + } +#endif + while (menuInfo[menuIndex].command != ShellMenuLastEntry) { if (menuInfo[menuIndex].command == ShellSeparator) @@ -1167,19 +1336,14 @@ STDMETHODIMP CShellExt::QueryContextMenu(HMENU hMenu, // handle special cases (sub menus) if ((menuInfo[menuIndex].command == ShellMenuIgnoreSub)||(menuInfo[menuIndex].command == ShellMenuUnIgnoreSub)) { - InsertIgnoreSubmenus(idCmd, idCmdFirst, hMenu, subMenu, indexMenu, indexSubMenu, topmenu, bShowIcons); + InsertIgnoreSubmenus(idCmd, idCmdFirst, hMenu, subMenu, indexMenu, indexSubMenu, topmenu, bShowIcons, uFlags); bMenuEntryAdded = true; bMenuEmpty = false; } else { - // the 'get lock' command is special bool bIsTop = ((topmenu & menuInfo[menuIndex].menuID) != 0); - if (menuInfo[menuIndex].command == ShellMenuLock) - { - if ((itemStates & ITEMIS_NEEDSLOCK) && g_ShellCache.IsGetLockTop()) - bIsTop = true; - } + // insert the menu entry InsertGitMenu( bIsTop, bIsTop ? hMenu : subMenu, @@ -1244,19 +1408,26 @@ STDMETHODIMP CShellExt::QueryContextMenu(HMENU hMenu, myIDMap[idCmd] = ShellSubMenu; } HBITMAP bmp = NULL; - if ((fullver < 0x500)||(fullver == 0x500 && !uFlags)) + if ((fullver < 0x500)||(fullver == 0x500 && !(uFlags&~(CMF_RESERVED|CMF_EXPLORE|CMF_EXTENDEDVERBS)))) { - bmp = IconToBitmap(uIcon); - menuiteminfo.fMask = MIIM_STRING | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_DATA; + menuiteminfo.fMask = MIIM_STRING | MIIM_ID | MIIM_SUBMENU | MIIM_DATA; + if (uIcon) + { + menuiteminfo.fMask |= MIIM_CHECKMARKS; + bmp = IconToBitmap(uIcon); + menuiteminfo.hbmpChecked = bmp; + menuiteminfo.hbmpUnchecked = bmp; + } } else { - menuiteminfo.fMask = MIIM_FTYPE | MIIM_ID | MIIM_SUBMENU | MIIM_DATA | MIIM_BITMAP | MIIM_STRING; - if (bShowIcons) + menuiteminfo.fMask = MIIM_FTYPE | MIIM_ID | MIIM_SUBMENU | MIIM_DATA | MIIM_STRING; + if (uIcon) + { + menuiteminfo.fMask |= MIIM_BITMAP; menuiteminfo.hbmpItem = (fullver >= 0x600) ? IconToBitmapPARGB32(uIcon) : HBMMENU_CALLBACK; + } } - menuiteminfo.hbmpChecked = bmp; - menuiteminfo.hbmpUnchecked = bmp; menuiteminfo.hSubMenu = subMenu; menuiteminfo.wID = idCmd++; InsertMenuItem(hMenu, indexMenu++, TRUE, &menuiteminfo); @@ -1331,13 +1502,29 @@ STDMETHODIMP CShellExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi) svnCmd += _T("\""); svnCmd += _T(" /deletepathfile"); break; + case ShellMenuSubSync: + tempfile = WriteFileListToTempFile(); + svnCmd += _T("subsync /pathfile:\""); + svnCmd += tempfile; + svnCmd += _T("\""); + svnCmd += _T(" /deletepathfile"); + if(itemStatesFolder&ITEMIS_SUBMODULE) + { + svnCmd += _T(" /bkpath:"); + svnCmd += folder_; + } + break; case ShellMenuUpdateExt: tempfile = WriteFileListToTempFile(); - svnCmd += _T("update /pathfile:\""); + svnCmd += _T("subupdate /pathfile:\""); svnCmd += tempfile; svnCmd += _T("\""); svnCmd += _T(" /deletepathfile"); - svnCmd += _T(" /rev"); + if(itemStatesFolder&ITEMIS_SUBMODULE) + { + svnCmd += _T(" /bkpath:"); + svnCmd += folder_; + } break; case ShellMenuCommit: tempfile = WriteFileListToTempFile(); @@ -1403,6 +1590,13 @@ STDMETHODIMP CShellExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi) svnCmd += _T("\""); svnCmd += _T(" /deletepathfile"); break; + case ShellMenuSendMail: + tempfile = WriteFileListToTempFile(); + svnCmd += _T("sendmail /pathfile:\""); + svnCmd += tempfile; + svnCmd += _T("\""); + svnCmd += _T(" /deletepathfile"); + break; case ShellMenuResolve: tempfile = WriteFileListToTempFile(); svnCmd += _T("resolve /pathfile:\""); @@ -1461,7 +1655,12 @@ STDMETHODIMP CShellExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi) svnCmd += _T("\""); break; case ShellMenuSettings: - svnCmd += _T("settings"); + svnCmd += _T("settings /path:\""); + if (files_.size() > 0) + svnCmd += files_.front(); + else + svnCmd += folder_; + svnCmd += _T("\""); break; case ShellMenuHelp: svnCmd += _T("help"); @@ -1620,6 +1819,14 @@ STDMETHODIMP CShellExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi) svnCmd += folder_; svnCmd += _T("\""); break; + case ShellMenuRebase: + svnCmd += _T("rebase /path:\""); + if (files_.size() > 0) + svnCmd += files_.front(); + else + svnCmd += folder_; + svnCmd += _T("\""); + break; case ShellMenuShowChanged: if (files_.size() > 1) { @@ -1639,14 +1846,51 @@ STDMETHODIMP CShellExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi) svnCmd += _T("\""); } break; - case ShellMenuRepoBrowse: - svnCmd += _T("repobrowser /path:\""); + case ShellMenuRefLog: + svnCmd += _T("reflog /path:\""); if (files_.size() > 0) svnCmd += files_.front(); else svnCmd += folder_; svnCmd += _T("\""); break; + + case ShellMenuStashSave: + svnCmd += _T("stashsave /path:\""); + if (files_.size() > 0) + svnCmd += files_.front(); + else + svnCmd += folder_; + svnCmd += _T("\""); + break; + + case ShellMenuStashApply: + svnCmd += _T("stashapply /path:\""); + if (files_.size() > 0) + svnCmd += files_.front(); + else + svnCmd += folder_; + svnCmd += _T("\""); + break; + + case ShellMenuStashList: + svnCmd += _T("reflog /path:\""); + if (files_.size() > 0) + svnCmd += files_.front(); + else + svnCmd += folder_; + svnCmd += _T("\" /ref:refs/stash"); + break; + + case ShellMenuSubAdd: + svnCmd += _T("subadd /path:\""); + if (files_.size() > 0) + svnCmd += files_.front(); + else + svnCmd += folder_; + svnCmd += _T("\""); + break; + case ShellMenuBlame: svnCmd += _T("blame /path:\""); if (files_.size() > 0) @@ -1759,28 +2003,6 @@ STDMETHODIMP CShellExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi) svnCmd += folder_; svnCmd += _T("\""); break; - case ShellMenuLock: - tempfile = WriteFileListToTempFile(); - svnCmd += _T("lock /pathfile:\""); - svnCmd += tempfile; - svnCmd += _T("\""); - svnCmd += _T(" /deletepathfile"); - break; - case ShellMenuUnlock: - tempfile = WriteFileListToTempFile(); - svnCmd += _T("unlock /pathfile:\""); - svnCmd += tempfile; - svnCmd += _T("\""); - svnCmd += _T(" /deletepathfile"); - break; - case ShellMenuUnlockForce: - tempfile = WriteFileListToTempFile(); - svnCmd += _T("unlock /pathfile:\""); - svnCmd += tempfile; - svnCmd += _T("\""); - svnCmd += _T(" /deletepathfile"); - svnCmd += _T(" /force"); - break; case ShellMenuProperties: tempfile = WriteFileListToTempFile(); svnCmd += _T("properties /pathfile:\""); @@ -1871,12 +2093,11 @@ STDMETHODIMP CShellExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi) break; case ShellMenuImportPatch: - svnCmd += _T("importpatch /path:\""); - if (files_.size() > 0) - svnCmd += files_.front(); - else - svnCmd += folder_; + tempfile = WriteFileListToTempFile(); + svnCmd += _T("importpatch /pathfile:\""); + svnCmd += tempfile; svnCmd += _T("\""); + svnCmd += _T(" /deletepathfile"); break; case ShellMenuCherryPick: @@ -2027,7 +2248,7 @@ STDMETHODIMP CShellExt::HandleMenuMsg2(UINT uMsg, WPARAM wParam, LPARAM lParam, case WM_MEASUREITEM: { MEASUREITEMSTRUCT* lpmis = (MEASUREITEMSTRUCT*)lParam; - if (lpmis==NULL) + if (lpmis==NULL||lpmis->CtlType!=ODT_MENU) break; lpmis->itemWidth += 2; if (lpmis->itemHeight < 16) @@ -2149,18 +2370,6 @@ LPCTSTR CShellExt::GetMenuTextFromResource(int id) resource = MAKEINTRESOURCE(menuInfo[menuIndex].iconID); switch (id) { - case ShellMenuLock: - // menu lock is special because it can be set to the top - // with a separate option in the registry - space = ((layout & MENULOCK) || ((itemStates & ITEMIS_NEEDSLOCK) && g_ShellCache.IsGetLockTop())) ? 0 : 6; - if ((layout & MENULOCK) || ((itemStates & ITEMIS_NEEDSLOCK) && g_ShellCache.IsGetLockTop())) - { - _tcscpy_s(textbuf, 255, _T("Git ")); - _tcscat_s(textbuf, 255, stringtablebuffer); - _tcscpy_s(stringtablebuffer, 255, textbuf); - } - break; - // the sub menu entries are special because they're *always* on the top level menu case ShellSubMenuMultiple: case ShellSubMenuLink: case ShellSubMenuFolder: @@ -2211,7 +2420,7 @@ bool CShellExt::IsIllegalFolder(std::wstring folder, int * cslidarray) return false; } -void CShellExt::InsertIgnoreSubmenus(UINT &idCmd, UINT idCmdFirst, HMENU hMenu, HMENU subMenu, UINT &indexMenu, int &indexSubMenu, unsigned __int64 topmenu, bool bShowIcons) +void CShellExt::InsertIgnoreSubmenus(UINT &idCmd, UINT idCmdFirst, HMENU hMenu, HMENU subMenu, UINT &indexMenu, int &indexSubMenu, unsigned __int64 topmenu, bool bShowIcons, UINT uFlags) { HMENU ignoresubmenu = NULL; int indexignoresub = 0; @@ -2331,13 +2540,27 @@ void CShellExt::InsertIgnoreSubmenus(UINT &idCmd, UINT idCmdFirst, HMENU hMenu, MENUITEMINFO menuiteminfo; SecureZeroMemory(&menuiteminfo, sizeof(menuiteminfo)); menuiteminfo.cbSize = sizeof(menuiteminfo); - menuiteminfo.fMask = MIIM_FTYPE | MIIM_ID | MIIM_SUBMENU | MIIM_DATA | MIIM_BITMAP | MIIM_STRING; + if (fullver < 0x500 || (fullver == 0x500 && !(uFlags&~(CMF_RESERVED|CMF_EXPLORE|CMF_EXTENDEDVERBS)))) + { + menuiteminfo.fMask = MIIM_STRING | MIIM_ID | MIIM_SUBMENU | MIIM_DATA; + if (icon) + { + HBITMAP bmp = IconToBitmap(icon); + menuiteminfo.fMask |= MIIM_CHECKMARKS; + menuiteminfo.hbmpChecked = bmp; + menuiteminfo.hbmpUnchecked = bmp; + } + } + else + { + menuiteminfo.fMask = MIIM_FTYPE | MIIM_ID | MIIM_SUBMENU | MIIM_DATA | MIIM_STRING; + if (icon) + { + menuiteminfo.fMask |= MIIM_BITMAP; + menuiteminfo.hbmpItem = (fullver >= 0x600) ? IconToBitmapPARGB32(icon) : HBMMENU_CALLBACK; + } + } menuiteminfo.fType = MFT_STRING; - HBITMAP bmp = (fullver >= 0x600) ? IconToBitmapPARGB32(icon) : IconToBitmap(icon); - if (icon) - menuiteminfo.hbmpItem = (fullver >= 0x600) ? bmp : HBMMENU_CALLBACK; - menuiteminfo.hbmpChecked = bmp; - menuiteminfo.hbmpUnchecked = bmp; menuiteminfo.hSubMenu = ignoresubmenu; menuiteminfo.wID = idCmd; SecureZeroMemory(stringtablebuffer, sizeof(stringtablebuffer));