diff options
Diffstat (limited to '')
-rw-r--r-- | src/message-stack.h | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/src/message-stack.h b/src/message-stack.h new file mode 100644 index 0000000..f86ae7b --- /dev/null +++ b/src/message-stack.h @@ -0,0 +1,190 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/** \file + * Raw stack of active status messages + */ + +/* + * Authors: + * MenTaLguY <mental@rydia.net> + * Jon A. Cruz <jon@joncruz.org> + * + * Copyright (C) 2004 MenTaLguY + * Copyright (C) 2011 Jon A. Cruz + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#ifndef SEEN_INKSCAPE_MESSAGE_STACK_H +#define SEEN_INKSCAPE_MESSAGE_STACK_H + +#include <cstdarg> +#include <cstddef> +#include <glib.h> // G_GNUC_PRINTF is the only thing worth having from here +#include <glibmm/ustring.h> +#include <sigc++/sigc++.h> + +#include "message.h" + +namespace Inkscape { + +/** + * A class which holds a stack of displayed messages. + * + * Messages can be pushed onto the top of the stack, and removed + * from any point in the stack by their id. + * + * Messages may also be "flashed", meaning that they will be + * automatically removed from the stack a fixed period of time + * after they are pushed. + * + * "Flashed" warnings and errors will persist longer than normal + * messages. + * + * There is no simple "pop" operation provided, since these + * stacks are intended to be shared by many different clients; + * assuming that the message you pushed is still on top is an + * invalid and unsafe assumption. + */ +class MessageStack final +{ +public: + MessageStack(); + ~MessageStack(); + + MessageStack(MessageStack const &) = delete; // no copy + void operator=(MessageStack const &) = delete; // no assign + + /** @brief returns the type of message currently at the top of the stack */ + MessageType currentMessageType() { + return _messages ? _messages->type : NORMAL_MESSAGE; + } + /** @brief returns the text of the message currently at the top of + * the stack + */ + char const *currentMessage() { + return _messages ? _messages->message : nullptr; + } + + /** @brief connects to the "changed" signal which is emitted whenever + * the topmost message on the stack changes. + */ + sigc::connection connectChanged(sigc::slot<void, MessageType, char const *> slot) + { + return _changed_signal.connect(slot); + } + + /** @brief pushes a message onto the stack + * + * @param type the message type + * @param message the message text + * + * @return the id of the pushed message + */ + MessageId push(MessageType type, char const *message); + + /** @brief pushes a message onto the stack using printf-like formatting + * + * @param type the message type + * @param format a printf-style format string + * + * @return the id of the pushed message + */ + MessageId pushF(MessageType type, char const *format, ...) G_GNUC_PRINTF(3,4); + + /** @brief pushes a message onto the stack using printf-like formatting, + * using a stdarg argument list + * + * @param type the message type + * @param format a printf-style format string + * @param args the subsequent printf-style arguments + * + * @return the id of the pushed message + */ + MessageId pushVF(MessageType type, char const *format, va_list args); + + /** @brief removes a message from the stack, given its id + * + * This method will remove a message from the stack if it has not + * already been removed. It may be removed from any part of the stack. + * + * @param id the message id to remove + */ + void cancel(MessageId id); + + /** + * Temporarily pushes a message onto the stack. + * + * @param type the message type + * @param message the message text + * + * @return the id of the pushed message + */ + MessageId flash(MessageType type, char const *message); + + /** + * Temporarily pushes a message onto the stack. + * + * @param type the message type + * @param message the message text + * + * @return the id of the pushed message + */ + MessageId flash(MessageType type, Glib::ustring const &message); + + + /** @brief temporarily pushes a message onto the stack using + * printf-like formatting + * + * @param type the message type + * @param format a printf-style format string + * + * @return the id of the pushed message + */ + MessageId flashF(MessageType type, char const *format, ...) G_GNUC_PRINTF(3,4); + + /** @brief temporarily pushes a message onto the stack using + * printf-like formatting, using a stdarg argument list + * + * @param type the message type + * @param format a printf-style format string + * @param args the printf-style arguments + * + * @return the id of the pushed message + */ + MessageId flashVF(MessageType type, char const *format, va_list args); + +private: + struct Message { + Message *next; + MessageStack *stack; + MessageId id; + MessageType type; + gchar *message; + guint timeout_id; + }; + + /// pushes a message onto the stack with an optional timeout + MessageId _push(MessageType type, unsigned int lifetime, char const *message); + + Message *_discard(Message *m); ///< frees a message struct and returns the next such struct in the list + void _emitChanged(); ///< emits the "changed" signal + static int _timeout(void* data); ///< callback to expire flashed messages + + sigc::signal<void, MessageType, char const *> _changed_signal; + Message *_messages; ///< the stack of messages as a linked list + MessageId _next_id; ///< the next message id to assign +}; + +} + +#endif +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : |