Code

Fixed const/non-const mismatch loop.
[inkscape.git] / src / message-stack.cpp
1 /*
2  * MessageStack - manages stack of active status messages
3  *
4  * Authors:
5  *   MenTaLguY <mental@rydia.net>
6  *
7  * Copyright (C) 2004 MenTaLguY
8  *
9  * Released under GNU GPL, read the file 'COPYING' for more information
10  */
12 #include <string.h>
13 #include <glib/gstrfuncs.h>
14 #include <cstring>
15 #include <string>
16 #include "message-stack.h"
18 namespace Inkscape {
20 MessageStack::MessageStack()
21 : _messages(NULL), _next_id(1)
22 {
23 }
25 MessageStack::~MessageStack()
26 {
27     while (_messages) {
28         _messages = _discard(_messages);
29     }
30 }
32 MessageId MessageStack::push(MessageType type, gchar const *message) {
33     return _push(type, 0, message);
34 }
36 MessageId MessageStack::pushF(MessageType type, gchar const *format, ...)
37 {
38     va_list args;
39     va_start(args, format);
40     MessageId id=pushVF(type, format, args);
41     va_end(args);
42     return id;
43 }
45 MessageId MessageStack::pushVF(MessageType type, gchar const *format, va_list args)
46 {
47     MessageId id;
48     gchar *message=g_strdup_vprintf(format, args);
49     id = push(type, message);
50     g_free(message);
51     return id;
52 }
54 void MessageStack::cancel(MessageId id) {
55     Message **ref;
56     for ( ref = &_messages ; *ref ; ref = &(*ref)->next ) {
57         if ( (*ref)->id == id ) {
58             *ref = _discard(*ref);
59             _emitChanged();
60             break;
61         }
62     }
63 }
65 MessageId MessageStack::flash(MessageType type, gchar const *message) {
66     switch (type) {
67     case INFORMATION_MESSAGE: // stay rather long so as to seem permanent, but eventually disappear
68         return _push(type, 6000 + 80*strlen(message), message);
69         break;
70     case ERROR_MESSAGE: // pretty important stuff, but temporary
71         return _push(type, 4000 + 60*strlen(message), message);
72         break;
73     case WARNING_MESSAGE: // a bit less important than error
74         return _push(type, 2000 + 40*strlen(message), message);
75         break;
76     case IMMEDIATE_MESSAGE: // same length as normal, higher priority
77         return _push(type, 1000 + 20*strlen(message), message);
78         break;
79     case NORMAL_MESSAGE: // something ephemeral
80     default:
81         return _push(type, 1000 + 20*strlen(message), message);
82         break;
83     }
84 }
86 MessageId MessageStack::flashF(MessageType type, gchar const *format, ...) {
87     va_list args;
88     va_start(args, format);
89     MessageId id = flashVF(type, format, args);
90     va_end(args);
91     return id;
92 }
94 MessageId MessageStack::flashVF(MessageType type, gchar const *format, va_list args)
95 {
96     gchar *message=g_strdup_vprintf(format, args);
97     MessageId id = flash(type, message);
98     g_free(message);
99     return id;
102 MessageId MessageStack::_push(MessageType type, guint lifetime, gchar const *message)
104     Message *m=new Message;
105     MessageId id=_next_id++;
107     m->stack = this;
108     m->id = id;
109     m->type = type;
110     m->message = g_strdup(message);
112     if (lifetime) {
113         m->timeout_id = g_timeout_add(lifetime, &MessageStack::_timeout, m);
114     } else {
115         m->timeout_id = 0;
116     }
118     m->next = _messages;
119     _messages = m;
121     _emitChanged();
123     return id;
126 MessageStack::Message *MessageStack::_discard(MessageStack::Message *m)
128     Message *next=m->next;
129     if (m->timeout_id) {
130         g_source_remove(m->timeout_id);
131         m->timeout_id = 0;
132     }
133     g_free(m->message);
134     m->message = NULL;
135     m->stack = NULL;
136     delete m;
137     return next;
140 void MessageStack::_emitChanged() {
141     if (_messages) {
142         _changed_signal.emit(_messages->type, _messages->message);
143     } else {
144         _changed_signal.emit(NORMAL_MESSAGE, NULL);
145     }
148 gboolean MessageStack::_timeout(gpointer data) {
149     Message *m=reinterpret_cast<Message *>(data);
150     m->timeout_id = 0;
151     m->stack->cancel(m->id);
152     return FALSE;
157 /*
158   Local Variables:
159   mode:c++
160   c-file-style:"stroustrup"
161   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
162   indent-tabs-mode:nil
163   fill-column:99
164   End:
165 */
166 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :