15#include <glibmm/i18n.h>
28 _event_list_view(event_list_view),
29 _callback_connections(callback_connections),
30 _event_list_selection(_event_list_view->get_selection())
34 Gtk::TreeView *_event_list_view;
39 Glib::RefPtr<Gtk::TreeSelection> _event_list_selection;
42class ConnectionMatcher
45 ConnectionMatcher(Gtk::TreeView *view,
52 bool operator() (DialogConnection
const &dlg)
54 return (_view == dlg._event_list_view) && (_callbacks == dlg._callback_connections);
79 bool isConnected()
const
81 return !_connections.empty();
84 void addDialogConnection(Gtk::TreeView *event_list_view,
86 Glib::RefPtr<Gtk::TreeStore> event_list_store,
89 if (std::find_if(_connections.begin(), _connections.end(), ConnectionMatcher(event_list_view, callback_connections)) != _connections.end()) {
94 DialogConnection dlg(event_list_view, callback_connections);
96 dlg._event_list_selection->set_mode(Gtk::SelectionMode::SINGLE);
99 std::vector<std::unique_ptr<SignalBlocker<sigc::connection>>> blockers;
103 dlg._event_list_view->expand_to_path(event_list_store->get_path(curr_event));
104 dlg._event_list_selection->select(curr_event);
106 _connections.push_back(dlg);
112 std::vector<DialogConnection>::iterator it = std::find_if(_connections.begin(), _connections.end(), ConnectionMatcher(event_list_view, callback_connections));
113 if (it != _connections.end()) {
114 _connections.erase(it);
118 void collapseRow(Gtk::TreeModel::Path
const &path)
120 std::vector<std::unique_ptr<SignalBlocker<sigc::connection>>> blockers;
121 for (
auto & _connection : _connections)
127 for (
auto & _connection : _connections)
129 _connection._event_list_view->collapse_row(path);
133 void selectRow(Gtk::TreeModel::Path
const &path)
135 std::vector<std::unique_ptr<SignalBlocker<sigc::connection>>> blockers;
136 for (
auto & _connection : _connections)
142 for (
auto & _connection : _connections)
144 _connection._event_list_view->expand_to_path(path);
145 _connection._event_list_selection->select(path);
146 _connection._event_list_view->scroll_to_row(path);
150 void clearEventList(Glib::RefPtr<Gtk::TreeStore> eventListStore)
152 if (eventListStore) {
153 std::vector<std::unique_ptr<SignalBlocker<sigc::connection>>> blockers;
154 for (
auto & _connection : _connections)
160 eventListStore->clear();
164 std::vector<DialogConnection> _connections;
175 _priv(new EventLogPrivate()),
176 _document (document),
177 _event_list_store (
Gtk::TreeStore::
create(getColumns())),
178 _curr_event_parent (nullptr),
179 _notifications_blocked (false)
189 curr_row[_columns.description] = _(
"[No more changes]");
190 curr_row[_columns.icon_name] =
"document-new";
191 curr_row[_columns.child_count] = 0;
239 if (
_priv->isConnected()) {
241 _priv->selectRow(curr_path);
288 if (
_priv->isConnected()) {
290 _priv->selectRow(curr_path);
303 auto icon_name =
log->icon_name;
305 Gtk::TreeRow curr_row;
309 if ( icon_name == Glib::ustring{(*_curr_event)[_columns.icon_name]} ) {
314 (*_curr_event_parent)[_columns.child_count] =
_curr_event_parent->children().size() + 1;
317 curr_row[_columns.child_count] = 1;
331 curr_row[_columns.event] =
log;
332 curr_row[_columns.icon_name] = icon_name;
333 curr_row[_columns.description] =
log->description;
338 if (
_priv->isConnected()) {
340 _priv->selectRow(curr_path);
361 assert((*iter)[columns.event] ==
log);
364 if (iter->children().size() > 0) {
366 to_remove = iter->children().begin();
368 Event *child_log = (*to_remove)[columns.event];
369 Glib::ustring desc = (*to_remove)[columns.description];
370 (*iter)[columns.event] = child_log;
371 (*iter)[columns.description] = desc;
377 assert(to_remove->children().size() == 0);
379 if (
auto parent = to_remove->parent()) {
380 (*parent)[columns.child_count] = to_remove->parent()->children().size() - 1;
387 (*_first_event)[columns.description] = _(
"[Changes forgotten]");
389 (*_first_event)[columns.child_count] = (*_first_event)[columns.child_count] + 1;
413 _priv->removeDialogConnection(event_list_view, callback_connections);
448 if ( redo_event->parent() &&
449 redo_event == redo_event->parent()->children().end() ) {
451 redo_event = redo_event->parent();
490 (*_last_event)[_columns.child_count] =
_last_event->children().size() + 1;
void enable_undo_actions(SPDocument *document, bool undo, bool redo)
Actions for Undo/Redo tied to document.
void addDialogConnection(Gtk::TreeView *event_list_view, CallbackMap *callback_connections)
Connect with a TreeView.
Glib::RefPtr< Gtk::TreeStore > _event_list_store
void removeDialogConnection(Gtk::TreeView *event_list_view, CallbackMap *callback_connections)
Disconnect from a TreeView.
EventLog(SPDocument *document)
void notifyUndoExpired(Event *log) override
Triggered when undo items are removed from the back of the log (expired)
Gtk::TreeModel::const_iterator const_iterator
void notifyClearRedoEvent() override
Triggered when the redo log is cleared.
void notifyUndoCommitEvent(Event *log) override
Triggered when a set of transactions is committed to the undo log.
Gtk::TreeModel::iterator iterator
void notifyClearUndoEvent() override
Triggered when the undo log is cleared.
void notifyUndoEvent(Event *log) override
Modifies the log's entries and the view's selection when triggered.
void notifyRedoEvent(Event *log) override
Triggered when the user issues a redo command.
std::map< const CallbackTypes, sigc::connection > CallbackMap
const_iterator _getUndoEvent() const
const_iterator _getRedoEvent() const
bool _notifications_blocked
iterator _curr_event_parent
static const EventModelColumns & getColumns()
Observes changes made to the undo and redo stacks.
Typed SVG document implementation.
void setModifiedSinceSave(bool const modified=true)
Indicate to the user if the document has been modified since the last save by displaying a "*" in fro...
RAII blocker for sigc++ signals.
static char const *const parent
Helper class to stream background task notifications as a series of messages.
Piecewise< SBasis > log(Interval in)