1 /** \file
2 * Managing current status messages.
3 */
5 /*
6 * Authors:
7 * MenTaLguY <mental@rydia.net>
8 *
9 * Copyright (C) 2004 MenTaLguY
10 *
11 * Released under GNU GPL, read the file 'COPYING' for more information
12 */
14 #ifndef SEEN_INKSCAPE_MESSAGE_STACK_H
15 #define SEEN_INKSCAPE_MESSAGE_STACK_H
17 #include <sigc++/sigc++.h>
18 #include <glib/gtypes.h>
19 #include <stdarg.h>
20 #include "gc-managed.h"
21 #include "gc-finalized.h"
22 #include "gc-anchored.h"
23 #include "message.h"
25 namespace Inkscape {
27 /**
28 * A class which holds a stack of displayed messages.
29 *
30 * Messages can be pushed onto the top of the stack, and removed
31 * from any point in the stack by their id.
32 *
33 * Messages may also be "flashed", meaning that they will be
34 * automatically removed from the stack a fixed period of time
35 * after they are pushed.
36 *
37 * "Flashed" warnings and errors will persist longer than normal
38 * messages.
39 *
40 * There is no simple "pop" operation provided, since these
41 * stacks are intended to be shared by many different clients;
42 * assuming that the message you pushed is still on top is an
43 * invalid and unsafe assumption.
44 */
45 class MessageStack : public GC::Managed<>,
46 public GC::Finalized,
47 public GC::Anchored
48 {
49 public:
50 MessageStack();
51 ~MessageStack();
53 /** @brief returns the type of message currently at the top of the stack */
54 MessageType currentMessageType() {
55 return _messages ? _messages->type : NORMAL_MESSAGE;
56 }
57 /** @brief returns the text of the message currently at the top of
58 * the stack
59 */
60 gchar const *currentMessage() {
61 return _messages ? _messages->message : NULL;
62 }
64 /** @brief connects to the "changed" signal which is emitted whenever
65 * the topmost message on the stack changes.
66 */
67 sigc::connection connectChanged(sigc::slot<void, MessageType, gchar const *> slot)
68 {
69 return _changed_signal.connect(slot);
70 }
72 /** @brief pushes a message onto the stack
73 *
74 * @param type the message type
75 * @param message the message text
76 *
77 * @return the id of the pushed message
78 */
79 MessageId push(MessageType type, gchar const *message);
81 /** @brief pushes a message onto the stack using printf-like formatting
82 *
83 * @param type the message type
84 * @param format a printf-style format string
85 *
86 * @return the id of the pushed message
87 */
88 MessageId pushF(MessageType type, gchar const *format, ...);
90 /** @brief pushes a message onto the stack using printf-like formatting,
91 * using a stdarg argument list
92 *
93 * @param type the message type
94 * @param format a printf-style format string
95 * @param args the subsequent printf-style arguments
96 *
97 * @return the id of the pushed message
98 */
99 MessageId pushVF(MessageType type, gchar const *format, va_list args);
101 /** @brief removes a message from the stack, given its id
102 *
103 * This method will remove a message from the stack if it has not
104 * already been removed. It may be removed from any part of the stack.
105 *
106 * @param id the message id to remove
107 */
108 void cancel(MessageId id);
110 /** @brief temporarily pushes a message onto the stack
111 *
112 * @param type the message type
113 * @param message the message text
114 *
115 * @return the id of the pushed message
116 */
117 MessageId flash(MessageType type, gchar const *message);
119 /** @brief temporarily pushes a message onto the stack using
120 * printf-like formatting
121 *
122 * @param type the message type
123 * @param format a printf-style format string
124 *
125 * @return the id of the pushed message
126 */
127 MessageId flashF(MessageType type, gchar const *format, ...);
129 /** @brief temporarily pushes a message onto the stack using
130 * printf-like formatting, using a stdarg argument list
131 *
132 * @param type the message type
133 * @param format a printf-style format string
134 * @param args the printf-style arguments
135 *
136 * @return the id of the pushed message
137 */
138 MessageId flashVF(MessageType type, gchar const *format, va_list args);
140 private:
141 struct Message {
142 Message *next;
143 MessageStack *stack;
144 MessageId id;
145 MessageType type;
146 gchar *message;
147 guint timeout_id;
148 };
150 MessageStack(MessageStack const &); // no copy
151 void operator=(MessageStack const &); // no assign
153 /// pushes a message onto the stack with an optional timeout
154 MessageId _push(MessageType type, guint lifetime, gchar const *message);
156 Message *_discard(Message *m); ///< frees a message struct and returns the next such struct in the list
157 void _emitChanged(); ///< emits the "changed" signal
158 static gboolean _timeout(gpointer data); ///< callback to expire flashed messages
160 sigc::signal<void, MessageType, gchar const *> _changed_signal;
161 Message *_messages; ///< the stack of messages as a linked list
162 MessageId _next_id; ///< the next message id to assign
163 };
165 }
167 #endif
168 /*
169 Local Variables:
170 mode:c++
171 c-file-style:"stroustrup"
172 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
173 indent-tabs-mode:nil
174 fill-column:99
175 End:
176 */
177 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :