OSDN Git Service

BrowseRefs: Option to delete multiple refs
authorJohan 't Hart <johanthart@gmail.com>
Sat, 27 Jun 2009 21:57:25 +0000 (23:57 +0200)
committerJohan 't Hart <johanthart@gmail.com>
Sat, 27 Jun 2009 22:05:00 +0000 (00:05 +0200)
src/TortoiseProc/BrowseRefsDlg.cpp
src/TortoiseProc/BrowseRefsDlg.h

index 05caeca..fc2801a 100644 (file)
@@ -386,65 +386,114 @@ void CBrowseRefsDlg::FillListCtrlForShadowTree(CShadowTree* pTree, CString refNa
        }\r
 }\r
 \r
-bool CBrowseRefsDlg::ConfirmDeleteRef(CString completeRefName)\r
+bool CBrowseRefsDlg::ConfirmDeleteRef(VectorPShadowTree& leafs)\r
 {\r
+       ASSERT(!leafs.empty());\r
+\r
        CString csMessage;\r
        CString csTitle;\r
 \r
        UINT mbIcon=MB_ICONQUESTION;\r
-       csMessage = L"Are you sure you want to delete the ";\r
+       csMessage = L"Are you sure you want to delete ";\r
 \r
        bool bIsRemoteBranch = false;\r
        bool bIsBranch = false;\r
-       if              (wcsncmp(completeRefName, L"refs/remotes",12)==0)       {bIsBranch = true; bIsRemoteBranch = true;}\r
-       else if (wcsncmp(completeRefName, L"refs/heads",10)==0)         {bIsBranch = true;}\r
+       if              (leafs[0]->IsFrom(L"refs/remotes"))     {bIsBranch = true; bIsRemoteBranch = true;}\r
+       else if (leafs[0]->IsFrom(L"refs/heads"))       {bIsBranch = true;}\r
 \r
        if(bIsBranch)\r
        {\r
-               CString branchToDelete = completeRefName.Mid(bIsRemoteBranch ? 13 : 11);\r
-               csTitle.Format(L"Confirm deletion of %sbranch %s", \r
-                       bIsRemoteBranch? L"remote ": L"", \r
-                       branchToDelete);\r
-               if(bIsRemoteBranch)\r
-                       csMessage += L"<ct=0x0000FF><i>remote</i></ct> "; \r
-               csMessage += L"branch:\r\n\r\n<b>";\r
-               csMessage += branchToDelete;\r
-               csMessage += L"</b>";\r
-\r
-               //Check if branch is fully merged in HEAD\r
-               CString branchHash = g_Git.GetHash(completeRefName);\r
-               CString commonAncestor;\r
-               CString cmd;\r
-               cmd.Format(L"git.exe merge-base HEAD %s",completeRefName);\r
-               g_Git.Run(cmd,&commonAncestor,CP_UTF8);\r
-\r
-               branchHash=branchHash.Left(40);\r
-               commonAncestor=commonAncestor.Left(40);\r
-               \r
-               if(commonAncestor != branchHash)\r
+               if(leafs.size() == 1)\r
                {\r
-                       csMessage += L"\r\n\r\n<b>Warning:\r\nThis branch is not fully merged into HEAD.</b>";\r
-                       mbIcon = MB_ICONWARNING;\r
+                       CString branchToDelete = leafs[0]->GetRefName().Mid(bIsRemoteBranch ? 13 : 11);\r
+                       csTitle.Format(L"Confirm deletion of %sbranch %s", \r
+                               bIsRemoteBranch? L"remote ": L"", \r
+                               branchToDelete);\r
+\r
+                       csMessage += "the ";\r
+                       if(bIsRemoteBranch)\r
+                               csMessage += L"<ct=0x0000FF><i>remote</i></ct> "; \r
+                       csMessage += L"branch:\r\n\r\n<b>";\r
+                       csMessage += branchToDelete;\r
+                       csMessage += L"</b>";\r
+\r
+                       //Check if branch is fully merged in HEAD\r
+                       CString branchHash = g_Git.GetHash(leafs[0]->GetRefName());\r
+                       CString commonAncestor;\r
+                       CString cmd;\r
+                       cmd.Format(L"git.exe merge-base HEAD %s", leafs[0]->GetRefName());\r
+                       g_Git.Run(cmd,&commonAncestor,CP_UTF8);\r
+\r
+                       branchHash=branchHash.Left(40);\r
+                       commonAncestor=commonAncestor.Left(40);\r
+                       \r
+                       if(commonAncestor != branchHash)\r
+                       {\r
+                               csMessage += L"\r\n\r\n<b>Warning:\r\nThis branch is not fully merged into HEAD.</b>";\r
+                               mbIcon = MB_ICONWARNING;\r
+                       }\r
+                       if(bIsRemoteBranch)\r
+                       {\r
+                               csMessage += L"\r\n\r\n<b>Warning:\r\nThis action will remove the branch on the remote.</b>";\r
+                               mbIcon = MB_ICONWARNING;\r
+                       }\r
                }\r
-               if(bIsRemoteBranch)\r
+               else\r
                {\r
-                       csMessage += L"\r\n\r\n<b>Warning:\r\nThis action will remove the branch on the remote.</b>";\r
+                       csTitle.Format(L"Confirm deletion of %d %sbranches",\r
+                               leafs.size(),\r
+                               bIsRemoteBranch? L"remote ": L"");\r
+\r
+                       CString csMoreMsgText;\r
+                       csMoreMsgText.Format(L"<b>%d</b> ", leafs.size());\r
+                       csMessage += csMoreMsgText;\r
+                       if(bIsRemoteBranch)\r
+                               csMessage += L"<ct=0x0000FF><i>remote</i></ct> "; \r
+                       csMessage += L"branches";\r
+\r
+                       csMessage += L"\r\n\r\n<b>Warning:\r\nIt has not been checked if these branches have been fully merged into HEAD.</b>";\r
                        mbIcon = MB_ICONWARNING;\r
+\r
+                       if(bIsRemoteBranch)\r
+                       {\r
+                               csMessage += L"\r\n\r\n<b>Warning:\r\nThis action will remove the branches on the remote.</b>";\r
+                               mbIcon = MB_ICONWARNING;\r
+                       }\r
                }\r
+\r
        }\r
-       else if(wcsncmp(completeRefName,L"refs/tags",9)==0)\r
+       else if(leafs[0]->IsFrom(L"refs/tags"))\r
        {\r
-               CString tagToDelete = completeRefName.Mid(10);\r
-               csTitle.Format(L"Confirm deletion of tag %s", tagToDelete);\r
-               csMessage += "tag:\r\n\r\n<b>";\r
-               csMessage += tagToDelete;\r
-               csMessage += "</b>";\r
+               if(leafs.size() == 1)\r
+               {\r
+                       CString tagToDelete = leafs[0]->GetRefName().Mid(10);\r
+                       csTitle.Format(L"Confirm deletion of tag %s", tagToDelete);\r
+                       csMessage += "the tag:\r\n\r\n<b>";\r
+                       csMessage += tagToDelete;\r
+                       csMessage += "</b>";\r
+               }\r
+               else\r
+               {\r
+                       CString tagToDelete = leafs[0]->GetRefName().Mid(10);\r
+                       csTitle.Format(L"Confirm deletion of %d tags", leafs.size());\r
+                       CString csMoreMsgText;\r
+                       csMoreMsgText.Format(L"<b>%d</b> ", leafs.size());\r
+                       csMessage += csMoreMsgText;\r
+                       csMessage += L"tags";\r
+               }\r
        }\r
 \r
        return CMessageBox::Show(m_hWnd,csMessage,csTitle,MB_YESNO|mbIcon)==IDYES;\r
 \r
 }\r
 \r
