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

KDE's Doxygen guidelines are available online.