Code

first set of updates to headers for clean gcc 4.3 builds
[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 "message-stack.h"
16 namespace Inkscape {
18 MessageStack::MessageStack()
19 : _messages(NULL), _next_id(1)
20 {
21 }
23 MessageStack::~MessageStack()
24 {
25     while (_messages) {
26         _messages = _discard(_messages);
27     }
28 }
30 MessageId MessageStack::push(MessageType type, gchar const *message) {
31     return _push(type, 0, message);
32 }
34 MessageId MessageStack::pushF(MessageType type, gchar const *format, ...)
35 {
36     va_list args;
37     va_start(args, format);
38     MessageId id=pushVF(type, format, args);
39     va_end(args);
40     return id;
41 }
43 MessageId MessageStack::pushVF(MessageType type, gchar const *format, va_list args)
44 {
45     MessageId id;
46     gchar *message=g_strdup_vprintf(format, args);
47     id = push(type, message);
48     g_free(message);
49     return id;
50 }
52 void MessageStack::cancel(MessageId id) {
53     Message **ref;
54     for ( ref = &_messages ; *ref ; ref = &(*ref)->next ) {
55         if ( (*ref)->id == id ) {
56             *ref = _discard(*ref);
57             _emitChanged();
58             break;
59         }
60     }
61 }
63 MessageId MessageStack::flash(MessageType type, gchar const *message) {
64     switch (type) {
65     case INFORMATION_MESSAGE: // stay rather long so as to seem permanent, but eventually disappear
66         return _push(type, 6000 + 80*strlen(message), message);
67         break;
68     case ERROR_MESSAGE: // pretty important stuff, but temporary
69         return _push(type, 4000 + 60*strlen(message), message);
70         break;
71     case WARNING_MESSAGE: // a bit less important than error
72         return _push(type, 2000 + 40*strlen(message), message);
73         break;
74     case IMMEDIATE_MESSAGE: // same length as normal, higher priority
75         return _push(type, 1000 + 20*strlen(message), message);
76         break;
77     case NORMAL_MESSAGE: // something ephemeral
78     default:
79         return _push(type, 1000 + 20*strlen(message), message);
80         break;
81     }
82 }
84 MessageId MessageStack::flashF(MessageType type, gchar const *format, ...) {
85     va_list args;
86     va_start(args, format);
87     MessageId id = flashVF(type, format, args);
88     va_end(args);
89     return id;
90 }
92 MessageId MessageStack::flashVF(MessageType type, gchar const *format, va_list args)
93 {
94     gchar *message=g_strdup_vprintf(format, args);
95     MessageId id = flash(type, message);
96     g_free(message);
97     return id;
98 }
100 MessageId MessageStack::_push(MessageType type, guint lifetime, gchar const *message)
102     Message *m=new Message;
103     MessageId id=_next_id++;
105     m->stack = this;
106     m->id = id;
107     m->type = type;
108     m->message = g_strdup(message);
110     if (lifetime) {
111         m->timeout_id = g_timeout_add(lifetime, &MessageStack::_timeout, m);
112     } else {
113         m->timeout_id = 0;
114     }
116     m->next = _messages;
117     _messages = m;
119     _emitChanged();
121     return id;
124 MessageStack::Message *MessageStack::_discard(MessageStack::Message *m)
126     Message *next=m->next;
127     if (m->timeout_id) {
128         g_source_remove(m->timeout_id);
129         m->timeout_id = 0;
130     }
131     g_free(m->message);
132     m->message = NULL;
133     m->stack = NULL;
134     delete m;
135     return next;
138 void MessageStack::_emitChanged() {
139     if (_messages) {
140         _changed_signal.emit(_messages->type, _messages->message);
141     } else {
142         _changed_signal.emit(NORMAL_MESSAGE, NULL);
143     }
146 gboolean MessageStack::_timeout(gpointer data) {
147     Message *m=reinterpret_cast<Message *>(data);
148     m->timeout_id = 0;
149     m->stack->cancel(m->id);
150     return FALSE;
155 /*
156   Local Variables:
157   mode:c++
158   c-file-style:"stroustrup"
159   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
160   indent-tabs-mode:nil
161   fill-column:99
162   End:
163 */
164 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :