summaryrefslogtreecommitdiffstats
path: root/tdehtml/rendering/counter_tree.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tdehtml/rendering/counter_tree.cpp')
-rw-r--r--tdehtml/rendering/counter_tree.cpp222
1 files changed, 222 insertions, 0 deletions
diff --git a/tdehtml/rendering/counter_tree.cpp b/tdehtml/rendering/counter_tree.cpp
new file mode 100644
index 000000000..931c54332
--- /dev/null
+++ b/tdehtml/rendering/counter_tree.cpp
@@ -0,0 +1,222 @@
+/*
+ * This file is part of the HTML rendering engine for KDE.
+ *
+ * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "rendering/counter_tree.h"
+#include "rendering/render_object.h"
+
+namespace tdehtml {
+
+CounterNode::CounterNode(RenderObject *o)
+ : m_hasCounters(false), m_isVisual(false),
+ m_value(0), m_count(0), m_parent(0), m_previous(0), m_next(0),
+ m_renderer(o) {}
+
+CounterNode::~CounterNode()
+{
+ if (m_parent) m_parent->removeChild(this);
+}
+
+void CounterNode::insertAfter ( CounterNode *, CounterNode *)
+{
+ Q_ASSERT( false);
+}
+
+void CounterNode::removeChild ( CounterNode *)
+{
+ Q_ASSERT( false);
+}
+
+void CounterNode::remove ()
+{
+ if (m_parent) m_parent->removeChild(this);
+ else {
+ Q_ASSERT(isReset());
+ Q_ASSERT(!firstChild());
+ Q_ASSERT(!lastChild());
+ }
+}
+
+void CounterNode::setHasCounters ()
+{
+ m_hasCounters = true;
+ if (parent())
+ parent()->setHasCounters();
+}
+
+void CounterNode::recount (bool first)
+{
+ int old_count = m_count;
+ if (m_previous)
+ m_count = m_previous->count() + m_value;
+ else {
+ assert(m_parent->firstChild() == this);
+ m_count = m_parent->value() + m_value;
+ }
+ if (old_count != m_count && !first)
+ setSelfDirty();
+ if (old_count != m_count || first) {
+ if (m_parent) m_parent->updateTotal(m_count);
+ if (m_next) m_next->recount();
+ }
+}
+
+void CounterNode::setSelfDirty ()
+{
+ if (m_renderer && m_isVisual)
+ m_renderer->setNeedsLayoutAndMinMaxRecalc();
+}
+
+void CounterNode::setParentDirty ()
+{
+ if (m_renderer && m_isVisual && m_hasCounters)
+ m_renderer->setNeedsLayoutAndMinMaxRecalc();
+}
+
+CounterReset::CounterReset(RenderObject *o) : CounterNode(o), m_total(0), m_first(0), m_last(0) {}
+CounterReset::~CounterReset() {}
+
+void CounterReset::insertAfter ( CounterNode *newChild, CounterNode *refChild )
+{
+ Q_ASSERT( newChild );
+ Q_ASSERT( !refChild || refChild->parent() == this );
+
+ newChild->m_parent = this;
+ newChild->m_previous = refChild;
+
+ if (refChild) {
+ newChild->m_next = refChild->m_next;
+ refChild->m_next = newChild;
+ } else {
+ newChild->m_next = m_first;
+ m_first = newChild;
+ }
+
+ if (newChild->m_next) {
+ assert(newChild->m_next->m_previous == refChild);
+ newChild->m_next->m_previous = newChild;
+ }
+ else {
+ assert (m_last == refChild);
+ m_last = newChild;
+ }
+
+ newChild->recount(true);
+}
+
+void CounterReset::removeChild ( CounterNode *oldChild )
+{
+ Q_ASSERT( oldChild );
+
+ CounterNode* next = oldChild->m_next;
+ CounterNode* prev = oldChild->m_previous;
+
+ if (oldChild->firstChild()) {
+ CounterNode* first = oldChild->firstChild();
+ CounterNode* last = oldChild->lastChild();
+ if (prev) {
+ prev->m_next = first;
+ first->m_previous = prev;
+ }
+ else {
+ assert ( m_first == oldChild );
+ m_first = first;
+ }
+
+ if (next) {
+ next->m_previous = last;
+ last->m_next = next;
+ }
+ else {
+ assert ( m_last == oldChild );
+ m_last = last;
+ }
+
+ next = first;
+ while (next) {
+ next->m_parent = this;
+ if (next == last) break;
+ next = next->m_next;
+ }
+
+ first->recount(true);
+ }
+ else {
+ if (prev) prev->m_next = next;
+ else {
+ assert ( m_first == oldChild );
+ m_first = next;
+ }
+ if (next) next->m_previous = prev;
+ else {
+ assert ( m_last == oldChild );
+ m_last = prev;
+ }
+ if (next)
+ next->recount();
+ }
+
+
+ oldChild->m_next = 0;
+ oldChild->m_previous = 0;
+ oldChild->m_parent = 0;
+}
+
+void CounterReset::recount (bool first)
+{
+ int old_count = m_count;
+ if (m_previous)
+ m_count = m_previous->count();
+ else if (m_parent)
+ m_count = m_parent->value();
+ else
+ m_count = 0;
+
+ updateTotal(m_value);
+ if (!first) setSelfDirty();
+ if (first || m_count != old_count) {
+ if (m_next) m_next->recount();
+ }
+}
+
+void CounterReset::setSelfDirty ()
+{
+ setParentDirty();
+}
+
+void CounterReset::setParentDirty ()
+{
+ if (hasCounters()) {
+ if (m_renderer && m_isVisual) m_renderer->setNeedsLayoutAndMinMaxRecalc();
+ CounterNode* n = firstChild();
+ for(; n; n = n->nextSibling())
+ {
+ n->setParentDirty();
+ }
+ }
+}
+
+void CounterReset::updateTotal (int value)
+{
+ if (value > m_total) m_total = value;
+}
+
+} // namespace