Code

New file. use for building with gtk28
[inkscape.git] / src / message-stack.cpp
1 /*
2  * MessageStack - context for posting 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 <glib/gstrfuncs.h>
13 #include "message-stack.h"
15 namespace Inkscape {
17 MessageStack::MessageStack()
18 : _messages(NULL), _next_id(1)
19 {
20 }
22 MessageStack::~MessageStack()
23 {
24     while (_messages) {
25         _messages = _discard(_messages);
26     }
27 }
29 MessageId MessageStack::push(MessageType type, gchar const *message) {
30     return _push(type, 0, message);
31 }
33 MessageId MessageStack::pushF(MessageType type, gchar const *format, ...)
34 {
35     va_list args;
36     va_start(args, format);
37     MessageId id=pushVF(type, format, args);
38     va_end(args);
39     return id;
40 }
42 MessageId MessageStack::pushVF(MessageType type, gchar const *format, va_list args)
43 {
44     MessageId id;
45     gchar *message=g_strdup_vprintf(format, args);
46     id = push(type, message);
47     g_free(message);
48     return id;
49 }
51 void MessageStack::cancel(MessageId id) {
52     Message **ref;
53     for ( ref = &_messages ; *ref ; ref = &(*ref)->next ) {
54         if ( (*ref)->id == id ) {
55             *ref = _discard(*ref);
56             _emitChanged();
57             break;
58         }
59     }
60 }
62 MessageId MessageStack::flash(MessageType type, gchar const *message) {
63     switch (type) {
64     case INFORMATION_MESSAGE: // stay rather long so as to seem permanent, but eventually disappear
65         return _push(type, 6000 + 80*strlen(message), message);
66         break;
67     case ERROR_MESSAGE: // pretty important stuff, but temporary
68         return _push(type, 4000 + 60*strlen(message), message);
69         break;
70     case WARNING_MESSAGE: // a bit less important than error
71         return _push(type, 2000 + 40*strlen(message), message);
72         break;
73     case NORMAL_MESSAGE: // something ephemeral
74     default:
75         return _push(type, 1000 + 20*strlen(message), message);
76         break;
77     }
78 }
80 MessageId MessageStack::flashF(MessageType type, gchar const *format, ...) {
81     va_list args;
82     va_start(args, format);
83     MessageId id = flashVF(type, format, args);
84     va_end(args);
85     return id;
86 }
88 MessageId MessageStack::flashVF(MessageType type, gchar const *format, va_list args)
89 {
90     gchar *message=g_strdup_vprintf(format, args);
91     MessageId id = flash(type, message);
92     g_free(message);
93     return id;
94 }
96 MessageId MessageStack::_push(MessageType type, guint lifetime, gchar const *message)
97 {
98     Message *m=new Message;
99     MessageId id=_next_id++;
101     m->stack = this;
102     m->id = id;
103     m->type = type;
104     m->message = g_strdup(message);
106     if (lifetime) {
107         m->timeout_id = g_timeout_add(lifetime, &MessageStack::_timeout, m);
108     } else {
109         m->timeout_id = 0;
110     }
112     m->next = _messages;
113     _messages = m;
115     _emitChanged();
117     return id;
120 MessageStack::Message *MessageStack::_discard(MessageStack::Message *m)
122     Message *next=m->next;
123     if (m->timeout_id) {
124         g_source_remove(m->timeout_id);
125         m->timeout_id = 0;
126     }
127     g_free(m->message);
128     m->message = NULL;
129     m->stack = NULL;
130     delete m;
131     return next;
134 void MessageStack::_emitChanged() {
135     if (_messages) {
136         _changed_signal.emit(_messages->type, _messages->message);
137     } else {
138         _changed_signal.emit(NORMAL_MESSAGE, NULL);
139     }
142 gboolean MessageStack::_timeout(gpointer data) {
143     Message *m=reinterpret_cast<Message *>(data);
144     m->timeout_id = 0;
145     m->stack->cancel(m->id);
146     return FALSE;
151 /*
152   Local Variables:
153   mode:c++
154   c-file-style:"stroustrup"
155   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
156   indent-tabs-mode:nil
157   fill-column:99
158   End:
159 */
160 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :