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

source code of ktexteditor/src/view/kateview.h