| 1 | /* This file is part of the KDE libraries |
| 2 | SPDX-FileCopyrightText: 2001 David Faure <faure@kde.org> |
| 3 | |
| 4 | SPDX-License-Identifier: LGPL-2.0-or-later |
| 5 | */ |
| 6 | |
| 7 | #ifndef kwordwrap_h |
| 8 | #define kwordwrap_h |
| 9 | |
| 10 | #include <kguiaddons_export.h> |
| 11 | |
| 12 | #include <QSharedDataPointer> |
| 13 | #include <qnamespace.h> |
| 14 | |
| 15 | class QFontMetrics; |
| 16 | class QRect; |
| 17 | class QString; |
| 18 | class QPainter; |
| 19 | class KWordWrapPrivate; |
| 20 | |
| 21 | /*! |
| 22 | * \class KWordWrap |
| 23 | * \inmodule KGuiAddons |
| 24 | * \brief Word-wrap algorithm that takes into account beautifulness. |
| 25 | * |
| 26 | * That means: |
| 27 | * \list |
| 28 | * \li not letting a letter alone on the last line, |
| 29 | * \li breaking at punctuation signs (not only at spaces) |
| 30 | * \li improved handling of (), [] and {} |
| 31 | * \li improved handling of '/' (e.g. for paths) |
| 32 | * \endlist |
| 33 | * |
| 34 | * Usage: call the static method, formatText, with the text to |
| 35 | * wrap and the constraining rectangle etc., it will return an instance of KWordWrap |
| 36 | * containing internal data, result of the word-wrapping. |
| 37 | * From that instance you can retrieve the boundingRect, and invoke drawing. |
| 38 | * |
| 39 | * This design allows to call the word-wrap algorithm only when the text changes |
| 40 | * and not every time we want to know the bounding rect or draw the text. * |
| 41 | */ |
| 42 | class KGUIADDONS_EXPORT KWordWrap |
| 43 | { |
| 44 | public: |
| 45 | /*! |
| 46 | * Use this flag in drawText() if you want to fade out the text if it does |
| 47 | * not fit into the constraining rectangle. |
| 48 | * |
| 49 | * \value FadeOut |
| 50 | * \value Truncate |
| 51 | */ |
| 52 | enum { |
| 53 | FadeOut = 0x10000000, |
| 54 | Truncate = 0x20000000, |
| 55 | }; |
| 56 | |
| 57 | /*! |
| 58 | * Main method for wrapping text. |
| 59 | * |
| 60 | * \a fm Font metrics, for the chosen font. Better cache it, creating a QFontMetrics is expensive. |
| 61 | * |
| 62 | * \a r Constraining rectangle. Only the width and height matter. With |
| 63 | * negative height the complete text will be rendered |
| 64 | * |
| 65 | * \a flags currently unused |
| 66 | * |
| 67 | * \a str The text to be wrapped. |
| 68 | * |
| 69 | * \a len Length of text to wrap (default is -1 for all). |
| 70 | * |
| 71 | * Returns a KWordWrap instance. The caller is responsible for storing and deleting the result. |
| 72 | */ |
| 73 | static KWordWrap formatText(QFontMetrics &fm, const QRect &r, int flags, const QString &str, int len = -1); |
| 74 | |
| 75 | /*! |
| 76 | * Returns the bounding rect, calculated by formatText. The width is the |
| 77 | * width of the widest text line, and never wider than |
| 78 | * the rectangle given to formatText. The height is the |
| 79 | * text block. X and Y are always 0. |
| 80 | */ |
| 81 | QRect boundingRect() const; |
| 82 | |
| 83 | /*! |
| 84 | * Returns the original string, with '\n' inserted where |
| 85 | * the text is broken by the wordwrap algorithm. |
| 86 | */ |
| 87 | QString wrappedString() const; // gift for Dirk :) |
| 88 | |
| 89 | /*! |
| 90 | * Returns the original string, truncated to the first line. |
| 91 | * If \a dots was set, '...' is appended in case the string was truncated. |
| 92 | * Bug: Note that the '...' come out of the bounding rect. |
| 93 | */ |
| 94 | QString truncatedString(bool dots = true) const; |
| 95 | |
| 96 | /*! |
| 97 | * Draw the text that has been previously wrapped, at position x,y. |
| 98 | * Flags are for alignment, e.g. Qt::AlignHCenter. Default is |
| 99 | * Qt::AlignAuto. |
| 100 | * |
| 101 | * \a painter the QPainter to use. |
| 102 | * |
| 103 | * \a x the horizontal position of the text |
| 104 | * |
| 105 | * \a y the vertical position of the text |
| 106 | * |
| 107 | * \a flags the ORed text alignment flags from the Qt namespace, |
| 108 | * ORed with FadeOut if you want the text to fade out if it |
| 109 | * does not fit (the \a painter's background must be set |
| 110 | * accordingly) |
| 111 | */ |
| 112 | void drawText(QPainter *painter, int x, int y, int flags = Qt::AlignLeft) const; |
| 113 | |
| 114 | ~KWordWrap(); |
| 115 | |
| 116 | KWordWrap(const KWordWrap &other); |
| 117 | |
| 118 | KWordWrap &operator=(const KWordWrap &other); |
| 119 | |
| 120 | /*! |
| 121 | * Draws the string \a t at the given coordinates, if it does not |
| 122 | * fit into @p maxW the text will be faded out. |
| 123 | * |
| 124 | * \a p the painter to use. Must have set the pen for the text |
| 125 | * color and the background for the color to fade out |
| 126 | * |
| 127 | * \a x the horizontal position of the text |
| 128 | * |
| 129 | * \a y the vertical position of the text |
| 130 | * |
| 131 | * \a maxW the maximum width of the text (including the fade-out |
| 132 | * effect) |
| 133 | * |
| 134 | * \a t the text to draw |
| 135 | */ |
| 136 | static void drawFadeoutText(QPainter *p, int x, int y, int maxW, const QString &t); |
| 137 | |
| 138 | /*! |
| 139 | * Draws the string \a t at the given coordinates, if it does not |
| 140 | * fit into \a maxW the text will be truncated. |
| 141 | * |
| 142 | * \a p the painter to use |
| 143 | * |
| 144 | * \a x the horizontal position of the text |
| 145 | * |
| 146 | * \a y the vertical position of the text |
| 147 | * |
| 148 | * \a maxW the maximum width of the text (including the '...') |
| 149 | * |
| 150 | * \a t the text to draw |
| 151 | */ |
| 152 | static void drawTruncateText(QPainter *p, int x, int y, int maxW, const QString &t); |
| 153 | |
| 154 | private: |
| 155 | KGUIADDONS_NO_EXPORT explicit KWordWrap(const QRect &r); |
| 156 | |
| 157 | QExplicitlySharedDataPointer<KWordWrapPrivate> d; |
| 158 | }; |
| 159 | |
| 160 | #endif |
| 161 | |