1/* This file is part of the KDE project
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 as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21#ifndef KTEXTEDITOR_MARKINTERFACE_H
22#define KTEXTEDITOR_MARKINTERFACE_H
23
24#include <ktexteditor_export.h>
25
26#include <QHash>
27#include <QObject>
28
29class QPixmap;
30class QPoint;
31class QMenu;
32
33namespace KTextEditor
34{
35
36class Document;
37
38/**
39 * \brief Mark class containing line and mark types.
40 *
41 * \section mark_intro Introduction
42 *
43 * The class Mark represents a mark in a Document. It contains the \e line
44 * and \e type. A line can have multiple marks, like a \e bookmark and a
45 * \e breakpoint, i.e. the \e type contains all marks combined with a logical
46 * \e OR (<tt>|</tt>). There are several predefined mark types, look into the
47 * MarkInterface for further details.
48 *
49 * \see KTextEditor::MarkInterface, KTextEditor::Document
50 */
51class Mark
52{
53public:
54 /** The line that contains the mark. */
55 int line;
56
57 /** The mark types in the line, combined with logical OR. */
58 uint type;
59};
60
61/**
62 * \brief Mark extension interface for the Document.
63 *
64 * \ingroup kte_group_doc_extensions
65 *
66 * \section markext_intro Introduction
67 *
68 * The MarkInterface provides methods to enable and disable marks in a
69 * Document, a marked line can be visualized for example with a shaded
70 * background color and/or a pixmap in the iconborder of the Document's View.
71 * There are a number of predefined mark types, specified in
72 * reservedMarkersCount(). Additionally it is possible to add custom marks
73 * and set custom pixmaps.
74 *
75 * \section markext_access Accessing the Interface
76 *
77 * The MarkInterface is supposed to be an extension interface for a Document,
78 * i.e. the Document inherits the interface \e provided that the
79 * KTextEditor library in use implements the interface. Use qobject_cast to access
80 * the interface:
81 * \code
82 * // doc is of type KTextEditor::Document*
83 * auto iface = qobject_cast<KTextEditor::MarkInterface*>(doc);
84 *
85 * if (iface) {
86 * // the implementation supports the interface
87 * // do stuff
88 * } else {
89 * // the implementation does not support the interface
90 * }
91 * \endcode
92 *
93 * \section markext_handling Handling Marks
94 *
95 * Get all marks in the document by calling marks(). Use clearMarks() to
96 * remove all marks in the entire document. A single mark can be retrieved
97 * with mark(). To remove all marks from a line call clearMark(). To add
98 * and remove marks from a given line use addMark() and removeMark(). It is
99 * also possible to replace all marks with setMark(), i.e. setMark() is the
100 * same as a call of clearMark() followed by addMark(). The signals
101 * marksChanged() and markChanged() are emitted whenever a line's marks
102 * changed.
103 *
104 * \attention A mark type is represented as an \e uint. An \e uint can have
105 * several mark types combined (see above: logical OR). That means for
106 * all functions/signals with an \e uint parameter, e.g. setMark(),
107 * removeMark(), etc, the \e uint may contain \e multiple marks, i.e.
108 * you can add and remove multiple marks \e simultaneously.
109 *
110 * \section markext_userdefined User Defined Marks
111 *
112 * All marks that should be editable by the user can be specified with a mark
113 * mask via setEditableMarks(). To set a description and pixmap of a mark type
114 * call setMarkDescription() and setMarkPixmap().
115 *
116 * \see KTextEditor::Document, KTextEditor::Mark
117 * \author Christoph Cullmann \<cullmann@kde.org\>
118 */
119class KTEXTEDITOR_EXPORT MarkInterface
120{
121public:
122 MarkInterface();
123
124 /**
125 * Virtual destructor.
126 */
127 virtual ~MarkInterface();
128
129 //
130 // slots !!!
131 //
132public:
133 /**
134 * Get all marks set on the \p line.
135 * \param line requested line
136 * \return a \e uint representing of the marks set in \p line concatenated
137 * by logical OR
138 * \see addMark(), removeMark()
139 */
140 virtual uint mark(int line) = 0;
141
142 /**
143 * Set the \p line's mark types to \p markType.
144 * If \p line already contains a mark of the given type it has no effect.
145 * All other marks are deleted before the mark is set. You can achieve
146 * the same by calling
147 * \code
148 * clearMark(line);
149 * addMark(line, markType);
150 * \endcode
151 * \param line line to set the mark
152 * \param markType mark type
153 * \see clearMark(), addMark(), mark()
154 */
155 virtual void setMark(int line, uint markType) = 0;
156
157 /**
158 * Clear all marks set in the \p line.
159 * \param line line to clear marks
160 * \see clearMarks(), removeMark(), addMark()
161 */
162 virtual void clearMark(int line) = 0;
163
164 /**
165 * Add marks of type \p markType to \p line. Existing marks on this line
166 * are preserved. If the mark \p markType already is set, nothing
167 * happens.
168 * \param line line to set the mark
169 * \param markType mark type
170 * \see removeMark(), setMark()
171 */
172 virtual void addMark(int line, uint markType) = 0;
173
174 /**
175 * Remove the mark mask of type \p markType from \p line.
176 * \param line line to remove the mark
177 * \param markType mark type to be removed
178 * \see clearMark()
179 */
180 virtual void removeMark(int line, uint markType) = 0;
181
182 /**
183 * Get a hash holding all marks in the document.
184 * The hash key for a mark is its line.
185 * \return a hash holding all marks in the document
186 */
187 virtual const QHash<int, KTextEditor::Mark *> &marks() = 0;
188
189 /**
190 * Clear all marks in the entire document.
191 * \see clearMark(), removeMark()
192 */
193 /// TODO: dominik: add argument unit mask = 0
194 virtual void clearMarks() = 0;
195
196 /**
197 * Get the number of predefined mark types we have so far.
198 * \note FIXME: If you change this you have to make sure katepart
199 * supports the new size!
200 * \return number of reserved marker types
201 */
202 static int reservedMarkersCount() {
203 return 7;
204 }
205
206 /**
207 * Predefined mark types.
208 *
209 * To add a new standard mark type, edit this interface and document
210 * the type.
211 */
212 enum MarkTypes {
213 /** Bookmark */
214 markType01 = 0x1,
215 /** Breakpoint active */
216 markType02 = 0x2,
217 /** Breakpoint reached */
218 markType03 = 0x4,
219 /** Breakpoint disabled */
220 markType04 = 0x8,
221 /** Execution mark */
222 markType05 = 0x10,
223 /** Warning */
224 markType06 = 0x20,
225 /** Error */
226 markType07 = 0x40,
227
228 markType08 = 0x80,
229 markType09 = 0x100,
230 markType10 = 0x200,
231 markType11 = 0x400,
232 markType12 = 0x800,
233 markType13 = 0x1000,
234 markType14 = 0x2000,
235 markType15 = 0x4000,
236 markType16 = 0x8000,
237 markType17 = 0x10000,
238 markType18 = 0x20000,
239 markType19 = 0x40000,
240 markType20 = 0x80000,
241 markType21 = 0x100000,
242 markType22 = 0x200000,
243 markType23 = 0x400000,
244 markType24 = 0x800000,
245 markType25 = 0x1000000,
246 markType26 = 0x2000000,
247 markType27 = 0x4000000,
248 markType28 = 0x8000000,
249 markType29 = 0x10000000,
250 markType30 = 0x20000000,
251 markType31 = 0x40000000,
252 markType32 = 0x80000000,
253 /* reserved marks */
254 Bookmark = markType01,
255 BreakpointActive = markType02,
256 BreakpointReached = markType03,
257 BreakpointDisabled = markType04,
258 Execution = markType05,
259 Warning = markType06,
260 Error = markType07,
261 SearchMatch = markType32,
262 };
263
264 //
265 // signals !!!
266 //
267public:
268 /**
269 * The \p document emits this signal whenever a mark mask changed.
270 * \param document document which emitted this signal
271 * \see markChanged()
272 */
273 virtual void marksChanged(KTextEditor::Document *document) = 0;
274
275 /*
276 * Methods to modify mark properties.
277 */
278public:
279 /**
280 * Set the \p mark's pixmap to \p pixmap.
281 * \param mark mark to which the pixmap will be attached
282 * \param pixmap new pixmap
283 * \see setMarkDescription()
284 */
285 virtual void setMarkPixmap(MarkTypes mark, const QPixmap &pixmap) = 0;
286
287 /**
288 * Get the \p mark's pixmap.
289 * \param mark mark type. If the pixmap does not exist the resulting is null
290 * (check with QPixmap::isNull()).
291 * \see setMarkDescription()
292 */
293 virtual QPixmap markPixmap(MarkTypes mark) const = 0;
294
295 /**
296 * Set the \p mark's description to \p text.
297 * \param mark mark to set the description
298 * \param text new descriptive text
299 * \see markDescription(), setMarkPixmap()
300 */
301 virtual void setMarkDescription(MarkTypes mark, const QString &text) = 0;
302
303 /**
304 * Get the \p mark's description to text.
305 * \param mark mark to set the description
306 * \return text of the given \p mark or QString(), if the entry does not
307 * exist
308 * \see setMarkDescription(), setMarkPixmap()
309 */
310 virtual QString markDescription(MarkTypes mark) const = 0;
311
312 /**
313 * Set the mark mask the user is allowed to toggle to \p markMask.
314 * I.e. concatenate all editable marks with a logical OR. If the user should
315 * be able to add a bookmark and set a breakpoint with the context menu in
316 * the icon pane, you have to call
317 * \code
318 * // iface is of Type KTextEditor::MarkInterface*
319 * // only make bookmark and breakpoint editable
320 * iface->setEditableMarks( MarkInterface::Bookmark |
321 * MarkInterface::BreakpointActive );
322 *
323 * // or preserve last settings, and add bookmark and breakpoint
324 * iface->setEditableMarks( iface->editableMarks() |
325 * MarkInterface::Bookmark |
326 * MarkInterface::BreakpointActive );
327 * \endcode
328 * \param markMask bitmap pattern
329 * \see editableMarks(), setMarkPixmap(), setMarkDescription()
330 */
331 virtual void setEditableMarks(uint markMask) = 0;
332
333 /**
334 * Get, which marks can be toggled by the user.
335 * The returned value is a mark mask containing all editable marks combined
336 * with a logical OR.
337 * \return mark mask containing all editable marks
338 * \see setEditableMarks()
339 */
340 virtual uint editableMarks() const = 0;
341
342 /**
343 * Possible actions on a mark.
344 * \see markChanged()
345 */
346 enum MarkChangeAction {
347 MarkAdded = 0, /**< action: a mark was added. */
348 MarkRemoved = 1 /**< action: a mark was removed. */
349 };
350
351 //
352 // signals !!!
353 //
354public:
355 /**
356 * The \p document emits this signal whenever the \p mark changes.
357 * \param document the document which emitted the signal
358 * \param mark changed mark
359 * \param action action, either removed or added
360 * \see marksChanged()
361 */
362 virtual void markChanged(KTextEditor::Document *document, KTextEditor::Mark mark,
363 KTextEditor::MarkInterface::MarkChangeAction action) = 0;
364
365Q_SIGNALS:
366
367 /**
368 * The \p document emits this signal whenever the \p mark is hovered using the mouse,
369 * and the receiver may show a tooltip.
370 * \param document the document which emitted the signal
371 * \param mark mark that was hovered
372 * \param position mouse position during the hovering
373 * \param handled set this to 'true' if this event was handled externally
374 */
375 void markToolTipRequested(KTextEditor::Document *document, KTextEditor::Mark mark,
376 QPoint position, bool &handled);
377
378 /**
379 * The \p document emits this signal whenever the \p mark is right-clicked to show a context menu.
380 * The receiver may show an own context menu instead of the kate internal one.
381 * \param document the document which emitted the signal
382 * \param mark mark that was right-clicked
383 * \param pos position where the menu should be started
384 * \param handled set this to 'true' if this event was handled externally, and kate should not create an own context menu.
385 */
386 void markContextMenuRequested(KTextEditor::Document *document, KTextEditor::Mark mark,
387 QPoint pos, bool &handled);
388
389 /**
390 * The \p document emits this signal whenever the \p mark is left-clicked.
391 * \param document the document which emitted the signal
392 * \param mark mark that was right-clicked
393 * \param handled set this to 'true' if this event was handled externally, and kate should not do own handling of the left click.
394 */
395 void markClicked(KTextEditor::Document *document, KTextEditor::Mark mark, bool &handled);
396
397private:
398 class MarkInterfacePrivate *const d = nullptr;
399};
400
401}
402
403Q_DECLARE_INTERFACE(KTextEditor::MarkInterface, "org.kde.KTextEditor.MarkInterface")
404
405#endif
406
407