Cancel edit in QTableView when delegate loses focus - c++

I am using a basic QTableView + QAbstractTableModel architecture.
Data can be edited via a QAbstractItemDelegate subclass. Everything works as expected but I need to slightly change the editing behaviour:
Qt default behaviour is:
For an open delegate editor, hitting Enter confirms the edit
For an open delegate editor, hitting Escape cancels the edit
For an open delegate editor, clicking in a different table view cell confirms the edit
I want to get rid of the last one. If the delegate editor loses focus, the edit shall be canceled (i. e. it shall not emit editingFinished()) so that a user can only submit changes by pressing Enter.
Is there a convenient way to do this?
Thanks in advance

Override the class, find out which function that last behaviour is that you dont want, then override that function and just leave the implementation of it empty, then it gets called just as it would usually but now it does nothing (or does something else, you're programming it make it do whatever you want)

I would override the QAbstractItemModel::setData() in your model and skip emitting dataChanged() on attempt to set the same data as it is already existing for the given item.

Related

Locking selection in QTableView/QTreeView

Is it possible to "lock" selection in QAbstractView?
I have a form with:
A list of objects I can edit (QTableView).Objects are stored in a database, the list shows their ID.
A New button, whose effect is to append an empty row I can edit to create a new ID and enable controls in the rest of the form.
An Edit button whose effect is to enable the edition of the rest of the form, but leaves the ID non editable.
Everything is driven by a state machine. There are parallel states but for the sake of this question, only transition between a Viewing state and an Editing state is relevant. Clicking either button enters the Editing state, which means testing if I am in the Editing state provides no information about whether I clicked on New or on Edit.
I am trying to lock the selection when entering the Editing state.
I cannot simply disable the view because I need to edit new IDs, I cannot connect a slot to the selectionChanged signal to restore the selection because of side effects (calls to the database + focus going all over the place), and if possible, I wish to avoid having to call QAbstractItemView::setSelectionModel (it is reset by QAbstractItemView::setModel, see below) and wish to drive this behavior thanks only to the Viewing and Editing states.
I have tried to use, but to no avail:
QAbstractItemModel::flags (the best I can do is prevent selecting another item but not clearing the selection.)
QAbstractItemView::selectionMode
QItemSelectionModel::select, with QItemSelectionModel::SelectionFlag::NoUpdate (The description of this enum value made me think it could block the next selection change but that is not the case).
Subclassing QItemSelectionModel (#chehrlic's comment below) to override all the virtual public slots.While it does work (a property can be used to stop the selection from changing), it is a pain that QAbstractItemView::setModel creates a new model. It does work now but I do not see any easy way to prevent the code from breaking after accumulating code changes over the span of several years.
Did I miss any existing property to achieve this? And if I did not, how can I implement a property to lock the selection but no have any other effect on my view?
At this point, the last item in the above list of things I tried does do the job but it has a downside I am trying to avoid.
This is similar to this question except it was for a now old version of Qt and the answer is not very satisfying anyway.

Updating CPropertyPage on tab selection

I am looking for the best way to update a CPropertyPage once it is clicked. Currently, my pages receive it's information during OnInitDialog(). However, when the user does something on page one, it can effect what is on page two.
The only solution I can think to use is an "Update" button. Once the button is clicked, the page refreshes its information by calling the same functions that take place during OnInitDialog(). Is there an event that occurs when the user clicks on a different CPropertyPage of a CPropertySheet?
Using an "Update" button is poor design because it requires the user to force the update. Instead, you should look to maintain the state of the values that could cause the update. This can be done in a structure or class object that can then be made accessible to CPropertyPage::OnSetActive of the page that needs the updated values. OnSetActive is called just before the page is to be made the active one. It's your opportunity to update values on the page before it displays.

Get text prior to edit from inside QLineEdit::textEdited()

When I receive a QLineEdit::textEdited() signal, can I see what the text was prior to the edit? I need to compare the text as it was prior to the edit and the text after the edit.
The textEdited() signal has only one argument, which is the new text. Calling QLineEdit::text() also returns the new text.
Right now I can only think of is holding the old text in a QString, and updating that QString each time there is an edit, but then I need to account for programmatic changes (made via QLineEdit::setText()).
Or is there another way to intercept a text change (via validators perhaps) that would allow me to get the text prior to change and after change simultaneously? Preferably for user-changes only (non programmatic).
Right now I can only think of is holding the old text in a QString, and updating that QString each time there is an edit, but then I need to account for programmatic changes (made via QLineEdit::setText())
Granted, I can also only think of that way, but please note that unlike textEdited(), textChanged() would allow you to even catch the programmatic changes as per documentation:
Unlike textChanged(), this signal is not emitted when the text is changed programmatically, for example, by calling setText().

custom combobox win32

I am trying to implement an auto-suggest feature in an win32 combobox (C++). I want to achieve a behaviour that is similar to the google auto suggest function. When the user types something into the edit-control of the combobox, its listbox opens and shows all possible matches. The Problem is the default behaviour of a win32 combobox is to always select the closest match and put the complete text (selected) into the edit control when the list is opened. I need to avoid this behaviour. The list should just open - dont select something and dont change the text in the edit-control!
I have tried to subclass the combobox and catch the CBN_DROPDOWN message, but this changes nothing on the default behavior.
Does anyone have a further idea? I dont want the auto-complete feature that just completes the text in the edit-control without opening the list.
Thx in advance
Greets, Michael

How to implement CEditListCtrl

How to implement CEditListCtrl?. List control with edit capabality (Report/Grid view).
I have a list view in Report View. It has some values. I need to extend this to edit the values present in the list view.
I declared a class which inherits from CListCtrl. And I have handled the two Window messages to start and end the edit. Upon getting the messages I am displaying a Text box. But I am not getting the control inside these message handlers. Is there a way to know the reason?
Or Is there a other way to implement this.
There are some neat grid controls on Code Project which might help:
http://www.codeproject.com/KB/miscctrl/gridctrl.aspx
http://www.codeproject.com/KB/library/gridprojects.aspx
http://www.codeproject.com/KB/MFC/UltimateGrid.aspx
Thanks for all answers
I have done it easily.
I have handled the WM_LBUTTONDOWN. This handler pops up the edit box to get the new
value for the field
Handled LVN_ENDLABELEDIT to know the end of update.
After receiving the above message, updated the values.
“One thing I forgotten was to set the flag in the resource view for CListCtrl (Edit Labels to TRUE)”
We have to implement OnPaint() (in CListCtrl's derived class) also otherwise the UI won't update properly
You need to use a CComboBox which is basically a combined CEdit and CListCtrl
This question was also asked here:
How to edit columns in-place with CListCtrl?
You can read my answer on that page.