OSDN Git Service

Add Resolve to explore context menu
[tortoisegit/TortoiseGitJp.git] / src / TortoiseShell / ContextMenu.cpp
index c85e65c..5f819b6 100644 (file)
@@ -73,6 +73,9 @@ CShellExt::MenuInfo CShellExt::menuInfo[] =
        { ShellMenuShowChanged,                                 MENUSHOWCHANGED,        IDI_SHOWCHANGED,                IDS_MENUSHOWCHANGED,            IDS_MENUDESCSHOWCHANGED,\r
        ITEMIS_INSVN|ITEMIS_ONLYONE, 0, ITEMIS_FOLDER|ITEMIS_FOLDERINSVN|ITEMIS_ONLYONE, 0, 0, 0, 0, 0},\r
 \r
+       { ShellMenuRebase,                                          MENUREBASE,                 IDI_SHOWCHANGED,                IDS_MENUREBASE,                         IDS_MENUREBASE,\r
+       ITEMIS_INSVN|ITEMIS_ONLYONE, 0, ITEMIS_FOLDER|ITEMIS_FOLDERINSVN|ITEMIS_ONLYONE, 0, 0, 0, 0, 0},\r
+\r
 //     { ShellMenuRevisionGraph,                               MENUREVISIONGRAPH,      IDI_REVISIONGRAPH,              IDS_MENUREVISIONGRAPH,          IDS_MENUDESCREVISIONGRAPH,\r
 //     ITEMIS_INSVN|ITEMIS_ONLYONE, ITEMIS_ADDED, ITEMIS_FOLDER|ITEMIS_FOLDERINSVN|ITEMIS_ONLYONE, ITEMIS_ADDED, 0, 0, 0, 0},\r
 \r
@@ -81,8 +84,8 @@ CShellExt::MenuInfo CShellExt::menuInfo[] =
        { ShellMenuConflictEditor,                              MENUCONFLICTEDITOR,     IDI_CONFLICT,                   IDS_MENUCONFLICT,                       IDS_MENUDESCCONFLICT,\r
        ITEMIS_INSVN|ITEMIS_CONFLICTED, ITEMIS_FOLDER, 0, 0, 0, 0, 0, 0 },\r
 \r
-//     { ShellMenuResolve,                                             MENURESOLVE,            IDI_RESOLVE,                    IDS_MENURESOLVE,                        IDS_MENUDESCRESOLVE,\r
-//     ITEMIS_INSVN|ITEMIS_CONFLICTED, 0, ITEMIS_INSVN|ITEMIS_FOLDER, 0, ITEMIS_FOLDERINSVN, 0, 0, 0 },\r
+       { ShellMenuResolve,                                             MENURESOLVE,            IDI_RESOLVE,                    IDS_MENURESOLVE,                        IDS_MENUDESCRESOLVE,\r
+       ITEMIS_INSVN|ITEMIS_CONFLICTED, 0, ITEMIS_INSVN|ITEMIS_FOLDER, 0, ITEMIS_FOLDERINSVN, 0, 0, 0 },\r
 \r
 //     { ShellMenuUpdateExt,                                   MENUUPDATEEXT,          IDI_UPDATE,                             IDS_MENUUPDATEEXT,                      IDS_MENUDESCUPDATEEXT,\r
 //     ITEMIS_INSVN, ITEMIS_ADDED, ITEMIS_FOLDERINSVN, ITEMIS_ADDED, 0, 0, 0, 0 },\r
@@ -156,7 +159,9 @@ CShellExt::MenuInfo CShellExt::menuInfo[] =
 //     ITEMIS_FOLDER, ITEMIS_INSVN, 0, 0, 0, 0, 0, 0 },\r
 \r
        { ShellMenuBlame,                                               MENUBLAME,                      IDI_BLAME,                              IDS_MENUBLAME,                          IDS_MENUDESCBLAME,\r
-       ITEMIS_INSVN|ITEMIS_ONLYONE, ITEMIS_FOLDER|ITEMIS_ADDED, 0, 0, 0, 0, 0, 0 },\r
+       ITEMIS_NORMAL|ITEMIS_ONLYONE, ITEMIS_FOLDER|ITEMIS_ADDED, 0, 0, 0, 0, 0, 0 },\r
+       // TODO: original code is ITEMIS_INSVN|ITEMIS_ONLYONE, makes sense to only allow blaming of versioned files\r
+       //       why was this changed, is this related to GitStatus?\r
 \r
        { ShellMenuIgnoreSub,                                   MENUIGNORE,                     IDI_IGNORE,                             IDS_MENUIGNORE,                         IDS_MENUDESCIGNORE,\r
        ITEMIS_INVERSIONEDFOLDER, ITEMIS_IGNORED|ITEMIS_INSVN, 0, 0, 0, 0, 0, 0 },\r
