Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Request: Undo/Redo Ability #370

Closed
marker5a opened this issue May 24, 2017 · 7 comments
Closed

Request: Undo/Redo Ability #370

marker5a opened this issue May 24, 2017 · 7 comments

Comments

@marker5a
Copy link
Contributor

As a user, when formulating recipes, it can be easy to to accidentally make a change to a recipe unintentionally. At the moment, there is no good way, that I can see, to undo or redo the change. When I make a mistake to a recipe, I generally use the clunkier approach of just restarting the program and risk losing unsaved changes to the recipe.

It seems that it might be nice to track changes made in a stack (or stacks for redo and undo) datatype and store "transactions" in these LIFO buffers. This is a potentially larger task as it would require user actions to be distilled into a transactional datatype to be placed in the LIFO.

Any ideas or suggestions? I'd like to work on this task, but would like to get some feedback from users as to the feasibility and/or how useful this would even be to other users.

@speshak
Copy link
Contributor

speshak commented May 28, 2017

I'm not sure how feasible it is to use, but QT5 does have an undo framework that might be worth looking at: http://doc.qt.io/qt-5/qundo.html

@marker5a
Copy link
Contributor Author

I like that idea of not having to build a new datatype... would be much nicer to use the built in framework for the heavy lifting. I need to dig into it further to understand the scope of what it can do, but it sounds promising!

In any case, I'm still going through the code to find a common way to handle different transactions. For instance, removing an item from the Fermentables table is a different type of operation than changing the name of a recipe. One thought I have is to fill up the stack (or QUndo) with callback functions to undo the task. Along with this would be a set of argument for the callback to perform it's function.

For instance, deleting a row in the fermentables table would push to the stack a callback for adding a fermentable with the arguments that would be needed to complete that transaction identically. Same would go for if someone renamed a recipe... you would just push a callback pointer to changing the recipe name and it's argument would be the old recipe name.

@matty0ung
Copy link
Contributor

FYI I am working on an implementation of this, using the QT5 undo framework as suggested above. I have simple cases working (edit a value). Adding/removing fermentables etc will be a bit more fun, but should be doable.

@matty0ung
Copy link
Contributor

Making progress on this. I have undo/redo pretty much working for adding/removing ingredients, which turned out to require touching a lot of different places in the codebase. Need to check a few edge cases and tidy up a couple of things but hope to have a pull request in the not too distant future.

@mikfire
Copy link
Contributor

mikfire commented Nov 23, 2020

Just out of curiosity, have you tested this against postgres as well? Since I am the only person who likely uses it, "No" is a perfectly acceptable answer.

@matty0ung
Copy link
Contributor

I haven't explicitly tested it with postgres, but I would be very hopeful that it would work fine. Rather than poke the database directly, I've tried to do things via the object model - eg undoable actions pass through MainWindow (which has the Undo/Redo controls), then MainWindow asks, say, the Recipe to add or remove a specific Fermentable, and then let Recipe make the necessary requests to the Database class.

@matty0ung
Copy link
Contributor

OK, I now have a pull request for the implementation of this: #499 This is extensive (but not, I hope, any more complicated than it needs to be!) because (a) we have to touch every place in the code that makes a change the user would want to be able to undo/redo and (b) being able to undo/redo add and remove in a clean way required some light refactoring of the current functions - partly because when we say 'add' what's often really happening under the covers is 'copy and then add'.

@mikfire Would greatly appreciate feedback and code review as and when you have time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants