OSDN Git Service

BrowseRefs: Added option to delete branch or tag.
[tortoisegit/TortoiseGitJp.git] / src / TortoiseProc / RevisionGraph / StandardLayoutNodeList.cpp
1 // TortoiseSVN - a Windows shell extension for easy version control\r
2 \r
3 // Copyright (C) 2003-2008 - TortoiseSVN\r
4 \r
5 // This program is free software; you can redistribute it and/or\r
6 // modify it under the terms of the GNU General Public License\r
7 // as published by the Free Software Foundation; either version 2\r
8 // of the License, or (at your option) any later version.\r
9 \r
10 // This program is distributed in the hope that it will be useful,\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 // GNU General Public License for more details.\r
14 \r
15 // You should have received a copy of the GNU General Public License\r
16 // along with this program; if not, write to the Free Software Foundation,\r
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
18 //\r
19 #include "StdAfx.h"\r
20 #include "resource.h"\r
21 #include "StandardLayoutNodeList.h"\r
22 #include "VisibleGraphNode.h"\r
23 #include "CachedLogInfo.h"\r
24 #include "SVN.h"\r
25 #include "UnicodeUtils.h"\r
26 \r
27 /// utilities\r
28 \r
29 index_t CStandardLayoutNodeList::GetStyle \r
30         (const CVisibleGraphNode* node) const\r
31 {\r
32         CNodeClassification classification = node->GetClassification();\r
33 \r
34         if (classification.Is (CNodeClassification::IS_ADDED))\r
35                 return ILayoutNodeList::SNode::STYLE_ADDED;\r
36         else if (classification.Is (CNodeClassification::IS_DELETED))\r
37                 return ILayoutNodeList::SNode::STYLE_DELETED;\r
38         else if (classification.Is (CNodeClassification::IS_RENAMED))\r
39                 return ILayoutNodeList::SNode::STYLE_RENAMED;\r
40         else if (classification.Is (CNodeClassification::IS_LAST))\r
41                 return ILayoutNodeList::SNode::STYLE_LAST;\r
42     else if (classification.Is (CNodeClassification::IS_MODIFIED))\r
43                 return ILayoutNodeList::SNode::STYLE_MODIFIED;\r
44         else\r
45                 return ILayoutNodeList::SNode::STYLE_DEFAULT;\r
46 }\r
47 \r
48 DWORD CStandardLayoutNodeList::GetStyleFlags \r
49         (const CVisibleGraphNode* /*node*/) const\r
50 {\r
51         return 0;\r
52 }\r
53 \r
54 // construction\r
55 \r
56 CStandardLayoutNodeList::CStandardLayoutNodeList \r
57     ( const std::vector<CStandardLayoutNodeInfo>& nodes\r
58     , const CCachedLogInfo* cache)\r
59     : cache (cache)\r
60     , nodes (nodes)\r
61 {\r
62 }\r
63 \r
64 // implement ILayoutItemList\r
65 \r
66 index_t CStandardLayoutNodeList::GetCount() const\r
67 {\r
68     return static_cast<index_t>(nodes.size());\r
69 }\r
70 \r
71 CString CStandardLayoutNodeList::GetToolTip (index_t index) const\r
72 {\r
73     CString strTipText;\r
74 \r
75     const CRevisionIndex& revisions = cache->GetRevisions();\r
76     const CRevisionInfoContainer& revisionInfo = cache->GetLogInfo();\r
77 \r
78     const CVisibleGraphNode* node = nodes[index].node;\r
79 \r
80     // node properties\r
81 \r
82         CNodeClassification classification = node->GetClassification();\r
83     revision_t revision = node->GetRevision();\r
84 \r
85     CString path \r
86         = CUnicodeUtils::StdGetUnicode \r
87             (node->GetPath().GetPath()).c_str();\r
88 \r
89     // special case: the "workspace is modified" node\r
90 \r
91     if (classification.Is (CNodeClassification::IS_MODIFIED_WC))\r
92     {\r
93             strTipText.Format ( IDS_REVGRAPH_BOXTOOLTIP_WC\r
94                           , revision-1\r
95                           , (LPCTSTR)path);\r
96         return strTipText;\r
97     }\r
98 \r
99     // find the revision in our cache. \r
100     // Might not be present if this is the WC / HEAD revision\r
101     // (but should not happen).\r
102 \r
103     index_t revisionIndex = revisions [revision];\r
104     assert (revisionIndex != NO_INDEX);\r
105     if (revisionIndex == NO_INDEX)\r
106         return strTipText;\r
107 \r
108     // get standard revprops\r
109 \r
110         TCHAR date[SVN_DATE_BUFFER];\r
111         apr_time_t timeStamp = revisionInfo.GetTimeStamp (revisionIndex);\r
112         SVN::formatDate(date, timeStamp);\r
113 \r
114     CString author \r
115         = CUnicodeUtils::StdGetUnicode \r
116             (revisionInfo.GetAuthor (revisionIndex)).c_str();\r
117     CString comment \r
118         = CUnicodeUtils::StdGetUnicode \r
119             (revisionInfo.GetComment (revisionIndex)).c_str();\r
120 \r
121     // description of the operation represented by this node\r
122 \r
123     CString revisionDescription;\r
124         if (classification.Is (CNodeClassification::IS_COPY_TARGET))\r
125     {\r
126         if (classification.Is (CNodeClassification::IS_TAG))\r
127             revisionDescription.LoadString (IDS_REVGRAPH_NODEIS_TAG);\r
128             else if (classification.Is (CNodeClassification::IS_BRANCH))\r
129             revisionDescription.LoadString (IDS_REVGRAPH_NODEIS_BRANCH);\r
130             else\r
131             revisionDescription.LoadString (IDS_REVGRAPH_NODEIS_COPY);\r
132     }\r
133         else if (classification.Is (CNodeClassification::IS_ADDED))\r
134         revisionDescription.LoadString (IDS_REVGRAPH_NODEIS_ADDED);\r
135         else if (classification.Is (CNodeClassification::IS_DELETED))\r
136         revisionDescription.LoadString (IDS_REVGRAPH_NODEIS_DELETE);\r
137         else if (classification.Is (CNodeClassification::IS_RENAMED))\r
138         revisionDescription.LoadString (IDS_REVGRAPH_NODEIS_RENAME);\r
139         else if (classification.Is (CNodeClassification::IS_LAST))\r
140         revisionDescription.LoadString (IDS_REVGRAPH_NODEIS_HEAD);\r
141     else if (classification.Is (CNodeClassification::IS_MODIFIED))\r
142         revisionDescription.LoadString (IDS_REVGRAPH_NODEIS_MODIFIED);\r
143         else\r
144         revisionDescription.LoadString (IDS_REVGRAPH_NODEIS_COPYSOURCE);\r
145 \r
146     // copy-from info, if available\r
147 \r
148     CString copyFromLine;\r
149     const CFullGraphNode* copySource = node->GetBase()->GetCopySource();\r
150         if (copySource != NULL)\r
151     {\r
152         CString copyFromPath \r
153             = CUnicodeUtils::StdGetUnicode \r
154                 (copySource->GetPath().GetPath()).c_str();\r
155         revision_t copyFromRevision = copySource->GetRevision();\r
156 \r
157         copyFromLine.Format ( IDS_REVGRAPH_BOXTOOLTIP_COPYSOURCE\r
158                             , (LPCTSTR)copyFromPath\r
159                             , copyFromRevision);\r
160     }\r
161 \r
162     // construct the tooltip\r
163 \r
164     if (node->GetFirstTag() == NULL)\r
165     {\r
166             strTipText.Format ( IDS_REVGRAPH_BOXTOOLTIP\r
167                           , revision, (LPCTSTR)revisionDescription\r
168                           , (LPCTSTR)path, (LPCTSTR)copyFromLine\r
169                           , (LPCTSTR)author, date, (LPCTSTR)comment);\r
170     }\r
171     else\r
172     {\r
173         CString tags;\r
174         int tagCount = 0;\r
175         for ( const CVisibleGraphNode::CFoldedTag* tag = node->GetFirstTag()\r
176             ; tag != NULL\r
177             ; tag = tag->GetNext())\r
178         {\r
179             ++tagCount;\r
180 \r
181             CString attributes;\r
182             if (tag->IsModified())\r
183                 attributes.LoadString (IDS_REVGRAPH_TAGMODIFIED);\r
184 \r
185             if (tag->IsDeleted())\r
186             {\r
187                 CString attribute;\r
188                 attribute.LoadString (IDS_REVGRAPH_TAGDELETED);\r
189                 if (attributes.IsEmpty())\r
190                     attributes = attribute;\r
191                 else\r
192                     attributes += _T(", ") + attribute;\r
193             }\r
194 \r
195             CString tagInfo;\r
196             std::string tagPath = tag->GetTag()->GetPath().GetPath();\r
197 \r
198             if (attributes.IsEmpty())\r
199             {\r
200                 tagInfo.Format (   tag->IsAlias() \r
201                                  ? IDS_REVGRAPH_TAGALIAS \r
202                                  : IDS_REVGRAPH_TAG\r
203                                , CUnicodeUtils::StdGetUnicode (tagPath).c_str());\r
204             }\r
205             else\r
206             {\r
207                 tagInfo.Format (   tag->IsAlias() \r
208                                  ? IDS_REVGRAPH_TAGALIASATTRIBUTED\r
209                                  : IDS_REVGRAPH_TAGATTRIBUTED\r
210                                , (LPCTSTR)attributes\r
211                                , CUnicodeUtils::StdGetUnicode (tagPath).c_str());\r
212             }\r
213 \r
214             tags +=   _T("\r\n")\r
215                     + CString (' ', tag->GetDepth() * 6) \r
216                     + tagInfo;\r
217         }\r
218 \r
219             strTipText.Format ( IDS_REVGRAPH_BOXTOOLTIP_TAGGED\r
220                           , revision, (LPCTSTR)revisionDescription\r
221                           , (LPCTSTR)path, (LPCTSTR)copyFromLine\r
222                           , (LPCTSTR)author, date, tagCount, (LPCTSTR)tags\r
223                           , (LPCTSTR)comment);\r
224     }\r
225 \r
226     // ready\r
227 \r
228     return strTipText;\r
229 }\r
230 \r
231 index_t CStandardLayoutNodeList::GetFirstVisible (const CRect& viewRect) const\r
232 {\r
233     return GetNextVisible (static_cast<index_t>(-1), viewRect);\r
234 }\r
235 \r
236 index_t CStandardLayoutNodeList::GetNextVisible ( index_t prev\r
237                                                 , const CRect& viewRect) const\r
238 {\r
239     for (size_t i = prev+1, count = nodes.size(); i < count; ++i)\r
240         if (FALSE != CRect().IntersectRect (nodes[i].rect, viewRect))\r
241             return static_cast<index_t>(i);\r
242 \r
243     return static_cast<index_t>(NO_INDEX);\r
244 }\r
245 \r
246 index_t CStandardLayoutNodeList::GetAt (const CPoint& point, CSize delta) const\r
247 {\r
248     for (size_t i = 0, count = nodes.size(); i < count; ++i)\r
249     {\r
250         const CRect& rect = nodes[i].rect;\r
251         if (   (rect.top - point.y <= delta.cy)\r
252             && (rect.left - point.x <= delta.cx)\r
253             && (point.y - rect.bottom <= delta.cy)\r
254             && (point.x - rect.right <= delta.cx))\r
255         {\r
256             return static_cast<index_t>(i);\r
257         }\r
258     }\r
259 \r
260     return static_cast<index_t>(NO_INDEX);\r
261 }\r
262 \r
263 // implement ILayoutNodeList\r
264 \r
265 CStandardLayoutNodeList::SNode \r
266 CStandardLayoutNodeList::GetNode (index_t index) const\r
267 {\r
268     SNode result;\r
269 \r
270         const CVisibleGraphNode* node = nodes[index].node;\r
271 \r
272     result.rect = nodes[index].rect;\r
273     result.node = node;\r
274     result.style = GetStyle (node);\r
275     result.styleFlags = GetStyleFlags (node);\r
276 \r
277     return result;\r
278 }\r