Warning, file /office/calligra/libs/textlayout/KoTextDocumentLayout.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* This file is part of the KDE project 0002 * Copyright (C) 2006-2007, 2009 Thomas Zander <zander@kde.org> 0003 * Copyright (C) 2006, 2011 Sebastian Sauer <mail@dipe.org> 0004 * Copyright (C) 2011 C. Boemann <cbo@kogmbh.com> 0005 * 0006 * This library is free software; you can redistribute it and/or 0007 * modify it under the terms of the GNU Library General Public 0008 * License as published by the Free Software Foundation; either 0009 * version 2 of the License, or (at your option) any later version. 0010 * 0011 * This library is distributed in the hope that it will be useful, 0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 * Library General Public License for more details. 0015 * 0016 * You should have received a copy of the GNU Library General Public License 0017 * along with this library; see the file COPYING.LIB. If not, write to 0018 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0019 * Boston, MA 02110-1301, USA. 0020 */ 0021 0022 #ifndef KOTEXTDOCUMENTLAYOUT_H 0023 #define KOTEXTDOCUMENTLAYOUT_H 0024 0025 #include "kotextlayout_export.h" 0026 0027 #include <QAbstractTextDocumentLayout> 0028 #include <QList> 0029 #include <QTextFrame> 0030 0031 class KoShape; 0032 class KoStyleManager; 0033 class KoChangeTracker; 0034 class KoTextRangeManager; 0035 class KoInlineTextObjectManager; 0036 class KoViewConverter; 0037 class KoImageCollection; 0038 class KoShapeAnchor; 0039 class KoTextLayoutRootArea; 0040 class KoTextLayoutRootAreaProvider; 0041 class KoTextLayoutObstruction; 0042 0043 class QRectF; 0044 class QSizeF; 0045 0046 class KOTEXTLAYOUT_EXPORT KoInlineObjectExtent 0047 { 0048 public: 0049 explicit KoInlineObjectExtent(qreal ascent = 0, qreal descent = 0); 0050 qreal m_ascent; 0051 qreal m_descent; 0052 }; 0053 0054 0055 /** 0056 * Text layouter that allows text to flow in multiple root area and around 0057 * obstructions. 0058 */ 0059 class KOTEXTLAYOUT_EXPORT KoTextDocumentLayout : public QAbstractTextDocumentLayout 0060 { 0061 Q_OBJECT 0062 public: 0063 /// This struct is a helper for painting of kotext texts. 0064 struct PaintContext { 0065 PaintContext() 0066 : viewConverter(0) 0067 , imageCollection(0) 0068 , showFormattingCharacters(false) 0069 , showSectionBounds(false) 0070 , showSpellChecking(false) 0071 , showSelections(true) 0072 , background(Qt::white) 0073 { 0074 } 0075 0076 /// the QText context 0077 QAbstractTextDocumentLayout::PaintContext textContext; 0078 /// A view converter, when set, is used to find out when the zoom is so low that painting of text is unneeded 0079 const KoViewConverter *viewConverter; 0080 0081 KoImageCollection *imageCollection; 0082 bool showFormattingCharacters; 0083 bool showTableBorders; 0084 bool showSectionBounds; 0085 bool showSpellChecking; 0086 bool showSelections; 0087 QColor background; 0088 }; 0089 0090 /// constructor 0091 explicit KoTextDocumentLayout(QTextDocument *doc, KoTextLayoutRootAreaProvider *provider = 0); 0092 ~KoTextDocumentLayout() override; 0093 0094 /// return the rootAreaProvider. 0095 KoTextLayoutRootAreaProvider *provider() const; 0096 0097 /// return the currently set manager, or 0 if none is set. 0098 KoInlineTextObjectManager *inlineTextObjectManager() const; 0099 void setInlineTextObjectManager(KoInlineTextObjectManager *manager); 0100 0101 /// return the currently set manager, or 0 if none is set. 0102 KoTextRangeManager *textRangeManager() const; 0103 void setTextRangeManager(KoTextRangeManager *manager); 0104 0105 /// return the currently set changeTracker, or 0 if none is set. 0106 KoChangeTracker *changeTracker() const; 0107 void setChangeTracker(KoChangeTracker *tracker); 0108 0109 /// return the currently set styleManager, or 0 if none is set. 0110 KoStyleManager *styleManager() const; 0111 void setStyleManager(KoStyleManager *manager); 0112 0113 /// Returns the bounding rectangle of block. 0114 QRectF blockBoundingRect(const QTextBlock &block) const override; 0115 /** 0116 * Returns the total size of the document. This is useful to display 0117 * widgets since they can use to information to update their scroll bars 0118 * correctly 0119 */ 0120 QSizeF documentSize() const override; 0121 0122 QRectF frameBoundingRect(QTextFrame*) const override; 0123 0124 /// the default tab size for this document 0125 qreal defaultTabSpacing() const; 0126 0127 /// set default tab size for this document 0128 void setTabSpacing(qreal spacing); 0129 0130 /// set if this is for a word processor (slight changes in layout may occur) 0131 void setWordprocessingMode(); 0132 0133 /// is it for a word processor (slight changes in layout may occur) 0134 bool wordprocessingMode() const; 0135 0136 /// are the tabs relative to indent or not 0137 bool relativeTabs(const QTextBlock &block) const; 0138 0139 /// visualize inline objects during paint 0140 void showInlineObjectVisualization(bool show); 0141 0142 /// Calc a bounding box rect of the selection 0143 QRectF selectionBoundingBox(QTextCursor &cursor) const; 0144 0145 /// Draws the layout on the given painter with the given context. 0146 void draw(QPainter * painter, const QAbstractTextDocumentLayout::PaintContext & context) override; 0147 0148 /// reimplemented DO NOT CALL - USE HITTEST IN THE ROOTAREAS INSTEAD 0149 int hitTest(const QPointF & point, Qt::HitTestAccuracy accuracy) const override; 0150 0151 /// reimplemented to always return 1 0152 int pageCount() const override; 0153 0154 QList<KoShapeAnchor *> textAnchors() const; 0155 0156 /** 0157 * Register the anchored obstruction for run around 0158 * 0159 * We have the concept of Obstructions which text has to run around in various ways. 0160 * We maintain two collections of obstructions. The free which are tied to just a position 0161 * (tied to pages), and the anchored obstructions which are each anchored to a KoShapeAnchor 0162 * 0163 * The free obstructions are collected from the KoTextLayoutRootAreaProvider during layout 0164 * 0165 * The anchored obstructions are created in the FloatingAnchorStrategy and registered using 0166 * this method. 0167 */ 0168 void registerAnchoredObstruction(KoTextLayoutObstruction *obstruction); 0169 0170 0171 /** 0172 * Anchors are special InlineObjects that we detect in positionInlineObject() 0173 * We save those for later so we can position them during layout instead. 0174 * During KoTextLayoutArea::layout() we call positionAnchoredObstructions() 0175 */ 0176 /// remove all anchors and associated obstructions and set up for collecting new ones 0177 void beginAnchorCollecting(KoTextLayoutRootArea *rootArea); 0178 0179 /// allow positionInlineObject() to do anything (incl saving anchors) 0180 void allowPositionInlineObject(bool allow); 0181 0182 /// Sets the paragraph rect that will be applied to anchorStrategies being created in 0183 /// positionInlineObject() 0184 void setAnchoringParagraphRect(const QRectF ¶graphRect); 0185 0186 /// Sets the paragraph content rect that will be applied to anchorStrategies being created in 0187 /// positionInlineObject() 0188 void setAnchoringParagraphContentRect(const QRectF ¶graphContentRect); 0189 0190 /// Sets the layoutEnvironment rect that will be applied to anchorStrategies being created in 0191 /// positionInlineObject() 0192 void setAnchoringLayoutEnvironmentRect(const QRectF &layoutEnvironmentRect); 0193 0194 /// Calculates the maximum y of anchored obstructions 0195 qreal maxYOfAnchoredObstructions(int firstCursorPosition, int lastCursorPosition) const; 0196 0197 int anchoringSoftBreak() const; 0198 0199 /// Positions all anchored obstructions 0200 /// the paragraphRect should be in textDocument coords and not global/document coords 0201 void positionAnchoredObstructions(); 0202 0203 /// remove inline object 0204 void removeInlineObject(KoShapeAnchor *textAnchor); 0205 0206 void clearInlineObjectRegistry(const QTextBlock& block); 0207 0208 KoInlineObjectExtent inlineObjectExtent(const QTextFragment&); 0209 0210 /** 0211 * We allow a text document to be distributed onto a sequence of KoTextLayoutRootArea; 0212 * which brings up the need to figure out which KoTextLayoutRootArea is used for a certain 0213 * text. 0214 * @param position the position of the character in the text document we want to locate. 0215 * @return the KoTextLayoutRootArea the text is laid-out in. Or 0 if there is no shape for that text character. 0216 */ 0217 KoTextLayoutRootArea *rootAreaForPosition(int position) const; 0218 0219 0220 KoTextLayoutRootArea *rootAreaForPoint(const QPointF &point) const; 0221 0222 /** 0223 * Remove the root-areas \p rootArea from the list of \a rootAreas() . 0224 * \param rootArea root-area to remove. If NULL then all root-areas are removed. 0225 */ 0226 void removeRootArea(KoTextLayoutRootArea *rootArea = 0); 0227 0228 /// reimplemented from QAbstractTextDocumentLayout 0229 void documentChanged(int position, int charsRemoved, int charsAdded) override; 0230 0231 void setContinuationObstruction(KoTextLayoutObstruction *continuationObstruction); 0232 0233 /// Return a list of obstructions intersecting current root area (during layout) 0234 QList<KoTextLayoutObstruction *> currentObstructions(); 0235 0236 QList<KoTextLayoutRootArea *> rootAreas() const; 0237 QList<KoShape*> shapes() const; 0238 0239 /// Set should layout be continued when done with current root area 0240 void setContinuousLayout(bool continuous); 0241 0242 /// Set \a layout() to be blocked (no layouting will happen) 0243 void setBlockLayout(bool block); 0244 bool layoutBlocked() const; 0245 0246 /// Set \a documentChanged() to be blocked (changes will not result in root-areas being marked dirty) 0247 void setBlockChanges(bool block); 0248 bool changesBlocked() const; 0249 0250 KoTextDocumentLayout* referencedLayout() const; 0251 void setReferencedLayout(KoTextDocumentLayout *layout); 0252 0253 /** 0254 * To be called during layout by KoTextLayoutArea - similar to how qt calls positionInlineObject 0255 * 0256 * It searches for anchor text ranges in the given span 0257 */ 0258 void positionAnchorTextRanges(int pos, int length, const QTextDocument *effectiveDocument); 0259 0260 Q_SIGNALS: 0261 /** 0262 * Signal that is emitted during layouting to inform about the progress done so far. 0263 */ 0264 void layoutProgressChanged(int percent); 0265 0266 /** 0267 * Signal is emitted every time a layout run has completely finished (all text is positioned). 0268 */ 0269 void finishedLayout(); 0270 0271 /** 0272 * Signal is emitted when emitLayoutIsDirty() is called which happens at 0273 * least when a root area is marked as dirty. 0274 * @see emitLayoutIsDirty 0275 */ 0276 void layoutIsDirty(); 0277 0278 void foundAnnotation(KoShape *annotationShape, const QPointF &refPosition); 0279 0280 public Q_SLOTS: 0281 /** 0282 * Does the layout of the text. 0283 * This method will layout the text into sections, tables and textlines, 0284 * chunk by chunk. 0285 * It may interrupt itself, @see contiuousLayout 0286 * calling this method when the layout is not dirty, doesn't take that much 0287 * time as it doesn't do much, although it does check every root area 0288 */ 0289 virtual void layout(); 0290 0291 /** 0292 * Schedules a \a layout call for later using a QTimer::singleShot. Multiple calls 0293 * to this slot will be compressed into one layout-call to prevent calling layouting 0294 * to much. Also if meanwhile \a layout was called then the scheduled layout won't 0295 * be executed. 0296 */ 0297 virtual void scheduleLayout(); 0298 0299 /** 0300 * Emits the \a layoutIsDirty signal. 0301 */ 0302 void emitLayoutIsDirty(); 0303 0304 private Q_SLOTS: 0305 /// Called by \a scheduleLayout to start a \a layout run if not done already meanwhile. 0306 void executeScheduledLayout(); 0307 0308 protected: 0309 /// reimplemented 0310 void drawInlineObject(QPainter *painter, const QRectF &rect, QTextInlineObject object, int position, const QTextFormat &format) override; 0311 /// reimplemented 0312 void positionInlineObject(QTextInlineObject item, int position, const QTextFormat &format) override; 0313 /// reimplemented 0314 void resizeInlineObject(QTextInlineObject item, int position, const QTextFormat &format) override; 0315 0316 /// should we continue layout when done with current root area 0317 bool continuousLayout() const; 0318 0319 void registerInlineObject(const QTextInlineObject &inlineObject); 0320 0321 private: 0322 class Private; 0323 Private * const d; 0324 0325 bool doLayout(); 0326 void updateProgress(const QTextFrame::iterator &it); 0327 }; 0328 0329 #endif