Greetings all,

I sat down this weekend and wrote a proof of concept patch for including 
undo/redo functionality.  It's ONLY purpose is to show the rough idea of what 
needs to be done.

The only feature that works is delete, you can undo a delete and redo a 
delete.  It is a hack for the moment and doesn't always put things back where 
they should be (there are good reasons too, please read on).  I did not do more 
yet, as it will require a sizeable refactoring of the bnpview.{h|cpp} and 
basketview.{h|cpp} to make it work with the Qt undo framework.

Using the Qt framework, all actions that we want to be put on the undo stack 
must be abstracted by an object (DeleteItem, AddItem, MoveItem, GroupItems, 
UngroupItems, etc.) that inherits from QUndoCommand.  Each of these objects 
will have a redo() and undo() method with sufficient knowledge to roll forward 
and backwards through the system state.  However, the code as it is written 
now, doesn't support this.  It will probably also require a few extra methods 
in the Note class.

I have no problem implementing this.  But before I spend a lot of time on this, 
please glance at the patch for a brief taste of what I'm proposing (the patch 
is a bit messy, sorry guys, I'm new to this).  If people are not adamantly 
opposed, I can write up a fairly short document describing what needs to be 
changed, what new objects need to be added, as well as a description of how the 
redo/undo functionality should work.  From there comments can be generated and 
hopefully we'll come to an agreement and I'll build from that.

-Syn2Fin

P.S.: I am very sorry for my long hiatus.  School + work (and the occasional 
female...) sucked away my time.  I have since graduated, and time is becoming 
more readily available.

=====PATCH=====
diff --git a/src/basket_part.rc b/src/basket_part.rc
index 4537f1a..a4ac7a7 100644
--- a/src/basket_part.rc
+++ b/src/basket_part.rc
@@ -35,6 +35,8 @@
   </Menu>
   <Menu name="edit" >
    <text>&amp;Edit</text>
+   <Action name="edit_undo" />
+   <Action name="edit_redo" />
    <Action name="edit_cut" />
    <Action name="edit_copy" />
    <Action name="edit_paste" />
@@ -118,6 +120,8 @@
   <text>Main Toolbar</text>
   <Action name="basket_properties" />
   <Separator lineSeparator="true" name="separator_0" />
+  <Action name="edit_undo" />
+  <Action name="edit_redo" />
   <Action name="edit_cut" />
   <Action name="edit_copy" />
   <Action name="edit_paste" />
@@ -207,6 +211,8 @@
   <Action name="note_group" />
   <Action name="note_ungroup" />
   <Separator/>
+  <Action name="edit_undo" />
+  <Action name="edit_redo" />
   <Action name="edit_cut" />
   <Action name="edit_copy" />
   <Action name="edit_delete" />
diff --git a/src/basketui.rc b/src/basketui.rc
index bdcf7a5..a581ed4 100644
--- a/src/basketui.rc
+++ b/src/basketui.rc
@@ -38,6 +38,8 @@
   </Menu>
   <Menu name="edit" >
    <text>&amp;Edit</text>
+   <Action name="edit_undo" />
+   <Action name="edit_redo" />
    <Action name="edit_cut" />
    <Action name="edit_copy" />
    <Action name="edit_paste" />
@@ -122,6 +124,8 @@
   <Action name="basket_new_menu" />
   <Action name="basket_properties" />
   <Separator lineSeparator="true" name="separator_0" />
+  <Action name="edit_undo" />
+  <Action name="edit_redo" />
   <Action name="edit_cut" />
   <Action name="edit_copy" />
   <Action name="edit_paste" />
@@ -214,6 +218,8 @@
   <Action name="note_group" />
   <Action name="note_ungroup" />
   <Separator/>
+  <Action name="edit_undo" />
+  <Action name="edit_redo" />
   <Action name="edit_cut" />
   <Action name="edit_copy" />
   <Action name="edit_delete" />
diff --git a/src/basketview.h b/src/basketview.h
index 61d2a7b..8949716 100644
--- a/src/basketview.h
+++ b/src/basketview.h
@@ -416,13 +416,13 @@ public:
     NoteSelection* selectedNotes();
 
 /// BLANK SPACES DRAWING:
-private:
+ private:
     QList<QRect> m_blankAreas;
     void recomputeBlankRects();
     QWidget *m_cornerWidget;
-
+    
 /// COMMUNICATION WITH ITS CONTAINER:
-signals:
+ signals:
     void postMessage(const QString &message);      /// << Post a temporar 
message in the statusBar.
     void setStatusBarText(const QString &message); /// << Set the permanent 
statusBar text or reset it if message isEmpty().
     void resetStatusBarText();                     /// << Equivalent to 
setStatusBarText("").
diff --git a/src/bnpview.cpp b/src/bnpview.cpp
index 5fbb3f0..bdbc84e 100644
--- a/src/bnpview.cpp
+++ b/src/bnpview.cpp
@@ -88,7 +88,7 @@
 #include "notefactory.h"
 #include "notecontent.h"
 #include "unistd.h" // usleep
-
+#include "noteselection.h"
 
 #include "bnpviewadaptor.h"
 /** class BNPView: */
@@ -813,7 +813,8 @@ void BNPView::setupActions()
 #endif
 
     /** Edit : 
****************************************************************/
-
+    /* synfin edit to include undo/redo functionality */
+    setupUndo(a,ac);
     //m_actUndo     = KStandardAction::undo(  this, 
SLOT(undo()),                 actionCollection() );
     //m_actUndo->setEnabled(false); // Not yet implemented !
     //m_actRedo     = KStandardAction::redo(  this, 
SLOT(redo()),                 actionCollection() );
@@ -886,6 +887,36 @@ void BNPView::setupActions()
     a->setText(i18n("&Welcome Baskets"));
 }
 
+/**
+ * syn2...@yahoo.com
+ * The actual code in bnpview is convoluted with items scattered everywhere
+ * I have given up figuring out where all the connect and QAction statements
+ * are located, and this method handles everything related to undo/redo
+ *
+ * Part of this is also my relative newness to the Basket code and QT Framework
+ * itself.  This will be merged with the rest of the code after acceptance and
+ * my own comfort level with Basket's source increases.
+ */
+void BNPView::setupUndo(KAction *a, KActionCollection *ac) {
+  m_undostack = new QUndoStack();
+  //a = ac->addAction("undo", this, SLOT(undo()));
+  m_actUndo=ac->addAction(KStandardAction::Undo,this,SLOT(undo()));
+  //a->setText(i18n("&undo"));
+  //a->setShortcut(0);
+  //m_actUndo=a;
+  m_actRedo=ac->addAction(KStandardAction::Redo,this,SLOT(redo()));
+  //a = ac->addAction("redo", this, SLOT(redo()));
+  //a->setText(i18n("&redo"));
+  //a->setShortcut(0);
+  //m_actRedo=a;
+  
+  // Connect appropriate items
+  
connect(m_undostack,SIGNAL(canUndoChanged(bool)),m_actUndo,SLOT(setEnabled(bool)));
+  
connect(m_undostack,SIGNAL(canRedoChanged(bool)),m_actRedo,SLOT(setEnabled(bool)));
+  connect(m_actUndo,SIGNAL(triggered()),m_undostack,SLOT(undo()));
+  connect(m_actRedo,SIGNAL(triggered()),m_undostack,SLOT(redo()));
+}
+
 BasketListViewItem* BNPView::topLevelItem(int i)
 {
     return (BasketListViewItem *)m_tree->topLevelItem(i);
@@ -1592,7 +1623,10 @@ void BNPView::copyNote()
 }
 void BNPView::delNote()
 {
-    currentBasket()->noteDelete();
+  //currentBasket()->noteDelete();
+  printf("You called BNPView::delNote()\n");
+  QUndoCommand * delItem = new DeleteItem(currentBasket());
+  m_undostack->push(delItem);
 }
 void BNPView::openNote()
 {
@@ -2042,11 +2076,13 @@ void BNPView::setFiltering(bool filtering)
 void BNPView::undo()
 {
     // TODO
+  printf("In BNPView::undo()\n");
 }
 
 void BNPView::redo()
 {
     // TODO
+  printf("In BNPView::redo()\n");
 }
 
 void BNPView::pasteToBasket(int /*index*/, QClipboard::Mode /*mode*/)
@@ -2811,3 +2847,34 @@ void BNPView::disconnectTagsMenuDelayed()
     disconnect(m_lastOpenedTagsMenu, SIGNAL(aboutToHide()),  currentBasket(), 
SLOT(unlockHovering()));
     disconnect(m_lastOpenedTagsMenu, SIGNAL(aboutToHide()),  currentBasket(), 
SLOT(disableNextClick()));
 }
