Code

support for <rect> tag (Bug 657289)
[inkscape.git] / src / event-log.cpp
index 40c8364acabdca5de0597dc265a323414172ef33..977d068f8a2b98d8f4fa940ca51f84cb8bfbbdd9 100644 (file)
@@ -2,7 +2,7 @@
  * Author:
  *   Gustav Broberg <broberg@kth.se>
  *
- * Copyright (c) 2006 Authors
+ * Copyright (c) 2006, 2007 Authors
  *
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
 #include <glibmm/i18n.h>
 
 #include "desktop.h"
-
 #include "event-log.h"
+#include "inkscape.h"
+#include "util/ucompose.hpp"
+#include "document.h"
+#include "xml/repr.h"
+#include "sp-object.h"
 
 namespace Inkscape {
 
-EventLog::EventLog() :
+EventLog::EventLog(SPDocument* document) :
     UndoStackObserver(),
     _connected (false),
+    _document (document),
     _event_list_store (Gtk::TreeStore::create(_columns)),
     _event_list_selection (NULL),
     _event_list_view (NULL),
@@ -27,7 +32,7 @@ EventLog::EventLog() :
 {
     // add initial pseudo event
     Gtk::TreeRow curr_row = *(_event_list_store->append());
-    _curr_event = _last_event = curr_row;
+    _curr_event = _last_saved = _last_event = curr_row;
     
     curr_row[_columns.description] = _("[Unchanged]");
     curr_row[_columns.type] = SP_VERB_FILE_NEW;
@@ -39,7 +44,10 @@ void
 EventLog::notifyUndoEvent(Event* log) 
 {
     if ( !_notifications_blocked ) {
-      
+    
+        // make sure the supplied event matches the next undoable event
+        g_return_if_fail ( _getUndoEvent() && (*(_getUndoEvent()))[_columns.event] == log );
+
         // if we're on the first child event...
         if ( _curr_event->parent() &&
              _curr_event == _curr_event->parent()->children().begin() )
@@ -67,6 +75,8 @@ EventLog::notifyUndoEvent(Event* log)
             }
        }
 
+        checkForVirginity();
+
         // update the view
         if (_connected) {
             (*_callback_connections)[CALLB_SELECTION_CHANGE].block();
@@ -75,13 +85,15 @@ EventLog::notifyUndoEvent(Event* log)
             Gtk::TreePath curr_path = _event_list_store->get_path(_curr_event);
             _event_list_view->expand_to_path(curr_path);
             _event_list_selection->select(curr_path);
-            _event_list_view->scroll_to_row(curr_path);  
+            _event_list_view->scroll_to_row(curr_path);
 
             (*_callback_connections)[CALLB_EXPAND].block(false);
             (*_callback_connections)[CALLB_SELECTION_CHANGE].block(false);
         }
 
+        updateUndoVerbs();
     }
+
 }
 
 void
@@ -89,6 +101,9 @@ EventLog::notifyRedoEvent(Event* log)
 {
     if ( !_notifications_blocked ) {
 
+        // make sure the supplied event matches the next redoable event
+        g_return_if_fail ( _getRedoEvent() && (*(_getRedoEvent()))[_columns.event] == log );
+
         // if we're on a parent event...
         if ( !_curr_event->children().empty() ) {
 
@@ -122,6 +137,8 @@ EventLog::notifyRedoEvent(Event* log)
             }
         }
 
+        checkForVirginity();
+
         // update the view
         if (_connected) {
             Gtk::TreePath curr_path = _event_list_store->get_path(_curr_event);
@@ -131,46 +148,21 @@ EventLog::notifyRedoEvent(Event* log)
 
             _event_list_view->expand_to_path(curr_path);
             _event_list_selection->select(curr_path);
-            _event_list_view->scroll_to_row(curr_path);  
+            _event_list_view->scroll_to_row(curr_path);
 
             (*_callback_connections)[CALLB_EXPAND].block(false);
             (*_callback_connections)[CALLB_SELECTION_CHANGE].block(false);
         }
 
+        updateUndoVerbs();
     }
