OSDN Git Service

BrowseRefs: Ref name prefix on wrong places removed
[tortoisegit/TortoiseGitJp.git] / src / TortoiseProc / BrowseRefsDlg.cpp
index f24931a..bf9ca63 100644 (file)
@@ -23,12 +23,14 @@ CBrowseRefsDlg::~CBrowseRefsDlg()
 void CBrowseRefsDlg::DoDataExchange(CDataExchange* pDX)\r
 {\r
        CDialog::DoDataExchange(pDX);\r
-       DDX_Control(pDX, IDC_TREE_REF, m_RefTreeCtrl);\r
+       DDX_Control(pDX, IDC_TREE_REF,                  m_RefTreeCtrl);\r
+       DDX_Control(pDX, IDC_LIST_REF_LEAFS,    m_ListRefLeafs);\r
 }\r
 \r
 \r
 BEGIN_MESSAGE_MAP(CBrowseRefsDlg, CResizableStandAloneDialog)\r
        ON_BN_CLICKED(IDOK, &CBrowseRefsDlg::OnBnClickedOk)\r
+       ON_NOTIFY(TVN_SELCHANGED, IDC_TREE_REF, &CBrowseRefsDlg::OnTvnSelchangedTreeRef)\r
 END_MESSAGE_MAP()\r
 \r
 \r
@@ -43,7 +45,14 @@ BOOL CBrowseRefsDlg::OnInitDialog()
 {\r
        CResizableStandAloneDialog::OnInitDialog();\r
 \r
-       AddAnchor(IDC_TREE_REF, TOP_LEFT, BOTTOM_RIGHT);\r
+       AddAnchor(IDC_TREE_REF, TOP_LEFT, BOTTOM_LEFT);\r
+       AddAnchor(IDC_LIST_REF_LEAFS, TOP_LEFT, BOTTOM_RIGHT);\r
+\r
+       m_ListRefLeafs.SetExtendedStyle(m_ListRefLeafs.GetExtendedStyle()|LVS_EX_FULLROWSELECT);\r
+       m_ListRefLeafs.InsertColumn(0,L"Name",0,150);\r
+       m_ListRefLeafs.InsertColumn(1,L"Date Last Commit",0,100);\r
+       m_ListRefLeafs.InsertColumn(2,L"Last Commit",0,300);\r
+       m_ListRefLeafs.InsertColumn(3,L"Hash",0,80);\r
 \r
        AddAnchor(IDOK,BOTTOM_RIGHT);\r
        AddAnchor(IDCANCEL,BOTTOM_RIGHT);\r
@@ -51,8 +60,7 @@ BOOL CBrowseRefsDlg::OnInitDialog()
        Refresh();\r
 \r
 \r
-       return TRUE;  // return TRUE unless you set the focus to a control\r
-       // EXCEPTION: OCX Property Pages should return FALSE\r
+       return TRUE;\r
 }\r
 \r
 CShadowTree* CShadowTree::GetNextSub(CString& nameLeft)\r
