1 /* This file is part of the KDE project
2  * Copyright (C) 2006-2009 Thomas Zander <zander@kde.org>
3  * Copyright (C) 2008 Thorsten Zachmann <zachmann@kde.org>
4  * Copyright (C) 2009 KO GmbH <cbo@kogmbh.com>
5  * Copyright (C) 2011 Mojtaba Shahi Senobari <mojtaba.shahi3000@gmail.com>
6  * Copyright (C) 2008, 2012 Pierre Stirnweiss <pstirnweiss@googlemail.org>
7  * Copyright (C) 2014 Denis Kuplyakov <dener.kup@gmail.com>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public License
20  * along with this library; see the file COPYING.LIB.  If not, write to
21  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  * Boston, MA 02110-1301, USA.
23  */
24 
25 #ifndef KOTEXTTOOL_H
26 #define KOTEXTTOOL_H
27 
28 #include "TextShape.h"
29 #include "KoPointedAt.h"
30 
31 #include <KoToolBase.h>
32 #include <KoTextCommandBase.h>
33 #include <KoUnit.h>
34 #include <KoBorder.h>
35 #include <KoTextEditor.h>
36 
37 #include <QClipboard>
38 #include <QHash>
39 #include <QTextBlock>
40 #include <QTextCursor>
41 #include <QTimer>
42 #include <QPointer>
43 #include <QRectF>
44 
45 #include <TextEditingPluginContainer.h>
46 
47 class InsertCharacter;
48 class KoChangeTracker;
49 class KoCharacterStyle;
50 class KoColor;
51 class KoColorPopupAction;
52 class KoParagraphStyle;
53 class KoStyleManager;
54 class KoTextEditor;
55 class UndoTextCommand;
56 
57 class QAction;
58 class KActionMenu;
59 class KoFontFamilyAction;
60 class FontSizeAction;
61 
62 class KUndo2Command;
63 
64 class QDrag;
65 class QMimeData;
66 
67 class MockCanvas;
68 class TextToolSelection;
69 
70 /**
71  * This is the tool for the text-shape (which is a flake-based plugin).
72  */
73 class TextTool : public KoToolBase, public KoUndoableTool
74 {
75     Q_OBJECT
76 public:
77     explicit TextTool(KoCanvasBase *canvas);
78 #ifndef NDEBUG
79     explicit TextTool(MockCanvas *canvas);
80 #endif
81     ~TextTool() override;
82 
83     /// reimplemented from superclass
84     void paint(QPainter &painter, const KoViewConverter &converter) override;
85 
86     /// reimplemented from superclass
87     void mousePressEvent(KoPointerEvent *event) override;
88     /// reimplemented from superclass
89     void mouseDoubleClickEvent(KoPointerEvent *event) override;
90     /// reimplemented from superclass
91     void mouseTripleClickEvent(KoPointerEvent *event) override;
92     /// reimplemented from superclass
93     void mouseMoveEvent(KoPointerEvent *event) override;
94     /// reimplemented from superclass
95     void mouseReleaseEvent(KoPointerEvent *event) override;
96     /// reimplemented from superclass
97     void shortcutOverrideEvent(QKeyEvent *event) override;
98     /// reimplemented from superclass
99     void keyPressEvent(QKeyEvent *event) override;
100     /// reimplemented from superclass
101     void keyReleaseEvent(QKeyEvent *event) override;
102 
103     /// reimplemented from superclass
104     void activate(ToolActivation toolActivation, const QSet<KoShape*> &shapes) override;
105     /// reimplemented from superclass
106     void deactivate() override;
107     /// reimplemented from superclass
108     void copy() const override;
109 
110     /// reimplemented from KoUndoableTool
setAddUndoCommandAllowed(bool allowed)111     void setAddUndoCommandAllowed(bool allowed) override { m_allowAddUndoCommand = allowed; }
112 
113     ///reimplemented
114     void deleteSelection() override;
115     /// reimplemented from superclass
116     void cut() override;
117     /// reimplemented from superclass
118     bool paste() override;
119     /// reimplemented from superclass
120     QStringList supportedPasteMimeTypes() const override;
121     /// reimplemented from superclass
122     void dragMoveEvent(QDragMoveEvent *event, const QPointF &point) override;
123     /// reimplemented from superclass
124     void dragLeaveEvent(QDragLeaveEvent *event) override;
125     /// reimplemented from superclass
126     void dropEvent(QDropEvent *event, const QPointF &point) override;
127 
128     /// reimplemented from superclass
129     void repaintDecorations() override;
130 
131     /// reimplemented from superclass
132     KoToolSelection* selection() override;
133     /// reimplemented from superclass
134     QList<QPointer<QWidget> > createOptionWidgets() override;
135 
136     /// reimplemented from superclass
137     QVariant inputMethodQuery(Qt::InputMethodQuery query, const KoViewConverter &converter) const override;
138     /// reimplemented from superclass
139     void inputMethodEvent(QInputMethodEvent * event) override;
140 
141 
142     /// 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.
143 
144     void startEditing(KUndo2Command* command);
145 
146     void stopEditing();
147 
148     void setShapeData(KoTextShapeData *data);
149 
150     QRectF caretRect(QTextCursor *cursor, bool *upToDate=0) const;
151 
152     QRectF textRect(QTextCursor &cursor) const;
153 
154 protected:
155     virtual void createActions();
textShape()156     TextShape *textShape() {return m_textShape;}
157 
158     friend class SimpleParagraphWidget;
159     friend class ParagraphSettingsDialog;
160 
textEditor()161     KoTextEditor *textEditor() { return m_textEditor.data(); }
162 
163 public Q_SLOTS:
164     /// Insert comment to document.
165      void insertAnnotation();
166     /// start the textedit-plugin.
167     void startTextEditingPlugin(const QString &pluginId);
168     /// reimplemented from KoToolBase
169     void canvasResourceChanged(int key, const QVariant &res) override;
170 
171 Q_SIGNALS:
172     /// emitted every time a different styleManager is set.
173     void styleManagerChanged(KoStyleManager *manager);
174     /// emitted every time a caret move leads to a different character format being under the caret
175     void charFormatChanged(const QTextCharFormat &format, const QTextCharFormat& refBlockCharFormat);
176     /// emitted every time a caret move leads to a different paragraph format being under the caret
177     void blockFormatChanged(const QTextBlockFormat &format);
178     /// emitted every time a caret move leads to a different paragraph format being under the caret
179     void blockChanged(const QTextBlock &block);
180 
181 private Q_SLOTS:
182     /// inserts new paragraph and includes it into the new section
183     void insertNewSection();
184     /// configures params of the current section
185     void configureSection();
186     /// inserts paragraph between sections bounds
187     void splitSections();
188     /// paste text from the clipboard without formatting
189     void pasteAsText();
190     /// make the selected text bold or not
191     void bold(bool);
192     /// make the selected text italic or not
193     void italic(bool);
194     /// underline of the selected text
195     void underline(bool underline);
196     /// strikethrough of the selected text
197     void strikeOut(bool strikeOut);
198     /// insert a non breaking space at the caret position
199     void nonbreakingSpace();
200     /// insert a non breaking hyphen at the caret position
201     void nonbreakingHyphen();
202     /// insert a soft hyphen at the caret position
203     void softHyphen();
204     /// insert a linebreak at the caret position
205     void lineBreak();
206     /// force the remainder of the text into the next page
207     void insertFrameBreak();
208     /// align all of the selected text left
209     void alignLeft();
210     /// align all of the selected text right
211     void alignRight();
212     /// align all of the selected text centered
213     void alignCenter();
214     /// align all of the selected text block-justified
215     void alignBlock();
216     /// make the selected text switch to be super-script
217     void superScript(bool);
218     /// make the selected text switch to be sub-script
219     void subScript(bool);
220     /// move the paragraph indent of the selected text to be less (left on LtR text)
221     void decreaseIndent();
222     /// move the paragraph indent of the selected text to be more (right on LtR text)
223     void increaseIndent();
224     /// Increase the font size. This will preserve eventual difference in font size within the selection.
225     void increaseFontSize();
226     /// Decrease font size. See above.
227     void decreaseFontSize();
228     /// Set font family
229     void setFontFamily(const QString &);
230     /// Set Font size
231     void setFontSize(qreal size);
232     /// see KoTextEditor::insertIndexMarker
233     void insertIndexMarker();
234     /// shows a dialog to insert a table
235     void insertTable();
236     /// insert a table of given dimensions
237     void insertTableQuick(int rows, int columns);
238     /// insert a row above
239     void insertTableRowAbove();
240     /// insert a row below
241     void insertTableRowBelow();
242     /// insert a column left
243     void insertTableColumnLeft();
244     /// insert a column right
245     void insertTableColumnRight();
246     /// delete a column
247     void deleteTableColumn();
248     /// delete a row
249     void deleteTableRow();
250     /// merge table cells
251     void mergeTableCells();
252     /// split previous merged table cells
253     void splitTableCells();
254     /// format the table border (enter table pen mode)
255     void setTableBorderData(const KoBorder::BorderData &data);
256     /// shows a dialog to alter the paragraph properties
257     void formatParagraph();
258     /// select all text in the current document.
259     void selectAll();
260     /// show the style manager
261     void showStyleManager(int styleId = -1);
262     /// change color of a selected text
263     void setTextColor(const KoColor &color);
264     /// change background color of a selected text
265     void setBackgroundColor(const KoColor &color);
266     /// Enable or disable auto-resize
267     void setAutoResize(bool enabled);
268     /// Enable or disable grow-width-to-fit-text.
269     void setGrowWidthToFit(bool enabled);
270     /// Enable or disable grow-height-to-fit-text.
271     void setGrowHeightToFit(bool enabled);
272     /// Enable or disable shrink-to-fit-text.
273     void setShrinkToFit(bool enabled);
274     /// set Paragraph style of current selection. Existing style will be completely overridden.
275     void setStyle(KoParagraphStyle *syle);
276     /// set the characterStyle of the current selection. see above.
277     void setStyle(KoCharacterStyle *style);
278     /// set the level of current selected list
279     void setListLevel(int level);
280 
281     /// slot to call when a series of commands is started that together need to become 1 undo action.
282     void startMacro(const QString &title);
283     /// slot to call when a series of commands has ended that together should be 1 undo action.
284     void stopMacro();
285 
286     /// show the insert special character docker.
287     void insertSpecialCharacter();
288     /// insert string
289     void insertString(const QString &string);
290 
291     /// returns the focus to canvas when styles are selected in the optionDocker
292     void returnFocusToCanvas();
293 
294     void selectFont();
295     void shapeAddedToCanvas();
296 
297     void blinkCaret();
298     void relayoutContent();
299 
300     // called when the m_textShapeData has been deleted.
301     void shapeDataRemoved();
302 
303     //Show tooltip with editing info
304     void showEditTip();
305 
306     /// print debug about the details of the text document
307     void debugTextDocument();
308     /// print debug about the details of the styles on the current text document
309     void debugTextStyles();
310 
311     void ensureCursorVisible(bool moveView = true);
312 
313     void createStyleFromCurrentBlockFormat(const QString &name);
314     void createStyleFromCurrentCharFormat(const QString &name);
315 
316     void testSlot(bool);
317 
318     /// change block text direction
319     void textDirectionChanged();
320 
321     void updateActions();
322 
323 private:
324     void repaintCaret();
325     void repaintSelection();
326     KoPointedAt hitTest(const QPointF & point) const;
327     void updateStyleManager();
328     void updateSelectedShape(const QPointF &point, bool noDocumentChange);
329     void updateSelectionHandler();
330     void editingPluginEvents();
331     void finishedWord();
332     void finishedParagraph();
333     void startingSimpleEdit();
334     void runUrl(KoPointerEvent *event, QString &url);
335     void useTableBorderCursor();
336 
337     QMimeData *generateMimeData() const;
338 
339     TextEditingPluginContainer *textEditingPluginContainer();
340 
341 private:
342     friend class UndoTextCommand;
343     friend class ChangeTracker;
344     friend class TextCutCommand;
345     friend class ShowChangesCommand;
346 
347     TextShape *m_textShape; // where caret of m_textEditor currently is
348     KoTextShapeData *m_textShapeData; // where caret of m_textEditor currently is
349     QPointer<KoTextEditor> m_textEditor;
350     QPointer<KoTextEditor> m_oldTextEditor;
351     KoChangeTracker *m_changeTracker;
352     KoUnit m_unit;
353     bool m_allowActions;
354     bool m_allowAddUndoCommand;
355     bool m_allowResourceManagerUpdates;
356     int m_prevCursorPosition; /// used by editingPluginEvents
357     int m_prevMouseSelectionStart, m_prevMouseSelectionEnd;
358 
359     QTimer m_caretTimer;
360     bool m_caretTimerState;
361     QAction *m_actionPasteAsText;
362     QAction *m_actionFormatBold;
363     QAction *m_actionFormatItalic;
364     QAction *m_actionFormatUnderline;
365     QAction *m_actionFormatStrikeOut;
366     QAction *m_actionAlignLeft;
367     QAction *m_actionAlignRight;
368     QAction *m_actionAlignCenter;
369     QAction *m_actionAlignBlock;
370     QAction *m_actionFormatSuper;
371     QAction *m_actionFormatSub;
372     QAction *m_actionFormatIncreaseIndent;
373     QAction *m_actionFormatDecreaseIndent;
374     QAction *m_autoResizeAction;
375     QAction *m_growWidthAction;
376     QAction *m_growHeightAction;
377     QAction *m_shrinkToFitAction;
378     QAction *m_actionChangeDirection;
379     QAction *m_actionInsertSection;
380     QAction *m_actionConfigureSection;
381     QAction *m_actionSplitSections;
382     KActionMenu *m_variableMenu;
383 
384     FontSizeAction *m_actionFormatFontSize;
385     KoFontFamilyAction *m_actionFormatFontFamily;
386     KoColorPopupAction *m_actionFormatTextColor;
387     KoColorPopupAction *m_actionFormatBackgroundColor;
388 
389     KUndo2Command *m_currentCommand; //this command will be the direct parent of undoCommands generated as the result of QTextDocument changes
390 
391     bool m_currentCommandHasChildren;
392 
393     InsertCharacter *m_specialCharacterDocker;
394 
395     QPointer<TextEditingPluginContainer> m_textEditingPlugins;
396 
397     bool m_textTyping;
398     bool m_textDeleting;
399 
400     QTimer m_editTipTimer;
401     KoPointedAt m_editTipPointedAt;
402     QPoint m_editTipPos;
403 
404     bool m_delayedEnsureVisible;
405     TextToolSelection *m_toolSelection;
406 
407     KoPointedAt m_tableDragInfo;
408     bool m_tableDraggedOnce;
409     bool m_tableDragWithShift;
410     QPointF m_draggingOrigin;
411     qreal m_dx;
412     qreal m_dy;
413     bool m_tablePenMode;
414     KoBorder::BorderData m_tablePenBorderData;
415     mutable QRectF m_lastImMicroFocus;
416 
417     bool m_clickWithinSelection;
418     QDrag *m_drag;
419     QAbstractTextDocumentLayout::Selection m_preDragSelection;
420 };
421 
422 #endif
423