Hi Syn2Fin, Thanks for working on this. Undo/Redo would be a very big step forward for us.
A couple of thoughts: 1. We need to get a release out the door first. We were supposed to release two weeks ago, but that never happened. Oops. (My fault -- Kelvie's been busy and I've had very little time this semester, but I should still have set some time aside to get this done). I'd like to focus on getting the new release out the door first, but then I will try to look at this more closely. So, please be a little patient. 2. It is hard to review this patch in its current form. Maybe we could set up a reviewboard account? I will try to look at this some more later this week when I have more time. -- Robert On Monday 22 February 2010 12:03:51 am Syn Fin wrote: > 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>&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>&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
signature.asc
Description: This is a digitally signed message part.
------------------------------------------------------------------------------ Download Intel® 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