1/* This file is part of the KDE project
2 *
3 * Copyright (C) 2012-2013 Dominik Haumann <dhaumann@kde.org>
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_MESSAGE_H
22#define KTEXTEDITOR_MESSAGE_H
23
24#include <QObject>
25#include <QList>
26#include <QAction>
27#include <QIcon>
28
29#include <ktexteditor_export.h>
30
31namespace KTextEditor
32{
33
34class View;
35class Document;
36
37/**
38 * @brief This class holds a Message to display in View%s.
39 *
40 * @section message_intro Introduction
41 *
42 * The Message class holds the data used to display interactive message widgets
43 * in the editor. Use the Document::postMessage() to post a message as follows:
44 *
45 * @code
46 * // always use a QPointer go guard your Message, if you keep a pointer
47 * // after calling postMessage()
48 * QPointer<KTextEditor::Message> message =
49 * new KTextEditor::Message("text", KTextEditor::Message::Information);
50 * message->setWordWrap(true);
51 * message->addAction(...); // add your actions...
52 * document->postMessage(message);
53 * @endcode
54 *
55 * A Message is deleted automatically if the Message gets closed, meaning that
56 * you usually can forget the pointer. If you really need to delete a message
57 * before the user processed it, always guard it with a QPointer!
58 *
59 * @section message_creation Message Creation and Deletion
60 *
61 * To create a new Message, use code like this:
62 * @code
63 * QPointer<KTextEditor::Message> message =
64 * new KTextEditor::Message("My information text", KTextEditor::Message::Information);
65 * message->setWordWrap(true);
66 * // ...
67 * @endcode
68 *
69 * Although discouraged in general, the text of the Message can be changed
70 * on the fly when it is already visible with setText().
71 *
72 * Once you posted the Message through Document::postMessage(), the
73 * lifetime depends on the user interaction. The Message gets automatically
74 * deleted either if the user clicks a closing action in the message, or for
75 * instance if the document is reloaded.
76 *
77 * If you posted a message but want to remove it yourself again, just delete
78 * the message. But beware of the following warning!
79 *
80 * @warning Always use QPointer\<Message\> to guard the message pointer from
81 * getting invalid, if you need to access the Message after you posted
82 * it.
83 *
84 * @section message_positioning Positioning
85 *
86 * By default, the Message appears right above of the View. However, if desired,
87 * the position can be changed through setPosition(). For instance, the
88 * search-and-replace code in Kate Part shows the number of performed replacements
89 * in a message floating in the view. For further information, have a look at
90 * the enum MessagePosition.
91 *
92 * @section message_hiding Autohiding Messages
93 *
94 * Message%s can be shown for only a short amount of time by using the autohide
95 * feature. With setAutoHide() a timeout in milliseconds can be set after which
96 * the Message is automatically hidden. Further, use setAutoHideMode() to either
97 * trigger the autohide timer as soon as the widget is shown (AutoHideMode::Immediate),
98 * or only after user interaction with the view (AutoHideMode::AfterUserInteraction).
99 *
100 * The default autohide mode is set to AutoHideMode::AfterUserInteraction.
101 * This way, it is unlikely the user misses a notification.
102 *
103 * @author Dominik Haumann \<dhaumann@kde.org\>
104 * @since 4.11
105 */
106class KTEXTEDITOR_EXPORT Message : public QObject
107{
108 Q_OBJECT
109
110 //
111 // public data types
112 //
113public:
114 /**
115 * Message types used as visual indicator.
116 * The message types match exactly the behavior of KMessageWidget::MessageType.
117 * For simple notifications either use Positive or Information.
118 */
119 enum MessageType {
120 Positive = 0, ///< positive information message
121 Information, ///< information message type
122 Warning, ///< warning message type
123 Error ///< error message type
124 };
125
126 /**
127 * Message position used to place the message either above or below of the
128 * KTextEditor::View.
129 */
130 enum MessagePosition {
131 /// show message above view.
132 AboveView = 0,
133 /// show message below view.
134 BelowView,
135 /// show message as view overlay in the top right corner.
136 TopInView,
137 /// show message as view overlay in the bottom right corner.
138 BottomInView,
139 /// show message as view overlay in the center of the view.
140 /// @since 5.42
141 CenterInView
142 };
143
144 /**
145 * The AutoHideMode determines when to trigger the autoHide timer.
146 * @see setAutoHide(), autoHide()
147 */
148 enum AutoHideMode {
149 Immediate = 0, ///< auto-hide is triggered as soon as the message is shown
150 AfterUserInteraction ///< auto-hide is triggered only after the user interacted with the view
151 };
152
153public:
154 /**
155 * Constructor for new messages.
156 * @param type the message type, e.g. MessageType::Information
157 * @param richtext text to be displayed
158 */
159 Message(const QString &richtext, MessageType type = Message::Information);
160
161 /**
162 * Destructor.
163 */
164 virtual ~Message();
165
166 /**
167 * Returns the text set in the constructor.
168 */
169 QString text() const;
170
171 /**
172 * Returns the icon of this message.
173 * If the message has no icon set, a null icon is returned.
174 * @see setIcon()
175 */
176 QIcon icon() const;
177
178 /**
179 * Returns the message type set in the constructor.
180 */
181 MessageType messageType() const;
182
183 /**
184 * Adds an action to the message.
185 *
186 * By default (@p closeOnTrigger = true), the action closes the message
187 * displayed in all View%s. If @p closeOnTrigger is @e false, the message
188 * is stays open.
189 *
190 * The actions will be displayed in the order you added the actions.
191 *
192 * To connect to an action, use the following code:
193 * @code
194 * connect(action, &QAction::triggered, receiver, &ReceiverType::slotActionTriggered);
195 * @endcode
196 *
197 * @param action action to be added
198 * @param closeOnTrigger when triggered, the message widget is closed
199 *
200 * @warning The added actions are deleted automatically.
201 * So do @em not delete the added actions yourself.
202 */
203 void addAction(QAction *action, bool closeOnTrigger = true);
204
205 /**
206 * Accessor to all actions, mainly used in the internal implementation
207 * to add the actions into the gui.
208 * @see addAction()
209 */
210 QList<QAction *> actions() const;
211
212 /**
213 * Set the auto hide time to @p delay milliseconds.
214 * If @p delay < 0, auto hide is disabled.
215 * If @p delay = 0, auto hide is enabled and set to a sane default
216 * value of several seconds.
217 *
218 * By default, auto hide is disabled.
219 *
220 * @see autoHide(), setAutoHideMode()
221 */
222 void setAutoHide(int delay = 0);
223
224 /**
225 * Returns the auto hide time in milliseconds.
226 * Please refer to setAutoHide() for an explanation of the return value.
227 *
228 * @see setAutoHide(), autoHideMode()
229 */
230 int autoHide() const;
231
232 /**
233 * Sets the auto hide mode to @p mode.
234 * The default mode is set to AutoHideMode::AfterUserInteraction.
235 * @param mode auto hide mode
236 * @see autoHideMode(), setAutoHide()
237 */
238 void setAutoHideMode(KTextEditor::Message::AutoHideMode mode);
239
240 /**
241 * Get the Message's auto hide mode.
242 * The default mode is set to AutoHideMode::AfterUserInteraction.
243 * @see setAutoHideMode(), autoHide()
244 */
245 KTextEditor::Message::AutoHideMode autoHideMode() const;
246
247 /**
248 * Enabled word wrap according to @p wordWrap.
249 * By default, auto wrap is disabled.
250 *
251 * Word wrap is enabled automatically, if the Message's width is larger than
252 * the parent widget's width to avoid breaking the gui layout.
253 *
254 * @see wordWrap()
255 */
256 void setWordWrap(bool wordWrap);
257
258 /**
259 * Check, whether word wrap is enabled or not.
260 *
261 * @see setWordWrap()
262 */
263 bool wordWrap() const;
264
265 /**
266 * Set the priority of this message to @p priority.
267 * Messages with higher priority are shown first.
268 * The default priority is 0.
269 *
270 * @see priority()
271 */
272 void setPriority(int priority);
273
274 /**
275 * Returns the priority of the message.
276 *
277 * @see setPriority()
278 */
279 int priority() const;
280
281 /**
282 * Set the associated view of the message.
283 * If @p view is 0, the message is shown in all View%s of the Document.
284 * If @p view is given, i.e. non-zero, the message is shown only in this view.
285 * @param view the associated view the message should be displayed in
286 */
287 void setView(KTextEditor::View *view);
288
289 /**
290 * This function returns the view you set by setView(). If setView() was
291 * not called, the return value is 0.
292 */
293 KTextEditor::View *view() const;
294
295 /**
296 * Set the document pointer to @p document.
297 * This is called by the implementation, as soon as you post a message
298 * through Document::postMessage(), so that you do not have to
299 * call this yourself.
300 * @see document()
301 */
302 void setDocument(KTextEditor::Document *document);
303
304 /**
305 * Returns the document pointer this message was posted in.
306 * This pointer is 0 as long as the message was not posted.
307 */
308 KTextEditor::Document *document() const;
309
310 /**
311 * Sets the position of the message to @p position.
312 * By default, the position is set to MessagePosition::AboveView.
313 * @see MessagePosition
314 */
315 void setPosition(MessagePosition position);
316
317 /**
318 * Returns the message position of this message.
319 * @see setPosition(), MessagePosition
320 */
321 MessagePosition position() const;
322
323public Q_SLOTS:
324 /**
325 * Sets the notification contents to @p richtext.
326 * If the message was already sent through Document::postMessage(),
327 * the displayed text changes on the fly.
328 * @note Change text on the fly with care, since changing the text may
329 * resize the notification widget, which may result in a distracting
330 * user experience.
331 * @param richtext new notification text (rich text supported)
332 * @see textChanged()
333 */
334 void setText(const QString &richtext);
335
336 /**
337 * Add an optional @p icon for this notification which will be shown next to
338 * the message text. If the message was already sent through Document::postMessage(),
339 * the displayed icon changes on the fly.
340 * @note Change the icon on the fly with care, since changing the text may
341 * resize the notification widget, which may result in a distracting
342 * user experience.
343 * @param icon the icon to be displayed
344 * @see iconChanged()
345 */
346 void setIcon(const QIcon &icon);
347
348Q_SIGNALS:
349 /**
350 * This signal is emitted before the @p message is deleted. Afterwards, this
351 * pointer is invalid.
352 *
353 * Use the function document() to access the associated Document.
354 *
355 * @param message the closed/processed message
356 */
357 void closed(KTextEditor::Message *message);
358
359 /**
360 * This signal is emitted whenever setText() was called.
361 *
362 * @param text the new notification text (rich text supported)
363 * @see setText()
364 */
365 void textChanged(const QString &text);
366
367 /**
368 * This signal is emitted whenever setIcon() was called.
369 * @param icon the new notification icon
370 * @see setIcon()
371 */
372 void iconChanged(const QIcon &icon);
373
374private:
375 class MessagePrivate *const d;
376};
377
378}
379
380#endif
381
382