OSDN Git Service

Webpage Compare: Add support for generating report files (#1941)
[winmerge-jp/winmerge-jp.git] / Src / DiffItemList.cpp
1 /**
2  *  @file DiffItemList.cpp
3  *
4  *  @brief Implementation of DiffItemList
5  */ 
6
7 #include "pch.h"
8 #include "DiffItemList.h"
9 #include <cassert>
10
11 /**
12  * @brief Constructor
13  */
14 DiffItemList::DiffItemList() : m_pRoot(nullptr)
15 {
16 }
17
18 /**
19  * @brief Destructor
20  */
21 DiffItemList::~DiffItemList()
22 {
23         RemoveAll();
24 }
25
26 /**
27  * @brief Add new diffitem to structured DIFFITEM tree.
28  * @param [in] par Parent item, or `nullptr` if no parent.
29  * @return Pointer to the added item.
30  */
31 DIFFITEM *DiffItemList::AddNewDiff(DIFFITEM *par)
32 {
33         DIFFITEM *p = new DIFFITEM;
34         if (par == nullptr)
35         {
36                 // if there is no `parent`, this item becomes a child of `m_pRoot`
37                 assert(m_pRoot != nullptr);
38                 m_pRoot->AddChildToParent(p);
39         }
40         else
41                 par->AddChildToParent(p);
42
43         return p;
44 }
45
46 /**
47  * @brief Empty structured DIFFITEM tree
48  */
49 void DiffItemList::RemoveAll()
50 {
51         delete m_pRoot;
52         m_pRoot = nullptr;
53 }
54
55 void DiffItemList::InitDiffItemList()
56 {
57         assert(m_pRoot == nullptr);
58         m_pRoot = new DIFFITEM;
59 }
60
61 void DiffItemList::ClearAllAdditionalProperties()
62 {
63         assert(m_pRoot != nullptr);
64         for (DIFFITEM* p = GetFirstDiffPosition(); p != nullptr; p = p->GetFwdSiblingLink())
65                 p->ClearAllAdditionalProperties();
66 }
67
68 /**
69  * @brief Get position of first item in structured DIFFITEM tree
70  */
71 DIFFITEM *DiffItemList::GetFirstDiffPosition() const
72 {
73         return GetFirstChildDiffPosition(m_pRoot);
74 }
75
76 /**
77  * @brief Get position of first child item in structured DIFFITEM tree
78  * @param  [in] par Position of parent diff item (maybe `nullptr`)
79  * @return Position of first child item (or `nullptr` if no children)
80  */
81 DIFFITEM *DiffItemList::GetFirstChildDiffPosition(const DIFFITEM *par) const
82 {
83         if (par == nullptr)
84         {
85                 assert(m_pRoot != nullptr);
86                 return m_pRoot->GetFirstChild();
87         }
88         else
89                 return par->GetFirstChild();
90 }
91
92 /**
93  * @brief Get position of next item in structured DIFFITEM tree
94  * @param [in,out] diffpos Position of current item, updated to next item position
95  * @return Diff Item (by reference) in current position
96  */
97 const DIFFITEM &DiffItemList::GetNextDiffPosition(DIFFITEM *&diffpos) const
98 {
99         DIFFITEM *p = diffpos;
100         if (diffpos->HasChildren())
101         {
102                 diffpos = GetFirstChildDiffPosition(diffpos);
103         }
104         else
105         {
106                 DIFFITEM *cur = diffpos;
107                 do
108                 {
109                         diffpos = cur->GetFwdSiblingLink();
110                         cur = cur->GetParentLink();
111                         assert(cur != nullptr);
112                 } while (diffpos == nullptr && cur->HasParent());
113         }
114         return *p;
115 }
116
117 /**
118  * @brief Get position of next item in structured DIFFITEM tree
119  * @param [in,out] diffpos Position of current item, updated to next item position
120  * @return Diff Item (by reference) in current position
121  */
122 DIFFITEM &DiffItemList::GetNextDiffRefPosition(DIFFITEM *&diffpos)
123 {
124         return (DIFFITEM &)GetNextDiffPosition(diffpos);
125 }
126
127 /**
128  * @brief Get position of next sibling item in structured DIFFITEM tree
129  * @param [in,out] diffpos Position of current item, updated to next sibling item position
130  * @return Diff Item (by reference) in current position
131  */
132 const DIFFITEM &DiffItemList::GetNextSiblingDiffPosition(DIFFITEM *&diffpos) const
133 {
134         DIFFITEM *p = diffpos;
135         diffpos = p->GetFwdSiblingLink();
136         assert(p==nullptr || diffpos==nullptr || p->GetParentLink() == diffpos->GetParentLink());
137         assert(p==nullptr || p->HasParent());
138         return *p;
139 }
140
141 /**
142  * @brief Get position of next sibling item in structured DIFFITEM tree
143  * @param [in,out] diffpos Position of current item, updated to next sibling item position
144  * @return Diff Item (by reference) in current position
145  */
146 DIFFITEM &DiffItemList::GetNextSiblingDiffRefPosition(DIFFITEM *&diffpos)
147 {
148         return (DIFFITEM &)GetNextSiblingDiffPosition(diffpos);
149 }
150
151 /**
152  * @brief Alter some bit flags of the diffcode.
153  *
154  * Examples:
155  *  SetDiffStatusCode(pos, DIFFCODE::SAME, DIFFCODE::COMPAREFLAGS)
156  *   changes the comparison result to be the same.
157  * 
158  *  SetDiffStatusCode(pos, DIFFCODE::BOTH, DIFFCODE::SIDEFLAG)
159  *   changes the side status to be both (sides).
160  *
161  * SetDiffStatusCode(pos, DIFFCODE::SAME+DIFFCODE::BOTH, DIFFCODE::COMPAREFLAGS+DIFFCODE::SIDEFLAG);
162  *  changes the comparison result to be the same and the side status to be both
163  */
164 void DiffItemList::SetDiffStatusCode(DIFFITEM *diffpos, unsigned diffcode, unsigned mask)
165 {
166         assert(diffpos != nullptr);
167         DIFFITEM &di = GetDiffRefAt(diffpos);
168         assert( ((~mask) & diffcode) == 0 ); // make sure they only set flags in their mask
169         di.diffcode.diffcode &= (~mask); // remove current data
170         di.diffcode.diffcode |= diffcode; // add new data
171 }
172
173 /**
174  * @brief Update difference counts.
175  */
176 void DiffItemList::SetDiffCounts(DIFFITEM *diffpos, unsigned diffs, unsigned ignored)
177 {
178         assert(diffpos != nullptr);
179         DIFFITEM &di = GetDiffRefAt(diffpos);
180         di.nidiffs = ignored; // see StoreDiffResult() in DirScan.cpp
181         di.nsdiffs = diffs;
182 }
183
184 /**
185  * @brief Returns item's custom (user) flags.
186  * @param [in] diffpos Position of item.
187  * @return Custom flags from item.
188  */
189 unsigned DiffItemList::GetCustomFlags1(DIFFITEM *diffpos) const
190 {
191         assert(diffpos != nullptr);
192         const DIFFITEM &di = GetDiffAt(diffpos);
193         return di.customFlags;
194 }
195
196 /**
197  * @brief Sets item's custom (user) flags.
198  * @param [in] diffpos Position of item.
199  * @param [in] flag Value of flag to set.
200  */
201 void DiffItemList::SetCustomFlags1(DIFFITEM *diffpos, unsigned flag)
202 {
203         assert(diffpos != nullptr);
204         DIFFITEM &di = GetDiffRefAt(diffpos);
205         di.customFlags = flag;
206 }
207
208 void DiffItemList::Swap(int idx1, int idx2)
209 {
210         assert(m_pRoot != nullptr);
211         for (DIFFITEM *p = GetFirstDiffPosition(); p != nullptr; p = p->GetFwdSiblingLink())
212                 p->Swap(idx1, idx2);
213 }