Warning, file /office/calligra/libs/text/KoTextEditor.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) 2009 Pierre Stirnweiss <pstirnweiss@googlemail.com>
0003 * Copyright (C) 2009 Thomas Zander <zander@kde.org>
0004 * Copyright (C) 2011 Boudewijn Rempt <boud@valdyas.org>
0005 * Copyright (C) 2011-2012 C. Boemann <cbo@boemann.dk>
0006 * Copyright (C) 2014 Denis Kuplyakov <dener.kup@gmail.com>
0007 *
0008 * This library is free software; you can redistribute it and/or
0009 * modify it under the terms of the GNU Library General Public
0010 * License as published by the Free Software Foundation; either
0011 * version 2 of the License, or (at your option) any later version.
0012 *
0013 * This library is distributed in the hope that it will be useful,
0014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0016 * Library General Public License for more details.
0017 *
0018 * You should have received a copy of the GNU Library General Public License
0019 * along with this library; see the file COPYING.LIB.  If not, write to
0020 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0021 * Boston, MA 02110-1301, USA.
0022 */
0023 #ifndef KOTEXTEDITOR_H
0024 #define KOTEXTEDITOR_H
0025 
0026 #include "kotext_export.h"
0027 
0028 #include <kundo2magicstring.h>
0029 #include <KoGenChange.h>
0030 #include <KoBorder.h>
0031 #include <KoSection.h>
0032 
0033 #include <QMetaType>
0034 #include <QTextCursor>
0035 #include <QTextFrame>
0036 
0037 class KoListLevelProperties;
0038 class KoCharacterStyle;
0039 class KoInlineObject;
0040 class KoParagraphStyle;
0041 class KoInlineNote;
0042 class KoInlineCite;
0043 class KoBibliographyInfo;
0044 class KoCanvasBase;
0045 class KoTableOfContentsGeneratorInfo;
0046 class KoShapeAnchor;
0047 class KoShape;
0048 class KoBookmark;
0049 class KoAnnotation;
0050 class KoTextRangeManager;
0051 class KoTextVisitor;
0052 
0053 class KUndo2Command;
0054 
0055 class QTextBlock;
0056 class QTextCharFormat;
0057 class QTextBlockFormat;
0058 class QTextDocument;
0059 class QTextDocumentFragment;
0060 class QString;
0061 class QMimeData;
0062 
0063 
0064 /**
0065  * KoTextEditor is a wrapper around QTextCursor. It handles undo/redo and change
0066  * tracking for all editing commands.
0067  */
0068 class KOTEXT_EXPORT KoTextEditor: public QObject
0069 {
0070     Q_OBJECT
0071 public:
0072     enum ChangeListFlag {
0073         NoFlags = 0,
0074         ModifyExistingList = 1,
0075         MergeWithAdjacentList = 2,
0076         MergeExactly = 4,
0077         CreateNumberedParagraph = 8,
0078         AutoListStyle = 16,
0079         DontUnsetIfSame = 32 /// do not unset the current list style if it is already been set the same
0080     };
0081     Q_DECLARE_FLAGS(ChangeListFlags, ChangeListFlag)
0082 
0083     explicit KoTextEditor(QTextDocument *document);
0084 
0085     ~KoTextEditor() override;
0086 
0087     /**
0088      * Retrieves the texteditor for the document of the first text shape in the current
0089      * set of selected shapes on the given canvas.
0090      *
0091      * @param canvas the canvas we will check for a suitable selected shape.
0092      * @returns a texteditor, or 0 if there is no shape active that has a QTextDocument as
0093      * userdata
0094      */
0095     static KoTextEditor *getTextEditorFromCanvas(KoCanvasBase *canvas);
0096 
0097 
0098 public: // KoToolSelection overloads
0099 
0100     /// returns true if the wrapped QTextCursor has a selection.
0101     bool hasSelection() const;
0102 
0103     /** returns true if the current cursor position is protected from editing
0104      * @param useCached use cached value if available.
0105      */
0106     bool isEditProtected(bool useCached = false) const;
0107 
0108 public:
0109 
0110     bool operator!=(const QTextCursor &other) const;
0111 
0112     bool operator<(const QTextCursor &other) const;
0113 
0114     bool operator<=(const QTextCursor &other) const;
0115 
0116     bool operator==(const QTextCursor &other) const;
0117 
0118     bool operator>(const QTextCursor &other) const;
0119 
0120     bool operator>=(const QTextCursor &other) const;
0121 
0122     const QTextCursor constCursor() const;
0123 
0124 private:
0125 
0126     // for the call to KoTextLoader::loadBody, which has a QTextCursor
0127     friend class KoTextPaste;
0128 
0129     // from KoTextEditor_p.h
0130     friend class CharFormatVisitor;
0131 
0132     // our commands can have access to us
0133     friend class DeleteTableRowCommand;
0134     friend class DeleteTableColumnCommand;
0135     friend class InsertTableRowCommand;
0136     friend class InsertTableColumnCommand;
0137     friend class ChangeTrackedDeleteCommand;
0138     friend class DeleteCommand;
0139     friend class InsertInlineObjectCommand;
0140     friend class InsertNoteCommand;
0141     friend class ParagraphFormattingCommand;
0142     friend class RenameSectionCommand;
0143     friend class NewSectionCommand;
0144     friend class SplitSectionsCommand;
0145 
0146     // for unittests
0147     friend class TestKoInlineTextObjectManager;
0148 
0149     // temporary...
0150     friend class TextShape;
0151     friend class TextTool;
0152 
0153     /**
0154      * This should be used only as read-only cursor or within a KUndo2Command sub-class which
0155      * will be added to the textEditor with addCommand. For examples of proper implementation of
0156      * such undoCommands, see the TextShape commands.
0157      */
0158     QTextCursor* cursor();
0159 
0160 public Q_SLOTS:
0161 
0162     /// This adds the \p command to the calligra undo stack.
0163     ///
0164     /// From this point forward all text manipulation is placed in the qt text systems internal
0165     /// undostack while also adding representative subcommands to \p command.
0166     ///
0167     /// The \p command is not redone as part of this process.
0168     ///
0169     /// Note: Be aware that many KoTextEditor methods start their own commands thus terminating
0170     /// the recording of this \p command. Only use QTextCursor manipulation (with all the issues
0171     /// that brings) or only use KoTextEditor methods that don't start their own command.
0172     ///
0173     /// The recording is automatically terminated when another command is added, which as mentioned
0174     /// can happen by executing some of the KoTextEditor methods.
0175     void addCommand(KUndo2Command *command);
0176 
0177     /// This instantly "redo" the command thus placing all the text manipulation the "redo" does
0178     /// (should be implemented with a "first redo" pattern) in the qt text systems internal
0179     /// undostack while also adding representative subcommands to \p command.
0180     ///
0181     /// When \p command is done "redoing" no further text manipulation is added as subcommands.
0182     ///
0183     /// \p command is not put on the calligra undo stack. That is the responsibility of the
0184     /// caller, or the caller can choose to quickly undo and then delete the \p command.
0185     void instantlyExecuteCommand(KUndo2Command *command);
0186 
0187     void registerTrackedChange(QTextCursor &selection, KoGenChange::Type changeType, const KUndo2MagicString &title, QTextFormat &format, QTextFormat &prevFormat, bool applyToWholeBlock = false);
0188 
0189     void bold(bool bold);
0190 
0191     void italic(bool italic);
0192 
0193     void underline(bool underline);
0194 
0195     void strikeOut(bool strikeOut);
0196 
0197     void setHorizontalTextAlignment(Qt::Alignment align);
0198 
0199     void setVerticalTextAlignment(Qt::Alignment align);
0200 
0201     void increaseIndent();
0202 
0203     void decreaseIndent();
0204 
0205     void increaseFontSize();
0206 
0207     void decreaseFontSize();
0208 
0209     void setFontFamily(const QString &font);
0210 
0211     void setFontSize(qreal size);
0212 
0213     void setTextColor(const QColor &color);
0214 
0215     void setTextBackgroundColor(const QColor &color);
0216 
0217     void setStyle(KoParagraphStyle *style);
0218 
0219     void setStyle(KoCharacterStyle *style);
0220 
0221     void mergeAutoStyle(const QTextCharFormat &deltaCharFormat);
0222 
0223     void applyDirectFormatting(const QTextCharFormat &deltaCharFormat, const QTextBlockFormat &deltaBlockFormat, const KoListLevelProperties &llp);
0224 
0225     /**
0226      * Insert an inlineObject (such as a variable) at the current cursor position. Possibly replacing the selection.
0227      * @param inliner the object to insert.
0228      * @param parent a parent command for the commands created by this methods. If present, the commands
0229      *    will not be added to the document's undo stack automatically.
0230      */
0231     void insertInlineObject(KoInlineObject *inliner, KUndo2Command *parent = 0);
0232 
0233     /**
0234      * update the position of all inline objects from the given start point to the given end point.
0235      * @param start start position for updating. If 0, we update from the start of the document
0236      * @param end end position for updating. If -1, we update to the end of the document
0237      */
0238     void updateInlineObjectPosition(int start = 0, int end = -1);
0239 
0240     /**
0241      * Remove the KoShapeAnchor objects from the document.
0242      *
0243      * NOTE: Call this method only when the shapes belonging to the anchors have been deleted.
0244      */
0245     void removeAnchors(const QList<KoShapeAnchor *> &anchors, KUndo2Command *parent);
0246 
0247     /**
0248      * Remove the KoAnnotation objects from the document.
0249      *
0250      * NOTE: Call this method only when the shapes belonging to the annotations have been deleted.
0251      * This is not the way to delete annotations directly - instead delete the shape or
0252      * delete the text containing the annotation
0253      */
0254     void removeAnnotations(const QList<KoAnnotation *> &annotations, KUndo2Command *parent);
0255 
0256     /**
0257     * At the current cursor position, insert a marker that marks the next word as being part of the index.
0258     * @returns returns the index marker when successful, or 0 if failed.  Failure can be because there is no word
0259     *  at the cursor position or there already is an index marker available.
0260     */
0261     KoInlineObject *insertIndexMarker();
0262 
0263     /// add a bookmark on current cursor location or current selection
0264     KoBookmark *addBookmark(const QString &name);
0265 
0266     /// Add an annotation at the current cursor location or the current selection.
0267     KoAnnotation *addAnnotation(KoShape *annotationShape);
0268 
0269     KoTextRangeManager *textRangeManager() const;
0270 
0271     /**
0272      * Insert a frame break at the cursor position, moving the rest of the text to the next frame.
0273      */
0274     void insertFrameBreak();
0275 
0276     /**
0277      * paste the given mimedata object at the current position
0278      * @param canvas the canvas we used when placing the shape.
0279      * @param mimeData: the mimedata containing text, html or odf
0280      * @param pasteAsText: if true, paste without formatting
0281      */
0282     void paste(KoCanvasBase *canvas, const QMimeData *mimeData, bool pasteAsText=false);
0283 
0284     /**
0285      * @param numberingEnabled when true, we will enable numbering for the current paragraph (block).
0286      */
0287     void toggleListNumbering(bool numberingEnabled);
0288 
0289     /**
0290      * change the current block's list properties
0291      */
0292     void setListProperties(const KoListLevelProperties &llp,
0293                            ChangeListFlags flags = ChangeListFlags(ModifyExistingList | MergeWithAdjacentList), KUndo2Command *parent = 0);
0294 
0295     // -------------------------------------------------------------
0296     // Wrapped QTextCursor methods
0297     // -------------------------------------------------------------
0298 
0299     int anchor() const;
0300 
0301     bool atBlockEnd() const;
0302 
0303     bool atBlockStart() const;
0304 
0305     bool atEnd() const;
0306 
0307     bool atStart() const;
0308 
0309     QTextBlock block() const;
0310 
0311     QTextCharFormat blockCharFormat() const;
0312 
0313     QTextBlockFormat blockFormat() const;
0314 
0315     int blockNumber() const;
0316 
0317     QTextCharFormat charFormat() const;
0318 
0319     void clearSelection();
0320 
0321     int columnNumber() const;
0322 
0323     void deleteChar();
0324 
0325     void deletePreviousChar();
0326 
0327     QTextDocument *document() const;
0328 
0329     /// Same as Qt, only to be used inside KUndo2Commands
0330     KUndo2Command *beginEditBlock(const KUndo2MagicString &title = KUndo2MagicString());
0331     void endEditBlock();
0332 
0333     /**
0334      * Delete one character in the specified direction or a selection.
0335      * Warning: From the outside this method should only be used with a parent command
0336      * and only if there is a selection
0337      * @p previous should be @c true if act like backspace
0338      */
0339     void deleteChar(bool previous, KUndo2Command *parent = 0);
0340 
0341 
0342     bool hasComplexSelection() const;
0343 
0344     /**
0345      * Insert a table at the current cursor position.
0346      * @param rows the number of rows in the created table.
0347      * @param columns the number of columns in the created table.
0348      */
0349     void insertTable(int rows, int columns);
0350 
0351     /**
0352      * Insert a table row above the current cursor position (if in a table).
0353      */
0354     void insertTableRowAbove();
0355 
0356     /**
0357      * Insert a table row below the current cursor position (if in a table).
0358      */
0359     void insertTableRowBelow();
0360 
0361     /**
0362      * Insert a table column to the left of the current cursor position (if in a table).
0363      */
0364     void insertTableColumnLeft();
0365 
0366     /**
0367      * Insert a table column to the right of the current cursor position (if in a table).
0368      */
0369     void insertTableColumnRight();
0370 
0371     /**
0372      * Delete a table column where the cursor is (if in a table).
0373      */
0374     void deleteTableColumn();
0375 
0376     /**
0377      * Delete a table row where the cursor is (if in a table).
0378      */
0379     void deleteTableRow();
0380 
0381     /**
0382      * Merge table cells (selected by the cursor).
0383      */
0384     void mergeTableCells();
0385 
0386     /**
0387      * Split table cells (selected by the cursor) that were previously merged.
0388      */
0389     void splitTableCells();
0390 
0391     /**
0392      * Sets the width of a table column.
0393      * @param table is the table to be adjusted.
0394      * @param column the column that is to be adjusted.
0395      * @param width the width.
0396      * @param parentCommand the parent command for stacking.
0397      */
0398     void adjustTableColumnWidth(QTextTable *table, int column, qreal width, KUndo2Command *parentCommand = 0);
0399 
0400     /**
0401      * Sets the height of a table row.
0402      * @param table is the table to be adjusted.
0403      * @param row the row that is to be adjusted.
0404      * @param height the height.
0405      * @param parentCommand the parent command for stacking.
0406      */
0407     void adjustTableRowHeight(QTextTable *table, int row, qreal height, KUndo2Command *parentCommand = 0);
0408 
0409     /**
0410      * Changes the width of a table by adjusting the margins.
0411      * @param table is the table to be adjusted.
0412      * @param dLeft delta value for the left margin.
0413      * @param dRight delta value for the right margin.
0414      */
0415     void adjustTableWidth(QTextTable *table, qreal dLeft, qreal dRight);
0416 
0417     /**
0418      * Sets the border formatting of a side in a table cell.
0419      * @param table is the table to be adjusted.
0420      * @param row the row coordinate of the cell that is to be adjusted.
0421      * @param column the column coordinate of the cell that is to be adjusted.
0422      * @param cellSide the cell side.
0423      * @param data the border data.
0424      */
0425     void setTableBorderData(QTextTable *table, int row, int column, KoBorder::BorderSide cellSide,
0426                 const KoBorder::BorderData &data);
0427 
0428     /**
0429      * Insert a footnote at the current cursor position
0430      * @return a pointer to the inserted footnote
0431      */
0432     KoInlineNote *insertFootNote();
0433 
0434     /**
0435      * Insert an endnote at the current cursor position
0436      * @return a pointer to the inserted endnote
0437      */
0438     KoInlineNote *insertEndNote();
0439 
0440     /**
0441      * Insert a table of Contents at the current cursor position.
0442      */
0443     void insertTableOfContents(KoTableOfContentsGeneratorInfo *info);
0444 
0445     /**
0446      * Configures various values of a ToC to the one passed in info
0447      */
0448     void setTableOfContentsConfig(KoTableOfContentsGeneratorInfo *info, const QTextBlock &block);
0449 
0450     void insertBibliography(KoBibliographyInfo *info);
0451 
0452     KoInlineCite *insertCitation();
0453 
0454     /**
0455      * Inserts the supplied text at the current cursor position. If the second argument is
0456      * supplied, a link is inserted at the current cursor position with the hRef as given
0457      * by the user. To test whether the supplied link destination is a web url or a bookmark,
0458      * a regular expression ( \\S+://\\S+ ) is used.
0459      * @param text is the text to be inserted
0460      * @param hRef if supplied is the Hypertext reference
0461      */
0462     void insertText(const QString &text, const QString &hRef = QString());
0463 
0464     void mergeBlockFormat( const QTextBlockFormat &modifier);
0465 
0466     bool movePosition(QTextCursor::MoveOperation operation, QTextCursor::MoveMode mode = QTextCursor::MoveAnchor, int n = 1);
0467 
0468     /**
0469      * Inserts a new paragraph and warps it to new section
0470      * Source:
0471      *  some|textP
0472      * Result:
0473      *  someP
0474      *  [|textP]
0475      *
0476      * [] -- section bounds
0477      * |  -- cursor зщышешщт
0478      * P  -- paragraph sign
0479      */
0480     void newSection();
0481 
0482     /**
0483      * Splits sections startings and inserts paragraph between them.
0484      * Source: {sectionIdToInsertBefore == 1}
0485      *   [[[sometext...
0486      *    ^
0487      *   012
0488      * Result:
0489      *   [P
0490      *   [[sometext...
0491      *
0492      * [] -- section bounds
0493      * P  -- paragraph sign
0494      */
0495     void splitSectionsStartings(int sectionIdToInsertBefore);
0496 
0497     /**
0498      * Splits section endings and insert paragraph between them.
0499      * Source: {sectionIdToInsertAfter == 1}
0500      *   sometext]]]
0501      *            ^
0502      *           012
0503      * Result:
0504      *   sometext]]P
0505      *   P]
0506      *
0507      * [] -- section bounds
0508      * P  -- paragraph sign
0509      */
0510     void splitSectionsEndings(int sectionIdToInsertAfter);
0511 
0512     void renameSection(KoSection *section, const QString &newName);
0513 
0514     void newLine();
0515 
0516     bool isWithinSelection(int position) const;
0517 
0518     int position() const;
0519 
0520     void select(QTextCursor::SelectionType selection);
0521 
0522     QString selectedText() const;
0523 
0524     QTextDocumentFragment selection() const;
0525 
0526     int selectionEnd() const;
0527 
0528     int selectionStart() const;
0529 
0530     void setBlockFormat(const QTextBlockFormat &format);
0531 
0532     void setCharFormat(const QTextCharFormat &format);
0533 
0534     void setPosition(int pos, QTextCursor::MoveMode mode = QTextCursor::MoveAnchor);
0535 
0536     void setVisualNavigation(bool on);
0537 
0538     bool visualNavigation() const;
0539 
0540     const QTextFrame *currentFrame () const;
0541     const QTextList *currentList () const;
0542     const QTextTable *currentTable () const;
0543 
0544 Q_SIGNALS:
0545     void cursorPositionChanged();
0546     void textFormatChanged();
0547     void characterStyleApplied(KoCharacterStyle *style);
0548     void paragraphStyleApplied(KoParagraphStyle *style);
0549 
0550 protected:
0551     void recursivelyVisitSelection(QTextFrame::iterator it, KoTextVisitor &visitor) const;
0552 
0553 private:
0554     Q_PRIVATE_SLOT(d, void documentCommandAdded())
0555 
0556     class Private;
0557     friend class Private;
0558     Private* const d;
0559 };
0560 
0561 Q_DECLARE_METATYPE(KoTextEditor*)
0562 Q_DECLARE_METATYPE(bool *)
0563 Q_DECLARE_OPERATORS_FOR_FLAGS(KoTextEditor::ChangeListFlags)
0564 
0565 #endif // KOTEXTEDITOR_H