+
 }
 
 void 
 EventLog::notifyUndoCommitEvent(Event* log)
 {
-    // If we're not at the last event in list then erase the previously undone events 
-    if ( _last_event != _curr_event ) {
-
-        _last_event = _curr_event;
-
-        if ( !_last_event->children().empty() ) {
-            _last_event = _last_event->children().begin();
-        } else {
-            ++_last_event;
-        }
-
-        while ( _last_event != _event_list_store->children().end() ) {
-
-            if (_last_event->parent()) {
-                while ( _last_event != _last_event->parent()->children().end() ) {
-                    _last_event = _event_list_store->erase(_last_event);
-                }
-                _last_event = _last_event->parent();
-
-                (*_last_event)[_columns.child_count] = _last_event->children().size() + 1;
-
-                ++_last_event;
-            } else {
-                _last_event = _event_list_store->erase(_last_event);
-            }
-
-        }
-    }
+    _clearRedo();
 
     const unsigned int event_type = log->type;
 
@@ -201,9 +193,12 @@ EventLog::notifyUndoCommitEvent(Event* log)
 
     _curr_event = _last_event = curr_row;
 
+    curr_row[_columns.event] = log;
     curr_row[_columns.type] = event_type;
     curr_row[_columns.description] = log->description;
 
+    checkForVirginity();
+
     // update the view
     if (_connected) {
         Gtk::TreePath curr_path = _event_list_store->get_path(_curr_event);
@@ -213,12 +208,27 @@ EventLog::notifyUndoCommitEvent(Event* log)
 
         _event_list_view->expand_to_path(curr_path);
         _event_list_selection->select(curr_path);
-        _event_list_view->scroll_to_row(curr_path);  
+        _event_list_view->scroll_to_row(curr_path);
 
         (*_callback_connections)[CALLB_EXPAND].block(false);
         (*_callback_connections)[CALLB_SELECTION_CHANGE].block(false);
     }
 
+    updateUndoVerbs();
+}
+
+void
+EventLog::notifyClearUndoEvent()
+{
+    _clearUndo();    
+    updateUndoVerbs();
+}
+
+void
+EventLog::notifyClearRedoEvent()
+{
+    _clearRedo();
+    updateUndoVerbs();
 }
 
 void 
@@ -242,7 +252,125 @@ EventLog::connectWithDialog(Gtk::TreeView *event_list_view, CallbackMap *callbac
     _connected = true;
 }
 
+void
+EventLog::updateUndoVerbs()
+{
+    if(_document) {
+
+        if(_getUndoEvent()) { 
+            Inkscape::Verb::get(SP_VERB_EDIT_UNDO)->sensitive(_document, true);
+
+            Inkscape::Verb::get(SP_VERB_EDIT_UNDO)->name(_document, String::ucompose("%1: %2", 
+                      Glib::ustring(_("_Undo")),
+                      Glib::ustring((*_getUndoEvent())[_columns.description])));
+        } else {
+            Inkscape::Verb::get(SP_VERB_EDIT_UNDO)->name(_document, _("_Undo"));
+            Inkscape::Verb::get(SP_VERB_EDIT_UNDO)->sensitive(_document, false);
+        }
+
+        if(_getRedoEvent()) {
+            Inkscape::Verb::get(SP_VERB_EDIT_REDO)->sensitive(_document, true);
+            Inkscape::Verb::get(SP_VERB_EDIT_REDO)->name(_document, String::ucompose("%1: %2", 
+                      Glib::ustring(_("_Redo")),
+                      Glib::ustring((*_getRedoEvent())[_columns.description])));
+
+        } else {
+            Inkscape::Verb::get(SP_VERB_EDIT_REDO)->name(_document, _("_Redo"));
+            Inkscape::Verb::get(SP_VERB_EDIT_REDO)->sensitive(_document, false);
+        }
+
+    }
+
+}
+
+
+EventLog::const_iterator
+EventLog::_getUndoEvent() const
+{
+    const_iterator undo_event = (const_iterator)NULL;
+    if( _curr_event != _event_list_store->children().begin() )
+        undo_event = _curr_event;
+    return undo_event;
+}
+
+EventLog::const_iterator
+EventLog::_getRedoEvent() const
+{
+    const_iterator redo_event = (const_iterator)NULL;
+
+    if ( _curr_event != _last_event ) {
+
+        if ( !_curr_event->children().empty() )
+            redo_event = _curr_event->children().begin();
+        else  {
+            redo_event = _curr_event;
+            ++redo_event;
+
+            if ( redo_event->parent() &&
+                 redo_event == redo_event->parent()->children().end() ) {
+
+                redo_event = redo_event->parent();
+                ++redo_event;
+
+            }
+        }
+
+    }
+
+    return redo_event;
+}
+
+void
+EventLog::_clearUndo()
+{
+    // TODO: Implement when needed
 }
+
+void
+EventLog::_clearRedo()
+{
+    if ( _last_event != _curr_event ) {
+
+        _last_event = _curr_event;
+
+        if ( !_last_event->children().empty() ) {
+            _last_event = _last_event->children().begin();
+        } else {
+            ++_last_event;
+        }
+
+        while ( _last_event != _event_list_store->children().end() ) {
+
+            if (_last_event->parent()) {
+                while ( _last_event != _last_event->parent()->children().end() ) {
+                    _last_event = _event_list_store->erase(_last_event);
+                }
+                _last_event = _last_event->parent();
+
+                (*_last_event)[_columns.child_count] = _last_event->children().size() + 1;
+
+                ++_last_event;
+            } else {
+                _last_event = _event_list_store->erase(_last_event);
+            }
+
+        }
+
+    }
+}
+
+/* mark document as untouched if we reach a state where the document was previously saved */
+void
+EventLog::checkForVirginity() {
+    g_return_if_fail (_document);
+    if (_curr_event == _last_saved) {
+        _document->setModifiedSinceSave(false);
+    }
+}
+
+} // namespace Inkscape
+
+
 /*
   Local Variables:
   mode:c++
@@ -252,4 +380,4 @@ EventLog::connectWithDialog(Gtk::TreeView *event_list_view, CallbackMap *callbac
   fill-column:99
   End:
 */
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :