[ fromfile: tablemodels.xml id: editablemodels ]
For editable models, you must override flags()
and setData()
.
If you want in-place editing (in the actual View), you would return Qt::ItemIsEditable
from flags()
.
Because we still pop up an ActionEditorDialog when an Item is clicked, we do not need in-place editing here and so Example 13.16 simply returns Qt::ItemIsEnabled
.
Example 13.16. src/libs/actioneditor/actiontablemodel.cpp
[ . . . . ] Qt::ItemFlags ActionTableModel:: flags(const QModelIndex& index) const { if (index.isValid()) return Qt::ItemIsEnabled; else return 0; }
<include segid="flags" mode="cpp" href="src/libs/actioneditor/actiontablemodel.cpp" id="actiontablemodel-flags-cpp" src="src/libs/actioneditor/actiontablemodel.cpp"/>
Example 13.17 shows how, in setData()
, you can check for ambiguous shortcuts before actually setting new values.
After the data is changed, it is important to emit a dataChanged()
signal so that views that may be showing old data know it is time to fetch newer data from the model.
Example 13.17. src/libs/actioneditor/actiontablemodel.cpp
[ . . . . ] bool ActionTableModel:: setData(const QModelIndex& index, const QVariant& value, int role) { if (role != Qt::EditRole) return false; int row = index.row(); if ((row < 0) | (row >= m_actions.size())) return false; QString str = value.toString(); QKeySequence ks(str); QAction* previousAction = 0; if (ks != QKeySequence() ) foreach (QAction* act, m_actions) { if (act->shortcut() == ks) { previousAction = act; break; } } if (previousAction != 0) { QString error = tr("%1 is already bound to %2."). arg(ks.toString()).arg(previousAction->text()); bool answer = QMessageBox::question(0, error, tr("%1\n Remove previous binding?").arg(error), QMessageBox::Yes, QMessageBox::No); if (!answer) return false; previousAction->setShortcut(QKeySequence()); } m_actions[row]->setShortcut(ks); QModelIndex changedIdx = createIndex(row, 1); emit dataChanged(changedIdx, changedIdx); return true; }
<include segid="setdata" mode="cpp" href="src/libs/actioneditor/actiontablemodel.cpp" id="actiontablemodel-setdata-cpp" src="src/libs/actioneditor/actiontablemodel.cpp"/>
To support inserting/removing rows, there are analogous signals, rowsInserted()
and rowsRemoved()
that we must emit from our implementations of insertRows()
/removeRows()
.
After 1 or more shortcuts have been changed, we save them to QSettings. Example 13.18 shows how to keep track of the modified QActions that need to be saved.
Example 13.18. src/libs/actioneditor/actiontableeditor.cpp
[ . . . . ] void ActionTableEditor:: on_m_tableView_activated(const QModelIndex& idx) { int row = idx.row(); QAction* action = m_model->action(row); ActionEditorDialog aed(action); int result = aed.exec(); if (result == QDialog::Accepted) { QKeySequence ks = aed.keySequence(); m_model->setData(idx, ks.toString()); m_changedActions << action; } }
<include segid="dialog" mode="cpp" href="src/libs/actioneditor/actiontableeditor.cpp" id="actioneditordialog-cpp" src="src/libs/actioneditor/actiontableeditor.cpp"/>
Example 13.19 shows how those shortcuts are saved to QSettings, but only if the user accept
s the dialog.
Example 13.19. src/libs/actioneditor/actiontableeditor.cpp
[ . . . . ] void ActionTableEditor::accept() { QSettings s; s.beginGroup("shortcut"); foreach (QAction* act, m_changedActions) { s.setValue(act->text(), act->shortcut() ); } s.endGroup(); QDialog::accept(); }
<include segid="settings" mode="cpp" href="src/libs/actioneditor/actiontableeditor.cpp" id="actioneditor-savesettings-cpp" src="src/libs/actioneditor/actiontableeditor.cpp"/>
Generated: 2012-03-02 | © 2012 Alan Ezust and Paul Ezust. |