lib

KoTextParag.h

00001 #ifndef KOTEXTPARAG_H
00002 #define KOTEXTPARAG_H
00003 
00004 /* This file is part of the KDE project
00005    Copyright (C) 2001-2005 David Faure <faure@kde.org>
00006 
00007    This library is free software; you can redistribute it and/or
00008    modify it under the terms of the GNU Library General Public
00009    License as published by the Free Software Foundation; either
00010    version 2 of the License, or (at your option) any later version.
00011 
00012    This library is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015    Library General Public License for more details.
00016 
00017    You should have received a copy of the GNU Library General Public License
00018    along with this library; see the file COPYING.LIB.  If not, write to
00019    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020  * Boston, MA 02110-1301, USA.
00021 */
00022 
00023 // -*- c++ -*-
00024 
00025 #include "KoParagLayout.h"
00026 
00027 #include "KoTextFormat.h"
00028 #include "KoRichText.h" // for KoTextString
00029 class KoTextFormatterBase;
00030 class KoTextParagLineStart;
00031 class KoTextString;
00032 class KoTextDocument;
00033 class KoParagCounter;
00034 class KoParagStyle;
00035 class KoTextCustomItem;
00036 class KoOasisContext;
00037 class KoSavingContext;
00038 class KoStyleCollection;
00039 
00040 struct KoTextParagSelection
00041 {
00042     int start, end;
00043 };
00044 
00045 #if defined(Q_TEMPLATEDLL)
00046 // MOC_SKIP_BEGIN
00047 template class QMap<int, KoTextParagSelection>;
00048 template class QMap<int, KoTextParagLineStart*>;
00049 // MOC_SKIP_END
00050 #endif
00051 
00052 class KOTEXT_EXPORT KoTextParag
00053 {
00054     friend class KoTextDocument;
00055     friend class KoTextCursor;
00056 
00057 public:
00058     KoTextParag( KoTextDocument *d, KoTextParag *pr = 0, KoTextParag *nx = 0, bool updateIds = TRUE );
00059     virtual ~KoTextParag();
00060 
00061     KoTextString *string() const;
00062     KoTextStringChar *at( int i ) const;
00063     int leftGap() const;
00064     int length() const;
00065 
00066     // Abstraction over the trailing-space thing, so that it can be removed later
00067     int lastCharPos() const { return str->length()-2; }
00068 
00069     void setFormat( KoTextFormat *fm );
00070     KoTextFormat *paragFormat() const;
00071 
00072     KoTextDocument *document() const;
00073 
00074     QRect rect() const;
00075     void setRect( const QRect& rect ) { r = rect; }
00076     void setHeight( int h ) { r.setHeight( h ); }
00077     void setWidth( int w ) { r.setWidth( w ); }
00078     void show();
00079     void hide();
00080     bool isVisible() const { return visible; }
00081 
00082     KoTextParag *prev() const;
00083     KoTextParag *next() const;
00084     void setPrev( KoTextParag *s );
00085     void setNext( KoTextParag *s );
00086 
00087     void insert( int index, const QString &s );
00088     void append( const QString &s, bool reallyAtEnd = FALSE );
00089     void truncate( int index );
00090     void remove( int index, int len );
00091 
00092     void move( int &dy );
00093     void format( int start = -1, bool doMove = TRUE );
00094 
00096     void invalidate( int chr /*ignored*/ = 0 );
00098     bool isValid() const;
00099 
00101     bool hasChanged() const;
00102     void setChanged( bool b, bool recursive = FALSE );
00103     short int lineChanged(); // first line that has been changed.
00104     void setLineChanged( short int line );
00105 
00106     int lineHeightOfChar( int i, int *bl = 0, int *y = 0 ) const;
00107     KoTextStringChar *lineStartOfChar( int i, int *index = 0, int *line = 0 ) const;
00108     int lines() const;
00109     KoTextStringChar *lineStartOfLine( int line, int *index = 0 ) const;
00110     int lineY( int l ) const;
00111     int lineBaseLine( int l ) const;
00112     int lineHeight( int l ) const;
00113     void lineInfo( int l, int &y, int &h, int &bl ) const;
00114 
00115     void setSelection( int id, int start, int end );
00116     void removeSelection( int id );
00117     int selectionStart( int id ) const;
00118     int selectionEnd( int id ) const;
00119     bool hasSelection( int id ) const;
00120     bool hasAnySelection() const;
00121     bool fullSelected( int id ) const;
00122 
00123     //void setEndState( int s );
00124     //int endState() const;
00125 
00126     void setParagId( int i );
00127     int paragId() const;
00128 
00129     QMap<int, KoTextParagLineStart*> &lineStartList();
00130 
00131     void setFormat( int index, int len, const KoTextFormat *f, bool useCollection = TRUE, int flags = -1 );
00132 
00133     void setAlignment( uint a );
00134     void setAlignmentDirect( uint a ) { align = a; }
00135     uint alignment() const;
00136 
00137     virtual void paint( QPainter &painter, const QColorGroup &cg, KoTextCursor *cursor, bool drawSelections,
00138                        int clipx, int clipy, int clipw, int cliph ); // kotextparag.cc
00139 
00140 
00141     int topMargin() const;
00142     int bottomMargin() const;
00143     int leftMargin() const;
00144     int firstLineMargin() const;
00145     int rightMargin() const;
00146     int lineSpacing( int line ) const;
00147     int calculateLineSpacing( int line, int start, int last ) const;
00148 
00149     void registerFloatingItem( KoTextCustomItem *i );
00150     void unregisterFloatingItem( KoTextCustomItem *i );
00151 
00152     void setFullWidth( bool b ) { fullWidth = b; }
00153     bool isFullWidth() const { return fullWidth; }
00154 
00155     int customItems() const;
00156 
00157     void setDocumentRect( const QRect &r );
00158     int documentWidth() const;
00159     //int documentVisibleWidth() const;
00160     int documentX() const;
00161     int documentY() const;
00162     KoTextFormatCollection *formatCollection() const;
00163     //void setFormatter( KoTextFormatterBase *f );
00164     KoTextFormatterBase *formatter() const;
00165     //int minimumWidth() const;
00166     int widthUsed() const;
00167 
00168     int nextTabDefault( int i, int x );
00169     int nextTab( int i, int x, int availableWidth );
00170     int *tabArray() const;
00171     void setTabArray( int *a );
00172     void setTabStops( int tw );
00173 
00176     void setNewLinesAllowed( bool b );
00178     bool isNewLinesAllowed() const;
00179 
00180     virtual void join( KoTextParag *s );
00181     virtual void copyParagData( KoTextParag *parag );
00182 
00183     //void setBreakable( bool b ) { breakable = b; }
00184     //bool isBreakable() const { return breakable; }
00185 
00186     void setMovedDown( bool b ) { movedDown = b; }
00187     bool wasMovedDown() const { return movedDown; }
00188 
00189     void setDirection( QChar::Direction d );
00190     QChar::Direction direction() const;
00191 
00193     void setPartOfTableOfContents( bool b ) { m_toc = b; }
00194     bool partOfTableOfContents() const { return m_toc; }
00195 
00196     // For KoTextFormatter only
00197     void insertLineStart( int index, KoTextParagLineStart *ls );
00198 
00199 protected:
00200     void drawLabel( QPainter* p, int x, int y, int w, int h, int base, const QColorGroup& cg );
00201     void drawCursorDefault( QPainter &painter, KoTextCursor *cursor, int curx, int cury, int curh, const QColorGroup &cg );
00202     void drawCursor( QPainter &painter, KoTextCursor *cursor, int curx, int cury, int curh, const QColorGroup &cg );
00203 
00209 public:
00210     KoTextDocument * textDocument() const { return document(); }
00211 
00212     KoTextFormat * paragraphFormat() const
00213     { return static_cast<KoTextFormat *>( paragFormat() ); }
00214 
00217     virtual void setParagLayout( const KoParagLayout &layout, int flags = KoParagLayout::All,
00218                                  int marginIndex = -1 );
00219 
00220     const KoParagLayout & paragLayout() { return m_layout; }
00221 
00222     // Margins
00223     double margin( QStyleSheetItem::Margin m ) { return m_layout.margins[m]; }
00224     const double * margins() const { return m_layout.margins; }
00225     void setMargin( QStyleSheetItem::Margin m, double _i );
00226     void setMargins( const double * _i );
00227 
00229     double kwLineSpacing() const { return m_layout.lineSpacingValue(); }
00230 
00231     void setLineSpacing( double _i );
00232 
00233     KoParagLayout::SpacingType kwLineSpacingType() const { return m_layout.lineSpacingType; }
00234 
00235     void setLineSpacingType( KoParagLayout::SpacingType _type );
00236 
00237 
00239     void setAlign( int align );
00241     int resolveAlignment() const;
00242 
00245     int breakableTopMargin() const;
00246 
00247     // Borders
00248     KoBorder leftBorder() const { return m_layout.leftBorder; }
00249     KoBorder rightBorder() const { return m_layout.rightBorder; }
00250     KoBorder topBorder() const { return m_layout.topBorder; }
00251     KoBorder bottomBorder() const { return m_layout.bottomBorder; }
00252     bool hasBorder() const { return m_layout.hasBorder(); }
00253     bool joinBorder() const { return m_layout.joinBorder; }
00254 
00255     void setLeftBorder( const KoBorder & _brd ) { m_layout.leftBorder = _brd; }
00256     void setRightBorder( const KoBorder & _brd ) { m_layout.rightBorder = _brd; }
00257     void setTopBorder( const KoBorder & _brd );
00258     void setBottomBorder( const KoBorder & _brd );
00259     void setJoinBorder( bool join );
00260 
00261     // Paragraph background
00262     QColor backgroundColor() { return m_layout.backgroundColor; }
00263     void setBackgroundColor( const QColor& color);
00264 
00265     // Counters are used to implement list and heading numbering/bullets.
00266     void setCounter( const KoParagCounter & counter );
00267     void setNoCounter();
00268     void setCounter( const KoParagCounter * pCounter );
00269     KoParagCounter *counter();
00270 
00274     int counterWidth() const;
00275 
00277     KoParagStyle *style() const { return m_layout.style; }
00279     void setStyle( KoParagStyle *style ) { m_layout.style = style; }
00281     void applyStyle( KoParagStyle *style );
00282 
00284     const KoTabulatorList& tabList() const { return m_layout.tabList(); }
00286     void setTabList( const KoTabulatorList &tabList );
00287 
00289     int shadowX( KoTextZoomHandler *zh ) const;
00291     int shadowY( KoTextZoomHandler *zh ) const;
00293     double shadowDistanceY() const;
00294 
00296     void setCustomItem( int index, KoTextCustomItem * custom, KoTextFormat * currentFormat );
00298     void removeCustomItem( int index );
00299 
00302     int findCustomItem( const KoTextCustomItem * custom ) const;
00303 
00305     QMap<int, int>& tabCache() { return m_tabCache; }
00306 
00308     QRect pixelRect( KoTextZoomHandler* zh ) const;
00309 
00313      static void drawFontEffects( QPainter * p, KoTextFormat *format, KoTextZoomHandler *zh, QFont font, const QColor & color, int startX, int baseLine, int bw, int y, int h, QChar firstChar );
00314 
00316     QString toString( int from = 0, int length = 0xffffffff) const;
00317 
00319     void fixParagWidth( bool viewFormattingChars );
00320 
00322     virtual void loadOasis( const QDomElement& e, KoOasisContext& context, KoStyleCollection *styleCollection, uint& pos );
00326     virtual void saveOasis( KoXmlWriter& writer, KoSavingContext& context,
00327                             int from, int to, bool saveAnchorsFramesets = false ) const;
00328 
00335     void loadOasisSpan( const QDomElement& parent, KoOasisContext& context, uint& pos, bool stripLeadingSpace = false );
00336 
00344     void loadOasisSpan( const QDomElement& parent, KoOasisContext& context, uint& pos, bool stripLeadingSpace, bool *hasTrailingSpace );
00345 
00346     void applyListStyle( KoOasisContext& context, int restartNumbering, bool orderedList, bool heading, int level );
00347 
00348 #ifndef NDEBUG
00349     void printRTDebug( int );
00350 #endif
00351 
00352 protected:
00353     void invalidateCounters();
00354     bool lineHyphenated( int l ) const;
00355 
00356     void paintLines( QPainter &painter, const QColorGroup &cg, KoTextCursor *cursor, bool drawSelections,
00357                      int clipx, int clipy, int clipw, int cliph );
00358 
00359     void drawParagString( QPainter &painter, const QString &str, int start, int len, int startX,
00360                           int lastY, int baseLine, int bw, int h, bool drawSelections,
00361                           KoTextFormat *lastFormat, const QMemArray<int> &selectionStarts,
00362                           const QMemArray<int> &selectionEnds, const QColorGroup &cg, bool rightToLeft, int line );
00363     void drawParagStringInternal( QPainter &painter, const QString &s, int start, int len, int startX,
00364                                   int lastY, int baseLine, int bw, int h, bool drawSelections,
00365                                   KoTextFormat *lastFormat, const QMemArray<int> &selectionStarts,
00366                                   const QMemArray<int> &selectionEnds, const QColorGroup &cg, bool rightToLeft, int line, KoTextZoomHandler* zh, bool drawingShadow );
00367 
00369     enum { FormattingSpace = 1, FormattingBreak = 2, FormattingEndParag = 4, FormattingTabs = 8,
00370            AllFormattingChars = FormattingSpace | FormattingBreak | FormattingEndParag | FormattingTabs };
00371 
00376     virtual void drawFormattingChars( QPainter &painter, int start, int len,
00377                                       int lastY_pix, int baseLine_pix, int h_pix, // in pixels
00378                                       bool drawSelections,
00379                                       KoTextFormat *format, const QMemArray<int> &selectionStarts,
00380                                       const QMemArray<int> &selectionEnds, const QColorGroup &cg,
00381                                       bool rightToLeft, int line, KoTextZoomHandler* zh,
00382                                       int whichFormattingChars );
00383 
00384 protected:
00385     KoParagLayout m_layout;
00386     QMap<int, int> m_tabCache;
00387 
00388 private:
00389     KoParagLayout loadParagLayout( KoOasisContext& context, KoStyleCollection *styleCollection, bool findStyle );
00390 
00391 
00392 
00394 private:
00395     QMap<int, KoTextParagSelection> &selections() const;
00396     QPtrList<KoTextCustomItem> &floatingItems() const;
00398     int heightForLineSpacing( int startChar, int lastChar ) const;
00399 
00400     QMap<int, KoTextParagLineStart*> lineStarts;
00401     QRect r;
00402     KoTextParag *p, *n;
00403     KoTextDocument *doc;
00404     bool m_invalid : 1;
00405     bool changed : 1;
00406     bool fullWidth : 1;
00407     bool newLinesAllowed : 1;
00408     bool visible : 1;
00409     bool movedDown : 1;
00410     bool m_toc : 1;
00411     uint align : 4;
00412     short int m_lineChanged;
00413     int id;
00414     int m_wused;
00415     KoTextString *str;
00416     QMap<int, KoTextParagSelection> *mSelections;
00417     QPtrList<KoTextCustomItem> *mFloatingItems;
00418     KoTextFormat *defFormat; // is this really used?
00419     int *tArray;
00420 
00421     // Those things are used by QRT for the case of a paragraph without document
00422     // We don't use this currently, and it's not worth making EVERY parag bigger
00423     // just for a special case that's rarely used. Better have lightweight KoTextDocument
00424     // replacement (with common base class), if we ever want efficient single-parag docs...
00425     //int tabStopWidth;
00426     //QRect docRect;
00427     //KoTextFormatterBase *pFormatter;
00428     //KoTextDocCommandHistory *commandHistory;
00429 };
00430 
00431 inline int KoTextParag::length() const
00432 {
00433     return str->length();
00434 }
00435 
00436 inline QRect KoTextParag::rect() const
00437 {
00438     return r;
00439 }
00440 
00441 inline KoTextStringChar *KoTextParag::at( int i ) const
00442 {
00443     return &str->at( i );
00444 }
00445 
00446 inline bool KoTextParag::isValid() const
00447 {
00448     return !m_invalid;
00449 }
00450 
00451 inline bool KoTextParag::hasChanged() const
00452 {
00453     return changed;
00454 }
00455 
00456 inline short int KoTextParag::lineChanged()
00457 {
00458     return m_lineChanged;
00459 }
00460 
00461 inline void KoTextParag::append( const QString &s, bool reallyAtEnd )
00462 {
00463     if ( reallyAtEnd )
00464     insert( str->length(), s );
00465     else
00466     insert( QMAX( str->length() - 1, 0 ), s );
00467 }
00468 
00469 inline KoTextParag *KoTextParag::prev() const
00470 {
00471     return p;
00472 }
00473 
00474 inline KoTextParag *KoTextParag::next() const
00475 {
00476     return n;
00477 }
00478 
00479 inline bool KoTextParag::hasAnySelection() const
00480 {
00481     return mSelections ? !selections().isEmpty() : FALSE;
00482 }
00483 
00484 /*inline void KoTextParag::setEndState( int s )
00485 {
00486     if ( s == state )
00487     return;
00488     state = s;
00489 }
00490 
00491 inline int KoTextParag::endState() const
00492 {
00493     return state;
00494 }*/
00495 
00496 inline void KoTextParag::setParagId( int i )
00497 {
00498     id = i;
00499 }
00500 
00501 inline int KoTextParag::paragId() const
00502 {
00503     //if ( id == -1 )
00504     //  kdWarning() << "invalid parag id!!!!!!!! (" << (void*)this << ")" << endl;
00505     return id;
00506 }
00507 
00508 inline QMap<int, KoTextParagLineStart*> &KoTextParag::lineStartList()
00509 {
00510     return lineStarts;
00511 }
00512 
00513 inline KoTextString *KoTextParag::string() const
00514 {
00515     return str;
00516 }
00517 
00518 inline KoTextDocument *KoTextParag::document() const
00519 {
00520     return doc;
00521 }
00522 
00523 inline void KoTextParag::setAlignment( uint a )
00524 {
00525     if ( a == align )
00526     return;
00527     align = a;
00528     invalidate( 0 );
00529 }
00530 
00531 /*inline void KoTextParag::setListStyle( QStyleSheetItem::ListStyle ls )
00532 {
00533     lstyle = ls;
00534     invalidate( 0 );
00535 }
00536 
00537 inline QStyleSheetItem::ListStyle KoTextParag::listStyle() const
00538 {
00539     return lstyle;
00540 }*/
00541 
00542 inline KoTextFormat *KoTextParag::paragFormat() const
00543 {
00544     return defFormat;
00545 }
00546 
00547 inline void KoTextParag::registerFloatingItem( KoTextCustomItem *i )
00548 {
00549     floatingItems().append( i );
00550 }
00551 
00552 inline void KoTextParag::unregisterFloatingItem( KoTextCustomItem *i )
00553 {
00554     floatingItems().removeRef( i );
00555 }
00556 
00557 /*inline void KoTextParag::addCustomItem()
00558 {
00559     numCustomItems++;
00560 }
00561 
00562 inline void KoTextParag::removeCustomItem()
00563 {
00564     numCustomItems--;
00565 }*/
00566 
00567 inline int KoTextParag::customItems() const
00568 {
00569     return mFloatingItems ? mFloatingItems->count() : 0;
00570     // was numCustomItems, but no need for a separate count
00571 }
00572 
00573 inline void KoTextParag::setNewLinesAllowed( bool b )
00574 {
00575     newLinesAllowed = b;
00576 }
00577 
00578 inline bool KoTextParag::isNewLinesAllowed() const
00579 {
00580     return newLinesAllowed;
00581 }
00582 
00583 #endif
KDE Home | KDE Accessibility Home | Description of Access Keys