summaryrefslogtreecommitdiffstats
path: root/kword/KWFrame.h
blob: 37a3ff25613ebb3dd78cb4b25627d285e9062576 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
/* This file is part of the KDE project
   Copyright (C) 1998, 1999, 2000 Reginald Stadlbauer <reggie@kde.org>
   Copyright (C) 2000-2006 David Faure <faure@kde.org>
   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; 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.
*/

#ifndef frame_h
#define frame_h

#include "defs.h"
#include <KoRect.h>
#include <qbrush.h>
#include "KoBorder.h"
#include <qptrlist.h>

class KWCanvas;
class KWDocument;
class KWFrame;
class KWFrameList;
class KWFrameSet;
class KWViewMode;

class KoGenStyle;
class KoGenStyles;
class KoOasisContext;
class KoStyleStack;
class KoXmlWriter;

class QDomElement;

/**
 * small utility class representing a sortable (by z-order) list of frames
 * you can use sort() and inSort(item)
 *
 * Deprecated, use QValueVector<KWFrame*> from now on, and sort it with
 * std::sort(frames.begin(),frames.end(),KWFrame::compareFrameZOrder);
 *
 * With Qt4 we'll be able to use qSort for lists.
 */
class ZOrderedFrameList : public QPtrList<KWFrame>
{
protected:
    virtual int compareItems(QPtrCollection::Item a, QPtrCollection::Item b);
};


/**
 * This class represents a single frame.
 * A frame belongs to a frameset which states its contents.
 * A frame does NOT have contents, the frameset stores that.
 * A frame is really just a square that is used to place the content
 * of a frameset.
 */
class KWFrame : public KoRect
{
public:
    /** Runaround types
     * RA_NO = No run around, all text is just printed.
     * RA_BOUNDINGRECT = run around the square of this frame.
     * RA_SKIP = stop running text on the whole horizontal space this frame occupies.
     */
    enum RunAround { RA_NO = 0, RA_BOUNDINGRECT = 1, RA_SKIP = 2 };

    /** Runaround side - only meaningful when RA_BOUNDINGRECT is used
     */
    enum RunAroundSide { RA_BIGGEST = 0, RA_LEFT = 1, RA_RIGHT = 2 };

    /**
     * Constructor
     * @param fs parent frameset
     * @param left, top, width, height coordinates of the frame
     * The page number will be automatically determined from the position of the frame.
     * @param ra the "runaround" setting, i.e. whether text should flow below the frame,
     * around the frame, or avoiding the frame on the whole horizontal band.
     */
    KWFrame(KWFrameSet *fs, double left, double top, double width, double height,
            RunAround ra = RA_BOUNDINGRECT);
    KWFrame(KWFrame * frame);
    /** Destructor
     */
    virtual ~KWFrame();

    double runAroundLeft() const { return m_runAroundLeft; }
    double runAroundRight() const { return m_runAroundRight; }
    double runAroundTop() const { return m_runAroundTop; }
    double runAroundBottom() const { return m_runAroundBottom; }

    void setRunAroundGap( double left, double right, double top, double bottom ) {
        m_runAroundLeft = left;
        m_runAroundRight = right;
        m_runAroundTop = top;
        m_runAroundBottom = bottom;
    }

    RunAround runAround()const { return m_runAround; }
    void setRunAround( RunAround _ra ) { m_runAround = _ra; }

    RunAroundSide runAroundSide() const { return m_runAroundSide; }
    void setRunAroundSide( RunAroundSide rs ) { m_runAroundSide = rs; }

    /** what should happen when the frame is full
     */
    enum FrameBehavior { AutoExtendFrame=0 , AutoCreateNewFrame=1, Ignore=2 };

    FrameBehavior frameBehavior()const { return m_frameBehavior; }
    void setFrameBehavior( FrameBehavior fb ) { m_frameBehavior = fb; }

    /* Frame duplication properties */

    /** This frame will only be copied to:
     *   AnySide, OddSide or EvenSide
     */
    enum SheetSide { AnySide=0, OddSide=1, EvenSide=2};
    SheetSide sheetSide()const { return m_sheetSide; }
    void setSheetSide( SheetSide ss ) { m_sheetSide = ss; }

