13.3.1.  Standard or Abstract?

[ fromfile: tablemodels.xml id: standardorabstract ]

Example 13.10. src/modelview/shortcutmodel-standarditem/actiontableeditor.h

[ . . . . ]
class ActionTableEditor : public QDialog {
    Q_OBJECT
public:
    ActionTableEditor(QWidget* parent = 0);
    ~ActionTableEditor();
protected slots:
    void on_m_tableView_activated(const QModelIndex& idx=QModelIndex());
    QList<QStandardItem*> createActionRow(QAction* a);
protected:
    void populateTable();
    void changeEvent(QEvent* e);
private:
    QList<QAction*> m_actions;
    QStandardItemModel* m_model;
    Ui_ActionTableEditor* m_ui;
};
[ . . . . ]

Example 13.11. src/modelview/shortcutmodel-standarditem/actiontableeditor_ui.h

[ . . . . ]
class Ui_ActionTableEditor
{
public:
  QVBoxLayout *verticalLayout;
  QTableView *m_tableView;
  QSpacerItem *verticalSpacer;
  QDialogButtonBox *m_buttonBox;

  void setupUi(QDialog *ActionTableEditor)
  {
    if (ActionTableEditor->objectName().isEmpty())
      ActionTableEditor->setObjectName(QString::
                                       fromUtf8("ActionTableEditor"));
    ActionTableEditor->resize(348, 302);
    verticalLayout = new QVBoxLayout(ActionTableEditor);
    verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
    m_tableView = new QTableView(ActionTableEditor);
    m_tableView->setObjectName(QString::fromUtf8("m_tableView"));
    verticalLayout->addWidget(m_tableView);
[ . . . . ]

Example 13.12. src/modelview/shortcutmodel-standarditem/actiontableeditor.cpp

[ . . . . ]

QList<QStandardItem*> ActionTableEditor::
createActionRow(QAction* a) {
    QList<QStandardItem*> row;
    QStandardItem* actionItem = new QStandardItem(a->text());
    QStandardItem* shortcutItem = 
        new QStandardItem(a->shortcut().toString());                1
    actionItem->setIcon(a->icon());                                 2
          
    actionItem->setToolTip(a->toolTip());                           3
    actionItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); 4
    shortcutItem->setFlags(Qt::ItemIsSelectable| Qt::ItemIsEnabled);
    shortcutItem->setIcon(a->icon());                               5
    row << actionItem << shortcutItem;
    return row;
}

void ActionTableEditor::populateTable() {
    foreach (QWidget* w, qApp->topLevelWidgets())                   6
        foreach (QAction* a, w->findChildren<QAction*>()) {         7            
            if (a->children().size() > 0) continue;                 8
            if (a->text().size() > 0) m_actions << a;
        }

    int rows = m_actions.size();
    m_model = new QStandardItemModel(this);
    m_model->setColumnCount(2);
    m_model->setHeaderData(0, Qt::Horizontal, QString("Action"),
                           Qt::DisplayRole);
    m_model->setHeaderData(1, Qt::Horizontal, QString("Shortcut"),
                           Qt::DisplayRole);
    QHeaderView* hv = m_ui->m_tableView->horizontalHeader();
    m_ui->m_tableView->
       setSelectionBehavior(QAbstractItemView::SelectRows);
    m_ui->m_tableView->
       setSelectionMode(QAbstractItemView::NoSelection);
    hv->setResizeMode(QHeaderView::ResizeToContents);
    hv->setStretchLastSection(true);
    m_ui->m_tableView->verticalHeader()->hide();
    for (int row=0; row < rows; ++row ) {
        m_model->appendRow(createActionRow(m_actions[row]));
    }
    m_ui->m_tableView->setModel(m_model);                           9
}

1

Duplicating data from QAction to QStandardItem.

2

More duplicate data.

3

More duplicate data.

4

Read-only model without Qt::ItemIsEditable.

5

More duplicate data.

6

All top level widgets.

7

All QActions that can be found.

8

Skip groups of actions.

9

Connect the view to its model.


Example 13.13. src/modelview/shortcutmodel-standarditem/actiontableeditor.cpp

[ . . . . ]

void ActionTableEditor::
on_m_tableView_activated(const QModelIndex& idx) {
    int row = idx.row();
    QAction* action = m_actions.at(row);
    ActionEditorDialog aed(action);
    int result = aed.exec();                        1
    if (result ==  QDialog::Accepted) {             2
        action->setShortcut(aed.keySequence());     3
        m_ui->m_tableView->reset();
    }
}

1

Pop up modal dialog for editing an action's shortcut.

2

This would be a good place to check for duplicate/ambiguous bindings.

3

Skip the model and set the QAction property directly.


A better approach...

Example 13.14. src/libs/actioneditor/actiontablemodel.h

[ . . . . ]
class ACTIONEDITOR_EXPORT ActionTableModel : public QAbstractTableModel {
    Q_OBJECT
 public:
    explicit ActionTableModel(QList<QAction*> actions, QObject* parent=0);
    int rowCount(const QModelIndex&  = QModelIndex()) const {
        return m_actions.size();
    }
    int columnCount(const QModelIndex& = QModelIndex()) const {
        return m_columns;
    }
    QAction* action(int row) const;
    
    QVariant headerData(int section, Qt::Orientation orientation,   1
        int role) const;  
    QVariant data(const QModelIndex& index, int role) const;        2
    Qt::ItemFlags flags(const QModelIndex& index) const;            3
    bool setData(const QModelIndex& index, const QVariant& value, 
        int role = Qt::EditRole);                                   4
    
 protected:
    QList<QAction*> m_actions;
    int m_columns;
};
[ . . . . ]

1

Optional override.

2

Required override.

3

required override.

4

Required for an editable model.


Example 13.15. src/libs/actioneditor/actiontablemodel.cpp

[ . . . . ]

QVariant ActionTableModel::
data(const QModelIndex& index, int role) const {
    int row = index.row();
    if (row >= m_actions.size()) return QVariant();
    int col = index.column();
    if (col >= columnCount()) return QVariant();
    if (role == Qt::DecorationRole)  
        if (col == 0)
            return m_actions[row]->icon();
    
    if (role == Qt::ToolTipRole) {
        return m_actions[row]->toolTip();
    }
    if (role == Qt::StatusTipRole) {
        return m_actions[row]->statusTip();
    }
    if (role == Qt::DisplayRole) {
        if (col == 1) return m_actions[row]->shortcut();
        if (col == 2) return m_actions[row]->parent()->objectName();
        else return m_actions[row]->text();
    }
    return QVariant();
}