Re: Undo framework
On Wed, 2007-09-26 at 13:08 +0200, Rodrigo Moya wrote: [...] > > It seems useful for anything that operates on persistent data, be it > > a document, or control-center settings. > > > I'm thinking, maybe a crazy idea though, but this could also be useful, > once the actions are stored in a file, to be able to repeat/run those > actions outside of the application. That is, you could do a set of > operations on a document-oriented application, save that to a file, and > use that as a sort of 'script' to do the same operations on another > document. I wrote a software updater once that had an undo/redo framework that was stored to a file, we used that to store the current step that was being executed, this way we could properly recover and undo everything if there was any errors, and even recover when losing power (by loading that file and continuing where we left off) Cheers, -Tristan ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Undo framework
On Mon, 2007-09-24 at 09:23 -0400, Jody Goldberg wrote: > On Mon, Sep 24, 2007 at 02:41:19PM +0200, Rodrigo Moya wrote: > > > > On Fri, 2007-09-21 at 16:21 -0300, Johan Dahlin wrote: > > > > > > I'm not sure we should talk about a 'document' there, there are many > > > operations outside of documents which are undoable. > > > > > yes, we are not talking only about document, and yes, I think it should > > be in Glib, except for the widgets that might be needed. > > Agreed. > > > As for transation-based framework, I'm not sure exactly what Jody is > > thinking about, but to me, if I understood it correctly, it makes a lot > > of sense to be able to group performed actions into a set that can be > > undone/redone and even repeated. That would, probably, fit the GIMP's > > needs, as stated by Sven, to have nested undo groups. Each group would > > be a transaction, that can be redone/undone/repeated as a single entity. > > The 'transaction' refered to a mechanism for persisting the details > of each operation to a file. > 1) The options could be re-played in the case of failure. > 2) The data would provide useful hooks for auditing and >validation. > > It seems useful for anything that operates on persistent data, be it > a document, or control-center settings. > I'm thinking, maybe a crazy idea though, but this could also be useful, once the actions are stored in a file, to be able to repeat/run those actions outside of the application. That is, you could do a set of operations on a document-oriented application, save that to a file, and use that as a sort of 'script' to do the same operations on another document. -- Rodrigo Moya <[EMAIL PROTECTED]> ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Undo framework
Hi, On Tue, 2007-09-25 at 08:16 -0400, Jody Goldberg wrote: > Undo comes with Redo, which is sufficient information to make a > replay a modification from a known state. Not necessarily. A common approach to Undo/Redo is to store the information before the operation on the undo stack. Then, when the user decides to undo, you push the information at this point to the redo stack and undo by going back to the saved state. This allows you to Undo and Redo, but it is not sufficient information to replay a modification from a known state. Not unless you actually reached this point by undo operations. Sven ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Undo framework
On Mon, Sep 24, 2007 at 08:32:01PM +0200, Sven Neumann wrote: > Hi, > > On Mon, 2007-09-24 at 09:23 -0400, Jody Goldberg wrote: > > > The 'transaction' refered to a mechanism for persisting the details > > of each operation to a file. > > 1) The options could be re-played in the case of failure. > > 2) The data would provide useful hooks for auditing and > >validation. > > This would certainly be useful but it is something different than an > Undo system. An undo system stores information on how to undo an > operation. This typically involves storing data and state information > from before the operation is performed. This information allows you to > undo the operation, but it typically doesn't allow you to replay it. Undo comes with Redo, which is sufficient information to make a replay a modification from a known state. ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Undo framework
I would find it useful if such an undo system would do away with the stack view of things and use the back-in-time view that Emacs uses. For example, if we have Do A, Do B, Do C, Undo C, Do D then it should be possible to rewind history to the point where C was done. Morten ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Undo framework
Hi, On Mon, 2007-09-24 at 09:23 -0400, Jody Goldberg wrote: > The 'transaction' refered to a mechanism for persisting the details > of each operation to a file. > 1) The options could be re-played in the case of failure. > 2) The data would provide useful hooks for auditing and >validation. This would certainly be useful but it is something different than an Undo system. An undo system stores information on how to undo an operation. This typically involves storing data and state information from before the operation is performed. This information allows you to undo the operation, but it typically doesn't allow you to replay it. Sven ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Undo framework
On Mon, Sep 24, 2007 at 02:41:19PM +0200, Rodrigo Moya wrote: > > On Fri, 2007-09-21 at 16:21 -0300, Johan Dahlin wrote: > > > > I'm not sure we should talk about a 'document' there, there are many > > operations outside of documents which are undoable. > > > yes, we are not talking only about document, and yes, I think it should > be in Glib, except for the widgets that might be needed. Agreed. > As for transation-based framework, I'm not sure exactly what Jody is > thinking about, but to me, if I understood it correctly, it makes a lot > of sense to be able to group performed actions into a set that can be > undone/redone and even repeated. That would, probably, fit the GIMP's > needs, as stated by Sven, to have nested undo groups. Each group would > be a transaction, that can be redone/undone/repeated as a single entity. The 'transaction' refered to a mechanism for persisting the details of each operation to a file. 1) The options could be re-played in the case of failure. 2) The data would provide useful hooks for auditing and validation. It seems useful for anything that operates on persistent data, be it a document, or control-center settings. ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Undo framework
On Sat, 2007-09-22 at 01:01 +0100, Iain * wrote: > > Do you allow nested undo groups? This is rather important > > if you want to compose actions from smaller actions and still allow > > scripts or other higher levels to combine these into a single undo step. > > We make heavy use of nested undo groups in GIMP. > > We allow one level of nesting, I can see your point about allowing > deeper nesting though and will think about how it could be done. I > suppose this is as much of the "merging" of actions that should take > place, I don't see that the UndoManager itself should support > automatic merging as each application has different requirements for > when a merge should happen, but if we allow multiple nesting of > actions then the applications can merge as they see fit. > > I can see the reason for the non-UI parts to go in GLib, but is there > any precedence in having stuff like this in GLib? If it was to go in > GLib it would be its own seperate library, which for one thing would > kinda suck? > why? we already have gthread, gmodule, glib, gobject, gio > As for transactional stuff, I would think that it seems overkill for > most applications, although it'd be great if we could work out some > way to allow those that want it to be able to implement it on top of > the base system. I can't see how you could make it generic enough to > make everyone happy. > this is easy, if the API provides, for instance, a 3-step mechanism: create_context add_stuff close_context thus, normal apps would just call the related 3 functions. More complicated apps would manage different contexts, and be able to associate a context to another one: set_parent_context for instance -- Rodrigo Moya <[EMAIL PROTECTED]> ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Undo framework
On Fri, 2007-09-21 at 16:21 -0300, Johan Dahlin wrote: > > > 3) Gtk seems like the right place for widgets to display the > >undo/redo stack. However, the core of the functionality seems > >non-gui. Something that would belong wherever we chose to put > >GDocument. To date that type of code has been migrating out of > >gnumeric and into goffice. If there is interest, we could > >collaborate on the next generation of this in there and rename to > >'libgdocument' or somesuch. > > While I agree that an undo stack should be in Gtk+ or lower I'm not sure a > transaction based should go there, but it should be possible to implement > one top of the interfaces/manager objects there. > > I'm not sure we should talk about a 'document' there, there are many > operations outside of documents which are undoable. > yes, we are not talking only about document, and yes, I think it should be in Glib, except for the widgets that might be needed. As for transation-based framework, I'm not sure exactly what Jody is thinking about, but to me, if I understood it correctly, it makes a lot of sense to be able to group performed actions into a set that can be undone/redone and even repeated. That would, probably, fit the GIMP's needs, as stated by Sven, to have nested undo groups. Each group would be a transaction, that can be redone/undone/repeated as a single entity. -- Rodrigo Moya <[EMAIL PROTECTED]> ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Undo framework
> Do you allow nested undo groups? This is rather important > if you want to compose actions from smaller actions and still allow > scripts or other higher levels to combine these into a single undo step. > We make heavy use of nested undo groups in GIMP. We allow one level of nesting, I can see your point about allowing deeper nesting though and will think about how it could be done. I suppose this is as much of the "merging" of actions that should take place, I don't see that the UndoManager itself should support automatic merging as each application has different requirements for when a merge should happen, but if we allow multiple nesting of actions then the applications can merge as they see fit. I can see the reason for the non-UI parts to go in GLib, but is there any precedence in having stuff like this in GLib? If it was to go in GLib it would be its own seperate library, which for one thing would kinda suck? As for transactional stuff, I would think that it seems overkill for most applications, although it'd be great if we could work out some way to allow those that want it to be able to implement it on top of the base system. I can't see how you could make it generic enough to make everyone happy. > Undo/Redo methods aren't sufficient. We've found it necessary to > differentiate Redo and Repeat sometimes. I'm not sure how repeat fits in here exactly, although maybe I'm not thinking of the same thing as you are. I'm thinking of GIMP's repeat filter functionality, and while its similar conceptually, I'm not sure why it is something that the undo manager should be taking care of? iain ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Undo framework
Jody Goldberg wrote: > On Fri, Sep 21, 2007 at 05:51:26PM +0100, Iain * wrote: >> Hi, >> >> I've had an undo framework in Marlin for years now, but recently >> people have been using it in other things (notably Ross in Tasks - ok, >> actually, he's the only one) and we discussed suggesting this for >> inclusion in GTK at some point in the future. QT4[1] and Cocoa[2] both >> have very similar frameworks. Attached are the header files. > > The concept sounds good, and while your implementation looks clean, > I'd rather not see it go into gtk in it's current form. > > 1) As you point out we've all had undo/redo implementations for >several years. If we're going to do this, let's skip a >generation and support transaction logging rather than just >picking a best of breed version of the existing code. >It's something I've been meaning to add to gnumeric [1] for >several years. The goal is to support a transaction file akin to >VIM's .swp. Doing this properly with permissioning for the >transact file isn't code that should get replicated in each app. I tend to agree, with the limited experience I had dealing with undo/redo in Gazpacho I found out that I strongly disliked the way of using commands. However I cannot heartily recommend a transaction based scheme since I only did a very simple prototype for applying GObject properties using transactions. It might end up way to complicated, perhaps someone with experience of implementing a transactional database could add something to this discussion. > 3) Gtk seems like the right place for widgets to display the >undo/redo stack. However, the core of the functionality seems >non-gui. Something that would belong wherever we chose to put >GDocument. To date that type of code has been migrating out of >gnumeric and into goffice. If there is interest, we could >collaborate on the next generation of this in there and rename to >'libgdocument' or somesuch. While I agree that an undo stack should be in Gtk+ or lower I'm not sure a transaction based should go there, but it should be possible to implement one top of the interfaces/manager objects there. I'm not sure we should talk about a 'document' there, there are many operations outside of documents which are undoable. Johan ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Undo framework
Hi, On Fri, 2007-09-21 at 17:51 +0100, Iain * wrote: > The basic concepts are that there is an UndoManager object. When you > start an operation that can be undone you call > undo_manger_context_begin and this returns a UndoContext. Each part of > your operation then creates an Undoable setting the functions that > undo, redo and destroy it and set some userdata which contains enough > information to undo/redo it. These Undoables are then added to the > UndoContext. When the operation is finished you call > undo_manager_context_end which adds the operation to the undo/redo > stack. This sounds similar to the undo system that we use in GIMP. I haven't looked at your code, but it appears to me that your system is somewhat less flexible. Do you allow nested undo groups? This is rather important if you want to compose actions from smaller actions and still allow scripts or other higher levels to combine these into a single undo step. We make heavy use of nested undo groups in GIMP. I am not trying to argue that the GIMP undo system would be suitable for use anywhere outside GIMP. But we might want to adopt a more general undo framework if it is provided by GLib/GTK+ and allows us to implement everything that our current undo system allows us to do. Sven ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Undo framework
On Fri, Sep 21, 2007 at 05:51:26PM +0100, Iain * wrote: > Hi, > > I've had an undo framework in Marlin for years now, but recently > people have been using it in other things (notably Ross in Tasks - ok, > actually, he's the only one) and we discussed suggesting this for > inclusion in GTK at some point in the future. QT4[1] and Cocoa[2] both > have very similar frameworks. Attached are the header files. The concept sounds good, and while your implementation looks clean, I'd rather not see it go into gtk in it's current form. 1) As you point out we've all had undo/redo implementations for several years. If we're going to do this, let's skip a generation and support transaction logging rather than just picking a best of breed version of the existing code. It's something I've been meaning to add to gnumeric [1] for several years. The goal is to support a transaction file akin to VIM's .swp. Doing this properly with permissioning for the transact file isn't code that should get replicated in each app. 2) Undo/Redo methods aren't sufficient. We've found it necessary to differentiate Redo and Repeat sometimes. In addition, having written dozens of these objects it feels like the design isn't quite right. There have many instances that required pre-validation. Code that is tightly coupled with the implementation, and should logically live in the same place. 3) Gtk seems like the right place for widgets to display the undo/redo stack. However, the core of the functionality seems non-gui. Something that would belong wherever we chose to put GDocument. To date that type of code has been migrating out of gnumeric and into goffice. If there is interest, we could collaborate on the next generation of this in there and rename to 'libgdocument' or somesuch. [1] http://svn.gnome.org/viewcvs/gnumeric/trunk/src/commands.c?view=markup ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Undo framework
Hi, On Fri, 2007-09-21 at 17:51 +0100, Iain * wrote: > I've had an undo framework in Marlin for years now, but recently > people have been using it in other things (notably Ross in Tasks - ok, > actually, he's the only one) and we discussed suggesting this for > inclusion in GTK at some point in the future. Please consider to add the basic parts to GLib. Otherwise applications with a strict separation of functionality and user interface will be unable to use your undo framework. The basics should go into GLib. UI code such as GtkActions built from undo objects can go into GTK+. Sven ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Undo framework
David Trowbridge wrote: > You might want to look at the undo implementation in Tomboy. It > implements the "mergeable command" idea fairly nicely. > Or look at GtkSourceView, or look for it in bugzilla, or look at bunch of other implementations (I am sure there are *plenty*, minimum two in every programming language). I don't know about tomboy's one, but what GtkSourceView has (or the patch in bugzilla, not too far from GtkSourceView's) are not flexible enough either. It just sucks when you want more, when you have textview where text may be modified by different entities without knowing about each other (plugins, that sort of stuff). Undo manager should allow merging and nesting. And ability to move groups/actions around. Please don't say "out of the scope", we already have bunch of undo implementations, so it's not just "let's have anything". On the other hand, of course, anything would do as a mean to undumbify gtk. If anyone's proposal has chances to get into gtk so I can press Ctrl-Z in xchat, I will vote for it with all my hands and legs even if I will continue using my own implementation in my entries and textviews. Not that my vote matters of course, I'd vote for my patch in that case :) Best regards, Yevgen ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Undo framework
You might want to look at the undo implementation in Tomboy. It implements the "mergeable command" idea fairly nicely. -David On 9/21/07, Iain * <[EMAIL PROTECTED]> wrote: > On 9/21/07, Yevgen Muntyan <[EMAIL PROTECTED]> wrote: > > > Another note, you need to be able to merge those undoables. > > For example, when you type in bunch of characters in an > > entry, you want to undo whole thing (e.g. entering a word, > > or sequence of inserted characters, whatever is more > > convenient), but the entry can't possibly know if something > > will be entered in advance, so simple > > "create context - add stuff - close context" won't do. > > Thats really up to the code using the undo manager to do, to work out > when an appropriate time to "add stuff" is. While it is outside of the > scope of the undo framework, it is perfectly within the scope of an > undoable entry, but that isn't really what i'm concerned with here > (plus, its more ross' domain as he wrote that stuff) > > iain > ___ > gtk-devel-list mailing list > gtk-devel-list@gnome.org > http://mail.gnome.org/mailman/listinfo/gtk-devel-list > ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Undo framework
On 9/21/07, Yevgen Muntyan <[EMAIL PROTECTED]> wrote: > Another note, you need to be able to merge those undoables. > For example, when you type in bunch of characters in an > entry, you want to undo whole thing (e.g. entering a word, > or sequence of inserted characters, whatever is more > convenient), but the entry can't possibly know if something > will be entered in advance, so simple > "create context - add stuff - close context" won't do. Thats really up to the code using the undo manager to do, to work out when an appropriate time to "add stuff" is. While it is outside of the scope of the undo framework, it is perfectly within the scope of an undoable entry, but that isn't really what i'm concerned with here (plus, its more ross' domain as he wrote that stuff) iain ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Undo framework
On 9/21/07, Tristan Van Berkom <[EMAIL PROTECTED]> wrote: > Should be noted here that from my particular experience, writing > code that is undoable (i.e. filling in the execute()/undo() routines > for a given undoable command) is far more challenging than writing > a framework that supports it - but it would be great if a common > framework could at least be shared. Defintely. > About GtkEntry... maybe it would be good to take a step back > and think MVC, GtkEntry usually effects some internal data in the > application - I'd much rather see built-in undoability implemented > in say, a GtkTextBuffer that might be viewed by multiple GtkEntries > or GtkTextViews... anyway just saying that usually you probably want > undo to effect the program's internal dataset, not the widgets that > are showing whatever happens to be current. Well, Ross and I discussed it. I think his use case is for in dialogs where the internal state of an object doesn't get changed until the dialog is closed, but wants to be able to allow the text entries to be undone in the meantime. The way it works in Cocoa is that entries are undoable until they lose focus. iain ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Undo framework
Please get it into gtk and make gtk suck less! Screw API, make it private if needed, just please please add undo to xchat's input entry. A side note, those basic concepts are implemented here and there hundred times. What would be nice to look at is actual usable code (e.g. in libegg). I.e. a real thing, not cocoa or qt docs. Another note, you need to be able to merge those undoables. For example, when you type in bunch of characters in an entry, you want to undo whole thing (e.g. entering a word, or sequence of inserted characters, whatever is more convenient), but the entry can't possibly know if something will be entered in advance, so simple "create context - add stuff - close context" won't do. Yevgen Iain * wrote: > Hi, > > I've had an undo framework in Marlin for years now, but recently > people have been using it in other things (notably Ross in Tasks - ok, > actually, he's the only one) and we discussed suggesting this for > inclusion in GTK at some point in the future. QT4[1] and Cocoa[2] both > have very similar frameworks. Attached are the header files. > > The basic concepts are that there is an UndoManager object. When you > start an operation that can be undone you call > undo_manger_context_begin and this returns a UndoContext. Each part of > your operation then creates an Undoable setting the functions that > undo, redo and destroy it and set some userdata which contains enough > information to undo/redo it. These Undoables are then added to the > UndoContext. When the operation is finished you call > undo_manager_context_end which adds the operation to the undo/redo > stack. > > The idea of having the smaller Undoables is to allow complex > operations to be built up from smaller ones. For example, in Marlin > muting a section of a sample is made up from a Delete and an Insert > Silence operation, but we want this to be presented to the user as a > single "Undo Mute Sample" operation rather than two: "Undo Insert > Silence" & "Undo Delete" > > Ross has also written GtkActions for Undo/Redo which hook into the > UndoManager and provide menu and toolbar actions that just Do The > Right Thing. The menus have "Undo 'Mute Sample'" and "Redo 'Mute > Sample'" and the text changes as appropriate. > > He has also written a GtkEntry subclass that has undo/redo > capabilities, and if/when this gets into GTK proper, we will hook it > into the GtkEntry/GtkTextView stuff as well. In these cases, each > widget would have its own UndoManager, so that the text entry changes > could be undone separatly from the main program's undo stack. > > We can add this to libegg until people play with it a bit more and > find the various issues, but its been in Marlin for 3 years and seems > to work, but all comments and thoughts are welcome. > > iain > > [1] http://doc.trolltech.com/4.2/qundo.html#undo-framework > [2] > http://developer.apple.com/documentation/Cocoa/Conceptual/UndoArchitecture/index.html > > > > /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ > /* > * Authors: Iain Holmes <[EMAIL PROTECTED]> > * > * Copyright 2002 - 2007 Iain Holmes > * > * This file is free software; you can redistribute it and/or > * modify it under the terms of version 2 of the GNU Library General Public > * License as published by the Free Software Foundation; > * > * This library is distributed in the hope that it will be useful, > * but WITHOUT ANY WARRANTY; without even the implied warranty of > * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > * Library General Public License for more details. > * > * You should have received a copy of the GNU Library General Public > * License along with this library; if not, write to the > * Free Software Foundation, Inc., 59 Temple Place - Suite 330, > * Boston, MA 02111-1307, USA. > * > */ > > #ifndef __EGG_UNDO_MANAGER_H__ > #define __EGG_UNDO_MANAGER_H__ > > #include > #include > > #include > > G_BEGIN_DECLS > > #define EGG_TYPE_UNDO_MANAGER (egg_undo_manager_get_type ()) > #define EGG_UNDO_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), > EGG_TYPE_UNDO_MANAGER, EggUndoManager)) > #define EGG_UNDO_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), > EGG_TYPE_UNDO_MANAGER, EggUndoManagerClass)) > #define EGG_IS_UNDO_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), > EGG_TYPE_UNDO_MANAGER)) > #define EGG_IS_UNDO_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), > EGG_TYPE_UNDO_MANAGER)) > #define EGG_UNDO_MANAGER_GET_CLASS(obj)
Re: Undo framework
On Fri, 2007-09-21 at 17:51 +0100, Iain * wrote: > Hi, > > I've had an undo framework in Marlin for years now, but recently > people have been using it in other things (notably Ross in Tasks - ok, > actually, he's the only one) and we discussed suggesting this for > inclusion in GTK at some point in the future. QT4[1] and Cocoa[2] both > have very similar frameworks. Attached are the header files. Hi, I think that would be a great thing to add to gtk+ if only to encourage software authors to write undoable code - the brief description of the framework pretty much matches the implementation in glade to the letter (we started out with "command" objects which had undo/redo capabilities... and then found that we needed them to be somewhat recursive, allowing you to group low-level commands together into more powerful highlevel commands). Should be noted here that from my particular experience, writing code that is undoable (i.e. filling in the execute()/undo() routines for a given undoable command) is far more challenging than writing a framework that supports it - but it would be great if a common framework could at least be shared. About GtkEntry... maybe it would be good to take a step back and think MVC, GtkEntry usually effects some internal data in the application - I'd much rather see built-in undoability implemented in say, a GtkTextBuffer that might be viewed by multiple GtkEntries or GtkTextViews... anyway just saying that usually you probably want undo to effect the program's internal dataset, not the widgets that are showing whatever happens to be current. Cheers, -Tristan ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Undo framework
On Fri, 2007-09-21 at 17:51 +0100, Iain * wrote: > I've had an undo framework in Marlin for years now, but recently > people have been using it in other things (notably Ross in Tasks - ok, > actually, he's the only one) and we discussed suggesting this for > inclusion in GTK at some point in the future. QT4[1] and Cocoa[2] both > have very similar frameworks. Attached are the header files. This is, erm, an entirely different Ross Burton, and I think that this should be added to GTK+. I for one will use it in my application, Tosks. Ross -- Ross Burton mail: [EMAIL PROTECTED] jabber: [EMAIL PROTECTED] www: http://www.burtonini.com./ PGP Fingerprint: 1A21 F5B0 D8D0 CFE3 81D4 E25A 2D09 E447 D0B4 33DF signature.asc Description: This is a digitally signed message part ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Undo framework
Hi, I've had an undo framework in Marlin for years now, but recently people have been using it in other things (notably Ross in Tasks - ok, actually, he's the only one) and we discussed suggesting this for inclusion in GTK at some point in the future. QT4[1] and Cocoa[2] both have very similar frameworks. Attached are the header files. The basic concepts are that there is an UndoManager object. When you start an operation that can be undone you call undo_manger_context_begin and this returns a UndoContext. Each part of your operation then creates an Undoable setting the functions that undo, redo and destroy it and set some userdata which contains enough information to undo/redo it. These Undoables are then added to the UndoContext. When the operation is finished you call undo_manager_context_end which adds the operation to the undo/redo stack. The idea of having the smaller Undoables is to allow complex operations to be built up from smaller ones. For example, in Marlin muting a section of a sample is made up from a Delete and an Insert Silence operation, but we want this to be presented to the user as a single "Undo Mute Sample" operation rather than two: "Undo Insert Silence" & "Undo Delete" Ross has also written GtkActions for Undo/Redo which hook into the UndoManager and provide menu and toolbar actions that just Do The Right Thing. The menus have "Undo 'Mute Sample'" and "Redo 'Mute Sample'" and the text changes as appropriate. He has also written a GtkEntry subclass that has undo/redo capabilities, and if/when this gets into GTK proper, we will hook it into the GtkEntry/GtkTextView stuff as well. In these cases, each widget would have its own UndoManager, so that the text entry changes could be undone separatly from the main program's undo stack. We can add this to libegg until people play with it a bit more and find the various issues, but its been in Marlin for 3 years and seems to work, but all comments and thoughts are welcome. iain [1] http://doc.trolltech.com/4.2/qundo.html#undo-framework [2] http://developer.apple.com/documentation/Cocoa/Conceptual/UndoArchitecture/index.html /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * Authors: Iain Holmes <[EMAIL PROTECTED]> * * Copyright 2002 - 2007 Iain Holmes * * This file is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU Library General Public * License as published by the Free Software Foundation; * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * */ #ifndef __EGG_UNDO_MANAGER_H__ #define __EGG_UNDO_MANAGER_H__ #include #include #include G_BEGIN_DECLS #define EGG_TYPE_UNDO_MANAGER (egg_undo_manager_get_type ()) #define EGG_UNDO_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_UNDO_MANAGER, EggUndoManager)) #define EGG_UNDO_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_UNDO_MANAGER, EggUndoManagerClass)) #define EGG_IS_UNDO_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_UNDO_MANAGER)) #define EGG_IS_UNDO_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_UNDO_MANAGER)) #define EGG_UNDO_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_UNDO_MANAGER, EggUndoManagerClass)) typedef struct _EggUndoContext EggUndoContext; typedef struct _EggUndoHistory { char *name; char *info; gboolean current; /* Is this the position we are at in the history */ EggUndoContext *ctxt; } EggUndoHistory; typedef struct _EggUndoManager EggUndoManager; typedef struct _EggUndoManagerClass EggUndoManagerClass; struct _EggUndoManager { GObject object; }; struct _EggUndoManagerClass { GObjectClass parent_class; void (*changed) (EggUndoManager *manager); }; GType egg_undo_manager_get_type (void); EggUndoManager *egg_undo_manager_new (guint size); gboolean egg_undo_manager_can_undo (EggUndoManager *manager); gboolean egg_undo_manager_can_redo (EggUndoManager *manager); EggUndoContext *egg_undo_manager_context_begin (EggUndoManager *manager, const char *name); void egg_undo_manager_context_end (EggUndoManager *manager, EggUndoContext *ctxt); void egg_undo_manager_context_cancel (EggUndoManager *manager, EggUndoContext *ctxt); void egg_undo_context_add (EggUndoContext *context, EggUndoable *undoable); const char *egg_undo_manager_get_undo_name (EggUndoManager *manager); const char *egg_undo_manager_get_redo_name (EggUndoManag