+bool CBrowseRefsDlg::DoDeleteRefs(VectorPShadowTree& leafs, bool bForce)\r
+{\r
+       for(VectorPShadowTree::iterator i = leafs.begin(); i != leafs.end(); ++i)\r
+               if(!DoDeleteRef((*i)->GetRefName(), bForce))\r
+                       return false;\r
+       return true;\r
+}\r
 \r
 bool CBrowseRefsDlg::DoDeleteRef(CString completeRefName, bool bForce)\r
 {\r
@@ -550,9 +599,6 @@ void CBrowseRefsDlg::ShowContextMenu(CPoint point, HTREEITEM hTreePos, VectorPSh
                bAddSeparator = true;\r
 \r
                bool bShowReflogOption                          = false;\r
-               bool bShowDeleteBranchOption            = false;\r
-               bool bShowDeleteTagOption                       = false;\r
-               bool bShowDeleteRemoteBranchOption      = false;\r
                bool bShowFetchOption                           = false;\r
                bool bShowSwitchOption                          = false;\r
 \r
@@ -561,13 +607,11 @@ void CBrowseRefsDlg::ShowContextMenu(CPoint point, HTREEITEM hTreePos, VectorPSh
                if(selectedLeafs[0]->IsFrom(L"refs/heads"))\r
                {\r
                        bShowReflogOption = true;\r
-                       bShowDeleteBranchOption = true;\r
                        bShowSwitchOption = true;\r
                }\r
                else if(selectedLeafs[0]->IsFrom(L"refs/remotes"))\r
                {\r
                        bShowReflogOption = true;\r
-                       bShowDeleteRemoteBranchOption = true;\r
                        bShowFetchOption = true;\r
 \r
                        int dummy = 0;//Needed for tokenize\r
@@ -578,23 +622,14 @@ void CBrowseRefsDlg::ShowContextMenu(CPoint point, HTREEITEM hTreePos, VectorPSh
                }\r
                else if(selectedLeafs[0]->IsFrom(L"refs/tags"))\r
                {\r
-                       bShowDeleteTagOption = true;\r
                }\r
 \r
                                                                                        popupMenu.AppendMenuIcon(eCmd_ViewLog, L"Show Log", IDI_LOG);\r
                if(bShowReflogOption)                           popupMenu.AppendMenuIcon(eCmd_ShowReflog, L"Show Reflog", IDI_LOG);\r
                if(bShowFetchOption)                            popupMenu.AppendMenuIcon(eCmd_Fetch, fetchFromCmd, IDI_PULL);\r
                if(bShowSwitchOption)                           popupMenu.AppendMenuIcon(eCmd_Switch, L"Switch to this Ref", IDI_SWITCH);\r
-               if(bShowDeleteTagOption)                        popupMenu.AppendMenuIcon(eCmd_DeleteTag, L"Delete Tag", IDI_DELETE);\r
-               if(bShowDeleteBranchOption)                     popupMenu.AppendMenuIcon(eCmd_DeleteBranch, L"Delete Branch", IDI_DELETE);\r
-               if(bShowDeleteRemoteBranchOption)       popupMenu.AppendMenuIcon(eCmd_DeleteRemoteBranch, L"Delete Remote Branch", IDI_DELETE);\r
-\r
-\r
-\r
-//             CShadowTree* pTree = (CShadowTree*)m_ListRefLeafs.GetItemData(pNMHDR->idFrom);\r
-//             if(pTree==NULL)\r
-//                     return;\r
        }\r
+\r
        else if(selectedLeafs.size() == 2)\r
        {\r
                bAddSeparator = true;\r
@@ -602,6 +637,42 @@ void CBrowseRefsDlg::ShowContextMenu(CPoint point, HTREEITEM hTreePos, VectorPSh
                popupMenu.AppendMenuIcon(eCmd_Diff, L"Compare These Refs", IDI_DIFF);\r
        }\r
 \r
+       if(!selectedLeafs.empty())\r
+       {\r
+               if(AreAllFrom(selectedLeafs, L"refs/remotes/"))\r
+               {\r
+                       CString menuItemName;\r
+                       if(selectedLeafs.size() == 1)\r
+                               menuItemName = L"Delete Remote Branch";\r
+                       else\r
+                               menuItemName.Format(L"Delete %d Remote Branches", selectedLeafs.size());\r
+\r
+                       popupMenu.AppendMenuIcon(eCmd_DeleteRemoteBranch, menuItemName, IDI_DELETE);\r
+               }\r
+\r
+               if(AreAllFrom(selectedLeafs, L"refs/heads/"))\r
+               {\r
+                       CString menuItemName;\r
+                       if(selectedLeafs.size() == 1)\r
+                               menuItemName = L"Delete Branch";\r
+                       else\r
+                               menuItemName.Format(L"Delete %d Branches", selectedLeafs.size());\r
+\r
+                       popupMenu.AppendMenuIcon(eCmd_DeleteBranch, menuItemName, IDI_DELETE);\r
+               }\r
+\r
+               if(AreAllFrom(selectedLeafs, L"refs/tags/"))\r
+               {\r
+                       CString menuItemName;\r
+                       if(selectedLeafs.size() == 1)\r
+                               menuItemName = L"Delete Tag";\r
+                       else\r
+                               menuItemName.Format(L"Delete %d Tags", selectedLeafs.size());\r
+\r
+                       popupMenu.AppendMenuIcon(eCmd_DeleteTag, menuItemName, IDI_DELETE);\r
+               }\r
+       }\r
+\r
        if(bAddSeparator) popupMenu.AppendMenu(MF_SEPARATOR);\r
 \r
        if(hTreePos!=NULL)\r
@@ -645,15 +716,15 @@ void CBrowseRefsDlg::ShowContextMenu(CPoint point, HTREEITEM hTreePos, VectorPSh
        case eCmd_DeleteBranch:\r
        case eCmd_DeleteRemoteBranch:\r
                {\r
-                       if(ConfirmDeleteRef(selectedLeafs[0]->GetRefName()))\r
-                               DoDeleteRef(selectedLeafs[0]->GetRefName(), true);\r
+                       if(ConfirmDeleteRef(selectedLeafs))\r
+                               DoDeleteRefs(selectedLeafs, true);\r
                        Refresh();\r
                }\r
                break;\r
        case eCmd_DeleteTag:\r
                {\r
-                       if(ConfirmDeleteRef(selectedLeafs[0]->GetRefName()))\r
-                               DoDeleteRef(selectedLeafs[0]->GetRefName(), true);\r
+                       if(ConfirmDeleteRef(selectedLeafs))\r
+                               DoDeleteRefs(selectedLeafs, true);\r
                        Refresh();\r
                }\r
                break;\r
@@ -718,6 +789,14 @@ void CBrowseRefsDlg::ShowContextMenu(CPoint point, HTREEITEM hTreePos, VectorPSh
        }\r
 }\r
 \r
+bool CBrowseRefsDlg::AreAllFrom(VectorPShadowTree& leafs, const wchar_t* from)\r
+{\r
+       for(VectorPShadowTree::iterator i = leafs.begin(); i != leafs.end(); ++i)\r
+               if(!(*i)->IsFrom(from))\r
+                       return false;\r
+       return true;\r
+}\r
+\r
 BOOL CBrowseRefsDlg::PreTranslateMessage(MSG* pMsg)\r
 {\r
        if (pMsg->message == WM_KEYDOWN)\r
index d722e87..31dd7de 100644 (file)
@@ -104,7 +104,8 @@ public:
 \r
        bool                    SelectRef(CString refName, bool bExactMatch);\r
 \r
-       bool                    ConfirmDeleteRef(CString completeRefName);\r
+       bool                    ConfirmDeleteRef(VectorPShadowTree& leafs);\r
+       bool                    DoDeleteRefs(VectorPShadowTree& leafs, bool bForce);\r
        bool                    DoDeleteRef(CString completeRefName, bool bForce);\r
 \r
        CString                 GetFullRefName(CString partialRefName);\r
@@ -126,6 +127,7 @@ public:
        void            OnContextMenu_ListRefLeafs(CPoint point);\r
        void            OnContextMenu_RefTreeCtrl(CPoint point);\r
 \r
+       bool            AreAllFrom(VectorPShadowTree& leafs, const wchar_t* from);\r
        void            ShowContextMenu(CPoint point, HTREEITEM hTreePos, VectorPShadowTree& selectedLeafs);\r
        virtual BOOL PreTranslateMessage(MSG* pMsg);\r
        afx_msg void OnLvnColumnclickListRefLeafs(NMHDR *pNMHDR, LRESULT *pResult);\r