1 // BrowseRefsDlg.cpp : implementation file
5 #include "TortoiseProc.h"
6 #include "BrowseRefsDlg.h"
9 // CBrowseRefsDlg dialog
11 IMPLEMENT_DYNAMIC(CBrowseRefsDlg
, CResizableStandAloneDialog
)
13 CBrowseRefsDlg::CBrowseRefsDlg(CWnd
* pParent
/*=NULL*/)
14 : CResizableStandAloneDialog(CBrowseRefsDlg::IDD
, pParent
)
19 CBrowseRefsDlg::~CBrowseRefsDlg()
23 void CBrowseRefsDlg::DoDataExchange(CDataExchange
* pDX
)
25 CDialog::DoDataExchange(pDX
);
26 DDX_Control(pDX
, IDC_TREE_REF
, m_RefTreeCtrl
);
27 DDX_Control(pDX
, IDC_LIST_REF_LEAFS
, m_ListRefLeafs
);
31 BEGIN_MESSAGE_MAP(CBrowseRefsDlg
, CResizableStandAloneDialog
)
32 ON_BN_CLICKED(IDOK
, &CBrowseRefsDlg::OnBnClickedOk
)
33 ON_NOTIFY(TVN_SELCHANGED
, IDC_TREE_REF
, &CBrowseRefsDlg::OnTvnSelchangedTreeRef
)
37 // CBrowseRefsDlg message handlers
39 void CBrowseRefsDlg::OnBnClickedOk()
44 BOOL
CBrowseRefsDlg::OnInitDialog()
46 CResizableStandAloneDialog::OnInitDialog();
48 AddAnchor(IDC_TREE_REF
, TOP_LEFT
, BOTTOM_LEFT
);
49 AddAnchor(IDC_LIST_REF_LEAFS
, TOP_LEFT
, BOTTOM_RIGHT
);
51 m_ListRefLeafs
.SetExtendedStyle(m_ListRefLeafs
.GetExtendedStyle()|LVS_EX_FULLROWSELECT
);
52 m_ListRefLeafs
.InsertColumn(0,L
"Name",0,150);
53 m_ListRefLeafs
.InsertColumn(1,L
"Date Last Commit",0,100);
54 m_ListRefLeafs
.InsertColumn(2,L
"Last Commit",0,300);
55 m_ListRefLeafs
.InsertColumn(3,L
"Hash",0,80);
57 AddAnchor(IDOK
,BOTTOM_RIGHT
);
58 AddAnchor(IDCANCEL
,BOTTOM_RIGHT
);
66 CShadowTree
* CShadowTree::GetNextSub(CString
& nameLeft
)
68 int posSlash
=nameLeft
.Find('/');
73 nameLeft
.Empty();//Nothing left
77 nameSub
=nameLeft
.Left(posSlash
);
78 nameLeft
=nameLeft
.Mid(posSlash
+1);
83 CShadowTree
& nextNode
=m_ShadowTree
[nameSub
];
84 nextNode
.m_csName
=nameSub
;
85 nextNode
.m_pParent
=this;
89 typedef std::map
<CString
,CString
> MAP_STRING_STRING
;
91 void CBrowseRefsDlg::Refresh()
94 g_Git
.GetMapHashToFriendName(m_RefMap
);
96 m_RefTreeCtrl
.DeleteAllItems();
97 m_TreeRoot
.m_ShadowTree
.clear();
98 m_TreeRoot
.m_csName
="Refs";
99 m_TreeRoot
.m_hTree
=m_RefTreeCtrl
.InsertItem(L
"Refs",NULL
,NULL
);
100 m_RefTreeCtrl
.SetItemData(m_TreeRoot
.m_hTree
,(DWORD_PTR
)&m_TreeRoot
);
103 MAP_STRING_STRING refName
;
105 //First sort on ref name
106 for(MAP_HASH_NAME::iterator iterRef
=m_RefMap
.begin();iterRef
!=m_RefMap
.end();++iterRef
)
107 for(STRING_VECTOR::iterator iterRefName
=iterRef
->second
.begin();iterRefName
!=iterRef
->second
.end();++iterRefName
)
108 refName
[*iterRefName
]=iterRef
->first
;
111 for(MAP_STRING_STRING::iterator iterRefName
=refName
.begin();iterRefName
!=refName
.end();++iterRefName
)
113 CShadowTree
& treeLeaf
=GetTreeNode(iterRefName
->first
);
114 treeLeaf
.m_csRef
=iterRefName
->second
;
117 m_RefTreeCtrl
.Expand(m_TreeRoot
.m_hTree
,TVE_EXPAND
);
121 CShadowTree
& CBrowseRefsDlg::GetTreeNode(CString refName
, CShadowTree
* pTreePos
)
125 if(wcsnicmp(refName
,L
"refs/",5)==0)
126 refName
=refName
.Mid(5);
127 pTreePos
=&m_TreeRoot
;
129 if(refName
.IsEmpty())
130 return *pTreePos
;//Found leaf
132 CShadowTree
* pNextTree
=pTreePos
->GetNextSub(refName
);
135 //Should not occur when all ref-names are valid.
140 if(!refName
.IsEmpty())
142 //When the refName is not empty, this node is not a leaf, so lets add it to the tree control.
143 //Leafs are for the list control.
144 if(pNextTree
->m_hTree
==NULL
)
146 //New tree. Create node in control.
147 pNextTree
->m_hTree
=m_RefTreeCtrl
.InsertItem(pNextTree
->m_csName
,pTreePos
->m_hTree
,NULL
);
148 m_RefTreeCtrl
.SetItemData(pNextTree
->m_hTree
,(DWORD_PTR
)pNextTree
);
152 return GetTreeNode(refName
,pNextTree
);
156 void CBrowseRefsDlg::OnTvnSelchangedTreeRef(NMHDR
*pNMHDR
, LRESULT
*pResult
)
158 LPNMTREEVIEW pNMTreeView
= reinterpret_cast<LPNMTREEVIEW
>(pNMHDR
);
161 FillListCtrlForTreeNode(pNMTreeView
->itemNew
.hItem
);
164 void CBrowseRefsDlg::FillListCtrlForTreeNode(HTREEITEM treeNode
)
166 m_ListRefLeafs
.DeleteAllItems();
168 CShadowTree
* pTree
=(CShadowTree
*)(m_RefTreeCtrl
.GetItemData(treeNode
));
174 FillListCtrlForShadowTree(pTree
,L
"",true);
177 void CBrowseRefsDlg::FillListCtrlForShadowTree(CShadowTree
* pTree
, CString refNamePrefix
, bool isFirstLevel
)
181 int indexItem
=m_ListRefLeafs
.InsertItem(m_ListRefLeafs
.GetItemCount(),L
"");
183 m_ListRefLeafs
.SetItemData(indexItem
,(DWORD_PTR
)pTree
);
184 m_ListRefLeafs
.SetItemText(indexItem
,0,refNamePrefix
+pTree
->m_csName
);
185 m_ListRefLeafs
.SetItemText(indexItem
,3,pTree
->m_csRef
);
192 csThisName
=refNamePrefix
+pTree
->m_csName
+L
"/";
193 for(CShadowTree::TShadowTreeMap::iterator itSubTree
=pTree
->m_ShadowTree
.begin(); itSubTree
!=pTree
->m_ShadowTree
.end(); ++itSubTree
)
195 FillListCtrlForShadowTree(&itSubTree
->second
,csThisName
,false);