Wed, 26 Dec 2018 23:01:45 +0200
reimplented shortcuts in the config dialog using model/view programming
--- a/CMakeLists.txt Wed Dec 26 16:38:38 2018 +0200 +++ b/CMakeLists.txt Wed Dec 26 23:01:45 2018 +0200 @@ -69,6 +69,7 @@ src/dialogs/externalprogrampathdialog.cpp src/dialogs/generateprimitivedialog.cpp src/dialogs/ldrawpathdialog.cpp + src/dialogs/shortcutsmodel.cpp src/dialogs/subfilereferenceeditor.cpp src/dialogs/newpartdialog.cpp src/editmodes/abstractEditMode.cpp @@ -101,6 +102,7 @@ src/widgets/circularsectioneditor.cpp src/widgets/colorbutton.cpp src/widgets/doublespinbox.cpp + src/widgets/extendedkeysequenceeditor.cpp src/widgets/headeredit.cpp src/widgets/matrixeditor.cpp src/widgets/vertexobjecteditor.cpp @@ -145,6 +147,7 @@ src/dialogs/generateprimitivedialog.h src/dialogs/ldrawpathdialog.h src/dialogs/newpartdialog.h + src/dialogs/shortcutsmodel.h src/dialogs/subfilereferenceeditor.h src/editmodes/abstractEditMode.h src/editmodes/circleMode.h @@ -185,6 +188,7 @@ src/widgets/circularsectioneditor.h src/widgets/colorbutton.h src/widgets/doublespinbox.h + src/widgets/extendedkeysequenceeditor.h src/widgets/headeredit.h src/widgets/matrixeditor.h src/widgets/vertexobjecteditor.h
--- a/src/basics.h Wed Dec 26 16:38:38 2018 +0200 +++ b/src/basics.h Wed Dec 26 23:01:45 2018 +0200 @@ -104,6 +104,9 @@ matrix(2, 3) += vector.z(); } +template<typename... Ts> +inline void ignore(Ts&&...) {} + qreal determinant(qreal a, qreal b, qreal c, qreal d); qreal determinant(qreal a, qreal b, qreal c, qreal d, qreal e, qreal f, qreal g, qreal h, qreal i); qreal determinant(const QMatrix2x2& matrix);
--- a/src/dialogs/configdialog.cpp Wed Dec 26 16:38:38 2018 +0200 +++ b/src/dialogs/configdialog.cpp Wed Dec 26 23:01:45 2018 +0200 @@ -14,10 +14,6 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. - * ===================================================================== - * - * configDialog.cxx: Settings dialog and everything related to it. - * Actual configuration core is in config.cxx. */ #include <QGridLayout> @@ -47,38 +43,19 @@ #endif "All files (*.*)(*.*)"; -ShortcutListItem::ShortcutListItem (QListWidget* view, int type) : - QListWidgetItem (view, type) {} - -QAction* ShortcutListItem::action() const -{ - return m_action; -} - -void ShortcutListItem::setAction (QAction* action) -{ - m_action = action; -} - -QKeySequence ShortcutListItem::sequence() const -{ - return m_sequence; -} - -void ShortcutListItem::setSequence (const QKeySequence& sequence) -{ - m_sequence = sequence; -} - ConfigDialog::ConfigDialog (QWidget* parent, ConfigDialog::Tab defaulttab, Qt::WindowFlags f) : QDialog (parent, f), HierarchyElement (parent), ui (*new Ui_ConfigDialog), librariesModel {new LibrariesModel {this->libraries, this}}, - libraries {config::libraries()} + libraries {config::libraries()}, + shortcuts {m_window}, + shortcutsDelegate {this} { ui.setupUi (this); ui.librariesView->setModel(this->librariesModel); + ui.shortcutsList->setModel(&shortcuts); + ui.shortcutsList->setItemDelegateForColumn(ShortcutsModel::KeySequenceColumn, &shortcutsDelegate); // Set defaults applyToWidgetOptions([&](QWidget* widget, QString confname) @@ -122,18 +99,8 @@ } }); - m_window->applyToActions ([&](QAction* act) - { - addShortcut (act); - }); - - ui.shortcutsList->setSortingEnabled (true); - ui.shortcutsList->sortItems(); initExtProgs(); selectPage (defaulttab); - connect (ui.shortcut_set, SIGNAL (clicked()), this, SLOT (slot_setShortcut())); - connect (ui.shortcut_reset, SIGNAL (clicked()), this, SLOT (slot_resetShortcut())); - connect (ui.shortcut_clear, SIGNAL (clicked()), this, SLOT (slot_clearShortcut())); connect (ui.findDownloadPath, SIGNAL (clicked (bool)), this, SLOT (slot_findDownloadFolder())); connect (ui.buttonBox, SIGNAL (clicked (QAbstractButton*)), this, SLOT (buttonClicked (QAbstractButton*))); @@ -195,25 +162,6 @@ } // -// Adds a shortcut entry to the list of shortcuts. -// -void ConfigDialog::addShortcut (QAction* act) -{ - ShortcutListItem* item = new ShortcutListItem; - item->setIcon (act->icon()); - item->setAction (act); - item->setSequence (act->shortcut()); - setShortcutText (item); - - // If the action doesn't have a valid icon, use an empty one - // so that the list is kept aligned. - if (act->icon().isNull()) - item->setIcon (MainWindow::getIcon ("empty")); - - ui.shortcutsList->insertItem (ui.shortcutsList->count(), item); -} - -// // Initializes the stuff in the ext programs tab // void ConfigDialog::initExtProgs() @@ -310,6 +258,7 @@ }); ui.colorToolbarEditor->saveChanges(); + shortcuts.saveChanges(); config::setLibraries(this->libraries); // Ext program settings @@ -324,13 +273,6 @@ toolset->setWineSetting (program, widgets.wineBox->isChecked()); } - // Apply shortcuts - for (int i = 0; i < ui.shortcutsList->count(); ++i) - { - auto item = static_cast<ShortcutListItem*> (ui.shortcutsList->item (i)); - item->action()->setShortcut (item->sequence()); - } - settingsObject().sync(); emit settingsChanged(); } @@ -391,81 +333,6 @@ } // -// Finds the given list widget item in the list of widget items given. -// -int ConfigDialog::getItemRow (QListWidgetItem* item, QVector<QListWidgetItem*>& haystack) -{ - int i = 0; - - for (QListWidgetItem* it : haystack) - { - if (it == item) - return i; - - ++i; - } - - return -1; -} - -// -// Get the list of shortcuts selected -// -QVector<ShortcutListItem*> ConfigDialog::getShortcutSelection() -{ - QVector<ShortcutListItem*> out; - - for (QListWidgetItem* entry : ui.shortcutsList->selectedItems()) - out << static_cast<ShortcutListItem*> (entry); - - return out; -} - -// -// Edit the shortcut of a given action. -// -void ConfigDialog::slot_setShortcut() -{ - QVector<ShortcutListItem*> sel = getShortcutSelection(); - - if (countof(sel) < 1) - return; - - ShortcutListItem* item = sel[0]; - - if (KeySequenceDialog::staticDialog (item, this)) - setShortcutText (item); -} - -// -// Reset a shortcut to defaults -// -void ConfigDialog::slot_resetShortcut() -{ - QVector<ShortcutListItem*> sel = getShortcutSelection(); - - for (ShortcutListItem* item : sel) - { - item->setSequence (m_window->defaultShortcut (item->action())); - setShortcutText (item); - } -} - -// -// Remove the shortcut of an action. -// -void ConfigDialog::slot_clearShortcut() -{ - QVector<ShortcutListItem*> sel = getShortcutSelection(); - - for (ShortcutListItem* item : sel) - { - item->setSequence (QKeySequence()); - setShortcutText (item); - } -} - -// // Set the path of an external program // void ConfigDialog::slot_setExtProgPath() @@ -506,72 +373,3 @@ if (not dpath.isEmpty()) ui.configDownloadFilePath->setText (dpath); } - -// -// -// Updates the text string for a given shortcut list item -// -void ConfigDialog::setShortcutText (ShortcutListItem* item) -{ - QAction* act = item->action(); - QString label = act->iconText(); - QString keybind = item->sequence().toString(); - item->setText (format ("%1 (%2)", label, keybind)); -} - -// -// -KeySequenceDialog::KeySequenceDialog (QKeySequence seq, QWidget* parent, Qt::WindowFlags f) : - QDialog (parent, f), seq (seq) -{ - lb_output = new QLabel; - - bbx_buttons = new QDialogButtonBox (QDialogButtonBox::Ok | QDialogButtonBox::Cancel); \ - connect (bbx_buttons, SIGNAL (accepted()), this, SLOT (accept())); \ - connect (bbx_buttons, SIGNAL (rejected()), this, SLOT (reject())); \ - - setWhatsThis (tr ("Into this dialog you can input a key sequence for use as a " - "shortcut in LDForge. Use OK to confirm the new shortcut and Cancel to " - "dismiss.")); - - QVBoxLayout* layout = new QVBoxLayout; - layout->addWidget (lb_output); - layout->addWidget (bbx_buttons); - setLayout (layout); - - updateOutput(); -} - -// -// -bool KeySequenceDialog::staticDialog (ShortcutListItem* item, QWidget* parent) -{ - KeySequenceDialog dlg (item->sequence(), parent); - - if (dlg.exec() == QDialog::Rejected) - return false; - - item->setSequence (dlg.seq); - return true; -} - -// -// -void KeySequenceDialog::updateOutput() -{ - QString shortcut = seq.toString(); - - if (seq == QKeySequence()) - shortcut = "<empty>"; - - QString text = format ("<center><b>%1</b></center>", shortcut); - lb_output->setText (text); -} - -// -// -void KeySequenceDialog::keyPressEvent (QKeyEvent* ev) -{ - seq = ev->key() + ev->modifiers(); - updateOutput(); -}
--- a/src/dialogs/configdialog.h Wed Dec 26 16:38:38 2018 +0200 +++ b/src/dialogs/configdialog.h Wed Dec 26 23:01:45 2018 +0200 @@ -19,24 +19,9 @@ #pragma once #include "../mainwindow.h" #include "../toolsets/extprogramtoolset.h" +#include "shortcutsmodel.h" #include <QDialog> -// ============================================================================= -class ShortcutListItem : public QListWidgetItem -{ -public: - explicit ShortcutListItem (QListWidget* view = nullptr, int type = Type); - - QAction* action() const; - QKeySequence sequence() const; - void setAction (QAction* action); - void setSequence (const QKeySequence& sequence); - -private: - QAction* m_action; - QKeySequence m_sequence; -}; - struct ExternalProgramWidgets { class QLineEdit* input; @@ -44,7 +29,6 @@ class QCheckBox* wineBox; }; -// ============================================================================= class ConfigDialog : public QDialog, public HierarchyElement { Q_OBJECT @@ -77,44 +61,18 @@ ExternalProgramWidgets m_externalProgramWidgets[NumExternalPrograms]; class LibrariesModel* librariesModel; Libraries libraries; + ShortcutsModel shortcuts; + KeySequenceDelegate shortcutsDelegate; void applySettings(); - void addShortcut (QAction* act); void setButtonBackground (QPushButton* button, QString value); - void setShortcutText (ShortcutListItem* item); - int getItemRow (QListWidgetItem* item, QVector<QListWidgetItem*>& haystack); - QVector<ShortcutListItem*> getShortcutSelection(); void initExtProgs(); void applyToWidgetOptions (std::function<void (QWidget*, QString)> func); private slots: void setButtonColor(); - void slot_setShortcut(); - void slot_resetShortcut(); - void slot_clearShortcut(); void slot_setExtProgPath(); void slot_findDownloadFolder(); void buttonClicked (QAbstractButton* button); void selectPage (int row); }; - -// ============================================================================= -// -class KeySequenceDialog : public QDialog -{ - Q_OBJECT - -public: - explicit KeySequenceDialog (QKeySequence seq, QWidget* parent = nullptr, Qt::WindowFlags f = 0); - static bool staticDialog (ShortcutListItem* item, QWidget* parent = nullptr); - - class QLabel* lb_output; - class QDialogButtonBox* bbx_buttons; - QKeySequence seq; - -private: - void updateOutput(); - -private slots: - virtual void keyPressEvent (QKeyEvent* ev) override; -};
--- a/src/dialogs/configdialog.ui Wed Dec 26 16:38:38 2018 +0200 +++ b/src/dialogs/configdialog.ui Wed Dec 26 23:01:45 2018 +0200 @@ -84,7 +84,7 @@ <item> <widget class="QStackedWidget" name="m_pages"> <property name="currentIndex"> - <number>5</number> + <number>0</number> </property> <widget class="QWidget" name="page_3"> <layout class="QVBoxLayout" name="verticalLayout_13"> @@ -617,58 +617,27 @@ </property> <layout class="QHBoxLayout" name="horizontalLayout_5"> <item> - <widget class="QListWidget" name="shortcutsList"> + <widget class="QTableView" name="shortcutsList"> <property name="verticalScrollBarPolicy"> <enum>Qt::ScrollBarAsNeeded</enum> </property> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + <attribute name="horizontalHeaderDefaultSectionSize"> + <number>200</number> + </attribute> + <attribute name="horizontalHeaderStretchLastSection"> + <bool>true</bool> + </attribute> + <attribute name="verticalHeaderVisible"> + <bool>false</bool> + </attribute> </widget> </item> - <item> - <layout class="QVBoxLayout" name="verticalLayout_4"> - <item> - <widget class="QPushButton" name="shortcut_set"> - <property name="text"> - <string>Set</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="shortcut_reset"> - <property name="text"> - <string>Reset</string> - </property> - <property name="icon"> - <iconset resource="../../ldforge.qrc"> - <normaloff>:/icons/undo.png</normaloff>:/icons/undo.png</iconset> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="shortcut_clear"> - <property name="text"> - <string>Clear</string> - </property> - <property name="icon"> - <iconset resource="../../ldforge.qrc"> - <normaloff>:/icons/delete.png</normaloff>:/icons/delete.png</iconset> - </property> - </widget> - </item> - <item> - <spacer name="verticalSpacer_2"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> </layout> </widget> </item>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dialogs/shortcutsmodel.cpp Wed Dec 26 23:01:45 2018 +0200 @@ -0,0 +1,262 @@ +/* + * LDForge: LDraw parts authoring CAD + * Copyright (C) 2013 - 2018 Teemu Piippo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <QKeySequenceEdit> +#include <QSettings> +#include "mainwindow.h" +#include "widgets/extendedkeysequenceeditor.h" +#include "shortcutsmodel.h" + +/* + * Constructs a new shortcuts model. + * Actions are acquired from the provided mainwindow. + */ +ShortcutsModel::ShortcutsModel(MainWindow* parent) +{ + for (QAction* action : parent->findChildren<QAction*>()) + { + if (not action->objectName().isEmpty()) + shortcuts.append({action, action->shortcut(), parent->defaultShortcut(action)}); + } +} + +/* + * Returns the amount of shortcuts. + */ +int ShortcutsModel::rowCount(const QModelIndex &) const +{ + return shortcuts.size(); +} + +/* + * Returns the amount of columns. + */ +int ShortcutsModel::columnCount(const QModelIndex &) const +{ + return 2; +} + +/* + * Returns various shortcut data. + */ +QVariant ShortcutsModel::data(const QModelIndex &index, int role) const +{ + if (not isValidIndex(index)) + return {}; + + Item const& entry = shortcuts[index.row()]; + + switch (role) + { + case Qt::DisplayRole: + switch (index.column()) + { + case ActionColumn: + return entry.action->text().replace("&", ""); + + case KeySequenceColumn: + return entry.sequence.toString(QKeySequence::NativeText); + + default: + return ""; + } + + case Qt::DecorationRole: + if (index.column() == ActionColumn) + return entry.action->icon(); + else + return {}; + + case Qt::EditRole: + switch (index.column()) + { + case KeySequenceColumn: + return QVariant::fromValue(entry.sequence); + + default: + return {}; + } + + case DefaultKeySequenceRole: + return entry.defaultSequence; + + default: + return {}; + } +} + +/* + * Reimplementation of QAbstractItemModel::flags that supplies the editable flag + * for the key sequence cells. + */ +Qt::ItemFlags ShortcutsModel::flags(const QModelIndex& index) const +{ + Qt::ItemFlags flags = QAbstractItemModel::flags(index); + + if (index.column() == KeySequenceColumn) + flags |= Qt::ItemIsEditable; + + return flags; +} + +/* + * Returns whether or not the specified row is valid. + */ +bool ShortcutsModel::isValidRow(int row) const +{ + return row >= 0 and row < shortcuts.size(); +} + +/* + * Returns whether or not the specified model index is valid. + */ +bool ShortcutsModel::isValidIndex(const QModelIndex &index) const +{ + return index.column() >= 0 and index.column() < 2 and isValidRow(index.row()); +} + +/* + * Provides an interface for changing the key sequence. + */ +bool ShortcutsModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (isValidIndex(index) and index.column() == KeySequenceColumn and role == Qt::EditRole) + { + shortcuts[index.row()].sequence = value.value<QKeySequence>(); + return true; + } + else + { + return false; + } +} + +/* + * Saves shortcuts to the settings object and updates the actions. + */ +void ShortcutsModel::saveChanges() +{ + for (Item& shortcut : shortcuts) + { + shortcut.action->setShortcut(shortcut.sequence); + QString const key = "shortcut_" + shortcut.action->objectName(); + + if (shortcut.defaultSequence != shortcut.sequence) + settingsObject().setValue(key, shortcut.sequence); + else + settingsObject().remove(key); + } +} + +/* + * Returns an index. + */ +QModelIndex ShortcutsModel::index(int row, int column, const QModelIndex& parent) const +{ + ignore(parent); + return createIndex(row, column); +} + +/* + * Returns nothing, because the shortcuts model does not use parents. + */ +QModelIndex ShortcutsModel::parent(const QModelIndex &child) const +{ + ignore(child); + return {}; +} + +/* + * Returns headers. + */ +QVariant ShortcutsModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (role == Qt::DisplayRole and orientation == Qt::Horizontal) + { + switch (section) + { + case ActionColumn: + return "Action"; + + case KeySequenceColumn: + return "Shortcut"; + + default: + return ""; + } + } + else + { + return {}; + } +} + +/* + * Constructs a new key sequence delegate. + */ +KeySequenceDelegate::KeySequenceDelegate(QObject *parent) : + QStyledItemDelegate {parent} {} + +/* + * Creates a key sequence editor. + */ +QWidget *KeySequenceDelegate::createEditor( + QWidget *parent, + const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + ignore(option, index); + const QVariant variant = index.model()->data(index, ShortcutsModel::DefaultKeySequenceRole); + const QKeySequence defaultSequence = variant.value<QKeySequence>(); + ExtendedKeySequenceEditor* editor = new ExtendedKeySequenceEditor {{}, defaultSequence, parent}; + return editor; +} + +/* + * Sets the initial key sequence used in the key sequence editor. + */ +void KeySequenceDelegate::setEditorData(QWidget *widget, const QModelIndex &index) const +{ + QKeySequence sequence = index.model()->data(index, Qt::EditRole).value<QKeySequence>(); + ExtendedKeySequenceEditor* editor = static_cast<ExtendedKeySequenceEditor*>(widget); + editor->setKeySequence(sequence); +} + +/* + * Updates the shortcuts model when the key sequence has been accepted by the user. + */ +void KeySequenceDelegate::setModelData( + QWidget *widget, + QAbstractItemModel *model, + const QModelIndex &index) const +{ + ExtendedKeySequenceEditor* editor = static_cast<ExtendedKeySequenceEditor*>(widget); + model->setData(index, editor->keySequence(), Qt::EditRole); +} + +/* + * Updates editor geometry. + */ +void KeySequenceDelegate::updateEditorGeometry( + QWidget *editor, + const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + ignore(index); + editor->setGeometry(option.rect); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dialogs/shortcutsmodel.h Wed Dec 26 23:01:45 2018 +0200 @@ -0,0 +1,89 @@ +/* + * LDForge: LDraw parts authoring CAD + * Copyright (C) 2013 - 2018 Teemu Piippo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once +#include <QAbstractItemModel> +#include <QAction> +#include <QStyledItemDelegate> +#include "main.h" + +/* + * Implements a delegate for editing key sequence cells. + */ +class KeySequenceDelegate : public QStyledItemDelegate +{ +public: + KeySequenceDelegate(QObject* parent = nullptr); + QWidget* createEditor( + QWidget *parent, + const QStyleOptionViewItem &option, + const QModelIndex &index) const override; + void setEditorData(QWidget *widget, const QModelIndex &index) const override; + void setModelData( + QWidget *widget, + QAbstractItemModel *model, + const QModelIndex &index) const override; + void updateEditorGeometry( + QWidget *editor, + const QStyleOptionViewItem &option, + const QModelIndex &index) const override; +}; + +/* + * Models a table of shortcuts. Each action in the provided main window is given + * a row, which contains editable shortcuts. + * + * Calling saveChanges updates the actions and updates the settings object. + */ +class ShortcutsModel : public QAbstractItemModel +{ +public: + enum Column + { + ActionColumn, + KeySequenceColumn + }; + + enum + { + DefaultKeySequenceRole = Qt::UserRole + }; + + ShortcutsModel(class MainWindow* parent); + int rowCount(QModelIndex const&) const override; + int columnCount(QModelIndex const&) const override; + QVariant data(const QModelIndex &index, int role) const override; + Qt::ItemFlags flags(const QModelIndex& index) const override; + bool isValidRow(int row) const; + bool isValidIndex(const QModelIndex &index) const; + bool setData(const QModelIndex &index, const QVariant &value, int role) override; + void saveChanges(); + QModelIndex index(int row, int column, const QModelIndex& parent) const override; + QModelIndex parent(const QModelIndex& child) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; + +private: + struct Item + { + QAction* action; + QKeySequence sequence; + const QKeySequence defaultSequence; + }; + + QVector<Item> shortcuts; +};
--- a/src/mainwindow.cpp Wed Dec 26 16:38:38 2018 +0200 +++ b/src/mainwindow.cpp Wed Dec 26 23:01:45 2018 +0200 @@ -757,21 +757,6 @@ // --------------------------------------------------------------------------------------------------------------------- // -void MainWindow::saveShortcuts() -{ - applyToActions([&](QAction* action) - { - QString const key = "shortcut_" + action->objectName(); - - if (m_defaultShortcuts[action] != action->shortcut()) - settingsObject().setValue(key, action->shortcut()); - else - settingsObject().remove(key); - }); -} - -// --------------------------------------------------------------------------------------------------------------------- -// void MainWindow::applyToActions(function<void(QAction*)> function) { for (QAction* act : findChildren<QAction*>())
--- a/src/mainwindow.h Wed Dec 26 16:38:38 2018 +0200 +++ b/src/mainwindow.h Wed Dec 26 23:01:45 2018 +0200 @@ -70,7 +70,6 @@ void replaceSelection(const QItemSelection& selection); CircularSection circleToolSection() const; bool save (LDDocument* doc, bool saveAs); - void saveShortcuts(); void select(const QModelIndex& objectIndex); QModelIndexList selectedIndexes() const; QSet<LDObject*> selectedObjects() const;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/widgets/extendedkeysequenceeditor.cpp Wed Dec 26 23:01:45 2018 +0200 @@ -0,0 +1,90 @@ +/* + * LDForge: LDraw parts authoring CAD + * Copyright (C) 2013 - 2018 Teemu Piippo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <QKeySequenceEdit> +#include <QPushButton> +#include <QHBoxLayout> +#include "extendedkeysequenceeditor.h" + +/* + * Constructs a new extended key sequence editor. + */ +ExtendedKeySequenceEditor::ExtendedKeySequenceEditor( + const QKeySequence& initialSequence, + const QKeySequence& defaultSequence, + QWidget* parent) : + QWidget {parent}, + defaultSequence {defaultSequence}, + editor {new QKeySequenceEdit {initialSequence, this}}, + clearButton {new QPushButton {"×", this}}, + resetButton {new QPushButton {"↺", this}}, + layout {new QHBoxLayout {this}} +{ + layout->addWidget(editor, 1); + layout->addWidget(clearButton, 0); + layout->addWidget(resetButton, 0); + layout->setContentsMargins({}); + setLayout(layout); + + // Set up focus proxies so that the actual editing widget gets focused when focus + // is applied to this widget. + setFocusProxy(editor); + clearButton->setFocusProxy(editor); + resetButton->setFocusProxy(editor); + + connect(clearButton, &QPushButton::clicked, editor, &QKeySequenceEdit::clear); + connect(resetButton, &QPushButton::clicked, [this]() + { + editor->setKeySequence(this->defaultSequence); + }); +} + +/* + * Destroys an extended key sequence editor. + */ +ExtendedKeySequenceEditor::~ExtendedKeySequenceEditor() +{ + delete editor; + delete clearButton; + delete resetButton; + delete layout; +} + +/* + * Returns the current key sequence in the editor. + */ +QKeySequence ExtendedKeySequenceEditor::keySequence() const +{ + return editor->keySequence(); +} + +/* + * Changes the key sequence in the editor. + */ +void ExtendedKeySequenceEditor::setKeySequence(const QKeySequence& newSequence) +{ + editor->setKeySequence(newSequence); +} + +/* + * Clears the key sequence. + */ +void ExtendedKeySequenceEditor::clear() +{ + editor->clear(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/widgets/extendedkeysequenceeditor.h Wed Dec 26 23:01:45 2018 +0200 @@ -0,0 +1,49 @@ +/* + * LDForge: LDraw parts authoring CAD + * Copyright (C) 2013 - 2018 Teemu Piippo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once +#include <QWidget> + +/* + * A widget which contains not only a key sequence editor, but also buttons for resetting and + * clearing the key sequence. + */ +class ExtendedKeySequenceEditor : public QWidget +{ + Q_OBJECT + +public: + explicit ExtendedKeySequenceEditor( + const QKeySequence& initialSequence = {}, + const QKeySequence& defaultSequence = {}, + QWidget *parent = nullptr); + ~ExtendedKeySequenceEditor(); + + QKeySequence keySequence() const; + +public slots: + void setKeySequence(const QKeySequence& newSequence); + void clear(); + +private: + const QKeySequence defaultSequence; + class QKeySequenceEdit* editor; + class QPushButton* clearButton; + class QPushButton* resetButton; + class QHBoxLayout* layout; +};