1/* This file is part of the KDE libraries
2 Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
3 Copyright (C) 2005 Dominik Haumann (dhdev@gmx.de) (documentation)
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License version 2 as published by the Free Software Foundation.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18*/
19
20#ifndef KDELIBS_KTEXTEDITOR_VIEW_H
21#define KDELIBS_KTEXTEDITOR_VIEW_H
22
23#include <ktexteditor/ktexteditor_export.h>
24#include <ktexteditor/range.h>
25
26// gui merging
27#include <kxmlguiclient.h>
28
29// widget
30#include <QtGui/QWidget>
31
32class QMenu;
33
34namespace KTextEditor
35{
36
37class Document;
38
39/**
40 * \brief A text widget with KXMLGUIClient that represents a Document.
41 *
42 * Topics:
43 * - \ref view_intro
44 * - \ref view_hook_into_gui
45 * - \ref view_selection
46 * - \ref view_cursors
47 * - \ref view_mouse_tracking
48 * - \ref view_modes
49 * - \ref view_extensions
50 *
51 * \section view_intro Introduction
52 *
53 * The View class represents a single view of a KTextEditor::Document,
54 * get the document on which the view operates with document().
55 * A view provides both the graphical representation of the text and the
56 * KXMLGUIClient for the actions. The view itself does not provide
57 * text manipulation, use the methods from the Document instead. The only
58 * method to insert text is insertText(), which inserts the given text
59 * at the current cursor position and emits the signal textInserted().
60 *
61 * Usually a view is created by using Document::createView().
62 * Furthermore a view can have a context menu. Set it with setContextMenu()
63 * and get it with contextMenu().
64 *
65 * \section view_hook_into_gui Merging the View's GUI
66 *
67 * A View is derived from the class KXMLGUIClient, so its GUI elements (like
68 * menu entries and toolbar items) can be merged into the application's GUI
69 * (or into a KXMLGUIFactory) by calling
70 * \code
71 * // view is of type KTextEditor::View*
72 * mainWindow()->guiFactory()->addClient( view );
73 * \endcode
74 * You can add only one view as client, so if you have several views, you first
75 * have to remove the current view, and then add the new one, like this
76 * \code
77 * mainWindow()->guiFactory()->removeClient( currentView );
78 * mainWindow()->guiFactory()->addClient( newView );
79 * \endcode
80 *
81 * \section view_selection Text Selection
82 *
83 * As the view is a graphical text editor it provides \e normal and \e block
84 * text selection. You can check with selection() whether a selection exists.
85 * removeSelection() will remove the selection without removing the text,
86 * whereas removeSelectionText() also removes both, the selection and the
87 * selected text. Use selectionText() to get the selected text and
88 * setSelection() to specify the selected textrange. The signal
89 * selectionChanged() is emitted whenever the selecteion changed.
90 *
91 * \section view_cursors Cursor Positions
92 *
93 * A view has one Cursor which represents a line/column tuple. Two different
94 * kinds of cursor positions are supported: first is the \e real cursor
95 * position where a \e tab character only counts one character. Second is the
96 * \e virtual cursor position, where a \e tab character counts as many
97 * spaces as defined. Get the real position with cursorPosition() and the
98 * virtual position with cursorPositionVirtual(). Set the real cursor
99 * position with setCursorPosition(). You can even get the screen coordinates
100 * of the current cursor position in pixel by using
101 * cursorPositionCoordinates(). The signal cursorPositionChanged() is emitted
102 * whenever the cursor position changed.
103 *
104 * \section view_mouse_tracking Mouse Tracking
105 *
106 * It is possible to get notified via the signal mousePositionChanged() for
107 * mouse move events, if mouseTrackingEnabled() returns \e true. Mouse tracking
108 * can be turned on/off by calling setMouseTrackingEnabled(). If an editor
109 * implementation does not support mouse tracking, mouseTrackingEnabled() will
110 * always return \e false.
111 *
112 * \section view_modes Edit Modes
113 *
114 * A view supports several edit modes (EditMode). Common edit modes are
115 * \e insert-mode (INS) and \e overwrite-mode (OVR). Which edit modes the
116 * editor supports depends on the implementation, another well-known mode is
117 * the \e command-mode for example in vim and yzis. The getter viewMode()
118 * returns a string like \p INS or \p OVR and is represented in the user
119 * interface for example in the status bar. Further you can get the edit
120 * mode as enum by using viewEditMode(). Whenever the edit mode changed the
121 * signals viewModeChanged() and viewEditModeChanged() are emitted.
122 *
123 * \section view_extensions View Extension Interfaces
124 *
125 * A simple view represents the text of a Document and provides a text cursor,
126 * text selection, edit modes etc.
127 * Advanced concepts like code completion and text hints are defined in the
128 * extension interfaces. An KTextEditor implementation does not need to
129 * support all the extensions. To implement the interfaces multiple
130 * inheritance is used.
131 *
132 * More information about interfaces for the view can be found in
133 * \ref kte_group_view_extensions.
134 *
135 * \see KTextEditor::Document, KTextEditor::TemplateInterface,
136 * KTextEditor::CodeCompletionInterface,
137 * KTextEditor::SessionConfigInterface, KTextEditor::TemplateInterface,
138 * KXMLGUIClient
139 * \author Christoph Cullmann \<cullmann@kde.org\>
140 */
141// KDE5: consider deriving from QFrame instead of QWidget, since e.g. the Oxygen style
142// http://lxr.kde.org/source/kde/kde-workspace/kstyles/oxygen/oxygenstyle.cpp#614
143// checks for a QFrame and then KStyle::pixelMetric returns a better margin (Frame_FrameWidth)
144// This is needed because the Oxygen "focus border" paints over the line numbers otherwise.
145class KTEXTEDITOR_EXPORT View : public QWidget, public KXMLGUIClient
146{
147 Q_OBJECT
148
149 public:
150 /**
151 * Constructor.
152 *
153 * Create a view attached to the widget \p parent.
154 * \param parent parent widget
155 * \see Document::createView()
156 */
157 View ( QWidget *parent );
158
159 /**
160 * Virtual destructor.
161 */
162 virtual ~View ();
163
164 /*
165 * Accessor for the document
166 */
167 public:
168 /**
169 * Get the view's \e document, that means the view is a view of the
170 * returned document.
171 * \return the view's document
172 */
173 virtual Document *document () const = 0;
174
175 /**
176 * Check whether this view is the document's active view.
177 * This is equal to the code:
178 * \code
179 * document()->activeView() == view
180 * \endcode
181 */
182 bool isActiveView() const;
183
184 /*
185 * General information about this view
186 */
187 public:
188 /**
189 * Get the current view mode/state.
190 * This can be used to visually indicate the view's current mode, for
191 * example \e INSERT mode, \e OVERWRITE mode or \e COMMAND mode - or
192 * whatever other edit modes are supported. The string should be
193 * translated (i18n), as this is a user aimed representation of the view
194 * state, which should be shown in the GUI, for example in the status bar.
195 * This string may be rich-text.
196 * \return
197 * \see viewModeChanged()
198 */
199 virtual QString viewMode () const = 0;
200
201 /**
202 * Possible edit modes.
203 * These correspond to various modes the text editor might be in.
204 */
205 enum EditMode {
206 EditInsert = 0, /**< Insert mode. Characters will be added. */
207 EditOverwrite = 1, /**< Overwrite mode. Characters will be replaced. */
208 EditViMode = 2 /**< Vi mode. The view will behave like the editor vi(m) @since 4.11 */
209 };
210
211 /**
212 * Get the view's current edit mode.
213 * The current mode can be \e insert mode, \e replace mode or any other
214 * the editor supports, e.g. a vim like \e command mode. If in doubt
215 * return EditInsert.
216 *
217 * \return the current edit mode of this view
218 * \see viewEditModeChanged()
219 */
220 virtual enum EditMode viewEditMode() const = 0;
221
222 /*
223 * SIGNALS
224 * following signals should be emitted by the editor view
225 */
226 Q_SIGNALS:
227 /**
228 * This signal is emitted whenever the \p view gets the focus.
229 * \param view view which gets focus
230 * \see focusOut()
231 */
232 void focusIn ( KTextEditor::View *view );
233
234 /**
235 * This signal is emitted whenever the \p view loses the focus.
236 * \param view view which lost focus
237 * \see focusIn()
238 */
239 void focusOut ( KTextEditor::View *view );
240
241 /**
242 * This signal is emitted whenever the view mode of \p view changes.
243 * \param view the view which changed its mode
244 * \see viewMode()
245 */
246 void viewModeChanged ( KTextEditor::View *view );
247
248 /**
249 * This signal is emitted whenever the \p view's edit \p mode changed from
250 * either EditInsert to EditOverwrite or vice versa.
251 * \param view view which changed its edit mode
252 * \param mode new edit mode
253 * \see viewEditMode()
254 */
255 void viewEditModeChanged ( KTextEditor::View *view,
256 enum KTextEditor::View::EditMode mode );
257
258 /**
259 * This signal is emitted whenever the \p view wants to display a
260 * information \p message. The \p message can be displayed in the status bar
261 * for example.
262 * \param view view which sends out information
263 * \param message information message
264 */
265 void informationMessage ( KTextEditor::View *view, const QString &message );
266
267 /**
268 * This signal is emitted from \p view whenever the users inserts \p text
269 * at \p position, that means the user typed/pasted text.
270 * \param view view in which the text was inserted
271 * \param position position where the text was inserted
272 * \param text the text the user has typed into the editor
273 * \see insertText()
274 */
275 void textInserted ( KTextEditor::View *view,
276 const KTextEditor::Cursor &position,
277 const QString &text );
278
279 /*
280 * Context menu handling
281 */
282 public:
283 /**
284 * Set a context menu for this view to \p menu.
285 *
286 * \note any previously assigned menu is not deleted. If you are finished
287 * with the previous menu, you may delete it.
288 *
289 * \warning Use this with care! Plugin xml gui clients are not merged
290 * into this menu!
291 * \warning !!!!!! DON'T USE THIS FUNCTION, UNLESS YOU ARE SURE YOU DON'T WANT PLUGINS TO WORK !!!!!!
292 *
293 * \param menu new context menu object for this view
294 * \see contextMenu()
295 */
296 virtual void setContextMenu ( QMenu *menu ) = 0;
297
298 /**
299 * Get the context menu for this view. The return value can be NULL
300 * if no context menu object was set and kxmlgui is not initialized yet.
301 * If there is no user set menu, the kxmlgui menu is returned. Do not delete this menu, if
302 * if it is the xmlgui menu.
303 * \return context menu object
304 * \see setContextMenu()
305 */
306 virtual QMenu *contextMenu () const = 0;
307
308 /**
309 * Populate \a menu with default text editor actions. If \a menu is
310 * null, a menu will be created with the view as its parent.
311 *
312 * \note to use this menu, you will next need to call setContextMenu(),
313 * as this does not assign the new context menu.
314 *
315 * \warning This contains only basic options from the editor component
316 * (katepart). Plugins are \p not merged/integrated into it!
317 * If you want to be a better citizen and take full advantage
318 * of KTextEditor plugins do something like:
319 * \code
320 * KXMLGUIClient* client = view;
321 * // search parent XmlGuiClient
322 * while (client->parentClient()) {
323 * client = client->parentClient();
324 * }
325 *
326 * if (client->factory()) {
327 * QList<QWidget*> conts = client->factory()->containers("menu");
328 * foreach (QWidget *w, conts) {
329 * if (w->objectName() == "ktexteditor_popup") {
330 * // do something with the menu (ie adding an onshow handler)
331 * break;
332 * }
333 * }
334 * }
335 * \endcode
336 * \warning or simply use the aboutToShow, aboutToHide signals !!!!!
337 *
338 * \param menu the menu to be populated, or null to create a new menu.
339 * \return the menu, whether created or passed initially
340 */
341 virtual QMenu* defaultContextMenu(QMenu* menu = 0L) const = 0;
342
343 Q_SIGNALS:
344 /**
345 * Signal which is emitted immediately prior to showing the current
346 * context \a menu.
347 */
348 void contextMenuAboutToShow(KTextEditor::View* view, QMenu* menu);
349
350 /*
351 * Cursor handling
352 */
353 public:
354 /**
355 * Set the view's new cursor to \p position. A \e TAB character
356 * is handeled as only on character.
357 * \param position new cursor position
358 * \return \e true on success, otherwise \e false
359 * \see cursorPosition()
360 */
361 virtual bool setCursorPosition (Cursor position) = 0;
362
363 /**
364 * Get the view's current cursor position. A \e TAB character is
365 * handeled as only one character.
366 * \return current cursor position
367 * \see setCursorPosition()
368 */
369 virtual Cursor cursorPosition () const = 0;
370
371 /**
372 * Get the current \e virtual cursor position, \e virtual means the
373 * tabulator character (TAB) counts \e multiple characters, as configured
374 * by the user (e.g. one TAB is 8 spaces). The virtual cursor
375 * position provides access to the user visible values of the current
376 * cursor position.
377 *
378 * \return virtual cursor position
379 * \see cursorPosition()
380 */
381 virtual Cursor cursorPositionVirtual () const = 0;
382
383 /**
384 * Get the screen coordinates (x, y) of the supplied \a cursor relative
385 * to the view widget in pixels. Thus, 0,0 represents the top left hand of
386 * the view widget.
387 *
388 * \param cursor cursor to determine coordinate for.
389 * \return cursor screen coordinates relative to the view widget
390 */
391 virtual QPoint cursorToCoordinate(const KTextEditor::Cursor& cursor) const = 0;
392
393 /**
394 * Get the screen coordinates (x/y) of the cursor position in pixels.
395 * \return cursor screen coordinates
396 */
397 virtual QPoint cursorPositionCoordinates () const = 0;
398
399 /*
400 * SIGNALS
401 * following signals should be emitted by the editor view
402 * if the cursor position changes
403 */
404 Q_SIGNALS:
405 /**
406 * This signal is emitted whenever the \p view's cursor position changed.
407 * \param view view which emitted the signal
408 * \param newPosition new position of the cursor (Kate will pass the real
409 * cursor potition, not the virtual)
410 * \see cursorPosition(), cursorPositionVirtual()
411 */
412 void cursorPositionChanged (KTextEditor::View *view,
413 const KTextEditor::Cursor& newPosition);
414
415 /**
416 * This signal should be emitted whenever the \p view is scrolled vertically.
417 * \param view view which emitted the signal
418 * \param newPos the new scroll position
419 */
420 void verticalScrollPositionChanged (KTextEditor::View *view, const KTextEditor::Cursor& newPos);
421
422 /**
423 * This signal should be emitted whenever the \p view is scrolled horizontally.
424 * \param view view which emitted the signal
425 */
426 void horizontalScrollPositionChanged (KTextEditor::View *view);
427 /*
428 * Mouse position
429 */
430 public:
431 /**
432 * Check, whether mouse tracking is enabled.
433 *
434 * Mouse tracking is required to have the signal mousePositionChanged()
435 * emitted.
436 * \return \e true, if mouse tracking is enabled, otherwise \e false
437 * \see setMouseTrackingEnabled(), mousePositionChanged()
438 */
439 virtual bool mouseTrackingEnabled() const = 0;
440
441 /**
442 * Try to enable or disable mouse tracking according to \p enable.
443 * The return value contains the state of mouse tracking \e after the
444 * request. Mouse tracking is required to have the mousePositionChanged()
445 * signal emitted.
446 *
447 * \note Implementation Notes: An implementation is not forced to support
448 * this, and should always return \e false if it does not have
449 * support.
450 *
451 * \param enable if \e true, try to enable mouse tracking, otherwise disable
452 * it.
453 * \return the current state of mouse tracking
454 * \see mouseTrackingEnabled(), mousePositionChanged()
455 */
456 virtual bool setMouseTrackingEnabled(bool enable) = 0;
457
458 Q_SIGNALS:
459 /**
460 * This signal is emitted whenever the position of the mouse changes over
461 * this \a view. If the mouse moves off the view, an invalid cursor position
462 * should be emitted, i.e. Cursor::invalid().
463 * \note If mouseTrackingEnabled() returns \e false, this signal is never
464 * emitted.
465 * \param view view which emitted the signal
466 * \param newPosition new position of the mouse or Cursor::invalid(), if the
467 * mouse moved out of the \p view.
468 * \see mouseTrackingEnabled()
469 */
470 void mousePositionChanged (KTextEditor::View *view,
471 const KTextEditor::Cursor& newPosition);
472
473 /*
474 * Selection methodes.
475 * This deals with text selection and copy&paste
476 */
477 public:
478 /**
479 * Set the view's selection to the range \p selection.
480 * The old selection will be discarded.
481 * \param range the range of the new selection
482 * \return \e true on success, otherwise \e false (e.g. when the cursor
483 * range is invalid)
484 * \see selectionRange(), selection()
485 */
486 virtual bool setSelection ( const Range &range ) = 0;
487
488 /**
489 * This is an overloaded member function, provided for convenience, it
490 * differs from the above function only in what argument(s) it accepts.
491 * An existing old selection will be discarded. If possible you should
492 * reimplement the default implementation with a more efficient one.
493 * \param position start or end position of the selection, depending
494 * on the \p length parameter
495 * \param length if >0 \p position defines the start of the selection,
496 * if <0 \p position specifies the end
497 * \param wrap if \e false the selection does not wrap lines and reaches
498 * only to start/end of the cursors line. Default: \e true
499 * \see selectionRange(), selection()
500 *
501 * \todo rodda - is this really needed? it can now be accomplished with
502 * SmartCursor::advance()
503 */
504 virtual bool setSelection ( const Cursor &position,
505 int length,
506 bool wrap = true );
507
508 /**
509 * Query the view whether it has selected text, i.e. whether a selection
510 * exists.
511 * \return \e true if a text selection exists, otherwise \e false
512 * \see setSelection(), selectionRange()
513 */
514 virtual bool selection() const = 0;
515
516 /**
517 * Get the range occupied by the current selection.
518 * \return selection range, valid only if a selection currently exists.
519 * \see setSelection()
520 */
521 virtual const Range &selectionRange() const = 0;
522
523 /**
524 * Get the view's selected text.
525 * \return the selected text
526 * \see setSelection()
527 */
528 virtual QString selectionText () const = 0;
529
530 /**
531 * Remove the view's current selection, \e without deleting the selected
532 * text.
533 * \return \e true on success, otherwise \e false
534 * \see removeSelectionText()
535 */
536 virtual bool removeSelection () = 0;
537
538 /**
539 * Remove the view's current selection \e including the selected text.
540 * \return \e true on success, otherwise \e false
541 * \see removeSelection()
542 */
543 virtual bool removeSelectionText () = 0;
544
545 /*
546 * Blockselection stuff
547 */
548 public:
549 /**
550 * Set block selection mode to state \p on.
551 * \param on if \e true, block selection mode is turned on, otherwise off
552 * \return \e true on success, otherwise \e false
553 * \see blockSelection()
554 */
555 virtual bool setBlockSelection (bool on) = 0;
556
557 /**
558 * Get the status of the selection mode. \e true indicates that block
559 * selection mode is on. If this is \e true, selections applied via the
560 * SelectionInterface are handled as block selections and the Copy&Paste
561 * functions work on rectangular blocks of text rather than normal.
562 * \return \e true, if block selection mode is enabled, otherwise \e false
563 * \see setBlockSelection()
564 */
565 virtual bool blockSelection () const = 0;
566
567 /*
568 * SIGNALS
569 * following signals should be emitted by the editor view for selection
570 * handling.
571 */
572 Q_SIGNALS:
573 /**
574 * This signal is emitted whenever the \p view's selection changes.
575 * \note If the mode switches from block selection to normal selection
576 * or vice versa this signal should also be emitted.
577 * \param view view in which the selection changed
578 * \see selection(), selectionRange(), selectionText()
579 */
580 void selectionChanged (KTextEditor::View *view);
581
582 public:
583 /**
584 * This is a convenience function which inserts \p text at the view's
585 * current cursor position. You do not necessarily need to reimplement
586 * it, except you want to do some special things.
587 * \param text Text to be inserted
588 * \return \e true on success of insertion, otherwise \e false
589 * \see textInserted()
590 */
591 virtual bool insertText (const QString &text);
592
593 private:
594 class ViewPrivate* const d;
595};
596
597/**
598 * \brief Pixel coordinate to Cursor extension interface for the View.
599 *
600 * \ingroup kte_group_view_extensions
601 *
602 * \section ctc_intro Introduction
603 *
604 * The CoordinatesToCursorInterface makes it possible to map a
605 * pixel coordinate to a cursor position. To map a cursor position
606 * to pixel coordinates use one of
607 * - KTextEditor::View::cursorToCoordinate()
608 * - KTextEditor::View::cursorPositionCoordinates()
609 *
610 * \section ctc_access Accessing the CoordinatesToCursorInterface
611 *
612 * The CoordinatesToCursorInterface is an extension interface for a
613 * View, i.e. the View inherits the interface \e provided that the
614 * used KTextEditor library implements the interface. Use qobject_cast to
615 * access the interface:
616 * \code
617 * // view is of type KTextEditor::View*
618 * KTextEditor::CoordinatesToCursorInterface *iface =
619 * qobject_cast<KTextEditor::CoordinatesToCursorInterface*>( view );
620 *
621 * if( iface ) {
622 * // the implementation supports the interface
623 * // do stuff
624 * }
625 * \endcode
626 *
627 * \see KTextEditor::View
628 * \since 4.2
629 * \note KDE5: merge into KTextEditor::View (or name it ViewportInterface
630 * and add accessors to the QScrollBars and convenience functions like
631 * cursorToCoordinate(), scollLines(int count), etc.
632 */
633class KTEXTEDITOR_EXPORT CoordinatesToCursorInterface
634{
635 public:
636 /** Virtual destructor. */
637 virtual ~CoordinatesToCursorInterface();
638
639 /**
640 * Get the text-cursor in the document from the screen coordinates,
641 * relative to the view widget.
642 *
643 * To map a cursor to pixel coordinates (the reverse transformation)
644 * use KTextEditor::View::cursorToCoordinate().
645 *
646 * \param coord coordinates relative to the view widget
647 * \return cursor in the View, that points onto the character under
648 * the given coordinate. May be KTextEditor::Cursor::invalid().
649 */
650 virtual KTextEditor::Cursor coordinatesToCursor(const QPoint& coord) const = 0;
651};
652
653}
654
655Q_DECLARE_INTERFACE(KTextEditor::CoordinatesToCursorInterface, "org.kde.KTextEditor.CoordinatesToCursorInterface")
656
657#endif
658
659// kate: space-indent on; indent-width 2; replace-tabs on;
660