@@ -82,8 +90,9 @@ typedef std::map<CString,CString> MAP_STRING_STRING;
 \r
 void CBrowseRefsDlg::Refresh()\r
 {\r
-       m_RefMap.clear();\r
-       g_Git.GetMapHashToFriendName(m_RefMap);\r
+//     m_RefMap.clear();\r
+//     g_Git.GetMapHashToFriendName(m_RefMap);\r
+               \r
 \r
        m_RefTreeCtrl.DeleteAllItems();\r
        m_TreeRoot.m_ShadowTree.clear();\r
@@ -91,23 +100,81 @@ void CBrowseRefsDlg::Refresh()
        m_TreeRoot.m_hTree=m_RefTreeCtrl.InsertItem(L"Refs",NULL,NULL);\r
        m_RefTreeCtrl.SetItemData(m_TreeRoot.m_hTree,(DWORD_PTR)&m_TreeRoot);\r
 \r
+       CString allRefs;\r
+       g_Git.Run(L"git for-each-ref --format="\r
+                         L"%(refname)%04"\r
+                         L"%(objectname)%04"\r
+                         L"%(authordate:relative)%04"\r
+                         L"%(subject)%04"\r
+                         L"%(authorname)",\r
+                         &allRefs,CP_UTF8);\r
+\r
+       int linePos=0;\r
+       CString singleRef;\r
 \r
-       MAP_STRING_STRING refName;\r
+       MAP_STRING_STRING refMap;\r
 \r
        //First sort on ref name\r
-       for(MAP_HASH_NAME::iterator iterRef=m_RefMap.begin();iterRef!=m_RefMap.end();++iterRef)\r
-               for(STRING_VECTOR::iterator iterRefName=iterRef->second.begin();iterRefName!=iterRef->second.end();++iterRefName)\r
-                       refName[*iterRefName]=iterRef->first;\r
+       while(!(singleRef=allRefs.Tokenize(L"\r\n",linePos)).IsEmpty())\r
+       {\r
+               int valuePos=0;\r
+               CString refName=singleRef.Tokenize(L"\04",valuePos);\r
+               CString refRest=singleRef.Mid(valuePos);\r
+               refMap[refName]=refRest;\r
+       }\r
+\r
+\r
+\r
+//     for(MAP_HASH_NAME::iterator iterRef=m_RefMap.begin();iterRef!=m_RefMap.end();++iterRef)\r
+//             for(STRING_VECTOR::iterator iterRefName=iterRef->second.begin();iterRefName!=iterRef->second.end();++iterRefName)\r
+//                     refName[*iterRefName]=iterRef->first;\r
 \r
        //Populate ref tree\r
-       for(MAP_STRING_STRING::iterator iterRefName=refName.begin();iterRefName!=refName.end();++iterRefName)\r
+       for(MAP_STRING_STRING::iterator iterRefMap=refMap.begin();iterRefMap!=refMap.end();++iterRefMap)\r
        {\r
-               CShadowTree& treeLeaf=GetTreeNode(iterRefName->first);\r
-               treeLeaf.m_csRef=iterRefName->second;\r
+               CShadowTree& treeLeaf=GetTreeNode(iterRefMap->first);\r
+               CString values=iterRefMap->second;\r
+\r
+               int valuePos=0;\r
+               treeLeaf.m_csRef=     values.Tokenize(L"\04",valuePos);\r
+               treeLeaf.m_csDate=    values.Tokenize(L"\04",valuePos);\r
+               treeLeaf.m_csSubject= values.Tokenize(L"\04",valuePos);\r
+               treeLeaf.m_csAuthor=  values.Tokenize(L"\04",valuePos);\r
        }\r
 \r
-       m_RefTreeCtrl.Expand(m_TreeRoot.m_hTree,TVE_EXPAND);\r
+       CString currHead;\r
+       g_Git.Run(L"git symbolic-ref HEAD",&currHead,CP_UTF8);\r
+\r
+       currHead.Trim(L"\r\n\t ");\r
+\r
+       if(!SelectRef(currHead))\r
+               //Probably not on a branch. Select root node.\r
+               m_RefTreeCtrl.Expand(m_TreeRoot.m_hTree,TVE_EXPAND);\r
+\r
+}\r
+\r
+bool CBrowseRefsDlg::SelectRef(CString refName)\r
+{\r
+       if(wcsnicmp(refName,L"refs/",5)!=0)\r
+               return false; // Not a ref name\r
+\r
+       CShadowTree& treeLeafHead=GetTreeNode(refName);\r
+       if(treeLeafHead.m_pParent==NULL)\r
+               return false; //Weird... should not occur.\r
+\r
+       //This is the current head.\r
+       m_RefTreeCtrl.Select(treeLeafHead.m_pParent->m_hTree,TVGN_CARET);\r
 \r
+       for(int indexPos = 0; indexPos < m_ListRefLeafs.GetItemCount(); ++indexPos)\r
+       {\r
+               CShadowTree* pCurrShadowTree = (CShadowTree*)m_ListRefLeafs.GetItemData(indexPos);\r
+               if(pCurrShadowTree == &treeLeafHead)\r
+               {\r
+                       m_ListRefLeafs.SetItemState(indexPos,LVIS_SELECTED,LVIS_SELECTED);\r
+               }\r
+       }\r
+\r
+       return true;\r
 }\r
 \r
 CShadowTree& CBrowseRefsDlg::GetTreeNode(CString refName, CShadowTree* pTreePos)\r
