File indexing completed on 2024-05-12 16:35:02

0001 /* This file is part of the KDE project
0002  * Copyright (C) 2006-2009 Thomas Zander <zander@kde.org>
0003  * Copyright (C) 2008 Thorsten Zachmann <zachmann@kde.org>
0004  * Copyright (C) 2009 KO GmbH <cbo@kogmbh.com>
0005  * Copyright (C) 2011 Mojtaba Shahi Senobari <mojtaba.shahi3000@gmail.com>
0006  * Copyright (C) 2008, 2012 Pierre Stirnweiss <pstirnweiss@googlemail.org>
0007  * Copyright (C) 2014 Denis Kuplyakov <dener.kup@gmail.com>
0008  *
0009  * This library is free software; you can redistribute it and/or
0010  * modify it under the terms of the GNU Library General Public
0011  * License as published by the Free Software Foundation; either
0012  * version 2 of the License, or (at your option) any later version.
0013  *
0014  * This library is distributed in the hope that it will be useful,
0015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0017  * Library General Public License for more details.
0018  *
0019  * You should have received a copy of the GNU Library General Public License
0020  * along with this library; see the file COPYING.LIB.  If not, write to
0021  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0022  * Boston, MA 02110-1301, USA.
0023  */
0024 
0025 #ifndef KOTEXTTOOL_H
0026 #define KOTEXTTOOL_H
0027 
0028 #include "TextShape.h"
0029 #include "KoPointedAt.h"
0030 
0031 #include <KoToolBase.h>
0032 #include <KoTextCommandBase.h>
0033 #include <KoUnit.h>
0034 #include <KoBorder.h>
0035 #include <KoTextEditor.h>
0036 
0037 #include <QClipboard>
0038 #include <QHash>
0039 #include <QTextBlock>
0040 #include <QTextCursor>
0041 #include <QTimer>
0042 #include <QPointer>
0043 #include <QRectF>
0044 
0045 #include <TextEditingPluginContainer.h>
0046 
0047 class InsertCharacter;
0048 class KoChangeTracker;
0049 class KoCharacterStyle;
0050 class KoColor;
0051 class KoColorPopupAction;
0052 class KoParagraphStyle;
0053 class KoStyleManager;
0054 class KoTextEditor;
0055 class UndoTextCommand;
0056 
0057 class QAction;
0058 class KActionMenu;
0059 class KoFontFamilyAction;
0060 class FontSizeAction;
0061 
0062 class KUndo2Command;
0063 
0064 class QDrag;
0065 class QMimeData;
0066 
0067 class MockCanvas;
0068 class TextToolSelection;
0069 
0070 /**
0071  * This is the tool for the text-shape (which is a flake-based plugin).
0072  */
0073 class TextTool : public KoToolBase, public KoUndoableTool
0074 {
0075     Q_OBJECT
0076 public:
0077     explicit TextTool(KoCanvasBase *canvas);
0078 #ifndef NDEBUG
0079     explicit TextTool(MockCanvas *canvas);
0080 #endif
0081     ~TextTool() override;
0082 
0083     /// reimplemented from superclass
0084     void paint(QPainter &painter, const KoViewConverter &converter) override;
0085 
0086     /// reimplemented from superclass
0087     void mousePressEvent(KoPointerEvent *event) override;
0088     /// reimplemented from superclass
0089     void mouseDoubleClickEvent(KoPointerEvent *event) override;
0090     /// reimplemented from superclass
0091     void mouseTripleClickEvent(KoPointerEvent *event) override;
0092     /// reimplemented from superclass
0093     void mouseMoveEvent(KoPointerEvent *event) override;
0094     /// reimplemented from superclass
0095     void mouseReleaseEvent(KoPointerEvent *event) override;
0096     /// reimplemented from superclass
0097     void shortcutOverrideEvent(QKeyEvent *event) override;
0098     /// reimplemented from superclass
0099     void keyPressEvent(QKeyEvent *event) override;
0100     /// reimplemented from superclass
0101     void keyReleaseEvent(QKeyEvent *event) override;
0102 
0103     /// reimplemented from superclass
0104     void activate(ToolActivation toolActivation, const QSet<KoShape*> &shapes) override;
0105     /// reimplemented from superclass
0106     void deactivate() override;
0107     /// reimplemented from superclass
0108     void copy() const override;
0109 
0110     /// reimplemented from KoUndoableTool
0111     void setAddUndoCommandAllowed(bool allowed) override { m_allowAddUndoCommand = allowed; }
0112 
0113     ///reimplemented
0114     void deleteSelection() override;
0115     /// reimplemented from superclass
0116     void cut() override;
0117     /// reimplemented from superclass
0118     bool paste() override;
0119     /// reimplemented from superclass
0120     QStringList supportedPasteMimeTypes() const override;
0121     /// reimplemented from superclass
0122     void dragMoveEvent(QDragMoveEvent *event, const QPointF &point) override;
0123     /// reimplemented from superclass
0124     void dragLeaveEvent(QDragLeaveEvent *event) override;
0125     /// reimplemented from superclass
0126     void dropEvent(QDropEvent *event, const QPointF &point) override;
0127 
0128     /// reimplemented from superclass
0129     void repaintDecorations() override;
0130 
0131     /// reimplemented from superclass
0132     KoToolSelection* selection() override;
0133     /// reimplemented from superclass
0134     QList<QPointer<QWidget> > createOptionWidgets() override;
0135 
0136     /// reimplemented from superclass
0137     QVariant inputMethodQuery(Qt::InputMethodQuery query, const KoViewConverter &converter) const override;
0138     /// reimplemented from superclass
0139     void inputMethodEvent(QInputMethodEvent * event) override;
0140 
0141 
0142     /// The following two methods allow an undo/redo command to tell the tool, it will modify the QTextDocument and wants to be parent of the undo/redo commands resulting from these changes.
0143 
0144     void startEditing(KUndo2Command* command);
0145 
0146     void stopEditing();
0147 
0148     void setShapeData(KoTextShapeData *data);
0149 
0150     QRectF caretRect(QTextCursor *cursor, bool *upToDate=0) const;
0151 
0152     QRectF textRect(QTextCursor &cursor) const;
0153 
0154 protected:
0155     virtual void createActions();
0156     TextShape *textShape() {return m_textShape;}
0157 
0158     friend class SimpleParagraphWidget;
0159     friend class ParagraphSettingsDialog;
0160 
0161     KoTextEditor *textEditor() { return m_textEditor.data(); }
0162 
0163 public Q_SLOTS:
0164     /// Insert comment to document.
0165      void insertAnnotation();
0166     /// start the textedit-plugin.
0167     void startTextEditingPlugin(const QString &pluginId);
0168     /// reimplemented from KoToolBase
0169     void canvasResourceChanged(int key, const QVariant &res) override;
0170 
0171 Q_SIGNALS:
0172     /// emitted every time a different styleManager is set.
0173     void styleManagerChanged(KoStyleManager *manager);
0174     /// emitted every time a caret move leads to a different character format being under the caret
0175     void charFormatChanged(const QTextCharFormat &format, const QTextCharFormat& refBlockCharFormat);
0176     /// emitted every time a caret move leads to a different paragraph format being under the caret
0177     void blockFormatChanged(const QTextBlockFormat &format);
0178     /// emitted every time a caret move leads to a different paragraph format being under the caret
0179     void blockChanged(const QTextBlock &block);
0180 
0181 private Q_SLOTS:
0182     /// inserts new paragraph and includes it into the new section
0183     void insertNewSection();
0184     /// configures params of the current section
0185     void configureSection();
0186     /// inserts paragraph between sections bounds
0187     void splitSections();
0188     /// paste text from the clipboard without formatting
0189     void pasteAsText();
0190     /// make the selected text bold or not
0191     void bold(bool);
0192     /// make the selected text italic or not
0193     void italic(bool);
0194     /// underline of the selected text
0195     void underline(bool underline);
0196     /// strikethrough of the selected text
0197     void strikeOut(bool strikeOut);
0198     /// insert a non breaking space at the caret position
0199     void nonbreakingSpace();
0200     /// insert a non breaking hyphen at the caret position
0201     void nonbreakingHyphen();
0202     /// insert a soft hyphen at the caret position
0203     void softHyphen();
0204     /// insert a linebreak at the caret position
0205     void lineBreak();
0206     /// force the remainder of the text into the next page
0207     void insertFrameBreak();
0208     /// align all of the selected text left
0209     void alignLeft();
0210     /// align all of the selected text right
0211     void alignRight();
0212     /// align all of the selected text centered
0213     void alignCenter();
0214     /// align all of the selected text block-justified
0215     void alignBlock();
0216     /// make the selected text switch to be super-script
0217     void superScript(bool);
0218     /// make the selected text switch to be sub-script
0219     void subScript(bool);
0220     /// move the paragraph indent of the selected text to be less (left on LtR text)
0221     void decreaseIndent();
0222     /// move the paragraph indent of the selected text to be more (right on LtR text)
0223     void increaseIndent();
0224     /// Increase the font size. This will preserve eventual difference in font size within the selection.
0225     void increaseFontSize();
0226     /// Decrease font size. See above.
0227     void decreaseFontSize();
0228     /// Set font family
0229     void setFontFamily(const QString &);
0230     /// Set Font size
0231     void setFontSize(qreal size);
0232     /// see KoTextEditor::insertIndexMarker
0233     void insertIndexMarker();
0234     /// shows a dialog to insert a table
0235     void insertTable();
0236     /// insert a table of given dimensions
0237     void insertTableQuick(int rows, int columns);
0238     /// insert a row above
0239     void insertTableRowAbove();
0240     /// insert a row below
0241     void insertTableRowBelow();
0242     /// insert a column left
0243     void insertTableColumnLeft();
0244     /// insert a column right
0245     void insertTableColumnRight();
0246     /// delete a column
0247     void deleteTableColumn();
0248     /// delete a row
0249     void deleteTableRow();
0250     /// merge table cells
0251     void mergeTableCells();
0252     /// split previous merged table cells
0253     void splitTableCells();
0254     /// format the table border (enter table pen mode)
0255     void setTableBorderData(const KoBorder::BorderData &data);
0256     /// shows a dialog to alter the paragraph properties
0257     void formatParagraph();
0258     /// select all text in the current document.
0259     void selectAll();
0260     /// show the style manager
0261     void showStyleManager(int styleId = -1);
0262     /// change color of a selected text
0263     void setTextColor(const KoColor &color);
0264     /// change background color of a selected text
0265     void setBackgroundColor(const KoColor &color);
0266     /// Enable or disable auto-resize
0267     void setAutoResize(bool enabled);
0268     /// Enable or disable grow-width-to-fit-text.
0269     void setGrowWidthToFit(bool enabled);
0270     /// Enable or disable grow-height-to-fit-text.
0271     void setGrowHeightToFit(bool enabled);
0272     /// Enable or disable shrink-to-fit-text.
0273     void setShrinkToFit(bool enabled);
0274     /// set Paragraph style of current selection. Existing style will be completely overridden.
0275     void setStyle(KoParagraphStyle *syle);
0276     /// set the characterStyle of the current selection. see above.
0277     void setStyle(KoCharacterStyle *style);
0278     /// set the level of current selected list
0279     void setListLevel(int level);
0280 
0281     /// slot to call when a series of commands is started that together need to become 1 undo action.
0282     void startMacro(const QString &title);
0283     /// slot to call when a series of commands has ended that together should be 1 undo action.
0284     void stopMacro();
0285 
0286     /// show the insert special character docker.
0287     void insertSpecialCharacter();
0288     /// insert string
0289     void insertString(const QString &string);
0290 
0291     /// returns the focus to canvas when styles are selected in the optionDocker
0292     void returnFocusToCanvas();
0293 
0294     void selectFont();
0295     void shapeAddedToCanvas();
0296 
0297     void blinkCaret();
0298     void relayoutContent();
0299 
0300     // called when the m_textShapeData has been deleted.
0301     void shapeDataRemoved();
0302 
0303     //Show tooltip with editing info
0304     void showEditTip();
0305 
0306     /// print debug about the details of the text document
0307     void debugTextDocument();
0308     /// print debug about the details of the styles on the current text document
0309     void debugTextStyles();
0310 
0311     void ensureCursorVisible(bool moveView = true);
0312 
0313     void createStyleFromCurrentBlockFormat(const QString &name);
0314     void createStyleFromCurrentCharFormat(const QString &name);
0315 
0316     void testSlot(bool);
0317 
0318     /// change block text direction
0319     void textDirectionChanged();
0320 
0321     void updateActions();
0322 
0323 private:
0324     void repaintCaret();
0325     void repaintSelection();
0326     KoPointedAt hitTest(const QPointF & point) const;
0327     void updateStyleManager();
0328     void updateSelectedShape(const QPointF &point, bool noDocumentChange);
0329     void updateSelectionHandler();
0330     void editingPluginEvents();
0331     void finishedWord();
0332     void finishedParagraph();
0333     void startingSimpleEdit();
0334     void runUrl(KoPointerEvent *event, QString &url);
0335     void useTableBorderCursor();
0336 
0337     QMimeData *generateMimeData() const;
0338 
0339     TextEditingPluginContainer *textEditingPluginContainer();
0340 
0341 private:
0342     friend class UndoTextCommand;
0343     friend class ChangeTracker;
0344     friend class TextCutCommand;
0345     friend class ShowChangesCommand;
0346 
0347     TextShape *m_textShape; // where caret of m_textEditor currently is
0348     KoTextShapeData *m_textShapeData; // where caret of m_textEditor currently is
0349     QPointer<KoTextEditor> m_textEditor;
0350     QPointer<KoTextEditor> m_oldTextEditor;
0351     KoChangeTracker *m_changeTracker;
0352     KoUnit m_unit;
0353     bool m_allowActions;
0354     bool m_allowAddUndoCommand;
0355     bool m_allowResourceManagerUpdates;
0356     int m_prevCursorPosition; /// used by editingPluginEvents
0357     int m_prevMouseSelectionStart, m_prevMouseSelectionEnd;
0358 
0359     QTimer m_caretTimer;
0360     bool m_caretTimerState;
0361     QAction *m_actionPasteAsText;
0362     QAction *m_actionFormatBold;
0363     QAction *m_actionFormatItalic;
0364     QAction *m_actionFormatUnderline;
0365     QAction *m_actionFormatStrikeOut;
0366     QAction *m_actionAlignLeft;
0367     QAction *m_actionAlignRight;
0368     QAction *m_actionAlignCenter;
0369     QAction *m_actionAlignBlock;
0370     QAction *m_actionFormatSuper;
0371     QAction *m_actionFormatSub;
0372     QAction *m_actionFormatIncreaseIndent;
0373     QAction *m_actionFormatDecreaseIndent;
0374     QAction *m_autoResizeAction;
0375     QAction *m_growWidthAction;
0376     QAction *m_growHeightAction;
0377     QAction *m_shrinkToFitAction;
0378     QAction *m_actionChangeDirection;
0379     QAction *m_actionInsertSection;
0380     QAction *m_actionConfigureSection;
0381     QAction *m_actionSplitSections;
0382     KActionMenu *m_variableMenu;
0383 
0384     FontSizeAction *m_actionFormatFontSize;
0385     KoFontFamilyAction *m_actionFormatFontFamily;
0386     KoColorPopupAction *m_actionFormatTextColor;
0387     KoColorPopupAction *m_actionFormatBackgroundColor;
0388 
0389     KUndo2Command *m_currentCommand; //this command will be the direct parent of undoCommands generated as the result of QTextDocument changes
0390 
0391     bool m_currentCommandHasChildren;
0392 
0393     InsertCharacter *m_specialCharacterDocker;
0394 
0395     QPointer<TextEditingPluginContainer> m_textEditingPlugins;
0396 
0397     bool m_textTyping;
0398     bool m_textDeleting;
0399 
0400     QTimer m_editTipTimer;
0401     KoPointedAt m_editTipPointedAt;
0402     QPoint m_editTipPos;
0403 
0404     bool m_delayedEnsureVisible;
0405     TextToolSelection *m_toolSelection;
0406 
0407     KoPointedAt m_tableDragInfo;
0408     bool m_tableDraggedOnce;
0409     bool m_tableDragWithShift;
0410     QPointF m_draggingOrigin;
0411     qreal m_dx;
0412     qreal m_dy;
0413     bool m_tablePenMode;
0414     KoBorder::BorderData m_tablePenBorderData;
0415     mutable QRectF m_lastImMicroFocus;
0416 
0417     bool m_clickWithinSelection;
0418     QDrag *m_drag;
0419     QAbstractTextDocumentLayout::Selection m_preDragSelection;
0420 };
0421 
0422 #endif