    /** What happens on new page
     * (create a new frame and reconnect, no followup, make copy) */
    enum NewFrameBehavior { Reconnect=0, NoFollowup=1, Copy=2 };
    NewFrameBehavior newFrameBehavior()const { return m_newFrameBehavior; }
    void setNewFrameBehavior( NewFrameBehavior nfb ) { m_newFrameBehavior = nfb; }

    /** Drawing property: if isCopy, this frame is a copy of the previous frame in the frameset
     */
    bool isCopy()const { return m_bCopy; }
    void setCopy( bool copy ) { m_bCopy = copy; }

    /** Data stucture methods
     */
    KWFrameSet *frameSet() const { return m_frameSet; }
    void setFrameSet( KWFrameSet *fs ) { m_frameSet = fs; }

    /** The page on which this frame is
     */
    int pageNumber() const;
    /** Same as pageNumber(), but works if the frame hasn't been added to a frameset yet
     */
    int pageNumber( KWDocument* doc ) const;

    /** The z-order of the frame, relative to the other frames on the same page
     */
    void setZOrder( int z ) { m_zOrder = z; }
    int zOrder() const { return m_zOrder; }

    /**
     * This is a method used to sort a list using the STL sorting methods.
     * @param f1 the first object
     * @param f2 the second object
     */
    static bool compareFrameZOrder(KWFrame *f1, KWFrame *f2);

    KWFrameList* frameStack() { return m_frameStack; }
    void setFrameStack(KWFrameList *fl) { m_frameStack = fl; }

    /** All borders can be custom drawn with their own colors etc.
     */
    const KoBorder &leftBorder() const { return m_borderLeft; }
    const KoBorder &rightBorder() const { return m_borderRight; }
    const KoBorder &topBorder() const { return m_borderTop; }
    const KoBorder &bottomBorder() const { return m_borderBottom; }


    void setLeftBorder( KoBorder _brd ) { m_borderLeft = _brd; }
    void setRightBorder( KoBorder _brd ) { m_borderRight = _brd; }
    void setTopBorder( KoBorder _brd ) { m_borderTop = _brd; }
    void setBottomBorder( KoBorder _brd ) { m_borderBottom = _brd; }

    /** Return the _zoomed_ rectangle for this frame, including the border - for drawing
     * @param viewMode needed to know if borders are visible or not
     */
    QRect outerRect( KWViewMode* viewMode ) const;

    /** Return the unzoomed rectangle, including the border, for the frames-on-top list.
     * The default border of size 1-pixel that is drawn on screen is _not_ included here
     * [since it depends on the zoom]
     */
    KoRect outerKoRect() const;

    /** Return the rectangle for this frame including the border and the runaround gap.
     * This is the rectangle that the surrounding text must run around.
     */
    KoRect runAroundRect() const;

    /** Return the rectangle for this frame.
     * This method is just so that new code doesn't rely on "KWFrame inherits KoRect",
     * which would be good to get rid of, at some point.
     */
    const KoRect& rect() const { return *this; }

    /** Marks a frame to have changed position/borders.
      Make sure you call this when the frame borders changed so when its inline it will be moved.
    */
    void frameBordersChanged();
    void updateRulerHandles();

    QBrush backgroundColor() const { return m_backgroundColor; }
    void setBackgroundColor( const QBrush &_color );
    bool isTransparent() const { return m_backgroundColor.style() != Qt::SolidPattern; }

    KoRect innerRect() const;

    double innerWidth() const;
    double innerHeight() const;


    /** The "internal Y" is the offset (in pt) of the real frame showed in this one
     * ("real" means "the last that isn't a copy")
     * This offset in pt is the sum of the height of the frames before that one.
     * For text frames, this is equivalent to the layout units (after multiplication). */
    void setInternalY( double y ) { m_internalY = y; }
    double internalY() const { return m_internalY; }

    /// set left padding (distance between frame contents and frame border)
    void setPaddingLeft( double b ) { m_paddingLeft = b; }
    /// set right padding
    void setPaddingRight( double b ) { m_paddingRight = b; }
    /// set top padding
    void setPaddingTop( double b ) { m_paddingTop = b; }
    /// set bottom padding
    void setPaddingBottom( double b ) { m_paddingBottom = b; }

    /// get left padding
    double paddingLeft() const { return m_paddingLeft; }
    /// get right padding
    double paddingRight() const { return m_paddingRight; }
    /// get top padding
    double paddingTop() const { return m_paddingTop; }
    /// get bottom padding
    double paddingBottom() const { return m_paddingBottom; }

    void setFramePadding( double _left, double _top, double right, double bottom);
    /** returns a copy of self
     */
    KWFrame *getCopy();

    void copySettings(KWFrame *frm);

    /** create XML to describe yourself
     */
    void save( QDomElement &frameElem );
    /** read attributes from XML. @p headerOrFooter if true some defaults are different
     */
    void load( QDomElement &frameElem, KWFrameSet* frameSet, int syntaxVersion );
    void loadCommonOasisProperties( KoOasisContext& context, KWFrameSet* frameSet, const char* typeProperties );
    void loadBorderProperties( KoStyleStack& styleStack );

    QString saveOasisFrameStyle( KoGenStyles& mainStyles ) const;
    /**
     * Write out a draw:frame element and its style.
     * The caller is responsible for creating the child element and closing the draw:frame element.
     * @p lastFrameName is the name of the previous frame in the same frameset; this is only used for copy-frames
     */
    void startOasisFrame( KoXmlWriter &xmlWriter, KoGenStyles& mainStyles, const QString& name,
                          const QString& lastFrameName = QString::null ) const;
    void saveBorderProperties( KoGenStyle& frameStyle ) const;
    void saveMarginProperties( KoGenStyle& frameStyle ) const;
    void saveMarginAttributes( KoXmlWriter &writer ) const;

    /**
     * The property minimum frame height is used to make the automatic frame shrinking code stop.
     * Each frame has a height based on its frame dimentions, but changes in content may change
     * the sizes automatically.  If all text is removed from a text frame it will grow smaller
     * until the minimum frame height is reached, and it will not shrink below that.
     * @param h the new minimum height
     */
    void setMinimumFrameHeight(double h) { m_minFrameHeight = h; }
    /**
     * @return the minimum frame height.
     * @see setMinimumFrameHeight() for details.
     */
    double minimumFrameHeight(void)const {return m_minFrameHeight;}

    /** Return if the point is on the frame.
        @param nPoint the point in normal coordinates.
        @param borderOfFrameOnly when true an additional check is done if the point
          is on the border.  */
    bool frameAtPos( const QPoint& nPoint, bool borderOfFrameOnly=false ) const;

    /**
     * Only applicable to frames of the main text frameset.
     * Set to true by KWFrameLayout if the "footnote line" should be
     * drawn under this frame.
     */
    void setDrawFootNoteLine( bool b ) { m_drawFootNoteLine = b; }
    bool drawFootNoteLine()const { return m_drawFootNoteLine; }

private:
    SheetSide m_sheetSide : 2;
    RunAround m_runAround : 2;
    RunAroundSide m_runAroundSide : 2;
    FrameBehavior m_frameBehavior : 2;
    NewFrameBehavior m_newFrameBehavior : 2;
    bool m_bCopy;
    bool m_drawFootNoteLine;

    double m_runAroundLeft, m_runAroundRight, m_runAroundTop, m_runAroundBottom;
    double m_paddingLeft, m_paddingRight, m_paddingTop, m_paddingBottom;
    double m_minFrameHeight;

    double m_internalY;
    int m_zOrder;

    QBrush m_backgroundColor;
    KoBorder m_borderLeft, m_borderRight, m_borderTop, m_borderBottom;

    /** List of frames we have below and on top of us.
     * Frames on top we should never overwrite.  Frames below us needd for selection code &
     * transparancy */
    KWFrameList *m_frameStack;
    KWFrameSet *m_frameSet;

    /** Prevent operator=
     */
    KWFrame &operator=( const KWFrame &_frame );
    /** Prevent copy constructor
     */
    KWFrame ( const KWFrame &_frame );
};

#endif