File indexing completed on 2024-05-26 16:15:53

0001 /* This file is part of the KDE project
0002  * Copyright (C) 2006 Thomas Zander <zander@kde.org>
0003  * Copyright (C) 2011 Boudewijn Rempt <boud@kogmbh.com>
0004  *
0005  * This library is free software; you can redistribute it and/or
0006  * modify it under the terms of the GNU Library General Public
0007  * License as published by the Free Software Foundation; either
0008  * version 2 of the License, or (at your option) any later version.
0009  *
0010  * This library is distributed in the hope that it will be useful,
0011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0013  * Library General Public License for more details.
0014  *
0015  * You should have received a copy of the GNU Library General Public License
0016  * along with this library; see the file COPYING.LIB.  If not, write to
0017  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0018  * Boston, MA 02110-1301, USA.
0019  */
0020 
0021 #ifndef KOTEXTBLOCKDATA_H
0022 #define KOTEXTBLOCKDATA_H
0023 
0024 #include <QTextBlockUserData>
0025 
0026 #include "kotext_export.h"
0027 
0028 class KoTextBlockBorderData;
0029 class KoTextBlockPaintStrategyBase;
0030 
0031 /**
0032  * This class is used to store properties for KoText layouting inside Qt QTextBlock
0033  * instances.
0034  */
0035 class KOTEXT_EXPORT KoTextBlockData
0036 {
0037 public:
0038     /**
0039      * Supplemental data to allow advanced tabs to be used for layout and painting.
0040      * Qt-Scribe knows only left-tabs and it also only knows tab-positions per paragraph
0041      * which is not enough for our needs.
0042      * Using the tabs list we calculated in the layout step, we can emulate
0043      * all tabs by setting these as left-tabs on scribe prior to the re-layout of the text in the
0044      * line which is redone at painting time.
0045      * The tabLength list holds a length for each tab in the line and thus corresponds to the tab
0046      * positions in the tabs list.  We can then calculate the tab to have started the position
0047      * minus the length and use that to paint special tab attributes.
0048      */
0049     struct TabLineData {
0050         /// the tab positions as set on the QTextOption.setTabArray()
0051         QList<qreal> tabs;
0052         /// the length of each tab so we know which area to paint when we want to decorate it.
0053         QList<qreal> tabLength;
0054     };
0055 
0056     /**
0057      * Datastructure to define a range of characters assigned a temporary meaning.
0058      * Common use cases are spellchecking and grammar.
0059      */
0060     struct MarkupRange {
0061         int firstChar;
0062         int lastChar;
0063         qreal startX;
0064         qreal endX;
0065         int firstRebased;
0066         int lastRebased;
0067     };
0068 
0069     /**
0070      * The different types of markups.
0071      */
0072     enum MarkupType {
0073         Misspell,
0074         Grammar
0075     };
0076 
0077     explicit KoTextBlockData(QTextBlock &block);
0078     explicit KoTextBlockData(QTextBlockUserData *userData);
0079     virtual ~KoTextBlockData();
0080 
0081     /**
0082      * Add a range to the _end_ of the list of markups. It's important that firstChar is after
0083      * lastChar of the previous range for that type of markup.
0084      */
0085     void appendMarkup(MarkupType type, int firstChar, int lastChar);
0086 
0087     /**
0088      * Clear all ranges for a specific type of markup.
0089      */
0090     void clearMarkups(MarkupType type);
0091 
0092     /**
0093      * Move all ranges following fromPosition delta number of characters to the right.
0094      * Applies to a specific type of markup.
0095      */
0096     void rebaseMarkups(MarkupType type, int fromPosition, int delta);
0097 
0098     /**
0099      * Find a range that contains positionWithin.
0100      * If none is found a default Markuprange firstChar = lastChar = 0 is returned
0101      */
0102     MarkupRange findMarkup(MarkupType type, int positionWithin) const;
0103 
0104     void setMarkupsLayoutValidity(MarkupType type, bool valid);
0105     bool isMarkupsLayoutValid(MarkupType type) const;
0106 
0107     QVector<MarkupRange>::Iterator markupsBegin(MarkupType type);
0108     QVector<MarkupRange>::Iterator markupsEnd(MarkupType type);
0109 
0110     /**
0111      * Clear the counter and set everything to default values.
0112      */
0113     void clearCounter();
0114 
0115     /// return if this block has up-to-date counter data
0116     bool hasCounterData() const;
0117     /// return the width (in pt) of the counter.
0118     qreal counterWidth() const;
0119     /// set the width of the counter in pt.
0120     void setCounterWidth(qreal width);
0121     /// return the spacing (in pt) between the counter and the text
0122     qreal counterSpacing() const;
0123     /// set the spacing (in pt) between the counter and the text
0124     void setCounterSpacing(qreal spacing);
0125 
0126     /** sets the index that is used at this level.
0127      * If this represents a paragraph with counter 3.1, then the text is the 1.
0128      * If this represents a paragraph with counter IV.V, then the index is 5.
0129      */
0130     void setCounterIndex(int index);
0131     /// returns the index for the counter at this level
0132     int counterIndex() const;
0133 
0134     /// return the exact text that will be painted as the counter
0135     QString counterText() const;
0136 
0137     /**
0138      * set the text that is used for the counter at this level. the text is formatted
0139      * depending on the language/style.
0140      * If this represents a parag with counter 3.1 then the text is the '1'..
0141      * If this represents a paragraph with counter IV.V, then the text is V.
0142      * since the rest is not dependent on this parag, but only its location in the text
0143      *
0144      */
0145     void setPartialCounterText(const QString &text);
0146     /// return the partial text for this paragraphs counter
0147     QString partialCounterText() const;
0148 
0149     /// set the plain counter text which equals the counterText minus prefix and suffix
0150     void setCounterPlainText(const QString &text);
0151     /// return the plain counter text which equals the counterText minus prefix and suffix
0152     QString counterPlainText() const;
0153 
0154     void setCounterPrefix(const QString &text);
0155     QString counterPrefix() const;
0156 
0157     void setCounterSuffix(const QString &text);
0158     QString counterSuffix() const;
0159 
0160     /// Set if the counter is a image or not
0161     void setCounterIsImage(bool isImage);
0162 
0163     /// return if the counter is a image or not
0164     bool counterIsImage() const;
0165 
0166     /**
0167      * The actual position of the counter can be set, in actual (text) document coordinates.
0168      * @param position the location of the top/left of the counter text line.
0169      */
0170     void setCounterPosition(const QPointF &position);
0171     /**
0172      * Return the counter position.
0173      * @see setCounterPosition
0174      */
0175     QPointF counterPosition() const;
0176 
0177     /**
0178      * Sets a textformat to be used for the counter/bullet
0179      * @param font the format
0180      */
0181     void setLabelFormat(const QTextCharFormat &format);
0182 
0183     /**
0184      * Return the format to be used for the counter/bullet
0185      */
0186     QTextCharFormat labelFormat() const;
0187 
0188     /**
0189      * When a paragraph has a border, it will have a KoTextBlockBorderData instance.
0190      * Adding the border will increase the refcount.
0191      * @param border the border used for this paragraph, or 0 if no border is needed (anymore).
0192      */
0193     void setBorder(KoTextBlockBorderData *border);
0194 
0195     /**
0196      * Return the border associated with this paragraph, or 0 if there is no border set.
0197      */
0198     KoTextBlockBorderData *border() const;
0199 
0200     /**
0201      * sets a paintStrategy of this paragraph
0202      * @param paintStrategy the paintStrategy to be used for this paragraph
0203      */
0204     void setPaintStrategy(KoTextBlockPaintStrategyBase *paintStrategy);
0205 
0206     /**
0207      * Return the paintStrategy of this paragraph
0208      */
0209     KoTextBlockPaintStrategyBase *paintStrategy() const;
0210 
0211     /**
0212      * @brief saveXmlID can be used to determine whether we need to save the xml:id
0213      *    for this text block data object. This is true if the text block data describes
0214      *    animations.
0215      * @return true of we need to save the xml id, false if not.
0216      */
0217     bool saveXmlID() const;
0218 
0219 private:
0220     class Private;
0221     Private * const d;
0222 };
0223 
0224 Q_DECLARE_TYPEINFO(KoTextBlockData::MarkupRange, Q_MOVABLE_TYPE);
0225 Q_DECLARE_METATYPE(QTextBlockUserData*)
0226 
0227 #endif