@@ -128,13 +195,65 @@ CShadowTree& CBrowseRefsDlg::GetTreeNode(CString refName, CShadowTree* pTreePos)
                ASSERT(FALSE);\r
                return *pTreePos;\r
        }\r
-       if(pNextTree->m_hTree==NULL)\r
+\r
+       if(!refName.IsEmpty())\r
        {\r
-               //New tree. Create node in control.\r
-               pNextTree->m_hTree=m_RefTreeCtrl.InsertItem(pNextTree->m_csName,pTreePos->m_hTree,NULL);\r
-               m_RefTreeCtrl.SetItemData(pNextTree->m_hTree,(DWORD_PTR)pNextTree);\r
+               //When the refName is not empty, this node is not a leaf, so lets add it to the tree control.\r
+               //Leafs are for the list control.\r
+               if(pNextTree->m_hTree==NULL)\r
+               {\r
+                       //New tree. Create node in control.\r
+                       pNextTree->m_hTree=m_RefTreeCtrl.InsertItem(pNextTree->m_csName,pTreePos->m_hTree,NULL);\r
+                       m_RefTreeCtrl.SetItemData(pNextTree->m_hTree,(DWORD_PTR)pNextTree);\r
+               }\r
        }\r
 \r
        return GetTreeNode(refName,pNextTree);\r
 }\r
 \r
+\r
+void CBrowseRefsDlg::OnTvnSelchangedTreeRef(NMHDR *pNMHDR, LRESULT *pResult)\r
+{\r
+       LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);\r
+       *pResult = 0;\r
+\r
+       FillListCtrlForTreeNode(pNMTreeView->itemNew.hItem);\r
+}\r
+\r
+void CBrowseRefsDlg::FillListCtrlForTreeNode(HTREEITEM treeNode)\r
+{\r
+       m_ListRefLeafs.DeleteAllItems();\r
+\r
+       CShadowTree* pTree=(CShadowTree*)(m_RefTreeCtrl.GetItemData(treeNode));\r
+       if(pTree==NULL)\r
+       {\r
+               ASSERT(FALSE);\r
+               return;\r
+       }\r
+       FillListCtrlForShadowTree(pTree,L"",true);\r
+}\r
+\r
+void CBrowseRefsDlg::FillListCtrlForShadowTree(CShadowTree* pTree, CString refNamePrefix, bool isFirstLevel)\r
+{\r
+       if(pTree->IsLeaf())\r
+       {\r
+               int indexItem=m_ListRefLeafs.InsertItem(m_ListRefLeafs.GetItemCount(),L"");\r
+\r
+               m_ListRefLeafs.SetItemData(indexItem,(DWORD_PTR)pTree);\r
+               m_ListRefLeafs.SetItemText(indexItem,0,refNamePrefix+pTree->m_csName);\r
+               m_ListRefLeafs.SetItemText(indexItem,1,pTree->m_csDate);\r
+               m_ListRefLeafs.SetItemText(indexItem,2,pTree->m_csSubject);\r
+               m_ListRefLeafs.SetItemText(indexItem,3,pTree->m_csRef);\r
+       }\r
+       else\r
+       {\r
+\r
+               CString csThisName;\r
+               if(!isFirstLevel)\r
+                       csThisName=refNamePrefix+pTree->m_csName+L"/";\r
+               for(CShadowTree::TShadowTreeMap::iterator itSubTree=pTree->m_ShadowTree.begin(); itSubTree!=pTree->m_ShadowTree.end(); ++itSubTree)\r
+               {\r
+                       FillListCtrlForShadowTree(&itSubTree->second,csThisName,false);\r
+               }\r
+       }\r
+}\r