--- /dev/null
+// TortoiseSVN - a Windows shell extension for easy version control\r
+\r
+// Copyright (C) 2003-2009 - TortoiseSVN\r
+\r
+// This program is free software; you can redistribute it and/or\r
+// modify it under the terms of the GNU General Public License\r
+// as published by the Free Software Foundation; either version 2\r
+// of the License, or (at your option) any later version.\r
+\r
+// This program is distributed in the hope that it will be useful,\r
+// but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+// GNU General Public License for more details.\r
+\r
+// You should have received a copy of the GNU General Public License\r
+// along with this program; if not, write to the Free Software Foundation,\r
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+//\r
+#include "StdAfx.h"\r
+#include "ShowPathsAsDiff.h"\r
+#include "StandardLayout.h"\r
+#include "VisibleGraphNode.h"\r
+\r
+// construction\r
+\r
+CShowPathsAsDiff::CShowPathsAsDiff (CRevisionGraphOptionList& list)\r
+ : inherited (list)\r
+{\r
+}\r
+\r
+// cast @a layout pointer to the respective modification\r
+// interface and write the data.\r
+\r
+void CShowPathsAsDiff::ApplyTo (IRevisionGraphLayout* layout)\r
+{\r
+ // we need access to actual data\r
+\r
+ IStandardLayoutNodeAccess* nodeAccess \r
+ = dynamic_cast<IStandardLayoutNodeAccess*>(layout);\r
+ if (nodeAccess == NULL) \r
+ return;\r
+\r
+ // calculate the path diffs for each node\r
+\r
+ for (index_t i = 0, count = nodeAccess->GetNodeCount(); i < count; ++i)\r
+ {\r
+ CStandardLayoutNodeInfo* nodeInfo = nodeAccess->GetNode(i);\r
+\r
+ const CVisibleGraphNode* node = nodeInfo->node;\r
+ const CVisibleGraphNode* source = node->GetSource();\r
+\r
+ if (source != NULL)\r
+ {\r
+ const CDictionaryBasedTempPath& nodePath = node->GetPath();\r
+ const CDictionaryBasedTempPath& sourcePath = source->GetPath();\r
+\r
+ // optimization: in most cases, paths will be equal\r
+\r
+ if (nodePath == sourcePath)\r
+ {\r
+ nodeInfo->skipStartPathElements = nodePath.GetDepth();\r
+ }\r
+ else\r
+ {\r
+ // determine the lengths of the unchanged head and tail\r
+\r
+ CDictionaryBasedTempPath commonRoot \r
+ = nodePath.GetCommonRoot (sourcePath);\r
+\r
+ size_t nodeDepth = nodePath.GetDepth();\r
+ size_t sourceDepth = sourcePath.GetDepth();\r
+ size_t commonDepth = commonRoot.GetDepth();\r
+\r
+ size_t maxTail = min (nodeDepth, sourceDepth) - commonDepth;\r
+ size_t tail = 0;\r
+ for (; tail < maxTail; ++tail)\r
+ if ( nodePath[nodeDepth - tail - 1] \r
+ != sourcePath[sourceDepth - tail - 1])\r
+ break;\r
+\r
+ // special case: no change but elements have been ommitted\r
+ // (e.g. copy to parent)\r
+\r
+ if ((commonDepth + tail == nodeDepth) && (nodeDepth > 0))\r
+ {\r
+ // show at least one element\r
+\r
+ if (tail > 0)\r
+ {\r
+ // show that the tail has been moved up\r
+\r
+ --tail;\r
+ }\r
+ else\r
+ {\r
+ // show that we cut off some levels\r
+\r
+ --commonDepth;\r
+ }\r
+ }\r
+\r
+ // store results\r
+\r
+ nodeInfo->skipStartPathElements = commonDepth;\r
+ nodeInfo->skipTailPathElements = tail;\r
+ }\r
+ }\r
+ }\r
+}\r