Implementing Undo feature (like Ctrl+Z) in Qt/C++ - c++

I am using Qt 4.5 and C++ on Windows XP.
Basically I will be having an UI where the user will enter some data. He can go and modify the values available in the UI. The UI will have basic Qt UI elements like QLineEdit,QTableWidget etc.,
So now, if the user presses Undo button (or Ctrl+Z) the previous value should be retained in the corresponding UI element.
Say, if there is QLineEdit with the text 25. Now the user modifies to 30. Now by clicking Undo, the older value 25 should be retained.
Like the Undo feature that usually available in many applications. Is there any way to do it?

You could use Qt's undo framework.

The typical way of implementing Undo is to represent each action done by the user, and store them. You also want the ability to compute the inverse of a given action.
So, for an insert into a text buffer, the action would store the text inserted, and the location at which the insert happened. The inverse then becomes a delete, at the same location and with the size of the inserted text.
When the user asks the application to undo, simply look at the most recent stored action, and execute its inverse. If you now instead of deleting the "spent" action remember it, too, you can implement Redo by moving the other way in the history of actions.
Note that this is an abstract and generic explanation; as other answers point out, Qt has a framwork in place for implementing Undo already, so you should of course investigate that, first.

You could use the Command Pattern to realize undo/redo

QLineEdit has a built-in undo/redo support, exported as public slots, check : http://doc.trolltech.com/4.7/qlineedit.html#undo

Related

WXWidgets TextCtrl or RichTextCtrl

I'm using wxWidgets for a log window of a piece of software which runs for many hours. The log can accumulate 10,000's of entries. Does the community have a suggestion for how not to have the GUI thread choke for many seconds when updating a textctrl or richtextctrl with this many lines? I'm open to using either control type but richtext is preferable to I can highlight warnings or errors.
It's currently set to readonly, so undo, redo, paste, etc are not active. I'm currently freezing and thawing it before and after adding content.
In a test case, I add 10000 lines to the text control with a freeze and thaw before and after. This operation still takes over a minute. Are these text controls simply incapable of handling long content?
Assuming your display is like a log, where each "line" is it's own entry, try using the wxListCtrl in "virtual mode". Basically, you maintain the data in your own control (a vector, array, whatever works) and the control asks you for only the data that is currently visible.
Inherit wxListCtrl with your own class and implement OnGetItem. When a row is visible, your derived control will have this method called for each row (and each column if you implement multiple columns) and you provide it with the data for that row, accessed directly from your array (list, vector, whatever).
More information is available in the wxWidgets docs here: http://docs.wxwidgets.org/3.0/classwx_list_ctrl.html#a92370967f97215e6068326645ee76624
The suggestion to use wxListCtrl in #avariant answer is a good one, however a wxTextCtrl with wxTE_RICH style should still be capable of appending 10000 lines in well less than a minute if you freeze/thaw it before/after. I'd be curious to know if you can reproduce the problem in the text sample included with wxWidgets (which already has a menu item doing something like this) and, if so, which wxWidgets port do you use.

Command pattern for undo/redo: when to NOT merge undo commands?

I'm implementing an undo/redo feature in our graphical Qt5-based app, using QUndoCommands which have a nice mergeWith() feature: for example, if the user repeatedly clicks the font size increase button on my app, rather than creating a ton of commands in the undo list, it just updates one command on the QUndoStack. So a single undo will go back to the original font size.
That's great, but there are times I don't want to automatically merge commands. For example, if I drag an item to a new location and drop it there, then drag the same item to another location: my app should create 2 move commands, not merge them both into one command.
So, here's a list of events that I think create a logical break, where the user will expect a command NOT to be merged with the next command, even if the next command changes the same property of the same object:
mouse release
widget lose focus
timer (after ??? seconds)
text typing, after ??? characters (or this can be handled with the timer?)
text typing, after certain keys are pressed, such as backspace?
As indicated by the question marks in my list, I'm not really sure in what situations to suppress merging commands. So my question is, are there any best practices in this regard? Where can I find them?
FWIW, I did not find any best practices, but for my software I suppressed merges on focus change (which in my app also occurs on mouse release on the graphics part). Additionally, for typing, I suppress merges if the input position changes in a way other that as expected for deleting or typing 1 character, and if the user switches between deleting characters and typing characters.
I did not bother with the timer, or with maximum characters when typing.

C++ MFC - CTreeCtrl - Difference between SelectItem and SetItemState

I need to create a Tree List for my windows application, with multiple selection of nodes with drag-and-drop support. Since Microsoft doesn't provide any such property for the tree which eases the work of the developer, I have to implement this features on my own.
Can somebody explain me the differences (also, the corresponding getters for the following statements) and when to use
SetItemState(hItem, 1, TVIS_SELECTED);
and
SelectItem(hItem);
and
SetItemState(hItem, TVIS_SELECTED, TVIS_SELECTED);
The primary difference is that SelectItem is functionally built off of SetItemState. Along with anything else it does, SelectItem will use SetItemState (or equivalent internal calls) to set TVIS_SELECTED for the new item, and, say, remove it from the previously selected item.
In order to implement your own multiple-selection control, you have to prevent SelectItem from being called when you want to augment the selection instead of replacing it. There are a lot of cases to consider, ranging from mouse clicks with various modifier keys held to keyboard navigation, so good luck in your implementation!

PopUp Menus in a custom GUI API?

I have made my own GUI API for games. One assumption that must be made is the user may want to use a derived version of a Widget I have made.
An example of how I dealt with this with ToolTips is, the user allocates a new ToolTip and sets a global one for the GUI. Ex: getGui().setToolTip(customToolTip);
The GUI then calls toolTip->show() when necessary. The problem with menus in general is that you can have many of them appearing at a given time.
I also would hate to have the user implement an interface:
PopUpFactory::createPopUp()
PopUpFactory::destroyPopup()
How is this usually dealt with? Who or how is the memory also managed for these?
There is always the option of limiting to something like 9 nested menus and have the user set an array of 9 PopUps but that seems messy.
Thanks

Unlimited number of checkboxes

I wonder how to create mechanism which create new checkbox below previous when you click on button. Number of checkboxes are unlimited.
I don't think that table of objects work well, so I think about implementation in list of objects.
Any suggestions?
Here is what I would do:
Create an event for clicking that button (let's call it OnBtnClick)
Use a vector/list to hold all the checkboxes
When OnBtnClick is called you do:
create a checkbox with the desired position and size and make sure it receives an unique id (this will help you differentiate between checkboxes when they are clicked/checked/etc).
add the checkbox to the list (to get its status: checked or not checked)
add the checkbox to the desired window, the parent window (though this may happen automatically when you create it)
if you want to add an event for the added checkbox you should check the manual of your GUI framework (you will probably use the same event handler for all checkboxes and treat them separately based on their id)
Depending on the GUI framework used the bottom details may vary but the idea remains the same. I did this with wxWidgets, QT and MFC but I don't know which framework you use. You should be able to find code samples for each framework.
What would you do with unlimited number of check boxes - confuse the user? So, that he/she wouldn't attempt to use it again? Bad idea, as you can guess now.
You may (should) limit the number of check boxes (or better, limit the number of controls on form/dialog). IMO, more than 10-12 CBs would be cumbersome for the end user. Therefore, better idea is to have all of them on dialog/dialog-resource, and make all of them invisible/disabled. When user does some action, make them visible/enabled - so that end user may do something with it.
Still demand N number of CBs, where N is not determined beforehand? Then you may have checkboxes under Combo box, or use check-boxes under List Control. List Control already hosts this feature, but for CBs under Combo, you may need to write your own class.See this article as an example.