/* This file is part of the KDE project Copyright (C) 2001 David Faure 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 class KWDocument; class TQPainter; class TQRegion; 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 TQPoint normalToView( const TQPoint & nPoint ) = 0; /** Normal coord -> view coord */ TQRect normalToView( const TQRect & nRect ) { return TQRect( normalToView( nRect.topLeft() ), nRect.size() ); } /** View coord -> normal coord */ virtual TQPoint viewToNormal( const TQPoint & vPoint ) = 0; /** View coord -> normal coord */ TQRect viewToNormal( const TQRect & nRect ) { return TQRect( viewToNormal( nRect.topLeft() ), viewToNormal( nRect.bottomRight() ) ); } /** Return view coord for page rect. Avoids rounding problems when doing normalToView(zoomedRect) */ virtual TQRect viewPageRect( int pgNum ) = 0; /** Size of the contents area, in pixels */ virtual TQSize 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 TQSize 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 TQPoint pageCorner(); /** The result of this is passed to setFrameStartEnd for both rulers * (after adjustement with pageCorner()) */ virtual TQRect 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( TQPainter * painter, const TQRect & crect, const TQRegion & 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 TQString 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 TQString& 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( TQPainter * painter, const TQRect & crect, const TQRect & pageRect, const TQRegion & emptySpaceRegion ); TQRect drawRightShadow( TQPainter * painter, const TQRect & crect, const TQRect & pageRect, int topOffset ); TQRect drawBottomShadow( TQPainter * painter, const TQRect & crect, const TQRect & 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 TQPoint normalToView( const TQPoint & nPoint ); virtual TQPoint viewToNormal( const TQPoint & vPoint ); virtual TQRect viewPageRect( int pgNum ); virtual TQSize contentsSize(); virtual const TQString type() const { return "ModeNormal"; } virtual void drawPageBorders( TQPainter * painter, const TQRect & crect, const TQRegion & 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 TQPoint normalToView( const TQPoint & nPoint ) { return nPoint; } virtual TQPoint viewToNormal( const TQPoint & vPoint ) { return vPoint; } virtual TQRect viewPageRect( int pgNum ); virtual TQSize contentsSize() { return TQSize(); } virtual bool hasPages() { return false; } virtual void drawPageBorders( TQPainter *, const TQRect &, const TQRegion & ){} virtual bool drawSelections() { return mDrawSelections; } virtual const TQString 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 TQPoint normalToView( const TQPoint & nPoint ); virtual TQPoint viewToNormal( const TQPoint & vPoint ); virtual TQRect viewPageRect( int pgNum ); virtual TQSize contentsSize(); virtual void drawPageBorders( TQPainter * painter, const TQRect & crect, const TQRegion & emptySpaceRegion ); virtual void setPagesPerRow(int _nb) {m_pagesPerRow=_nb;} virtual int pagesPerRow() {return m_pagesPerRow;} virtual const TQString 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 TQPoint normalToView( const TQPoint & nPoint ); virtual TQPoint viewToNormal( const TQPoint & vPoint ); virtual TQSize contentsSize(); virtual TQRect viewPageRect( int ) { return TQRect(); } virtual TQSize availableSizeForText( KWTextFrameSet* textfs ); // There is no page concept. Keep everything relative to (0,0) virtual TQPoint pageCorner() { return TQPoint( 0, 0 ); } virtual TQRect rulerFrameRect(); virtual void setPageLayout( KoRuler* hRuler, KoRuler* vRuler, const KoPageLayout& layout ); virtual void drawPageBorders( TQPainter * painter, const TQRect & crect, const TQRegion & emptySpaceRegion ); virtual const TQString 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