/* * 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