4 * @brief Implementation of DIFFITEM
12 DIFFITEM DIFFITEM::emptyitem;
14 /** @brief DIFFITEM's destructor */
18 assert(children == nullptr);
21 /** @brief Return path to left/right file, including all but file name */
22 String DIFFITEM::getFilepath(int nIndex, const String &sRoot) const
24 if (diffcode.exists(nIndex))
26 return paths::ConcatPath(sRoot, diffFileInfo[nIndex].path);
31 /** @brief Return depth of path */
32 int DIFFITEM::GetDepth() const
36 for (depth = 0, cur = parent; cur->parent != nullptr; depth++, cur = cur->parent)
42 * @brief Return whether the specified item is an ancestor of the current item
44 bool DIFFITEM::IsAncestor(const DIFFITEM *pdi) const
47 for (cur = this; cur->parent != nullptr; cur = cur->parent)
49 if (cur->parent == pdi)
55 /** @brief Remove and delete all children DIFFITEM entries */
56 void DIFFITEM::RemoveChildren()
58 DIFFITEM *pRem = children;
59 while (pRem != nullptr)
61 assert(pRem->parent == this);
62 DIFFITEM *pNext = pRem->Flink;
69 /** @brief Swap two items in `diffFileInfo[]`. Used when swapping GUI panes. */
70 void DIFFITEM::Swap(int idx1, int idx2)
72 std::swap(diffFileInfo[idx1], diffFileInfo[idx2]);
73 diffcode.swap(idx1, idx2);
76 for (DIFFITEM *p = children; p != nullptr; p = p->Flink)
83 DIFFITEM *DIFFITEM::GetEmptyItem()
85 // TODO: It would be better if there were individual items
86 // (for whatever these special items are?) because here we
87 // have to *hope* client does not modify this static (shared) item
89 assert(emptyitem.parent == nullptr);
90 assert(emptyitem.Flink == nullptr);
91 assert(emptyitem.Blink == nullptr);
92 assert(emptyitem.children == nullptr);
93 assert(emptyitem.nidiffs == -1);
94 assert(emptyitem.nsdiffs == -1);
95 assert(emptyitem.customFlags == ViewCustomFlags::INVALID_CODE);
96 assert(emptyitem.diffcode.diffcode == 0);
103 * @brief Add Sibling item
104 * @param [in] p The item to be added
106 void DIFFITEM::AppendSibling(DIFFITEM *p)
108 assert(parent->children == this);
112 if (Blink == nullptr)
114 // Insert first sibling (besides ourself)
115 assert(Flink == nullptr);
122 // Insert additional siblings
123 assert(Flink != nullptr);
131 void DIFFITEM::AddChildToParent(DIFFITEM *p)
134 if (children == nullptr)
139 children->AppendSibling(p);
142 void DIFFITEM::DelinkFromSiblings()
144 if (parent != nullptr && parent->children != nullptr)
146 // If `this` is at end of Sibling linkage, fix First Child's end link
147 if (parent->children->Blink == this)
149 assert(Flink == nullptr);
150 parent->children->Blink = Blink;
154 // If `this` is the First Child, link parent to next Sibling
155 if (parent->children == this)
157 parent->children = Flink;
160 if (Blink != nullptr && Blink->Flink != nullptr)
161 Blink->Flink = Flink;
162 if (Flink != nullptr)
163 Flink->Blink = Blink;
164 Flink = Blink = nullptr;
167 void DIFFCODE::swap(int idx1, int idx2)
169 bool e[3] = { false, false, false };
170 for (int i = 0; i < 3; ++i)
172 std::swap(e[idx1], e[idx2]);
174 for (int i = 0; i < 3; ++i)
175 if (e[i]) setSideFlag(i);
176 bool binflag1 = (diffcode & (BINSIDE1 << idx1));
177 bool binflag2 = (diffcode & (BINSIDE1 << idx2));
178 Set(BINSIDE1 << idx1, binflag2 ? (BINSIDE1 << idx1) : 0);
179 Set(BINSIDE1 << idx2, binflag1 ? (BINSIDE1 << idx2) : 0);
180 if ((diffcode & THREEWAY) != 0)
183 switch (diffcode & COMPAREFLAGS3WAY)
186 if (idx1 == 0 || idx2 == 0)
187 idx = (idx1 == 0) ? idx2 : idx1;
190 if (idx1 == 1 || idx2 == 1)
191 idx = (idx1 == 1) ? idx2 : idx1;
194 if (idx1 == 2 || idx2 == 2)
195 idx = (idx1 == 2) ? idx2 : idx1;
199 Set(COMPAREFLAGS3WAY, DIFF1STONLY);
201 Set(COMPAREFLAGS3WAY, DIFF2NDONLY);
203 Set(COMPAREFLAGS3WAY, DIFF3RDONLY);