kword

KWFrameList.cpp
1/* This file is part of the KOffice project
2 * Copyright (C) 2005 Thomas Zander <zander@kde.org>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; version 2.
7
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Library General Public License for more details.
12 *
13 * You should have received a copy of the GNU Library General Public License
14 * along with this library; see the file COPYING.LIB. If not, write to
15 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 * Boston, MA 02110-1301, USA.
17 */
18#include <algorithm>
19#include "KWFrameList.h"
20#include "KWFrame.h"
21#include "KWFrameSet.h"
22#include "KWTextFrameSet.h"
23#include "KWDocument.h"
24#include "KWViewMode.h"
25#include "KWPageManager.h"
26
27//#define DEBUG_SPEED
28
29KWFrameList::KWFrameList(KWDocument *doc, KWFrame *theFrame) {
30 m_doc = doc;
31 m_frame = theFrame;
32
33 update();
34}
35
36TQValueList<KWFrame *> KWFrameList::framesBelow() const {
37 TQValueList<KWFrame *> frames;
38//kdDebug() << "framesBelow " << endl;
39
40 // Copy until we find m_frame
41 for ( TQValueVector<KWFrame*>::const_iterator it = m_frames.begin(), end = m_frames.end(); it != end && *it != m_frame; ++it) {
42 frames.append( *it );
43 }
44
45 return frames;
46}
47
48TQValueList<KWFrame *> KWFrameList::framesOnTop() const {
49//kdDebug() << "framesOnTop " << endl;
50 TQValueList<KWFrame *> frames;
51
52 // Copy from m_frame to the end
53 bool found = false;
54 for ( TQValueVector<KWFrame*>::const_iterator it = m_frames.begin(), end = m_frames.end(); it != end; ++it) {
55 KWFrame* frame = *it;
56 if ( found ) {
57 Q_ASSERT( !frame->frameSet()->isFloating() );
58 frames.append( frame );
59 }
60 else if ( frame == m_frame )
61 found = true;
62 }
63
64 return frames;
65}
66
67void KWFrameList::setFrames(const TQPtrList<KWFrame> &frames) {
68 // kdDebug(31001) << "KWFrameList::setFrames for " << m_frame->frameSet()->name() << endl;
69 m_frames.clear();
70 if ( m_doc->layoutViewMode() && !m_doc->layoutViewMode()->hasFrames() )
71 return;
72
73 TQPtrList<KWFrameSet> parentFramesets;
74 KWFrameSet *fs = m_frame->frameSet();
75 while(fs) {
76 parentFramesets.append(fs);
77 fs = (KWFrameSet*) fs->anchorFrameset();
78 }
79
80 // We now look at all other frames (in the same page)
81 // to check for intersections. This is o(n^2), but with n small.
82 TQPtrListIterator<KWFrame> it( frames );
83 for ( ; it.current() ; ++it )
84 {
85 KWFrame* daFrame = it.current();
86 // kdDebug(32001) << "frame: " << daFrame->frameSet()->name() << endl;
87 if ( m_frame == daFrame ) {
88 m_frames.append( daFrame );
89 continue;
90 }
91 // Skip 'daFrame' if it belongs to a table.
92 // We trust that KWTableFrameSet will not make cells overlap ;)
93 if ( m_frame->frameSet()->groupmanager() || daFrame->frameSet()->groupmanager() )
94 continue;
95 // Skip all frames from the parent frameset, if 'm_frame' is floating
96 // ## might need a for loop for the case of inline-inside-inline,
97 // or maybe calling isPaintedBy instead [depending on what should happen for tables]
98 if ( daFrame->frameSet()->isFloating() &&
99 (parentFramesets.contains(daFrame->frameSet()->anchorFrameset()) ||
100 daFrame->frameSet()->isPaintedBy(m_frame->frameSet())) )
101 continue;
102 // Floating frames are not "on top", they are "inside".
103 // They are not "below" anything either - the parent frameset is.
104 if ( m_frame->frameSet()->isFloating() )
105 continue;
106 KoRect intersect = m_frame->intersect( daFrame->outerKoRect() );
107 if ( !intersect.isEmpty() )
108 m_frames.append( daFrame );
109 }
110 std::sort( m_frames.begin(), m_frames.end(), KWFrame::compareFrameZOrder );
111}
112
113void KWFrameList::updateAfterMove(int oldPageNum) {
114 int pageNumber = m_doc->pageManager()->pageNumber(m_frame);
115 updateZOrderFor(m_doc->framesInPage( pageNumber, false ));
116
117 if (pageNumber != oldPageNum)
118 updateZOrderFor(m_doc->framesInPage( oldPageNum, false ));
119}
120
122 int pageNumber = m_doc->pageManager()->pageNumber(m_frame);
123 if(pageNumber == -1)
124 return;
125 updateZOrderFor(m_doc->framesInPage( pageNumber, false ));
126}
127
128void KWFrameList::updateZOrderFor(const TQPtrList<KWFrame> &frames) {
129#ifdef DEBUG_SPEED
130 kdDebug(32001) << "KWFrameList::updateZOrderFor " << frames.count() << " frames"<< endl;
131 TQTime dt;
132 dt.start();
133 int numberAdded = 0;
134#endif
135
136 TQPtrListIterator<KWFrame> iter(frames);
137 while( iter.current() ) {
138 KWFrame *frame = iter.current();
139 Q_ASSERT( frame->frameStack() );
140
141 frame->frameStack()->setFrames(frames);
142#ifdef DEBUG_SPEED
143 numberAdded += frame->frameStack()->m_frames.count();
144#endif
145 ++iter;
146 }
147
148#ifdef DEBUG_SPEED
149 kdDebug(32001) << " updateZOrderFor took " << (float)(dt.elapsed()) / 1000 << " seconds, added " << numberAdded << " frames" << endl;
150#endif
151}
152
153// ****** statics ******
154KWFrameList *KWFrameList::getFirstFrameList(KWDocument *doc) {
155 for (TQPtrListIterator<KWFrameSet> fsit = doc->framesetsIterator(); fsit.current() ; ++fsit ) {
156 KWFrame *frame = fsit.current()->frame(0);
157 if (frame && frame->frameStack())
158 return frame->frameStack();
159 }
160 return 0;
161}
162
163void KWFrameList::recalcFrames(KWDocument *doc, int pageFrom, int pageTo) {
164 for(int i=pageTo; i >= pageFrom; i--) {
165 TQPtrList<KWFrame> framesOnPage = doc->framesInPage( i, false );
166 KWFrame *f = framesOnPage.first();
167 while(f) {
168 Q_ASSERT(f->frameStack());
169 f->frameStack()->setFrames(framesOnPage);
170 f = framesOnPage.next();
171 }
172 }
173}
174
175void KWFrameList::recalcAllFrames(KWDocument *doc) {
176 recalcFrames(doc, doc->startPage(), doc->lastPage());
177}
178
179void KWFrameList::createFrameList(KWFrame *f, KWDocument *doc) {
180 Q_ASSERT(f);
181 Q_ASSERT(doc);
182 if(f->frameStack())
183 return;
184 f->setFrameStack(new KWFrameList(doc, f));
185}
186
187void KWFrameList::createFrameList(KWFrameSet *fs, KWDocument *doc, bool forceUpdate) {
188 TQPtrListIterator<KWFrame> iter( fs->frameIterator() );
189 KWFrame *f = iter.current();
190 while(f) {
191 createFrameList(f, doc);
192 if(forceUpdate)
193 f->frameStack()->update();
194 ++iter;
195 f = iter.current();
196 }
197}
This class calculates and caches a list of frames that are on top or below the KWFrame instance this ...
Definition KWFrameList.h:32
static void recalcAllFrames(KWDocument *doc)
Update the z-ordering for all frames of the whole document.
void update()
Update the z-ordering around the frame we host the framelist for.
TQValueList< KWFrame * > framesBelow() const
Fetches the frames below the frame this frameList is for.
KWFrameList(KWDocument *doc, KWFrame *theFrame)
Constructor.
static void recalcFrames(KWDocument *doc, int pageFrom, int pageTo)
Update the z-ordering for all frames in the page section of the whole document.
void updateAfterMove(int oldPageNum)
Update the z-ordering around the frame we host the framelist for.
static void createFrameList(KWFrame *f, KWDocument *doc)
Factory method to create and attach a new instance of a framelist.
TQValueList< KWFrame * > framesOnTop() const
Fetches the frames on top of the frame this frameList is for.
Class: KWFrameSet Base type, a frameset holds content as well as frames to show that content.
Definition KWFrameSet.h:62
const TQPtrList< KWFrame > & frameIterator() const
Iterator over the child frames.
Definition KWFrameSet.h:159
bool isFloating() const
Return true if this frameset is floating (inline), false if it's fixed.
Definition KWFrameSet.h:372
KWTableFrameSet * groupmanager() const
returns the groupManager this frameset belongs to.
Definition KWFrameSet.h:408
KWTextFrameSet * anchorFrameset() const
Return the frameset in which our anchor is - assuming isFloating()
Definition KWFrameSet.h:374
This class represents a single frame.
Definition KWFrame.h:68
KWFrameSet * frameSet() const
Data stucture methods.
Definition KWFrame.h:143
static bool compareFrameZOrder(KWFrame *f1, KWFrame *f2)
This is a method used to sort a list using the STL sorting methods.
Definition KWFrame.cpp:750
KoRect outerKoRect() const
Return the unzoomed rectangle, including the border, for the frames-on-top list.
Definition KWFrame.cpp:200