@@ -308,12 +313,12 @@ STDMETHODIMP CShellExt::Initialize(LPCITEMIDLIST pIDFolder,
                                                                        fetchedstatus = status;\r
                                                                        //if ((stat.status->entry)&&(stat.status->entry->lock_token))\r
                                                                        //      itemStates |= (stat.status->entry->lock_token[0] != 0) ? ITEMIS_LOCKED : 0;\r
-                                                                       //if ((stat.status->entry)&&(stat.status->entry->kind == git_node_dir))\r
-                                                                       //{\r
-                                                                       //      itemStates |= ITEMIS_FOLDER;\r
-                                                                       //      if ((status != git_wc_status_unversioned)&&(status != git_wc_status_ignored)&&(status != git_wc_status_none))\r
-                                                                       //              itemStates |= ITEMIS_FOLDERINGit;\r
-                                                                       //}\r
+                                                                       if ( askedpath.IsDirectory() )//if ((stat.status->entry)&&(stat.status->entry->kind == git_node_dir))\r
+                                                                       {\r
+                                                                               itemStates |= ITEMIS_FOLDER;\r
+                                                                               if ((status != git_wc_status_unversioned)&&(status != git_wc_status_ignored)&&(status != git_wc_status_none))\r
+                                                                                       itemStates |= ITEMIS_FOLDERINSVN;\r
+                                                                       }\r
                                                                        //if ((stat.status->entry)&&(stat.status->entry->present_props))\r
                                                                        //{\r
                                                                        //      if (strstr(stat.status->entry->present_props, "svn:needs-lock"))\r
@@ -335,6 +340,14 @@ STDMETHODIMP CShellExt::Initialize(LPCITEMIDLIST pIDFolder,
                                                        {\r
                                                                ATLTRACE2(_T("Exception in GitStatus::GetStatus()\n"));\r
                                                        }\r
+\r
+                                                       // TODO: should we really assume any sub-directory to be versioned\r
+                                                       //       or only if it contains versioned files\r
+                                                       if ( askedpath.IsDirectory() )\r
+                                                       {\r
+                                                               if (askedpath.HasAdminDir())\r
+                                                                       itemStates |= ITEMIS_INSVN;\r
+                                                       }\r
                                                        if ((status != git_wc_status_unversioned)&&(status != git_wc_status_ignored)&&(status != git_wc_status_none))\r
                                                                itemStates |= ITEMIS_INSVN;\r
                                                        if (status == git_wc_status_ignored)\r
@@ -401,14 +414,15 @@ STDMETHODIMP CShellExt::Initialize(LPCITEMIDLIST pIDFolder,
                                                                                fetchedstatus = status;\r
                                                                                //if ((stat.status->entry)&&(stat.status->entry->lock_token))\r
                                                                                //      itemStates |= (stat.status->entry->lock_token[0] != 0) ? ITEMIS_LOCKED : 0;\r
-                                                                               //if ((stat.status->entry)&&(stat.status->entry->kind == git_node_dir))\r
-                                                                               //{\r
-                                                                               //      itemStates |= ITEMIS_FOLDER;\r
-                                                                               //      if ((status != git_wc_status_unversioned)&&(status != git_wc_status_ignored)&&(status != git_wc_status_none))\r
-                                                                               //              itemStates |= ITEMIS_FOLDERINGit;\r
-                                                                               //}\r
-                                                                               //if ((stat.status->entry)&&(stat.status->entry->conflict_wrk))\r
-                                                                               //      itemStates |= ITEMIS_CONFLICTED;\r
+                                                                               if ( strpath.IsDirectory() )//if ((stat.status->entry)&&(stat.status->entry->kind == git_node_dir))\r
+                                                                               {\r
+                                                                                       itemStates |= ITEMIS_FOLDER;\r
+                                                                                       if ((status != git_wc_status_unversioned)&&(status != git_wc_status_ignored)&&(status != git_wc_status_none))\r
+                                                                                               itemStates |= ITEMIS_FOLDERINSVN;\r
+                                                                               }\r
+                                                                               // TODO: do we need to check that it's not a dir? does conflict options makes sense for dir in git?\r
+                                                                               if (status == git_wc_status_conflicted)//if ((stat.status->entry)&&(stat.status->entry->conflict_wrk))\r
+                                                                                       itemStates |= ITEMIS_CONFLICTED;\r
                                                                                //if ((stat.status->entry)&&(stat.status->entry->present_props))\r
                                                                                //{\r
                                                                                //      if (strstr(stat.status->entry->present_props, "svn:needs-lock"))\r
@@ -435,6 +449,14 @@ STDMETHODIMP CShellExt::Initialize(LPCITEMIDLIST pIDFolder,
                                                                        ATLTRACE2(_T("Exception in GitStatus::GetStatus()\n"));\r
                                                                }\r
                                                        }\r
+\r
+                                                       // TODO: should we really assume any sub-directory to be versioned\r
+                                                       //       or only if it contains versioned files\r
+                                                       if ( strpath.IsDirectory() )\r
+                                                       {\r
+                                                               if (strpath.HasAdminDir())\r
+                                                                       itemStates |= ITEMIS_INSVN;\r
+                                                       }\r
                                                        if ((status != git_wc_status_unversioned)&&(status != git_wc_status_ignored)&&(status != git_wc_status_none))\r
                                                                itemStates |= ITEMIS_INSVN;\r
                                                        if (status == git_wc_status_ignored)\r
@@ -468,9 +490,8 @@ STDMETHODIMP CShellExt::Initialize(LPCITEMIDLIST pIDFolder,
                                        }\r
                                } // for (int i = 0; i < count; ++i)\r
                                ItemIDList child (GetPIDLItem (cida, 0), &parent);\r
-// ? was this disabled because the /wc option does not work safely with Git? or because the code below didn't compile before?\r
-//                             if (g_ShellCache.HasSVNAdminDir(child.toString().c_str(), FALSE))\r
-//                                     itemStates |= ITEMIS_INVERSIONEDFOLDER;\r
+                               if (g_ShellCache.HasSVNAdminDir(child.toString().c_str(), FALSE))\r
+                                       itemStates |= ITEMIS_INVERSIONEDFOLDER;\r
                                GlobalUnlock(medium.hGlobal);\r
 \r
                                // if the item is a versioned folder, check if there's a patch file\r
@@ -504,10 +525,13 @@ STDMETHODIMP CShellExt::Initialize(LPCITEMIDLIST pIDFolder,
                git_wc_status_kind status = git_wc_status_none;\r
                if (IsClipboardFormatAvailable(CF_HDROP)) \r
                        itemStatesFolder |= ITEMIS_PATHINCLIPBOARD;\r
+               \r
+               CTGitPath askedpath;\r
+               askedpath.SetFromWin(folder_.c_str());\r
+\r
                if ((folder_.compare(statuspath)!=0)&&(g_ShellCache.IsContextPathAllowed(folder_.c_str())))\r
                {\r
-                       CTGitPath askedpath;\r
-                       askedpath.SetFromWin(folder_.c_str());\r
+                       \r
                        try\r
                        {\r
                                GitStatus stat;\r
@@ -524,16 +548,7 @@ STDMETHODIMP CShellExt::Initialize(LPCITEMIDLIST pIDFolder,
 //                                     }\r
 //                                     if ((stat.status->entry)&&(stat.status->entry->uuid))\r
 //                                             uuidTarget = CUnicodeUtils::StdGetUnicode(stat.status->entry->uuid);\r
-                                       if ((status != git_wc_status_unversioned)&&(status != git_wc_status_ignored)&&(status != git_wc_status_none))\r
-                                               itemStatesFolder |= ITEMIS_INSVN;\r
-                                       if (status == git_wc_status_normal)\r
-                                               itemStatesFolder |= ITEMIS_NORMAL;\r
-                                       if (status == git_wc_status_conflicted)\r
-                                               itemStatesFolder |= ITEMIS_CONFLICTED;\r
-                                       if (status == git_wc_status_added)\r
-                                               itemStatesFolder |= ITEMIS_ADDED;\r
-                                       if (status == git_wc_status_deleted)\r
-                                               itemStatesFolder |= ITEMIS_DELETED;\r
+                               \r
                                }\r
                                else\r
                                {\r
@@ -543,6 +558,19 @@ STDMETHODIMP CShellExt::Initialize(LPCITEMIDLIST pIDFolder,
                                        if (askedpath.HasAdminDir())\r
                                                status = git_wc_status_normal;\r
                                }\r
+                               \r
+                               //if ((status != git_wc_status_unversioned)&&(status != git_wc_status_ignored)&&(status != git_wc_status_none))\r
+                               if (askedpath.HasAdminDir())\r
+                                       itemStatesFolder |= ITEMIS_INSVN;\r
+                               if (status == git_wc_status_normal)\r
+                                       itemStatesFolder |= ITEMIS_NORMAL;\r
+                               if (status == git_wc_status_conflicted)\r
+                                       itemStatesFolder |= ITEMIS_CONFLICTED;\r
+                               if (status == git_wc_status_added)\r
+                                       itemStatesFolder |= ITEMIS_ADDED;\r
+                               if (status == git_wc_status_deleted)\r
+                                       itemStatesFolder |= ITEMIS_DELETED;\r
+\r
                        }\r
                        catch ( ... )\r
                        {\r
@@ -553,7 +581,8 @@ STDMETHODIMP CShellExt::Initialize(LPCITEMIDLIST pIDFolder,
                {\r
                        status = fetchedstatus;\r
                }\r
-               if ((status != git_wc_status_unversioned)&&(status != git_wc_status_ignored)&&(status != git_wc_status_none))\r
+               //if ((status != git_wc_status_unversioned)&&(status != git_wc_status_ignored)&&(status != git_wc_status_none))\r
+               if (askedpath.HasAdminDir())\r
                {\r
                        itemStatesFolder |= ITEMIS_FOLDERINSVN;\r
                }\r
@@ -578,10 +607,11 @@ STDMETHODIMP CShellExt::Initialize(LPCITEMIDLIST pIDFolder,
                        {\r
                                folder_ = files_.front();\r
                                git_wc_status_kind status = git_wc_status_none;\r
+                               CTGitPath askedpath;\r
+                               askedpath.SetFromWin(folder_.c_str());\r
+\r
                                if (folder_.compare(statuspath)!=0)\r
-                               {\r
-                                       CTGitPath askedpath;\r
-                                       askedpath.SetFromWin(folder_.c_str());\r
+                               {                               \r
                                        try\r
                                        {\r
                                                GitStatus stat;\r
@@ -609,7 +639,8 @@ STDMETHODIMP CShellExt::Initialize(LPCITEMIDLIST pIDFolder,
                                {\r
                                        status = fetchedstatus;\r
                                }\r
-                               if ((status != git_wc_status_unversioned)&&(status != git_wc_status_ignored)&&(status != git_wc_status_none))\r
+                               //if ((status != git_wc_status_unversioned)&&(status != git_wc_status_ignored)&&(status != git_wc_status_none))\r
+                               if (askedpath.HasAdminDir())\r
                                        itemStates |= ITEMIS_FOLDERINSVN;\r
                                if (status == git_wc_status_ignored)\r
                                        itemStates |= ITEMIS_IGNORED;\r
@@ -1052,10 +1083,12 @@ STDMETHODIMP CShellExt::QueryContextMenu(HMENU hMenu,
        int menuIndex = 0;\r
        bool bAddSeparator = false;\r
        bool bMenuEntryAdded = false;\r
+       bool bMenuEmpty = true;\r
        // insert separator at start\r
        InsertMenu(hMenu, indexMenu++, MF_SEPARATOR|MF_BYPOSITION, 0, NULL); idCmd++;\r
        bool bShowIcons = !!DWORD(CRegStdWORD(_T("Software\\TortoiseGit\\ShowContextMenuIcons"), TRUE));\r
-       if (fullver <= 0x0500)\r
+       // ?? TortoiseSVN had this as (fullver <= 0x0500) this disabled icons in win2k, but icons work fine in win2k\r
+       if (fullver < 0x0500)\r
                bShowIcons = false;\r
        while (menuInfo[menuIndex].command != ShellMenuLastEntry)\r
        {\r
@@ -1065,7 +1098,8 @@ STDMETHODIMP CShellExt::QueryContextMenu(HMENU hMenu,
                        // another 'normal' menu entry after we insert a separator.\r
                        // we simply set a flag here, indicating that before the next\r
                        // 'normal' menu entry, a separator should be added.\r
-                       bAddSeparator = true;\r
+                       if (!bMenuEmpty)\r
+                               bAddSeparator = true;\r
                }\r
                else\r
                {\r
@@ -1138,16 +1172,12 @@ STDMETHODIMP CShellExt::QueryContextMenu(HMENU hMenu,
                                        {\r
                                                InsertIgnoreSubmenus(idCmd, idCmdFirst, hMenu, subMenu, indexMenu, indexSubMenu, topmenu, bShowIcons);\r
                                                bMenuEntryAdded = true;\r
+                                               bMenuEmpty = false;\r
                                        }\r
                                        else\r
                                        {\r
-                                               // the 'get lock' command is special\r
                                                bool bIsTop = ((topmenu & menuInfo[menuIndex].menuID) != 0);\r
-                                               if (menuInfo[menuIndex].command == ShellMenuLock)\r
-                                               {\r
-                                                       if ((itemStates & ITEMIS_NEEDSLOCK) && g_ShellCache.IsGetLockTop())\r
-                                                               bIsTop = true;\r
-                                               }\r
+\r
                                                // insert the menu entry\r
                                                InsertGitMenu(  bIsTop,\r
                                                                                bIsTop ? hMenu : subMenu,\r
@@ -1159,7 +1189,10 @@ STDMETHODIMP CShellExt::QueryContextMenu(HMENU hMenu,
                                                                                menuInfo[menuIndex].command,\r
                                                                                uFlags);\r
                                                if (!bIsTop)\r
+                                               {\r
                                                        bMenuEntryAdded = true;\r
+                                                       bMenuEmpty = false;\r
+                                               }\r
                                        }\r
                                }\r
                        }\r
@@ -1585,6 +1618,14 @@ STDMETHODIMP CShellExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)
                                        svnCmd += folder_;\r
                                svnCmd += _T("\"");\r
                                break;\r
+                       case ShellMenuRebase:\r
+                               svnCmd += _T("rebase /path:\"");\r
+                               if (files_.size() > 0)\r
+                                       svnCmd += files_.front();\r
+                               else\r
+                                       svnCmd += folder_;\r
+                               svnCmd += _T("\"");\r
+                               break;\r
                        case ShellMenuShowChanged:\r
                                if (files_.size() > 1)\r
                 {\r
@@ -1724,28 +1765,6 @@ STDMETHODIMP CShellExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)
                                        svnCmd += folder_;\r
                                svnCmd += _T("\"");\r
                                break;\r
-                       case ShellMenuLock:\r
-                               tempfile = WriteFileListToTempFile();\r
-                               svnCmd += _T("lock /pathfile:\"");\r
-                               svnCmd += tempfile;\r
-                               svnCmd += _T("\"");\r
-                               svnCmd += _T(" /deletepathfile");\r
-                               break;\r
-                       case ShellMenuUnlock:\r
-                               tempfile = WriteFileListToTempFile();\r
-                               svnCmd += _T("unlock /pathfile:\"");\r
-                               svnCmd += tempfile;\r
-                               svnCmd += _T("\"");\r
-                               svnCmd += _T(" /deletepathfile");\r
-                               break;\r
-                       case ShellMenuUnlockForce:\r
-                               tempfile = WriteFileListToTempFile();\r
-                               svnCmd += _T("unlock /pathfile:\"");\r
-                               svnCmd += tempfile;\r
-                               svnCmd += _T("\"");\r
-                               svnCmd += _T(" /deletepathfile");\r
-                               svnCmd += _T(" /force");\r
-                               break;\r
                        case ShellMenuProperties:\r
                                tempfile = WriteFileListToTempFile();\r
                                svnCmd += _T("properties /pathfile:\"");\r
@@ -2114,18 +2133,6 @@ LPCTSTR CShellExt::GetMenuTextFromResource(int id)
                        resource = MAKEINTRESOURCE(menuInfo[menuIndex].iconID);\r
                        switch (id)\r
                        {\r
-                       case ShellMenuLock:\r
-                               // menu lock is special because it can be set to the top\r
-                               // with a separate option in the registry\r
-                               space = ((layout & MENULOCK) || ((itemStates & ITEMIS_NEEDSLOCK) && g_ShellCache.IsGetLockTop())) ? 0 : 6;\r
-                               if ((layout & MENULOCK) || ((itemStates & ITEMIS_NEEDSLOCK) && g_ShellCache.IsGetLockTop()))\r
-                               {\r
-                                       _tcscpy_s(textbuf, 255, _T("Git "));\r
-                                       _tcscat_s(textbuf, 255, stringtablebuffer);\r
-                                       _tcscpy_s(stringtablebuffer, 255, textbuf);\r
-                               }\r
-                               break;\r
-                               // the sub menu entries are special because they're *always* on the top level menu\r
                        case ShellSubMenuMultiple:\r
                        case ShellSubMenuLink:\r
                        case ShellSubMenuFolder:\r