summaryrefslogtreecommitdiffstats
path: root/kword/KWFrameList.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kword/KWFrameList.cpp')
-rw-r--r--kword/KWFrameList.cpp197
1 files changed, 197 insertions, 0 deletions
diff --git a/kword/KWFrameList.cpp b/kword/KWFrameList.cpp
new file mode 100644
index 00000000..8df2da8d
--- /dev/null
+++ b/kword/KWFrameList.cpp
@@ -0,0 +1,197 @@
+/* This file is part of the KOffice project
+ * Copyright (C) 2005 Thomas Zander <zander@kde.org>
+ *
+ * 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; version 2.
+
+ * 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 <algorithm>
+#include "KWFrameList.h"
+#include "KWFrame.h"
+#include "KWFrameSet.h"
+#include "KWTextFrameSet.h"
+#include "KWDocument.h"
+#include "KWViewMode.h"
+#include "KWPageManager.h"
+
+//#define DEBUG_SPEED
+
+KWFrameList::KWFrameList(KWDocument *doc, KWFrame *theFrame) {
+ m_doc = doc;
+ m_frame = theFrame;
+
+ update();
+}
+
+QValueList<KWFrame *> KWFrameList::framesBelow() const {
+ QValueList<KWFrame *> frames;
+//kdDebug() << "framesBelow " << endl;
+
+ // Copy until we find m_frame
+ for ( QValueVector<KWFrame*>::const_iterator it = m_frames.begin(), end = m_frames.end(); it != end && *it != m_frame; ++it) {
+ frames.append( *it );
+ }
+
+ return frames;
+}
+
+QValueList<KWFrame *> KWFrameList::framesOnTop() const {
+//kdDebug() << "framesOnTop " << endl;
+ QValueList<KWFrame *> frames;
+
+ // Copy from m_frame to the end
+ bool found = false;
+ for ( QValueVector<KWFrame*>::const_iterator it = m_frames.begin(), end = m_frames.end(); it != end; ++it) {
+ KWFrame* frame = *it;
+ if ( found ) {
+ Q_ASSERT( !frame->frameSet()->isFloating() );
+ frames.append( frame );
+ }
+ else if ( frame == m_frame )
+ found = true;
+ }
+
+ return frames;
+}
+
+void KWFrameList::setFrames(const QPtrList<KWFrame> &frames) {
+ // kdDebug(31001) << "KWFrameList::setFrames for " << m_frame->frameSet()->name() << endl;
+ m_frames.clear();
+ if ( m_doc->layoutViewMode() && !m_doc->layoutViewMode()->hasFrames() )
+ return;
+
+ QPtrList<KWFrameSet> parentFramesets;
+ KWFrameSet *fs = m_frame->frameSet();
+ while(fs) {
+ parentFramesets.append(fs);
+ fs = (KWFrameSet*) fs->anchorFrameset();
+ }
+
+ // We now look at all other frames (in the same page)
+ // to check for intersections. This is o(n^2), but with n small.
+ QPtrListIterator<KWFrame> it( frames );
+ for ( ; it.current() ; ++it )
+ {
+ KWFrame* daFrame = it.current();
+ // kdDebug(32001) << "frame: " << daFrame->frameSet()->name() << endl;
+ if ( m_frame == daFrame ) {
+ m_frames.append( daFrame );
+ continue;
+ }
+ // Skip 'daFrame' if it belongs to a table.
+ // We trust that KWTableFrameSet will not make cells overlap ;)
+ if ( m_frame->frameSet()->groupmanager() || daFrame->frameSet()->groupmanager() )
+ continue;
+ // Skip all frames from the parent frameset, if 'm_frame' is floating
+ // ## might need a for loop for the case of inline-inside-inline,
+ // or maybe calling isPaintedBy instead [depending on what should happen for tables]
+ if ( daFrame->frameSet()->isFloating() &&
+ (parentFramesets.contains(daFrame->frameSet()->anchorFrameset()) ||
+ daFrame->frameSet()->isPaintedBy(m_frame->frameSet())) )
+ continue;
+ // Floating frames are not "on top", they are "inside".
+ // They are not "below" anything either - the parent frameset is.
+ if ( m_frame->frameSet()->isFloating() )
+ continue;
+ KoRect intersect = m_frame->intersect( daFrame->outerKoRect() );
+ if ( !intersect.isEmpty() )
+ m_frames.append( daFrame );
+ }
+ std::sort( m_frames.begin(), m_frames.end(), KWFrame::compareFrameZOrder );
+}
+
+void KWFrameList::updateAfterMove(int oldPageNum) {
+ int pageNumber = m_doc->pageManager()->pageNumber(m_frame);
+ updateZOrderFor(m_doc->framesInPage( pageNumber, false ));
+
+ if (pageNumber != oldPageNum)
+ updateZOrderFor(m_doc->framesInPage( oldPageNum, false ));
+}
+
+void KWFrameList::update() {
+ int pageNumber = m_doc->pageManager()->pageNumber(m_frame);
+ if(pageNumber == -1)
+ return;
+ updateZOrderFor(m_doc->framesInPage( pageNumber, false ));
+}
+
+void KWFrameList::updateZOrderFor(const QPtrList<KWFrame> &frames) {
+#ifdef DEBUG_SPEED
+ kdDebug(32001) << "KWFrameList::updateZOrderFor " << frames.count() << " frames"<< endl;
+ QTime dt;
+ dt.start();
+ int numberAdded = 0;
+#endif
+
+ QPtrListIterator<KWFrame> iter(frames);
+ while( iter.current() ) {
+ KWFrame *frame = iter.current();
+ Q_ASSERT( frame->frameStack() );
+
+ frame->frameStack()->setFrames(frames);
+#ifdef DEBUG_SPEED
+ numberAdded += frame->frameStack()->m_frames.count();
+#endif
+ ++iter;
+ }
+
+#ifdef DEBUG_SPEED
+ kdDebug(32001) << " updateZOrderFor took " << (float)(dt.elapsed()) / 1000 << " seconds, added " << numberAdded << " frames" << endl;
+#endif
+}
+
+// ****** statics ******
+KWFrameList *KWFrameList::getFirstFrameList(KWDocument *doc) {
+ for (QPtrListIterator<KWFrameSet> fsit = doc->framesetsIterator(); fsit.current() ; ++fsit ) {
+ KWFrame *frame = fsit.current()->frame(0);
+ if (frame && frame->frameStack())
+ return frame->frameStack();
+ }
+ return 0;
+}
+
+void KWFrameList::recalcFrames(KWDocument *doc, int pageFrom, int pageTo) {
+ for(int i=pageTo; i >= pageFrom; i--) {
+ QPtrList<KWFrame> framesOnPage = doc->framesInPage( i, false );
+ KWFrame *f = framesOnPage.first();
+ while(f) {
+ Q_ASSERT(f->frameStack());
+ f->frameStack()->setFrames(framesOnPage);
+ f = framesOnPage.next();
+ }
+ }
+}
+
+void KWFrameList::recalcAllFrames(KWDocument *doc) {
+ recalcFrames(doc, doc->startPage(), doc->lastPage());
+}
+
+void KWFrameList::createFrameList(KWFrame *f, KWDocument *doc) {
+ Q_ASSERT(f);
+ Q_ASSERT(doc);
+ if(f->frameStack())
+ return;
+ f->setFrameStack(new KWFrameList(doc, f));
+}
+
+void KWFrameList::createFrameList(KWFrameSet *fs, KWDocument *doc, bool forceUpdate) {
+ QPtrListIterator<KWFrame> iter( fs->frameIterator() );
+ KWFrame *f = iter.current();
+ while(f) {
+ createFrameList(f, doc);
+ if(forceUpdate)
+ f->frameStack()->update();
+ ++iter;
+ f = iter.current();
+ }
+}