+// BrowseRefsDlg.cpp : implementation file\r
+//\r
+\r
+#include "stdafx.h"\r
+#include "TortoiseProc.h"\r
+#include "BrowseRefsDlg.h"\r
+\r
+\r
+// CBrowseRefsDlg dialog\r
+\r
+IMPLEMENT_DYNAMIC(CBrowseRefsDlg, CDialog)\r
+\r
+CBrowseRefsDlg::CBrowseRefsDlg(CWnd* pParent /*=NULL*/)\r
+ : CDialog(CBrowseRefsDlg::IDD, pParent)\r
+{\r
+\r
+}\r
+\r
+CBrowseRefsDlg::~CBrowseRefsDlg()\r
+{\r
+}\r
+\r
+void CBrowseRefsDlg::DoDataExchange(CDataExchange* pDX)\r
+{\r
+ CDialog::DoDataExchange(pDX);\r
+ DDX_Control(pDX, IDC_TREE_REF, m_RefTreeCtrl);\r
+}\r
+\r
+\r
+BEGIN_MESSAGE_MAP(CBrowseRefsDlg, CDialog)\r
+ ON_BN_CLICKED(IDOK, &CBrowseRefsDlg::OnBnClickedOk)\r
+END_MESSAGE_MAP()\r
+\r
+\r
+// CBrowseRefsDlg message handlers\r
+\r
+void CBrowseRefsDlg::OnBnClickedOk()\r
+{\r
+ OnOK();\r
+}\r
+\r
+BOOL CBrowseRefsDlg::OnInitDialog()\r
+{\r
+ CDialog::OnInitDialog();\r
+\r
+ 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
+}\r
+\r
+CShadowTree* CShadowTree::GetNextSub(CString& nameLeft)\r
+{\r
+ int posSlash=nameLeft.Find('/');\r
+ CString nameSub;\r
+ if(posSlash<0)\r
+ {\r
+ nameSub=nameLeft;\r
+ nameLeft.Empty();//Nothing left\r
+ }\r
+ else\r
+ {\r
+ nameSub=nameLeft.Left(posSlash);\r
+ nameLeft=nameLeft.Mid(posSlash+1);\r
+ }\r
+ if(nameSub.IsEmpty())\r
+ return NULL;\r
+\r
+ CShadowTree& nextNode=m_ShadowTree[nameSub];\r
+ nextNode.m_csName=nameSub;\r
+ nextNode.m_pParent=this;\r
+ return &nextNode;\r
+}\r
+\r
+typedef std::map<CString,CString> MAP_STRING_STRING;\r
+\r
+void CBrowseRefsDlg::Refresh()\r
+{\r
+ m_RefMap.clear();\r
+ g_Git.GetMapHashToFriendName(m_RefMap);\r
+\r
+ m_RefTreeCtrl.DeleteAllItems();\r
+ m_TreeRoot.m_ShadowTree.clear();\r
+ m_TreeRoot.m_csName="Refs";\r
+ 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
+\r
+ MAP_STRING_STRING refName;\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
+\r
+ //Populate ref tree\r
+ for(MAP_STRING_STRING::iterator iterRefName=refName.begin();iterRefName!=refName.end();++iterRefName)\r
+ {\r
+ CShadowTree& treeLeaf=GetTreeNode(iterRefName->first);\r
+ treeLeaf.m_csRef=iterRefName->second;\r
+ }\r
+\r
+ m_RefTreeCtrl.Expand(m_TreeRoot.m_hTree,TVE_EXPAND);\r
+\r
+}\r
+\r
+CShadowTree& CBrowseRefsDlg::GetTreeNode(CString refName, CShadowTree* pTreePos)\r
+{\r
+ if(pTreePos==NULL)\r
+ {\r
+ if(wcsnicmp(refName,L"refs/",5)==0)\r
+ refName=refName.Mid(5);\r
+ pTreePos=&m_TreeRoot;\r
+ }\r
+ if(refName.IsEmpty())\r
+ return *pTreePos;//Found leaf\r
+\r
+ CShadowTree* pNextTree=pTreePos->GetNextSub(refName);\r
+ if(pNextTree==NULL)\r
+ {\r
+ //Should not occur when all ref-names are valid.\r
+ ASSERT(FALSE);\r
+ return *pTreePos;\r
+ }\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
+ return GetTreeNode(refName,pNextTree);\r
+}\r
+\r