fix logic
[personal-kdelibs.git] / khtml / rendering / counter_tree.cpp
blob104ac68e04fc3431dd8362c933f23ff5eb791f45
1 /*
2 * This file is part of the HTML rendering engine for KDE.
4 * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
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.
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.
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.
23 #include "rendering/counter_tree.h"
24 #include "rendering/render_object.h"
26 namespace khtml {
28 CounterNode::CounterNode(RenderObject *o)
29 : m_hasCounters(false), m_isVisual(false),
30 m_value(0), m_count(0), m_parent(0), m_previous(0), m_next(0),
31 m_renderer(o) {}
33 CounterNode::~CounterNode()
35 if (m_parent) m_parent->removeChild(this);
38 void CounterNode::insertAfter ( CounterNode *, CounterNode *)
40 Q_ASSERT( false);
43 void CounterNode::removeChild ( CounterNode *)
45 Q_ASSERT( false);
48 void CounterNode::remove ()
50 if (m_parent) m_parent->removeChild(this);
51 else {
52 Q_ASSERT(isReset());
53 // abandon our children
54 CounterNode *n = firstChild();
55 for(; n; n = n->m_next)
56 n->m_parent = 0;
60 void CounterNode::setHasCounters ()
62 m_hasCounters = true;
63 if (parent())
64 parent()->setHasCounters();
67 void CounterNode::recount (bool first)
69 int old_count = m_count;
70 if (m_previous)
71 m_count = m_previous->count() + m_value;
72 else {
73 assert(m_parent->firstChild() == this);
74 m_count = m_parent->value() + m_value;
76 if (old_count != m_count && !first)
77 setSelfDirty();
78 if (old_count != m_count || first) {
79 if (m_parent) m_parent->updateTotal(m_count);
80 if (m_next) m_next->recount();
84 void CounterNode::setSelfDirty ()
86 if (m_renderer && m_isVisual)
87 m_renderer->setNeedsLayoutAndMinMaxRecalc();
90 void CounterNode::setParentDirty ()
92 if (m_renderer && m_isVisual && m_hasCounters)
93 m_renderer->setNeedsLayoutAndMinMaxRecalc();
96 CounterReset::CounterReset(RenderObject *o) : CounterNode(o), m_total(0), m_first(0), m_last(0) {}
97 CounterReset::~CounterReset() {}
99 void CounterReset::insertAfter ( CounterNode *newChild, CounterNode *refChild )
101 Q_ASSERT( newChild );
102 Q_ASSERT( !refChild || refChild->parent() == this );
104 newChild->m_parent = this;
105 newChild->m_previous = refChild;
107 if (refChild) {
108 newChild->m_next = refChild->m_next;
109 refChild->m_next = newChild;
110 } else {
111 newChild->m_next = m_first;
112 m_first = newChild;
115 if (newChild->m_next) {
116 assert(newChild->m_next->m_previous == refChild);
117 newChild->m_next->m_previous = newChild;
119 else {
120 assert (m_last == refChild);
121 m_last = newChild;
124 newChild->recount(true);
127 void CounterReset::removeChild ( CounterNode *oldChild )
129 Q_ASSERT( oldChild );
131 CounterNode* next = oldChild->m_next;
132 CounterNode* prev = oldChild->m_previous;
134 if (oldChild->firstChild()) {
135 CounterNode* first = oldChild->firstChild();
136 CounterNode* last = oldChild->lastChild();
137 if (prev) {
138 prev->m_next = first;
139 first->m_previous = prev;
141 else {
142 assert ( m_first == oldChild );
143 m_first = first;
146 if (next) {
147 next->m_previous = last;
148 last->m_next = next;
150 else {
151 assert ( m_last == oldChild );
152 m_last = last;
155 next = first;
156 while (next) {
157 next->m_parent = this;
158 if (next == last) break;
159 next = next->m_next;
162 first->recount(true);
164 else {
165 if (prev) prev->m_next = next;
166 else {
167 assert ( m_first == oldChild );
168 m_first = next;
170 if (next) next->m_previous = prev;
171 else {
172 assert ( m_last == oldChild );
173 m_last = prev;
175 if (next)
176 next->recount();
180 oldChild->m_next = 0;
181 oldChild->m_previous = 0;
182 oldChild->m_parent = 0;
185 void CounterReset::recount (bool first)
187 int old_count = m_count;
188 if (m_previous)
189 m_count = m_previous->count();
190 else if (m_parent)
191 m_count = m_parent->value();
192 else
193 m_count = 0;
195 updateTotal(m_value);
196 if (!first) setSelfDirty();
197 if (first || m_count != old_count) {
198 if (m_next) m_next->recount();
202 void CounterReset::setSelfDirty ()
204 setParentDirty();
207 void CounterReset::setParentDirty ()
209 if (hasCounters()) {
210 if (m_renderer && m_isVisual) m_renderer->setNeedsLayoutAndMinMaxRecalc();
211 CounterNode* n = firstChild();
212 for(; n; n = n->nextSibling())
214 n->setParentDirty();
219 void CounterReset::updateTotal (int value)
221 if (value > m_total) m_total = value;
224 } // namespace