1 /*
2     SPDX-FileCopyrightText: 2002 John Firebaugh <jfirebaugh@kde.org>
3     SPDX-FileCopyrightText: 2001 Christoph Cullmann <cullmann@kde.org>
4     SPDX-FileCopyrightText: 2001-2010 Joseph Wenninger <jowenn@kde.org>
5     SPDX-FileCopyrightText: 1999 Jochen Wilhelmy <digisnap@cs.tu-berlin.de>
6 
7     SPDX-License-Identifier: LGPL-2.0-or-later
8 */
9 
10 #ifndef kate_view_h
11 #define kate_view_h
12 
13 #include <ktexteditor/annotationinterface.h>
14 #include <ktexteditor/codecompletioninterface.h>
15 #include <ktexteditor/configinterface.h>
16 #include <ktexteditor/inlinenoteinterface.h>
17 #include <ktexteditor/linerange.h>
18 #include <ktexteditor/mainwindow.h>
19 #include <ktexteditor/texthintinterface.h>
20 #include <ktexteditor/view.h>
21 
22 #include <QJsonDocument>
23 #include <QMenu>
24 #include <QModelIndex>
25 #include <QPointer>
26 #include <QScopedPointer>
27 #include <QSpacerItem>
28 #include <QTextLayout>
29 #include <QTimer>
30 
31 #include <array>
32 
33 #include "katetextfolding.h"
34 #include "katetextrange.h"
35 
36 namespace KTextEditor
37 {
38 class AnnotationModel;
39 class Message;
40 class InlineNoteProvider;
41 }
42 
43 namespace KTextEditor
44 {
45 class DocumentPrivate;
46 }
47 class KateBookmarks;
48 class KateViewConfig;
49 class KateRenderer;
50 class KateSpellCheckDialog;
51 class KateCompletionWidget;
52 class KateViewInternal;
53 class KateViewBar;
54 class KateTextPreview;
55 class KateGotoBar;
56 class KateDictionaryBar;
57 class KateSpellingMenu;
58 class KateMessageWidget;
59 class KateIconBorder;
60 class KateStatusBar;
61 class KateViewEncodingAction;
62 class KateModeMenu;
63 class KateAbstractInputMode;
64 class KateScriptActionMenu;
65 class KateMessageLayout;
66 class KateInlineNoteData;
67 
68 class KToggleAction;
69 class KSelectAction;
70 
71 class QAction;
72 
73 namespace KTextEditor
74 {
75 //
76 // Kate KTextEditor::View class ;)
77 //
78 class KTEXTEDITOR_EXPORT ViewPrivate : public KTextEditor::View,
79                                        public KTextEditor::TextHintInterface,
80                                        public KTextEditor::CodeCompletionInterfaceV2,
81                                        public KTextEditor::ConfigInterface,
82                                        public KTextEditor::InlineNoteInterface,
83                                        public KTextEditor::AnnotationViewInterfaceV2
84 {
85     Q_OBJECT
86     Q_INTERFACES(KTextEditor::TextHintInterface)
87     Q_INTERFACES(KTextEditor::ConfigInterface)
88     Q_INTERFACES(KTextEditor::CodeCompletionInterface)
89     Q_INTERFACES(KTextEditor::CodeCompletionInterfaceV2)
90     Q_INTERFACES(KTextEditor::AnnotationViewInterface)
91     Q_INTERFACES(KTextEditor::AnnotationViewInterfaceV2)
92     Q_INTERFACES(KTextEditor::InlineNoteInterface)
93 
94     friend class KTextEditor::View;
95     friend class ::KateViewInternal;
96     friend class ::KateIconBorder;
97     friend class ::KateTextPreview;
98 
99 public:
100     ViewPrivate(KTextEditor::DocumentPrivate *doc, QWidget *parent, KTextEditor::MainWindow *mainWindow = nullptr);
101     ~ViewPrivate() override;
102 
103     /**
104      * Get the view's main window, if any
105      * \return the view's main window
106      */
mainWindow()107     KTextEditor::MainWindow *mainWindow() const override
108     {
109         return m_mainWindow;
110     }
111 
112     KTextEditor::Document *document() const override;
113 
114     ViewMode viewMode() const override;
115     QString viewModeHuman() const override;
116     InputMode viewInputMode() const override;
117     QString viewInputModeHuman() const override;
118 
119     void setInputMode(InputMode mode);
120 
121 public:
getViewInternal()122     KateViewInternal *getViewInternal()
123     {
124         return m_viewInternal;
125     }
126 
127     //
128     // KTextEditor::ClipboardInterface
129     //
130 public Q_SLOTS:
131     void paste(const QString *textToPaste = nullptr);
132     void cut();
133     void copy() const;
134 
135 private Q_SLOTS:
136     /**
137      * Paste the global mouse selection. Support for Selection is provided only
138      * on systems with a global mouse selection (e.g. X11).
139      */
140     void pasteSelection();
141 
142     /**
143      * Copy current selected stuff and paste previous content of clipboard as one operation.
144      */
145     void swapWithClipboard();
146 
147     /**
148      * Wrap lines touched by the selection with respect of existing paragraphs.
149      * Work is done by KTextEditor::DocumentPrivate::wrapParagraph
150      */
151     void applyWordWrap();
152 
153     //
154     // KTextEditor::PopupMenuInterface
155     //
156 public:
157     void setContextMenu(QMenu *menu) override;
158     QMenu *contextMenu() const override;
159     QMenu *defaultContextMenu(QMenu *menu = nullptr) const override;
160 
161 private Q_SLOTS:
162     void aboutToShowContextMenu();
163     void aboutToHideContextMenu();
164 
165 private:
166     QPointer<QMenu> m_contextMenu;
167 
168     //
169     // KTextEditor::ViewCursorInterface
170     //
171 public:
172     bool setCursorPosition(KTextEditor::Cursor position) override;
173 
174     KTextEditor::Cursor cursorPosition() const override;
175 
176     KTextEditor::Cursor cursorPositionVirtual() const override;
177 
178     QPoint cursorToCoordinate(const KTextEditor::Cursor &cursor) const override;
179 
180     KTextEditor::Cursor coordinatesToCursor(const QPoint &coord) const override;
181 
182     QPoint cursorPositionCoordinates() const override;
183 
184     bool setCursorPositionVisual(const KTextEditor::Cursor position);
185 
186     /**
187      * Return the virtual cursor column, each tab is expanded into the
188      * document's tabWidth characters. If word wrap is off, the cursor may be
189      * behind the line's length.
190      */
191     int virtualCursorColumn() const;
192 
193     bool mouseTrackingEnabled() const override;
194     bool setMouseTrackingEnabled(bool enable) override;
195 
196 private:
197     void notifyMousePositionChanged(const KTextEditor::Cursor newPosition);
198 
199     // Internal
200 public:
201     bool setCursorPositionInternal(const KTextEditor::Cursor position, uint tabwidth = 1, bool calledExternally = false);
202 
203     //
204     // KTextEditor::ConfigInterface
205     //
206 public:
207     QStringList configKeys() const override;
208     QVariant configValue(const QString &key) override;
209     void setConfigValue(const QString &key, const QVariant &value) override;
210 
211 public:
212     /**
213      * Try to fold an unfolded range starting at @p line
214      * @return the new folded range on success, otherwise an unvalid range
215      */
216     KTextEditor::Range foldLine(int line);
217 
218     /**
219      * Try to unfold a folded range starting at @p line
220      * @return true when a range was unfolded, otherwise false
221      */
222     bool unfoldLine(int line);
223 
224     /**
225      * Try to toggle the folding state of a range starting at line @p line
226      * @return true when the line was toggled, false when not
227      */
228     bool toggleFoldingOfLine(int line);
229 
230     /**
231      * Try to change all the foldings inside a folding range starting at @p line
232      * but not the range itself starting there.
233      * However, should the range itself be folded, will only the range unfolded
234      * and the containing ranges kept untouched.
235      * Should the range not contain other ranges will the range itself folded,
236      * @return true when any range was folded or unfolded, otherwise false
237      */
238     bool toggleFoldingsInRange(int line);
239 
240     //
241     // KTextEditor::CodeCompletionInterfaceV2
242     //
243 public:
244     bool isCompletionActive() const override;
245     void startCompletion(const KTextEditor::Range &word, KTextEditor::CodeCompletionModel *model) override;
246     void startCompletion(const Range &word,
247                          const QList<KTextEditor::CodeCompletionModel *> &models = QList<KTextEditor::CodeCompletionModel *>(),
248                          KTextEditor::CodeCompletionModel::InvocationType invocationType = KTextEditor::CodeCompletionModel::ManualInvocation) override;
249     void abortCompletion() override;
250     void forceCompletion() override;
251     void registerCompletionModel(KTextEditor::CodeCompletionModel *model) override;
252     void unregisterCompletionModel(KTextEditor::CodeCompletionModel *model) override;
253     bool isCompletionModelRegistered(KTextEditor::CodeCompletionModel *model) const;
254     QList<KTextEditor::CodeCompletionModel *> codeCompletionModels() const override;
255     bool isAutomaticInvocationEnabled() const override;
256     void setAutomaticInvocationEnabled(bool enabled = true) override;
257 
258 Q_SIGNALS:
259     void completionExecuted(KTextEditor::View *view, const KTextEditor::Cursor &position, KTextEditor::CodeCompletionModel *model, const QModelIndex &);
260     void completionAborted(KTextEditor::View *view);
261 
262 public Q_SLOTS:
263     void userInvokedCompletion();
264 
265 public:
266     KateCompletionWidget *completionWidget() const;
267     mutable KateCompletionWidget *m_completionWidget;
268     void sendCompletionExecuted(const KTextEditor::Cursor position, KTextEditor::CodeCompletionModel *model, const QModelIndex &index);
269     void sendCompletionAborted();
270 
271     //
272     // KTextEditor::TextHintInterface
273     //
274 public:
275     void registerTextHintProvider(KTextEditor::TextHintProvider *provider) override;
276     void unregisterTextHintProvider(KTextEditor::TextHintProvider *provider) override;
277     void setTextHintDelay(int delay) override;
278     int textHintDelay() const override;
279 
280 public:
dynWordWrap()281     bool dynWordWrap() const
282     {
283         return m_hasWrap;
284     }
285 
286     //
287     // Inline Notes Interface
288     //
289 public:
290     void registerInlineNoteProvider(KTextEditor::InlineNoteProvider *provider) override;
291     void unregisterInlineNoteProvider(KTextEditor::InlineNoteProvider *provider) override;
292     QRect inlineNoteRect(const KateInlineNoteData &note) const;
293 
294     QVarLengthArray<KateInlineNoteData, 8> inlineNotes(int line) const;
295 
296 private:
297     std::vector<KTextEditor::InlineNoteProvider *> m_inlineNoteProviders;
298 
299 private Q_SLOTS:
300     void inlineNotesReset();
301     void inlineNotesLineChanged(int line);
302 
303     //
304     // KTextEditor::SelectionInterface stuff
305     //
306 public Q_SLOTS:
307     bool setSelection(const KTextEditor::Range &selection) override;
308 
removeSelection()309     bool removeSelection() override
310     {
311         return clearSelection();
312     }
313 
removeSelectionText()314     bool removeSelectionText() override
315     {
316         return removeSelectedText();
317     }
318 
319     bool setBlockSelection(bool on) override;
320     bool toggleBlockSelection();
321 
322     bool clearSelection();
323     bool clearSelection(bool redraw, bool finishedChangingSelection = true);
324 
325     bool removeSelectedText();
326 
327     bool selectAll();
328 
329 public:
330     bool selection() const override;
331     QString selectionText() const override;
332     bool blockSelection() const override;
333     KTextEditor::Range selectionRange() const override;
334 
335     static void blockFix(KTextEditor::Range &range);
336 
337     //
338     // Arbitrary Syntax HL + Action extensions
339     //
340 public:
341     // Action association extension
342     void deactivateEditActions();
343     void activateEditActions();
344 
345     //
346     // internal helper stuff, for katerenderer and so on
347     //
348 public:
349     // should cursor be wrapped ? take config + blockselection state in account
350     bool wrapCursor() const;
351 
352     // some internal functions to get selection state of a line/col
353     bool cursorSelected(const KTextEditor::Cursor cursor);
354     bool lineSelected(int line);
355     bool lineEndSelected(const KTextEditor::Cursor lineEndPos);
356     bool lineHasSelected(int line);
357     bool lineIsSelection(int line);
358 
359     void ensureCursorColumnValid();
360 
361     void tagSelection(const KTextEditor::Range &oldSelection);
362 
363     void selectWord(const KTextEditor::Cursor cursor);
364     void selectLine(const KTextEditor::Cursor cursor);
365 
366     // BEGIN EDIT STUFF
367 public:
368     void editStart();
369     void editEnd(int editTagLineStart, int editTagLineEnd, bool tagFrom);
370 
371     void editSetCursor(const KTextEditor::Cursor cursor);
372     // END
373 
374     // BEGIN TAG & CLEAR
375 public:
376     bool tagLine(const KTextEditor::Cursor virtualCursor);
377 
378     bool tagRange(const KTextEditor::Range &range, bool realLines = false);
379     bool tagLines(KTextEditor::LineRange lineRange, bool realLines = false);
380     bool tagLines(KTextEditor::Cursor start, KTextEditor::Cursor end, bool realCursors = false);
381     bool tagLines(KTextEditor::Range range, bool realRange = false);
382 
383     void tagAll();
384 
385     void clear();
386 
387     void repaintText(bool paintOnlyDirty = false);
388 
389     void updateView(bool changed = false);
390     // END
391 
392     //
393     // KTextEditor::AnnotationView
394     //
395 public:
396     void setAnnotationModel(KTextEditor::AnnotationModel *model) override;
397     KTextEditor::AnnotationModel *annotationModel() const override;
398     void setAnnotationBorderVisible(bool visible) override;
399     bool isAnnotationBorderVisible() const override;
400     void setAnnotationItemDelegate(KTextEditor::AbstractAnnotationItemDelegate *delegate) override;
401     KTextEditor::AbstractAnnotationItemDelegate *annotationItemDelegate() const override;
402     void setAnnotationUniformItemSizes(bool enable) override;
403     bool uniformAnnotationItemSizes() const override;
404 
405 Q_SIGNALS:
406     void annotationContextMenuAboutToShow(KTextEditor::View *view, QMenu *menu, int line) override;
407     void annotationActivated(KTextEditor::View *view, int line) override;
408     // KF6: fix View -> KTextEditor::View
409     void annotationBorderVisibilityChanged(View *view, bool visible) override;
410 
411     void navigateLeft();
412     void navigateRight();
413     void navigateUp();
414     void navigateDown();
415     void navigateAccept();
416     void navigateBack();
417 
418 private:
419     KTextEditor::AnnotationModel *m_annotationModel;
420 
421     //
422     // KTextEditor::View
423     //
424 public:
emitNavigateLeft()425     void emitNavigateLeft()
426     {
427         Q_EMIT navigateLeft();
428     }
emitNavigateRight()429     void emitNavigateRight()
430     {
431         Q_EMIT navigateRight();
432     }
emitNavigateUp()433     void emitNavigateUp()
434     {
435         Q_EMIT navigateUp();
436     }
emitNavigateDown()437     void emitNavigateDown()
438     {
439         Q_EMIT navigateDown();
440     }
emitNavigateAccept()441     void emitNavigateAccept()
442     {
443         Q_EMIT navigateAccept();
444     }
emitNavigateBack()445     void emitNavigateBack()
446     {
447         Q_EMIT navigateBack();
448     }
449     /**
450      Return values for "save" related commands.
451     */
452     bool isOverwriteMode() const;
453 
454     QString currentTextLine();
455 
456     QTextLayout *textLayout(int line) const;
457     QTextLayout *textLayout(const KTextEditor::Cursor pos) const;
458 
459 public Q_SLOTS:
460     void indent();
461     void unIndent();
462     void cleanIndent();
463     void align();
464     void comment();
465     void uncomment();
466     void toggleComment();
467     void killLine();
468 
469     /**
470      * Sets the cursor to the previous editing position in this document
471      */
472     void goToPreviousEditingPosition();
473 
474     /**
475      * Sets the cursor to the next editing position in this document.
476      */
477     void goToNextEditingPosition();
478 
479     /**
480      * Uppercases selected text, or an alphabetic character next to the cursor.
481      */
482     void uppercase();
483 
484     /**
485      * Lowercases selected text, or an alphabetic character next to the cursor.
486      */
487     void lowercase();
488 
489     /**
490      * Capitalizes the selection (makes each word start with an uppercase) or
491      * the word under the cursor.
492      */
493     void capitalize();
494 
495     /**
496      * Joins lines touched by the selection.
497      */
498     void joinLines();
499 
500     /**
501      * Performs a line break (insert a new line char) at current cursor position
502      * and indent the new line.
503      *
504      * Most work is done by @c KTextEditor::DocumentPrivate::newLine and
505      * @c KateAutoIndent::userTypedChar
506      * @see KTextEditor::DocumentPrivate::newLine, KateAutoIndent
507      */
508     void keyReturn();
509 
510     /**
511      * Performs a line break (insert a new line char) at current cursor position
512      * but keep all leading non word char as indent for the new line.
513      */
514     void smartNewline();
515 
516     /**
517      * Inserts a new line character at the current cursor position, with
518      * the newly inserted line having no indentation regardless of indentation
519      * settings. Useful e.g. for inserting a new, empty, line to separate
520      * blocks of code inside a function.
521      */
522     void noIndentNewline();
523 
524     /**
525      * Insert a tabulator char at current cursor position.
526      */
527     void backspace();
528 
529     /**
530      * Remove the word left from the current cursor position including all leading
531      * space.
532      * @see KateViewInternal::wordPrev
533      */
534     void deleteWordLeft();
535 
536     /**
537      * Remove the current selection. When nothing is selected the char right
538      * from the current cursor position is removed.
539      * @see KTextEditor::DocumentPrivate::del
540      */
541     void keyDelete();
542 
543     /**
544      * When the char right from the current cursor position is a space is all
545      * space to the right removed. Otherwise is the word to the right including
546      * all trialling space removed.
547      * @see KateViewInternal::wordNext
548      */
549     void deleteWordRight();
550 
551     /**
552      * Transpose the characters left and right from the current cursor position
553      * and move the cursor one position to the right. If the char right to the
554      * current cursor position is a new line char, nothing is done.
555      * @see KTextEditor::DocumentPrivate::transpose
556      */
557     void transpose();
558 
559     /**
560      * Transpose the word at the current cursor position with the word to the right (or to the left for RTL layouts).
561      * If the word is the last in the line, try swapping with the previous word instead.
562      * If the word is the only one in the line, no swapping is done.
563      * @see KTextEditor::DocumentPrivate::swapTextRanges
564      */
565     void transposeWord();
566     void cursorLeft();
567     void shiftCursorLeft();
568     void cursorRight();
569     void shiftCursorRight();
570     void wordLeft();
571     void shiftWordLeft();
572     void wordRight();
573     void shiftWordRight();
574     void home();
575     void shiftHome();
576     void end();
577     void shiftEnd();
578     void up();
579     void shiftUp();
580     void down();
581     void shiftDown();
582     void scrollUp();
583     void scrollDown();
584     void topOfView();
585     void shiftTopOfView();
586     void bottomOfView();
587     void shiftBottomOfView();
588     void pageUp();
589     void shiftPageUp();
590     void pageDown();
591     void shiftPageDown();
592     void top();
593     void shiftTop();
594     void bottom();
595     void shiftBottom();
596     void toMatchingBracket();
597     void shiftToMatchingBracket();
598     void toPrevModifiedLine();
599     void toNextModifiedLine();
600     /**
601      * Insert a tabulator char at current cursor position.
602      */
603     void insertTab();
604 
605     void gotoLine();
606 
607     // config file / session management functions
608 public:
609     /**
610      * Read session settings from the given \p config.
611      *
612      * Known flags:
613      *  "SkipUrl" => don't save/restore the file
614      *  "SkipMode" => don't save/restore the mode
615      *  "SkipHighlighting" => don't save/restore the highlighting
616      *  "SkipEncoding" => don't save/restore the encoding
617      *
618      * \param config read the session settings from this KConfigGroup
619      * \param flags additional flags
620      * \see writeSessionConfig()
621      */
622     void readSessionConfig(const KConfigGroup &config, const QSet<QString> &flags = QSet<QString>()) override;
623 
624     /**
625      * Write session settings to the \p config.
626      * See readSessionConfig() for more details.
627      *
628      * \param config write the session settings to this KConfigGroup
629      * \param flags additional flags
630      * \see readSessionConfig()
631      */
632     void writeSessionConfig(KConfigGroup &config, const QSet<QString> &flags = QSet<QString>()) override;
633 
634 public Q_SLOTS:
635     void setEol(int eol);
636     void setAddBom(bool enabled);
637     void find();
638     void findSelectedForwards();
639     void findSelectedBackwards();
640     void replace();
641     void findNext();
642     void findPrevious();
643     void showSearchWrappedHint(bool isReverseSearch);
644 
645     void setFoldingMarkersOn(bool enable); // Not in KTextEditor::View, but should be
646     void setIconBorder(bool enable);
647     void setLineNumbersOn(bool enable);
648     void setScrollBarMarks(bool enable);
649     void setScrollBarMiniMap(bool enable);
650     void setScrollBarMiniMapAll(bool enable);
651     void setScrollBarMiniMapWidth(int width);
652     void toggleFoldingMarkers();
653     void toggleIconBorder();
654     void toggleLineNumbersOn();
655     void toggleScrollBarMarks();
656     void toggleScrollBarMiniMap();
657     void toggleScrollBarMiniMapAll();
658     void toggleDynWordWrap();
659     void setDynWrapIndicators(int mode);
660 
661 public:
662     int getEol() const;
663 
664 public:
665     KateRenderer *renderer();
666 
667     bool iconBorder();
668     bool lineNumbersOn();
669     bool scrollBarMarks();
670     bool scrollBarMiniMap();
671     bool scrollBarMiniMapAll();
672     int dynWrapIndicators();
673     bool foldingMarkersOn();
674 
675 private Q_SLOTS:
676     /**
677      * used to update actions after selection changed
678      */
679     void slotSelectionChanged();
680 
681     void toggleInputMode();
682     void cycleInputMode();
683 
684 public:
685     /**
686      * accessor to katedocument pointer
687      * @return pointer to document
688      */
doc()689     KTextEditor::DocumentPrivate *doc()
690     {
691         return m_doc;
692     }
doc()693     const KTextEditor::DocumentPrivate *doc() const
694     {
695         return m_doc;
696     }
697 
698 public Q_SLOTS:
699     void slotUpdateUndo();
700     void toggleInsert();
701     void reloadFile();
702     void toggleWWMarker();
703     void toggleNPSpaces();
704     void toggleWordCount(bool on);
705     void toggleWriteLock();
706     void switchToCmdLine();
707     void slotReadWriteChanged();
708     void slotClipboardHistoryChanged();
709 
710 Q_SIGNALS:
711     void dropEventPass(QDropEvent *);
712 
713 public:
714     /**
715      * Folding handler for this view.
716      * @return folding handler
717      */
textFolding()718     Kate::TextFolding &textFolding()
719     {
720         return m_textFolding;
721     }
722 
723 public:
724     void slotTextInserted(KTextEditor::View *view, const KTextEditor::Cursor position, const QString &text);
725 
726     void exportHtmlToFile(const QString &file);
727 
728 private Q_SLOTS:
729     void slotDocumentReloaded();
730     void slotDocumentAboutToReload();
731     void slotGotFocus();
732     void slotLostFocus();
733     void slotSaveCanceled(const QString &error);
734     void slotConfigDialog();
735     void exportHtmlToClipboard();
736     void exportHtmlToFile();
737 
738 public Q_SLOTS:
739     void slotFoldToplevelNodes();
740     void slotExpandToplevelNodes();
741     void slotToggleFolding();
742     void slotToggleFoldingsInRange();
743 
744 private:
745     void setupLayout();
746     void setupConnections();
747     void setupActions();
748     void setupEditActions();
749     void setupCodeFolding();
750 
751     std::vector<QAction *> m_editActions;
752     QAction *m_editUndo;
753     QAction *m_editRedo;
754     QAction *m_pasteMenu;
755     bool m_gotoBottomAfterReload;
756     KToggleAction *m_toggleFoldingMarkers;
757     KToggleAction *m_toggleIconBar;
758     KToggleAction *m_toggleLineNumbers;
759     KToggleAction *m_toggleScrollBarMarks;
760     KToggleAction *m_toggleScrollBarMiniMap;
761     KToggleAction *m_toggleScrollBarMiniMapAll;
762     KToggleAction *m_toggleDynWrap;
763     KSelectAction *m_setDynWrapIndicators;
764     KToggleAction *m_toggleWWMarker;
765     KToggleAction *m_toggleNPSpaces;
766     KToggleAction *m_toggleWordCount;
767     QAction *m_switchCmdLine;
768     KToggleAction *m_viInputModeAction;
769 
770     KSelectAction *m_setEndOfLine;
771     KToggleAction *m_addBom;
772 
773     QAction *m_cut;
774     QAction *m_copy;
775     QAction *m_copyHtmlAction;
776     QAction *m_paste;
777     // always nullptr if paste selection isn't supported
778     QAction *m_pasteSelection = nullptr;
779     QAction *m_swapWithClipboard;
780     QAction *m_selectAll;
781     QAction *m_deSelect;
782 
783     QActionGroup *m_inputModeActions;
784 
785     KToggleAction *m_toggleBlockSelection;
786     KToggleAction *m_toggleInsert;
787     KToggleAction *m_toggleWriteLock;
788 
789     bool m_hasWrap;
790 
791     KTextEditor::DocumentPrivate *const m_doc;
792     Kate::TextFolding m_textFolding;
793     KateViewConfig *const m_config;
794     KateRenderer *const m_renderer;
795     KateViewInternal *const m_viewInternal;
796     KateSpellCheckDialog *m_spell;
797     KateBookmarks *const m_bookmarks;
798 
799     //* margins
800     QSpacerItem *m_topSpacer;
801     QSpacerItem *m_leftSpacer;
802     QSpacerItem *m_rightSpacer;
803     QSpacerItem *m_bottomSpacer;
804 
805 private Q_SLOTS:
806     void slotHlChanged();
807 
808     /**
809      * Configuration
810      */
811 public:
config()812     inline KateViewConfig *config()
813     {
814         return m_config;
815     }
816 
817     void updateConfig();
818 
819     void updateDocumentConfig();
820 
821     void updateRendererConfig();
822 
823 private Q_SLOTS:
824     void updateFoldingConfig();
825 
826 private:
827     bool m_startingUp;
828     bool m_updatingDocumentConfig;
829 
830     // stores the current selection
831     Kate::TextRange m_selection;
832 
833     // do we select normal or blockwise ?
834     bool blockSelect;
835 
836     // templates
837 public:
838     bool insertTemplateInternal(const KTextEditor::Cursor insertPosition, const QString &templateString, const QString &script = QString());
839 
840     /**
841      * Accessors to the bars...
842      */
843 public:
844     KateViewBar *bottomViewBar() const;
845     KateDictionaryBar *dictionaryBar();
846 
847 private:
848     KateGotoBar *gotoBar();
849 
850     /**
851      * viewbar + its widgets
852      * they are created on demand...
853      */
854 private:
855     // created in constructor of the view
856     KateViewBar *m_bottomViewBar;
857 
858     // created on demand..., only access them through the above accessors....
859     KateGotoBar *m_gotoBar;
860     KateDictionaryBar *m_dictionaryBar;
861 
862     // input modes
863 public:
864     KateAbstractInputMode *currentInputMode() const;
865 
866 public:
867     KTextEditor::Range visibleRange();
868 
869 Q_SIGNALS:
870     void displayRangeChanged(KTextEditor::ViewPrivate *view);
871 
872 protected:
873     bool event(QEvent *e) override;
874     void paintEvent(QPaintEvent *e) override;
875 
876     KToggleAction *m_toggleOnTheFlySpellCheck;
877     KateSpellingMenu *m_spellingMenu;
878 
879 protected Q_SLOTS:
880     void toggleOnTheFlySpellCheck(bool b);
881 
882 public Q_SLOTS:
883     void changeDictionary();
884     void reflectOnTheFlySpellCheckStatus(bool enabled);
885 
886 public:
887     KateSpellingMenu *spellingMenu();
888 
889 private:
890     bool m_userContextMenuSet;
891 
892 private Q_SLOTS:
893     /**
894      * save folding state before document reload
895      */
896     void saveFoldingState();
897 
898     /**
899      * restore folding state after document reload
900      */
901     void applyFoldingState();
902 
903     void clearHighlights();
904     void createHighlights();
905 
906 private:
907     void selectionChangedForHighlights();
908 
909     /**
910      * saved folding state
911      */
912     QJsonDocument m_savedFoldingState;
913 
914     QString m_currentTextForHighlights;
915 
916     std::vector<std::unique_ptr<KTextEditor::MovingRange>> m_rangesForHighlights;
917 
918 public:
919     /**
920      * Attribute of a range changed or range with attribute changed in given line range.
921      * @param lineRange line range that the change spans
922      * @param needsRepaint do we need to trigger repaints? e.g. if ranges with attributes change
923      */
924     void notifyAboutRangeChange(KTextEditor::LineRange lineRange, bool needsRepaint);
925 
926 private Q_SLOTS:
927     /**
928      * Delayed update for view after text ranges changed
929      */
930     void slotDelayedUpdateOfView();
931 
932 Q_SIGNALS:
933     /**
934      * Delayed update for view after text ranges changed
935      */
936     void delayedUpdateOfView();
937 
938     /**
939      * Emitted whenever the caret enter or leave a range.
940      * ATM only used by KateStatusBar to update the dict button
941      */
942     void caretChangedRange(KTextEditor::View *);
943 
944 public:
945     /**
946      * set of ranges which had the mouse inside last time, used for rendering
947      * @return set of ranges which had the mouse inside last time checked
948      */
rangesMouseIn()949     const QSet<Kate::TextRange *> *rangesMouseIn() const
950     {
951         return &m_rangesMouseIn;
952     }
953 
954     /**
955      * set of ranges which had the caret inside last time, used for rendering
956      * @return set of ranges which had the caret inside last time checked
957      */
rangesCaretIn()958     const QSet<Kate::TextRange *> *rangesCaretIn() const
959     {
960         return &m_rangesCaretIn;
961     }
962 
963     /**
964      * check if ranges changed for mouse in and caret in
965      * @param activationType type of activation to check
966      */
967     void updateRangesIn(KTextEditor::Attribute::ActivationType activationType);
968 
969     //
970     // helpers for delayed view update after ranges changes
971     //
972 private:
973     /**
974      * delayed update timer
975      */
976     QTimer m_delayedUpdateTimer;
977 
978     /**
979      * line range to update
980      */
981     KTextEditor::LineRange m_lineToUpdateRange;
982 
983     /**
984      * set of ranges which had the mouse inside last time
985      */
986     QSet<Kate::TextRange *> m_rangesMouseIn;
987 
988     /**
989      * set of ranges which had the caret inside last time
990      */
991     QSet<Kate::TextRange *> m_rangesCaretIn;
992 
993     //
994     // forward impl for KTextEditor::MessageInterface
995     //
996 public:
997     /**
998      * Used by Document::postMessage().
999      */
1000     void postMessage(KTextEditor::Message *message, QList<QSharedPointer<QAction>> actions);
1001 
1002 private:
1003     /**
1004      * Message widgets showing KTextEditor::Messages.
1005      * The index of the array maps to the enum KTextEditor::Message::MessagePosition.
1006      */
1007     std::array<KateMessageWidget *, 5> m_messageWidgets{{nullptr}};
1008     /** Layout for floating notifications */
1009     KateMessageLayout *m_notificationLayout = nullptr;
1010 
1011     // for unit test 'tests/messagetest.cpp'
1012 public:
1013     KateMessageWidget *messageWidget();
1014 
1015 private:
1016     /**
1017      * The main window responsible for this view, if any
1018      */
1019     QPointer<KTextEditor::MainWindow> m_mainWindow;
1020 
1021     //
1022     // KTextEditor::PrintInterface
1023     //
1024 public Q_SLOTS:
1025     bool print() override;
1026     void printPreview() override;
1027 
1028 public:
1029     /**
1030      * Get the view status bar
1031      * @return status bar, in enabled
1032      */
statusBar()1033     KateStatusBar *statusBar() const
1034     {
1035         return m_statusBar;
1036     }
1037 
1038     /**
1039      * Toogle status bar, e.g. create or remove it
1040      */
1041     void toggleStatusBar();
1042 
1043     /**
1044      * Get the encoding menu
1045      * @return the encoding menu
1046      */
encodingAction()1047     KateViewEncodingAction *encodingAction() const
1048     {
1049         return m_encodingAction;
1050     }
1051 
1052     /**
1053      * Get the mode menu
1054      * @return the mode menu
1055      */
modeAction()1056     KateModeMenu *modeAction() const
1057     {
1058         return m_modeAction;
1059     }
1060 
1061 private:
1062     /**
1063      * the status bar of this view
1064      */
1065     KateStatusBar *m_statusBar;
1066 
1067     /**
1068      * the encoding selection menu, used by view + status bar
1069      */
1070     KateViewEncodingAction *m_encodingAction;
1071 
1072     /**
1073      * the mode selection menu, used by view
1074      */
1075     KateModeMenu *m_modeAction;
1076 
1077     /**
1078      * is automatic invocation of completion disabled temporarily?
1079      */
1080     bool m_temporaryAutomaticInvocationDisabled;
1081 
1082 public:
1083     /**
1084      * Returns the attribute for the default style \p defaultStyle.
1085      */
1086     Attribute::Ptr defaultStyleAttribute(DefaultStyle defaultStyle) const override;
1087 
1088     /**
1089      * Get the list of AttributeBlocks for a given \p line in the document.
1090      *
1091      * \return list of AttributeBlocks for given \p line.
1092      */
1093     QList<KTextEditor::AttributeBlock> lineAttributes(int line) override;
1094 
1095 private:
1096     // remember folding state to prevent refolding the first line if it was manually unfolded,
1097     // e.g. when saving a file or changing other config vars
1098     bool m_autoFoldedFirstLine;
1099 
1100 public:
1101     void setScrollPositionInternal(KTextEditor::Cursor cursor);
1102 
1103     void setHorizontalScrollPositionInternal(int x);
1104 
1105     KTextEditor::Cursor maxScrollPositionInternal() const;
1106 
1107     int firstDisplayedLineInternal(LineType lineType) const;
1108 
1109     int lastDisplayedLineInternal(LineType lineType) const;
1110 
1111     QRect textAreaRectInternal() const;
1112 
1113 private:
1114     /**
1115      * script action menu, stored in scoped pointer to ensure
1116      * destruction before other QObject auto-cleanup as it
1117      * manage sub objects on its own that have this view as parent
1118      */
1119     QScopedPointer<KateScriptActionMenu> m_scriptActionMenu;
1120 
1121     // for showSearchWrappedHint()
1122     QPointer<KTextEditor::Message> m_wrappedMessage;
1123     bool m_isLastSearchReversed = false;
1124 };
1125 
1126 }
1127 
1128 #endif
1129