KHtml

counter_tree.cpp
1 /*
2  * This file is part of the HTML rendering engine for KDE.
3  *
4  * Copyright (C) 2005 Allan Sandfeld Jensen ([email protected])
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB. If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include "rendering/counter_tree.h"
24 
25 namespace khtml
26 {
27 
28 CounterNode::CounterNode(RenderObject *o)
29  : m_hasCounters(false), m_isVisual(false),
30  m_value(0), m_count(0), m_parent(nullptr), m_previous(nullptr), m_next(nullptr),
31  m_renderer(o) {}
32 
33 CounterNode::~CounterNode()
34 {
35  if (m_parent) {
36  m_parent->removeChild(this);
37  }
38 }
39 
40 void CounterNode::insertAfter(CounterNode *, CounterNode *)
41 {
42  Q_ASSERT(false);
43 }
44 
45 void CounterNode::removeChild(CounterNode *)
46 {
47  Q_ASSERT(false);
48 }
49 
50 void CounterNode::remove()
51 {
52  if (m_parent) {
53  m_parent->removeChild(this);
54  } else {
55  Q_ASSERT(isReset());
56  // abandon our children
57  CounterNode *n = firstChild();
58  for (; n; n = n->m_next) {
59  n->m_parent = nullptr;
60  }
61  }
62 }
63 
64 void CounterNode::setHasCounters()
65 {
66  m_hasCounters = true;
67  if (parent()) {
68  parent()->setHasCounters();
69  }
70 }
71 
72 void CounterNode::recount(bool first)
73 {
74  int old_count = m_count;
75  if (m_previous) {
76  m_count = m_previous->count() + m_value;
77  } else {
78  assert(m_parent->firstChild() == this);
79  m_count = m_parent->value() + m_value;
80  }
81  if (old_count != m_count && !first) {
82  setSelfDirty();
83  }
84  if (old_count != m_count || first) {
85  if (m_parent) {
86  m_parent->updateTotal(m_count);
87  }
88  if (m_next) {
89  m_next->recount();
90  }
91  }
92 }
93 
94 void CounterNode::setSelfDirty()
95 {
96  if (m_renderer && m_isVisual) {
97  m_renderer->setNeedsLayoutAndMinMaxRecalc();
98  }
99 }
100 
101 void CounterNode::setParentDirty()
102 {
103  if (m_renderer && m_isVisual && m_hasCounters) {
104  m_renderer->setNeedsLayoutAndMinMaxRecalc();
105  }
106 }
107 
108 CounterReset::CounterReset(RenderObject *o) : CounterNode(o), m_total(0), m_first(nullptr), m_last(nullptr) {}
109 CounterReset::~CounterReset() {}
110 
111 void CounterReset::insertAfter(CounterNode *newChild, CounterNode *refChild)
112 {
113  Q_ASSERT(newChild);
114  Q_ASSERT(!refChild || refChild->parent() == this);
115 
116  newChild->m_parent = this;
117  newChild->m_previous = refChild;
118 
119  if (refChild) {
120  newChild->m_next = refChild->m_next;
121  refChild->m_next = newChild;
122  } else {
123  newChild->m_next = m_first;
124  m_first = newChild;
125  }
126 
127  if (newChild->m_next) {
128  assert(newChild->m_next->m_previous == refChild);
129  newChild->m_next->m_previous = newChild;
130  } else {
131  assert(m_last == refChild);
132  m_last = newChild;
133  }
134 
135  newChild->recount(true);
136 }
137 
138 void CounterReset::removeChild(CounterNode *oldChild)
139 {
140  Q_ASSERT(oldChild);
141 
142  CounterNode *next = oldChild->m_next;
143  CounterNode *prev = oldChild->m_previous;
144 
145  if (oldChild->firstChild()) {
146  CounterNode *first = oldChild->firstChild();
147  CounterNode *last = oldChild->lastChild();
148  if (prev) {
149  prev->m_next = first;
150  first->m_previous = prev;
151  } else {
152  assert(m_first == oldChild);
153  m_first = first;
154  }
155 
156  if (next) {
157  next->m_previous = last;
158  last->m_next = next;
159  } else {
160  assert(m_last == oldChild);
161  m_last = last;
162  }
163 
164  next = first;
165  while (next) {
166  next->m_parent = this;
167  if (next == last) {
168  break;
169  }
170  next = next->m_next;
171  }
172 
173  first->recount(true);
174  } else {
175  if (prev) {
176  prev->m_next = next;
177  } else {
178  assert(m_first == oldChild);
179  m_first = next;
180  }
181  if (next) {
182  next->m_previous = prev;
183  } else {
184  assert(m_last == oldChild);
185  m_last = prev;
186  }
187  if (next) {
188  next->recount();
189  }
190  }
191 
192  oldChild->m_next = nullptr;
193  oldChild->m_previous = nullptr;
194  oldChild->m_parent = nullptr;
195 }
196 
197 void CounterReset::recount(bool first)
198 {
199  int old_count = m_count;
200  if (m_previous) {
201  m_count = m_previous->count();
202  } else if (m_parent) {
203  m_count = m_parent->value();
204  } else {
205  m_count = 0;
206  }
207 
208  updateTotal(m_value);
209  if (!first) {
210  setSelfDirty();
211  }
212  if (first || m_count != old_count) {
213  if (m_next) {
214  m_next->recount();
215  }
216  }
217 }
218 
219 void CounterReset::setSelfDirty()
220 {
221  setParentDirty();
222 }
223 
224 void CounterReset::setParentDirty()
225 {
226  if (hasCounters()) {
227  if (m_renderer && m_isVisual) {
228  m_renderer->setNeedsLayoutAndMinMaxRecalc();
229  }
230  CounterNode *n = firstChild();
231  for (; n; n = n->nextSibling()) {
232  n->setParentDirty();
233  }
234  }
235 }
236 
237 void CounterReset::updateTotal(int value)
238 {
239  if (value > m_total) {
240  m_total = value;
241  }
242 }
243 
244 } // namespace
This file is part of the HTML rendering engine for KDE.
MESSAGECORE_EXPORT KMime::Content * next(KMime::Content *node, bool allowChildren=true)
MESSAGECORE_EXPORT KMime::Content * firstChild(const KMime::Content *node)
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Mon Oct 25 2021 22:48:11 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.