// SPDX-License-Identifier: GPL-2.0-or-later /** \file * Raw stack of active status messages */ /* * Authors: * MenTaLguY * Jon A. Cruz * * 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 #include #include // G_GNUC_PRINTF is the only thing worth having from here #include #include #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 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 _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 :