You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
koffice/kword/KWViewMode.h

298 lines
12 KiB

/* This file is part of the KDE project
Copyright (C) 2001 David Faure <faure@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 kwviewmode_h
#define kwviewmode_h
#include <qrect.h>
class KWDocument;
class QPainter;
class QRegion;
class KWTextFrameSet;
class KWFrameSet;
class KWCanvas;
class KoRuler;
class KoPageLayout;
class KWPage;
/**
* Abstract base class for KWCanvas's view modes.
*
* The 'normal' mode is the WYSIWYG mode ("page mode"), in which pages are one
* below another. Since frames are in this coordinate system, the view modes
* other than the normal mode implement a transformation between the normal mode's
* coordinate system and its own.
* When drawing, we use normalcoord->viewcoord and when handling mouse clicks
* we use viewcoord->normalcoord.
* Note that this all in zoomed (pixel) coordinates (see DESIGN file).
*
* The View Mode is obviously also responsible for drawing pages etc.
*/
class KWViewMode
{
protected:
KWViewMode( KWDocument * doc, KWCanvas* canvas, bool drawFrameBorders )
: m_doc( doc ), m_canvas( canvas ), m_drawFrameBorders( drawFrameBorders )
{}
public:
virtual ~KWViewMode() {}
/** Normal coord -> view coord */
virtual QPoint normalToView( const QPoint & nPoint ) = 0;
/** Normal coord -> view coord */
QRect normalToView( const QRect & nRect )
{ return QRect( normalToView( nRect.topLeft() ), nRect.size() ); }
/** View coord -> normal coord */
virtual QPoint viewToNormal( const QPoint & vPoint ) = 0;
/** View coord -> normal coord */
QRect viewToNormal( const QRect & nRect )
{ return QRect( viewToNormal( nRect.topLeft() ), viewToNormal( nRect.bottomRight() ) ); }
/** Return view coord for page rect. Avoids rounding problems when doing normalToView(zoomedRect) */
virtual QRect viewPageRect( int pgNum ) = 0;
/** Size of the contents area, in pixels */
virtual QSize contentsSize() = 0;
/** Size (in pixels) of the total area available for text in a given textframeset
* This is used by KWTextFrameSet::drawFrame to erase between the bottom of the
* last paragraph and the bottom of the available area. */
virtual QSize availableSizeForText( KWTextFrameSet* textfs );
/** "Topleft of current page" - concept used by the rulers.
* The default implementation is good enough for any page-based viewmode,
* since it calls normalToView. But the textmode has no page concept. */
virtual QPoint pageCorner();
/** The result of this is passed to setFrameStartEnd for both rulers
* (after adjustement with pageCorner()) */
virtual QRect rulerFrameRect();
/** Called when the page layout is set, or changes.
* Usually this is directly passed to KoRuler (for page-based viewmodes) */
virtual void setPageLayout( KoRuler* hRuler, KoRuler* vRuler, const KoPageLayout& layout );
virtual void drawPageBorders( QPainter * painter, const QRect & crect, const QRegion & emptySpaceRegion ) = 0;
/** Config option for KWViewModePreview (a bit of a hack) */
virtual void setPagesPerRow(int) {}
virtual int pagesPerRow() { return 0; }
/** Should selected text be drawn as such? */
virtual bool drawSelections() { return true; }
/** Should frame background be drawn? Usually yes, but not for embedded docs with transparent=true */
virtual bool drawFrameBackground() { return true; }
/** Should we see frame borders? This setting doesn't always come from KWView... */
bool drawFrameBorders() const { return m_drawFrameBorders; }
void setDrawFrameBorders(bool b) { m_drawFrameBorders = b; }
/** Should this frameset be visible in this viewmode? True by default, all are shown. */
virtual bool isFrameSetVisible( const KWFrameSet* /*frameset*/ ) { return true; }
/** Should formatVertically() happen (to skip frame bottom, frames on top, etc.) */
// TODO: maybe this should be more fine-grained.
virtual bool shouldFormatVertically() { return true; }
/** Should adjust[LR]Margin() happen (to run the text around frames on top etc.) */
virtual bool shouldAdjustMargins() { return true; }
/** Does this viewmode know anything about frames? */
virtual bool hasFrames() { return true; }
/** Does this viewmode know anything about pages? */
virtual bool hasPages() { return true; }
/** Return the name of the viewmode, used for loading/saving. */
virtual const QString type() const = 0;
/** Answers the question if argument frameset has to be drawn as a text-mode
* text area if true, or if false as a frame with its own contents. */
virtual bool isTextModeFrameset(KWFrameSet *) const { return false; }
static KWViewMode *create( const QString& viewModeType, KWDocument* doc, KWCanvas* canvas );
KWCanvas * canvas() const { return m_canvas; }
protected:
/**
* Draw the border around one page, and clear up the empty space in that page
* @param crect the rect we're interested in painting (in view pixels)
* @param pageRect the rect for the page, in view pixels
* @param emptySpaceRegion the empty space to clear up inside the page (in view pixels)
* @param painter the painter to paint the border on.
*/
void drawOnePageBorder( QPainter * painter, const QRect & crect, const QRect & pageRect,
const QRegion & emptySpaceRegion );
QRect drawRightShadow( QPainter * painter, const QRect & crect, const QRect & pageRect, int topOffset );
QRect drawBottomShadow( QPainter * painter, const QRect & crect, const QRect & pageRect, int leftOffset );
static const unsigned short s_shadowOffset;
KWDocument * m_doc;
KWCanvas * m_canvas;
bool m_drawFrameBorders;
};
/** The 'normal' view mode (pages below one another) */
class KWViewModeNormal : public KWViewMode
{
public:
KWViewModeNormal( KWDocument * doc, KWCanvas* canvas, bool drawFrameBorders )
: KWViewMode( doc, canvas, drawFrameBorders ) {}
virtual ~KWViewModeNormal() {}
virtual QPoint normalToView( const QPoint & nPoint );
virtual QPoint viewToNormal( const QPoint & vPoint );
virtual QRect viewPageRect( int pgNum );
virtual QSize contentsSize();
virtual const QString type() const { return "ModeNormal"; }
virtual void drawPageBorders( QPainter * painter, const QRect & crect, const QRegion & emptySpaceRegion );
protected:
virtual int xOffset(KWPage *page, int canvasWidth = -1);
};
/** The view mode used when printing (pages under one another, no selections) */
class KWViewModePrint : public KWViewModeNormal // we inherit the "normal" viewmode
{
public:
KWViewModePrint( KWDocument * doc, KWCanvas* canvas )
: KWViewModeNormal( doc, canvas, false /*drawFrameBorders*/ ) {}
virtual ~KWViewModePrint() {}
virtual bool drawSelections() { return false; }
protected:
virtual int xOffset(KWPage *page, int canvasWidth = -1);
};
/** The 'embedded' view mode (usually a single page, no selections) */
class KWViewModeEmbedded : public KWViewMode
{
public:
KWViewModeEmbedded ( KWDocument * doc, KWCanvas* canvas )
: KWViewMode( doc, canvas, false /*drawFrameBorders*/ ),
mDrawFrameBackground( true ),
mDrawSelections( true )
{}
virtual ~ KWViewModeEmbedded() {}
void setDrawFrameBackground( bool b ) { mDrawFrameBackground = b; }
void setDrawSelections( bool b ) { mDrawSelections = b; }
// This view mode is very easy to implement ;-P
virtual QPoint normalToView( const QPoint & nPoint ) { return nPoint; }
virtual QPoint viewToNormal( const QPoint & vPoint ) { return vPoint; }
virtual QRect viewPageRect( int pgNum );
virtual QSize contentsSize() { return QSize(); }
virtual bool hasPages() { return false; }
virtual void drawPageBorders( QPainter *, const QRect &, const QRegion & ){}
virtual bool drawSelections() { return mDrawSelections; }
virtual const QString type() const { return "ModeEmbedded"; }
virtual bool drawFrameBackground() { return mDrawFrameBackground; }
private:
bool mDrawFrameBackground;
bool mDrawSelections;
};
/** A mode for previewing the overall document
Pages are organized in a grid (mostly useful when zooming out a lot) */
class KWViewModePreview : public KWViewMode
{
public:
KWViewModePreview( KWDocument * doc, KWCanvas* canvas, bool drawFrameBorders, int _nbPagePerRow );
virtual ~KWViewModePreview() {}
virtual QPoint normalToView( const QPoint & nPoint );
virtual QPoint viewToNormal( const QPoint & vPoint );
virtual QRect viewPageRect( int pgNum );
virtual QSize contentsSize();
virtual void drawPageBorders( QPainter * painter, const QRect & crect, const QRegion & emptySpaceRegion );
virtual void setPagesPerRow(int _nb) {m_pagesPerRow=_nb;}
virtual int pagesPerRow() {return m_pagesPerRow;}
virtual const QString type() const { return "ModePreview"; }
int numRows() const;
//protected:
/** Return the spacing between the left border of the canvas and the page. */
int leftSpacing();
/** Return the spacing between the top border of the canvas and the page. */
int topSpacing();
private:
int m_pagesPerRow;
int m_spacing;
};
/** The 'edit only one text frameset' view mode */
class KWViewModeText : public KWViewMode
{
public:
KWViewModeText( KWDocument * doc, KWCanvas* canvas, KWTextFrameSet* fs );
virtual ~KWViewModeText() {}
KWTextFrameSet *textFrameSet() const;
/**
* Return a text frameset that the user has either selected or is currently editing,
* returning the main text frameset otherwise.
* If the selected frame is not a text FS, and the user is not editing one in the
* first view plus the document has no main text frameset then this method will return 0
*/
static KWTextFrameSet *determineTextFrameSet( KWDocument* doc );
virtual QPoint normalToView( const QPoint & nPoint );
virtual QPoint viewToNormal( const QPoint & vPoint );
virtual QSize contentsSize();
virtual QRect viewPageRect( int ) { return QRect(); }
virtual QSize availableSizeForText( KWTextFrameSet* textfs );
// There is no page concept. Keep everything relative to (0,0)
virtual QPoint pageCorner() { return QPoint( 0, 0 ); }
virtual QRect rulerFrameRect();
virtual void setPageLayout( KoRuler* hRuler, KoRuler* vRuler, const KoPageLayout& layout );
virtual void drawPageBorders( QPainter * painter, const QRect & crect, const QRegion & emptySpaceRegion );
virtual const QString type() const { return "ModeText"; }
virtual bool shouldFormatVertically() { return false; }
virtual bool shouldAdjustMargins() { return false; }
virtual bool hasFrames() { return false; }
virtual bool hasPages() { return false; }
virtual bool isFrameSetVisible( const KWFrameSet* fs );
virtual bool isTextModeFrameset(KWFrameSet *fs) const;
/// hardcoded distance from the left side this viewmode starts its rendering
static const int OFFSET = 10;
private:
mutable KWTextFrameSet *m_textFrameSet;
};
#endif