+
+DeleteItem::DeleteItem(BasketView *currentBasket, QUndoCommand *parent) : 
QUndoCommand(parent) {
+  this->currentBasket=currentBasket;
+  NoteSelection *selection = currentBasket->selectedNotes();
+  if (selection->firstStacked()) {
+    d = NoteDrag::dragObject(selection, true, /*source=*/0);
+    mimeData = d->mimeData();
+    currentBasket->noteDelete();
+  }
+}
+void DeleteItem::undo() {
+  printf("in DeleteItem::undo()");
+  //The trick is to "paste" the note where it used to be.
+  currentBasket->closeEditor();
+  currentBasket->unselectAll();
+  Note *note = NoteFactory::dropNote(mimeData,currentBasket);
+  if (note) {currentBasket->insertCreatedNote(note);}
+  else {printf("Note was null\n");}
+}
+void DeleteItem::redo() {
+  currentBasket->noteDelete();
+  printf("in DeleteItem::redo()");
+}
+//AddItem::AddItem() {
+//}
+void AddItem::undo() {
+  printf("in AddItem::undo()");
+}
+void AddItem::redo() {
+  printf("in AddItem::redo()");
+}
diff --git a/src/bnpview.h b/src/bnpview.h
index ecd6057..140eed4 100644
--- a/src/bnpview.h
+++ b/src/bnpview.h
@@ -32,6 +32,8 @@
 #include <QHideEvent>
 #include <QEvent>
 #include <QShowEvent>
+#include <QUndoStack>
+#include <QUndoCommand>
 
 #include "global.h"
 #include "basket_export.h"
@@ -59,6 +61,8 @@ class BasketStatusBar;
 class Tag;
 class State;
 class Note;
+class DeleteItem;
+class AddItem;
 
 class BASKET_EXPORT BNPView : public QSplitter
 {
@@ -332,6 +336,7 @@ private slots:
     void slotContextMenu(const QPoint &pos);
     void slotShowProperties(QTreeWidgetItem *item);
     void initialize();
+    void setupUndo(KAction *a,KActionCollection *ac);
 
 signals:
     void basketNumberChanged(int number);
@@ -345,6 +350,7 @@ protected:
 
 private:
     BasketTreeListView *m_tree;
+    QUndoStack *m_undostack;
     QStackedWidget *m_stack;
     bool          m_loading;
     bool          m_newBasketPopup;
@@ -364,4 +370,20 @@ private:
     QTimer             *m_hideTimer;
 };
 
+class DeleteItem : public QUndoCommand {
+ public:
+  DeleteItem(BasketView * currentBasket, QUndoCommand *parent = 0);
+  void undo();
+  void redo();
+ private:
+  BasketView *currentBasket;
+  QDrag *d;
+  QMimeData * mimeData;
+};
+class AddItem : public QUndoCommand {
+ public:
+  void undo();
+  void redo();
+};
+
 #endif // BNPVIEW_H




      
------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Basket-devel mailing list
Basket-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/basket-devel

Reply via email to