1 // TortoiseSVN - a Windows shell extension for easy version control
\r
3 // Copyright (C) 2003-2008 - TortoiseSVN
\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
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
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
20 #include "resource.h"
\r
21 #include "StandardLayoutNodeList.h"
\r
22 #include "VisibleGraphNode.h"
\r
23 #include "CachedLogInfo.h"
\r
25 #include "UnicodeUtils.h"
\r
29 index_t CStandardLayoutNodeList::GetStyle
\r
30 (const CVisibleGraphNode* node) const
\r
32 CNodeClassification classification = node->GetClassification();
\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
45 return ILayoutNodeList::SNode::STYLE_DEFAULT;
\r
48 DWORD CStandardLayoutNodeList::GetStyleFlags
\r
49 (const CVisibleGraphNode* /*node*/) const
\r
56 CStandardLayoutNodeList::CStandardLayoutNodeList
\r
57 ( const std::vector<CStandardLayoutNodeInfo>& nodes
\r
58 , const CCachedLogInfo* cache)
\r
64 // implement ILayoutItemList
\r
66 index_t CStandardLayoutNodeList::GetCount() const
\r
68 return static_cast<index_t>(nodes.size());
\r
71 CString CStandardLayoutNodeList::GetToolTip (index_t index) const
\r
75 const CRevisionIndex& revisions = cache->GetRevisions();
\r
76 const CRevisionInfoContainer& revisionInfo = cache->GetLogInfo();
\r
78 const CVisibleGraphNode* node = nodes[index].node;
\r
82 CNodeClassification classification = node->GetClassification();
\r
83 revision_t revision = node->GetRevision();
\r
86 = CUnicodeUtils::StdGetUnicode
\r
87 (node->GetPath().GetPath()).c_str();
\r
89 // special case: the "workspace is modified" node
\r
91 if (classification.Is (CNodeClassification::IS_MODIFIED_WC))
\r
93 strTipText.Format ( IDS_REVGRAPH_BOXTOOLTIP_WC
\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
103 index_t revisionIndex = revisions [revision];
\r
104 assert (revisionIndex != NO_INDEX);
\r
105 if (revisionIndex == NO_INDEX)
\r
108 // get standard revprops
\r
110 TCHAR date[SVN_DATE_BUFFER];
\r
111 apr_time_t timeStamp = revisionInfo.GetTimeStamp (revisionIndex);
\r
112 SVN::formatDate(date, timeStamp);
\r
115 = CUnicodeUtils::StdGetUnicode
\r
116 (revisionInfo.GetAuthor (revisionIndex)).c_str();
\r
118 = CUnicodeUtils::StdGetUnicode
\r
119 (revisionInfo.GetComment (revisionIndex)).c_str();
\r
121 // description of the operation represented by this node
\r
123 CString revisionDescription;
\r
124 if (classification.Is (CNodeClassification::IS_COPY_TARGET))
\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
131 revisionDescription.LoadString (IDS_REVGRAPH_NODEIS_COPY);
\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
144 revisionDescription.LoadString (IDS_REVGRAPH_NODEIS_COPYSOURCE);
\r
146 // copy-from info, if available
\r
148 CString copyFromLine;
\r
149 const CFullGraphNode* copySource = node->GetBase()->GetCopySource();
\r
150 if (copySource != NULL)
\r
152 CString copyFromPath
\r
153 = CUnicodeUtils::StdGetUnicode
\r
154 (copySource->GetPath().GetPath()).c_str();
\r
155 revision_t copyFromRevision = copySource->GetRevision();
\r
157 copyFromLine.Format ( IDS_REVGRAPH_BOXTOOLTIP_COPYSOURCE
\r
158 , (LPCTSTR)copyFromPath
\r
159 , copyFromRevision);
\r
162 // construct the tooltip
\r
164 if (node->GetFirstTag() == NULL)
\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
175 for ( const CVisibleGraphNode::CFoldedTag* tag = node->GetFirstTag()
\r
177 ; tag = tag->GetNext())
\r
181 CString attributes;
\r
182 if (tag->IsModified())
\r
183 attributes.LoadString (IDS_REVGRAPH_TAGMODIFIED);
\r
185 if (tag->IsDeleted())
\r
188 attribute.LoadString (IDS_REVGRAPH_TAGDELETED);
\r
189 if (attributes.IsEmpty())
\r
190 attributes = attribute;
\r
192 attributes += _T(", ") + attribute;
\r
196 std::string tagPath = tag->GetTag()->GetPath().GetPath();
\r
198 if (attributes.IsEmpty())
\r
200 tagInfo.Format ( tag->IsAlias()
\r
201 ? IDS_REVGRAPH_TAGALIAS
\r
203 , CUnicodeUtils::StdGetUnicode (tagPath).c_str());
\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
215 + CString (' ', tag->GetDepth() * 6)
\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
231 index_t CStandardLayoutNodeList::GetFirstVisible (const CRect& viewRect) const
\r
233 return GetNextVisible (static_cast<index_t>(-1), viewRect);
\r
236 index_t CStandardLayoutNodeList::GetNextVisible ( index_t prev
\r
237 , const CRect& viewRect) const
\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
243 return static_cast<index_t>(NO_INDEX);
\r
246 index_t CStandardLayoutNodeList::GetAt (const CPoint& point, CSize delta) const
\r
248 for (size_t i = 0, count = nodes.size(); i < count; ++i)
\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
256 return static_cast<index_t>(i);
\r
260 return static_cast<index_t>(NO_INDEX);
\r
263 // implement ILayoutNodeList
\r
265 CStandardLayoutNodeList::SNode
\r
266 CStandardLayoutNodeList::GetNode (index_t index) const
\r
270 const CVisibleGraphNode* node = nodes[index].node;
\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