KTextEditor

kateviewinternal.h
1/*
2 SPDX-FileCopyrightText: 2002-2007 Hamish Rodda <rodda@kde.org>
3 SPDX-FileCopyrightText: 2002 John Firebaugh <jfirebaugh@kde.org>
4 SPDX-FileCopyrightText: 2002 Joseph Wenninger <jowenn@kde.org>
5 SPDX-FileCopyrightText: 2002 Christoph Cullmann <cullmann@kde.org>
6 SPDX-FileCopyrightText: 2007 Mirko Stocker <me@misto.ch>
7
8 Based on KWriteView:
9 SPDX-FileCopyrightText: 1999 Jochen Wilhelmy <digisnap@cs.tu-berlin.de>
10
11 SPDX-License-Identifier: LGPL-2.0-or-later
12*/
13#ifndef _KATE_VIEW_INTERNAL_
14#define _KATE_VIEW_INTERNAL_
15
16#include <KSyntaxHighlighting/FoldingRegion>
17
18#include <ktexteditor/attribute.h>
19#include <ktexteditor/range.h>
20#include <ktexteditor/view.h>
21
22#include "inlinenotedata.h"
23#include "katetextcursor.h"
24#include "katetextline.h"
25
26#include <QDrag>
27#include <QElapsedTimer>
28#include <QPoint>
29#include <QPointer>
30#include <QSet>
31#include <QTime>
32#include <QTimer>
33#include <QWidget>
34
35#include <array>
36#include <memory>
37
38namespace KTextEditor
39{
40class MovingRange;
42class DocumentPrivate;
43class ViewPrivate;
44}
45
46class KateIconBorder;
47class KateScrollBar;
48class KateAnnotationItemDelegate;
49class KateAnnotationGroupPositionState;
50class KateTextLayout;
52class KateAbstractInputMode;
53class ZoomEventFilter;
54class KateRenderer;
55class KateTextPreview;
56class KateViewTest;
57
58class QScrollBar;
59class QScroller;
60class QScrollEvent;
62
63class KateViewInternal final : public QWidget
64{
66
67 friend class KTextEditor::ViewPrivate;
68 friend class KateIconBorder;
69 friend class KateScrollBar;
70 friend class KateAnnotationGroupPositionState;
71 friend class CalculatingCursor;
72 friend class BoundedCursor;
73 friend class WrappingCursor;
74 friend class CamelCursor;
75 friend class KateAbstractInputMode;
76 friend class ::KateTextPreview;
77 friend class KateViewTest;
78
79public:
80 enum Bias {
81 left = -1,
82 none = 0,
83 right = 1
84 };
85
86public:
87 explicit KateViewInternal(KTextEditor::ViewPrivate *view);
88 ~KateViewInternal() override;
89 KTextEditor::ViewPrivate *view() const
90 {
91 return m_view;
92 }
93
94 // BEGIN EDIT STUFF
95public:
96 void editStart();
97 void editEnd(int editTagLineStart, int editTagLineEnd, bool tagFrom);
98
99 void editSetCursor(const KTextEditor::Cursor cursor);
100
101private:
102 uint editSessionNumber;
103 bool editIsRunning;
104 KTextEditor::Cursor editOldCursor;
105 KTextEditor::Range editOldSelection;
106 // END
107
108 // BEGIN TAG & CLEAR & UPDATE STUFF
109public:
110 bool tagLine(const KTextEditor::Cursor virtualCursor);
111
112 bool tagLines(int start, int end, bool realLines = false);
113 // cursors not const references as they are manipulated within
114 bool tagLines(KTextEditor::Cursor start, KTextEditor::Cursor end, bool realCursors = false);
115
116 bool tagRange(KTextEditor::Range range, bool realCursors);
117
118 void tagAll();
119
120 void updateDirty();
121
122 void clear();
123 // END
124
125private Q_SLOTS:
126 // Updates the view and requests a redraw.
127 void updateView(bool changed = false, int viewLinesScrolled = 0);
128
129private:
130 void makeVisible(const KTextEditor::Cursor c, int endCol, bool force = false, bool center = false, bool calledExternally = false);
131
132public:
133 // Start Position is a virtual cursor
134 KTextEditor::Cursor startPos() const
135 {
136 return m_startPos;
137 }
138 int startLine() const
139 {
140 return m_startPos.line();
141 }
142 int startX() const
143 {
144 return m_startX;
145 }
146
147 KTextEditor::Cursor endPos() const;
148 int endLine() const;
149
150 KateTextLayout yToKateTextLayout(int y) const;
151
152 void dynWrapChanged();
153
154public Q_SLOTS:
155 void slotIncFontSizes(qreal step = 1.0);
156 void slotDecFontSizes(qreal step = 1.0);
157 void slotResetFontSizes();
158
159 void paintCursor();
160
161private Q_SLOTS:
162 void scrollLines(int line); // connected to the sliderMoved of the m_lineScroll
163 void scrollViewLines(int offset);
164 void scrollAction(int action);
165 void scrollNextPage();
166 void scrollPrevPage();
167 void scrollPrevLine();
168 void scrollNextLine();
169 void scrollColumns(int x); // connected to the valueChanged of the m_columnScroll
170 void viewSelectionChanged();
171
172public:
173 void cursorPrevChar(bool sel = false);
174 void cursorNextChar(bool sel = false);
175 void wordPrev(bool sel = false, bool subword = false);
176 void wordNext(bool sel = false, bool subword = false);
177 void home(bool sel = false);
178 void end(bool sel = false);
179 void cursorUp(bool sel = false);
180 void cursorDown(bool sel = false);
181 void cursorToMatchingBracket(bool sel = false);
182 void scrollUp();
183 void scrollDown();
184 void topOfView(bool sel = false);
185 void bottomOfView(bool sel = false);
186 void pageUp(bool sel = false, bool half = false);
187 void pageDown(bool sel = false, bool half = false);
188 void top(bool sel = false);
189 void bottom(bool sel = false);
190 void top_home(bool sel = false);
191 void bottom_end(bool sel = false);
192
193private:
194 // Takes as input @p c and applies the home command on it
195 KTextEditor::Cursor moveCursorToLineStart(KTextEditor::Cursor c);
196 // Takes as input @p c and applies the end command on it
197 KTextEditor::Cursor moveCursorToLineEnd(KTextEditor::Cursor c);
198
199public:
200 /**
201 * Accessor to the current caret position
202 * @return position of the caret as @c KTextEditor::Cursor
203 * @see KTextEditor::Cursor
204 */
205 KTextEditor::Cursor cursorPosition() const
206 {
207 return m_cursor;
208 }
209
210 /**
211 * Accessor to the current mouse position
212 * @return position of the mouse as @c KTextEditor::Cursor
213 * @see KTextEditor::Cursor
214 */
215 KTextEditor::Cursor mousePosition() const
216 {
217 return m_mouse;
218 }
219
220 QPoint cursorToCoordinate(const KTextEditor::Cursor cursor, bool realCursor = true, bool includeBorder = true) const;
221 // by default, works on coordinates of the whole widget, eg. offsetted by the border
222 KTextEditor::Cursor coordinatesToCursor(const QPoint &coord, bool includeBorder = true) const;
223 QPoint cursorCoordinates(bool includeBorder = true) const;
224 KTextEditor::Cursor findMatchingBracket();
225
226 // exported for unit tests
227 KTEXTEDITOR_EXPORT KTextEditor::Range
228 findMatchingFoldingMarker(const KTextEditor::Cursor current_cursor_pos, const KSyntaxHighlighting::FoldingRegion foldingRegion, const int maxLines);
229 KTEXTEDITOR_EXPORT void updateFoldingMarkersHighlighting();
230
231 inline int getStartOffset(int direction, int offset, int length) const
232 {
233 return direction == 1 ? offset - length : offset;
234 }
235
236 inline int getEndOffset(int direction, int offset, int length) const
237 {
238 return direction == 1 ? offset : offset + length;
239 }
240
241 KateIconBorder *iconBorder() const
242 {
243 return m_leftBorder;
244 }
245
246 // EVENT HANDLING STUFF - IMPORTANT
247private:
248 void fixDropEvent(QDropEvent *event);
249
250 static bool isAcceptableInput(const QKeyEvent *e);
251
252protected:
253 void hideEvent(QHideEvent *e) override;
254 void paintEvent(QPaintEvent *e) override;
255 bool eventFilter(QObject *obj, QEvent *e) override;
256 void keyPressEvent(QKeyEvent *) override;
257 void keyReleaseEvent(QKeyEvent *) override;
258 void resizeEvent(QResizeEvent *) override;
259 void moveEvent(QMoveEvent *) override;
260 void mousePressEvent(QMouseEvent *) override;
261 void mouseDoubleClickEvent(QMouseEvent *) override;
262 void mouseReleaseEvent(QMouseEvent *) override;
263 void mouseMoveEvent(QMouseEvent *) override;
264 void leaveEvent(QEvent *) override;
265 void dragEnterEvent(QDragEnterEvent *) override;
266 void dragMoveEvent(QDragMoveEvent *) override;
267 void dropEvent(QDropEvent *) override;
268 void showEvent(QShowEvent *) override;
269 void wheelEvent(QWheelEvent *e) override;
270 void scrollPrepareEvent(QScrollPrepareEvent *);
271 void scrollEvent(QScrollEvent *);
272 void focusInEvent(QFocusEvent *) override;
273 void focusOutEvent(QFocusEvent *) override;
274 void inputMethodEvent(QInputMethodEvent *e) override;
275
276 void contextMenuEvent(QContextMenuEvent *e) override;
277
278private Q_SLOTS:
279 void tripleClickTimeout();
280
282 // emitted when KateViewInternal is not handling its own URI drops
283 void dropEventPass(QDropEvent *);
284
285private Q_SLOTS:
286 void slotRegionVisibilityChanged();
287 void slotRegionBeginEndAddedRemoved(unsigned int);
288
289private:
290 void moveChar(Bias bias, bool sel);
291 void moveEdge(Bias bias, bool sel);
292 KTextEditor::Cursor maxStartPos(bool changed = false);
293 void scrollPos(KTextEditor::Cursor &c, bool force = false, bool calledExternally = false, bool emitSignals = true);
294 void scrollLines(int lines, bool sel);
295
296 KTextEditor::Attribute::Ptr attributeAt(const KTextEditor::Cursor position) const;
297 int linesDisplayed() const;
298
299 int lineToY(int viewLine) const;
300
301 void updateSecondarySelection(int cursorIdx, KTextEditor::Cursor old, KTextEditor::Cursor newPos) const;
302 void updateSelection(const KTextEditor::Cursor, bool keepSel);
303 void setSelection(KTextEditor::Range);
304 void moveCursorToSelectionEdge(bool scroll = true);
305 void updateCursor(const KTextEditor::Cursor newCursor, bool force = false, bool center = false, bool calledExternally = false, bool scroll = true);
306 void updateBracketMarks();
307 void beginSelectLine(const QPoint &pos);
308
309 struct CursorPair {
310 KTextEditor::Cursor oldPos;
311 KTextEditor::Cursor newPos;
312 };
313 // @brief updates the secondary cursor, schedules repaint
314 // MUST setPosition of the corresponding moving cursors before calling this
315 void updateSecondaryCursors(const QVarLengthArray<CursorPair, 16> &cursors, bool sel);
316 void mergeSelections();
317
318 KTextEditor::Cursor cursorForPoint(QPoint p);
319 void placeCursor(const QPoint &p, bool keepSelection = false, bool updateSelection = true);
320 bool isTargetSelected(const QPoint &p);
321 // Returns whether the given range affects the area currently visible in the view
322 bool rangeAffectsView(KTextEditor::Range range, bool realCursors) const;
323
324 void doDrag();
325
326 KateRenderer *renderer() const;
327
328 bool sendMouseEventToInputContext(QMouseEvent *e);
329 void commitPreedit();
330
331 KTextEditor::ViewPrivate *m_view;
332 class KateIconBorder *m_leftBorder;
333
334 int m_mouseX;
335 int m_mouseY;
336 int m_scrollX;
337 int m_scrollY;
338
339 std::unique_ptr<ZoomEventFilter> m_zoomEventFilter;
340
341 Qt::CursorShape m_mouseCursor;
342
343 Kate::TextCursor m_cursor;
344 KTextEditor::Cursor m_mouse;
345 KTextEditor::Cursor m_displayCursor;
346
347 bool m_possibleTripleClick;
348
349 // Bracket mark and corresponding decorative ranges
350 std::unique_ptr<KTextEditor::MovingRange> m_bm, m_bmStart, m_bmEnd;
351 std::unique_ptr<KTextEditor::MovingCursor> m_bmLastFlashPos;
352 std::unique_ptr<KateTextPreview> m_bmPreview;
353 void updateBracketMarkAttributes();
354
355 // Folding mark
356 std::unique_ptr<KTextEditor::MovingRange> m_fmStart, m_fmEnd;
357
358 enum DragState {
359 diNone,
360 diPending,
361 diDragging
362 };
363
364 struct _dragInfo {
365 DragState state;
366 QPoint start;
367 QDrag *dragObject;
368 } m_dragInfo;
369
370 //
371 // line scrollbar + first visible (virtual) line in the current view
372 //
373 KateScrollBar *m_lineScroll;
374 qreal m_accumulatedScroll = 0.0;
375 QWidget *m_dummy;
376
377 // These are now cursors to account for word-wrap.
378 // Start Position is a virtual cursor
379 Kate::TextCursor m_startPos;
380 // Count of lines that are visible behind m_startPos.
381 // This does not respect dynamic word wrap, so take it as an approximation.
382 uint m_visibleLineCount;
383
384 // This is set to false on resize or scroll (other than that called by makeVisible),
385 // so that makeVisible is again called when a key is pressed and the cursor is in the same spot
386 bool m_madeVisible;
387 bool m_shiftKeyPressed;
388
389 // How many lines to should be kept visible above/below the cursor when possible
390 void setAutoCenterLines(int viewLines, bool updateView = true);
391 int m_autoCenterLines;
392 int m_minLinesVisible;
393
394 //
395 // column scrollbar + x position
396 //
397 QScrollBar *m_columnScroll;
398 QScroller *m_scroller;
399 int m_startX;
400
401 // has selection changed while your mouse or shift key is pressed
402 bool m_selChangedByUser;
403 KTextEditor::Cursor m_selectAnchor;
404
405 enum SelectionMode {
406 Default = 0,
407 Mouse,
408 Word,
409 Line
410 }; ///< for drag selection.
411 uint m_selectionMode;
412 // when drag selecting after double/triple click, keep the initial selected
413 // word/line independent of direction.
414 // They get set in the event of a double click, and is used with mouse move + leftbutton
415 KTextEditor::Range m_selectionCached;
416
417 // maximal length of textlines visible from given startLine
418 int maxLen(int startLine);
419
420 // are we allowed to scroll columns?
421 bool columnScrollingPossible();
422
423 // the same for lines
424 bool lineScrollingPossible();
425
426 // returns the maximum X value / col value a cursor can take for a specific line range
427 int lineMaxCursorX(const KateTextLayout &line);
428 static int lineMaxCol(const KateTextLayout &line);
429
430 class KateLayoutCache *cache() const;
431 KateLayoutCache *m_layoutCache;
432
433 // convenience methods
434
435 /// returns layout for the line c.line()
436 KateTextLayout currentLayout(KTextEditor::Cursor c) const;
437 // returns layout for the line previous to @p c
438 KateTextLayout previousLayout(KTextEditor::Cursor c) const;
439 // returns layout for the line next to @p c
440 KateTextLayout nextLayout(KTextEditor::Cursor c) const;
441
442 // find the cursor offset by (offset) view lines from a cursor.
443 // when keepX is true, the column position will be calculated based on the x
444 // position of the specified cursor.
445 KTextEditor::Cursor viewLineOffset(const KTextEditor::Cursor virtualCursor, int offset, bool keepX = false);
446
447 KTextEditor::Cursor toRealCursor(const KTextEditor::Cursor virtualCursor) const;
448 KTextEditor::Cursor toVirtualCursor(const KTextEditor::Cursor realCursor) const;
449
450 // These variable holds the most recent maximum real & visible column number
451 bool m_preserveX;
452 int m_preservedX;
453
454 KTextEditor::Cursor m_cachedMaxStartPos;
455
456 //
457 // implementation details for KTextEditor::FlashTextInterface
458 //
459public:
460 void flashChar(const KTextEditor::Cursor pos, KTextEditor::Attribute::Ptr attribute);
461 void showBracketMatchPreview();
462 void hideBracketMatchPreview();
463
464private:
465 QPointer<KateTextAnimation> m_textAnimation;
466
467private Q_SLOTS:
468 void doDragScroll();
469 void startDragScroll();
470 void stopDragScroll();
471
472private:
473 // Timers
474 QTimer m_dragScrollTimer;
475 QTimer m_scrollTimer;
476 QTimer m_cursorTimer;
477 QTimer m_textHintTimer;
478
479 static const int s_scrollTime = 30;
480 static const int s_scrollMargin = 16;
481
482private Q_SLOTS:
483 void scrollTimeout();
484 void cursorTimeout();
485 void textHintTimeout();
486
487 void documentTextInserted(KTextEditor::Document *document, KTextEditor::Range range);
488 void documentTextRemoved(KTextEditor::Document *document, KTextEditor::Range range, const QString &oldText);
489
490 //
491 // KTE::TextHintInterface
492 //
493public:
494 void registerTextHintProvider(KTextEditor::TextHintProvider *provider);
495 void unregisterTextHintProvider(KTextEditor::TextHintProvider *provider);
496 void setTextHintDelay(int delay);
497 int textHintDelay() const;
498 bool textHintsEnabled(); // not part of the interface
499
500private:
501 std::vector<KTextEditor::TextHintProvider *> m_textHintProviders;
502 int m_textHintDelay;
503 QPoint m_textHintPos;
504
505 //
506 // IM input stuff
507 //
508public:
509 QVariant inputMethodQuery(Qt::InputMethodQuery query) const override;
510
511private:
512 std::unique_ptr<KTextEditor::MovingRange> m_imPreeditRange;
513 std::vector<std::unique_ptr<KTextEditor::MovingRange>> m_imPreeditRangeChildren;
514
515private:
516 void mouseMoved();
517 void cursorMoved();
518
519private:
520 KTextEditor::DocumentPrivate *doc();
521 KTextEditor::DocumentPrivate *doc() const;
522
523 // input modes
524private:
525 std::array<std::unique_ptr<KateAbstractInputMode>, KTextEditor::View::ViInputMode + 1> m_inputModes;
526 KateAbstractInputMode *m_currentInputMode;
527
528 KateInlineNoteData m_activeInlineNote;
529 KateInlineNoteData inlineNoteAt(const QPoint &globalPos) const;
530 QRect inlineNoteRect(const KateInlineNoteData &note) const;
531};
532
533#endif
QExplicitlySharedDataPointer< Attribute > Ptr
Shared data pointer for Attribute.
Definition attribute.h:56
Backend of KTextEditor::Document related public KTextEditor interfaces.
A range that is bound to a specific Document, and maintains its position.
Class to provide text hints for a View.
@ ViInputMode
Vi mode.
Definition view.h:288
Handles all of the work of rendering the text (used for the views and printing)
This class is required because QScrollBar's sliderMoved() signal is really supposed to be a sliderDra...
This class is used to flash text in the text view.
This class represents one visible line of text; with dynamic wrapping, many KateTextLayouts can be ne...
Q_SCRIPTABLE Q_NOREPLY void start()
The KTextEditor namespace contains all the public API that is required to use the KTextEditor compone...
QObject(QObject *parent)
Q_OBJECTQ_OBJECT
Q_SIGNALSQ_SIGNALS
Q_SLOTSQ_SLOTS
virtual bool event(QEvent *e)
CursorShape
InputMethodQuery
QWidget(QWidget *parent, Qt::WindowFlags f)
void scroll(int dx, int dy)
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Feb 21 2025 11:52:52 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.