cmake: avoid de-duplication of user's CXXFLAGS
[quassel.git] / src / qtui / settingspages / shortcutssettingspage.cpp
1 /***************************************************************************
2  *   Copyright (C) 2005-2020 by the Quassel Project                        *
3  *   devel@quassel-irc.org                                                 *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) version 3.                                           *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
19  ***************************************************************************/
20
21 #include "shortcutssettingspage.h"
22
23 #include <QTimer>
24
25 #include "action.h"
26 #include "actioncollection.h"
27 #include "qtui.h"
28 #include "shortcutsmodel.h"
29 #include "util.h"
30
31 ShortcutsFilter::ShortcutsFilter(QObject* parent)
32     : QSortFilterProxyModel(parent)
33 {
34     setDynamicSortFilter(true);
35 }
36
37 void ShortcutsFilter::setFilterString(const QString& filterString)
38 {
39     _filterString = filterString;
40     invalidateFilter();
41 }
42
43 bool ShortcutsFilter::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
44 {
45     if (!source_parent.isValid())
46         return true;
47
48     QModelIndex index = source_parent.model()->index(source_row, 0, source_parent);
49     Q_ASSERT(index.isValid());
50     if (!qobject_cast<Action*>(index.data(ShortcutsModel::ActionRole).value<QObject*>())->isShortcutConfigurable())
51         return false;
52
53     for (int col = 0; col < source_parent.model()->columnCount(source_parent); col++) {
54         if (source_parent.model()->index(source_row, col, source_parent).data().toString().contains(_filterString, Qt::CaseInsensitive))
55             return true;
56     }
57     return false;
58 }
59
60 /****************************************************************************/
61
62 ShortcutsSettingsPage::ShortcutsSettingsPage(const QHash<QString, ActionCollection*>& actionCollections, QWidget* parent)
63     : SettingsPage(tr("Interface"), tr("Shortcuts"), parent)
64     , _shortcutsModel(new ShortcutsModel(actionCollections, this))
65     , _shortcutsFilter(new ShortcutsFilter(this))
66 {
67     ui.setupUi(this);
68
69     _shortcutsFilter->setSourceModel(_shortcutsModel);
70     ui.shortcutsView->setModel(_shortcutsFilter);
71     ui.shortcutsView->expandAll();
72     ui.shortcutsView->resizeColumnToContents(0);
73     ui.shortcutsView->sortByColumn(0, Qt::AscendingOrder);
74
75     ui.keySequenceWidget->setModel(_shortcutsModel);
76     connect(ui.keySequenceWidget, &KeySequenceWidget::keySequenceChanged, this, &ShortcutsSettingsPage::keySequenceChanged);
77
78     connect(ui.shortcutsView->selectionModel(), &QItemSelectionModel::currentChanged, this, &ShortcutsSettingsPage::setWidgetStates);
79
80     setWidgetStates();
81
82     connect(ui.useDefault, &QAbstractButton::clicked, this, &ShortcutsSettingsPage::toggledCustomOrDefault);
83     connect(ui.useCustom, &QAbstractButton::clicked, this, &ShortcutsSettingsPage::toggledCustomOrDefault);
84
85     connect(_shortcutsModel, &ShortcutsModel::changed, this, &ShortcutsSettingsPage::setChangedState);
86
87     // fugly, but directly setting it from the ctor doesn't seem to work
88     QTimer::singleShot(0, ui.searchEdit, [widget = ui.searchEdit]() { widget->setFocus(); });
89 }
90
91 void ShortcutsSettingsPage::setWidgetStates()
92 {
93     if (ui.shortcutsView->currentIndex().isValid() && ui.shortcutsView->currentIndex().parent().isValid()) {
94         QKeySequence active = ui.shortcutsView->currentIndex().data(ShortcutsModel::ActiveShortcutRole).value<QKeySequence>();
95         QKeySequence def = ui.shortcutsView->currentIndex().data(ShortcutsModel::DefaultShortcutRole).value<QKeySequence>();
96         ui.defaultShortcut->setText(def.isEmpty() ? tr("None") : def.toString(QKeySequence::NativeText));
97         ui.actionBox->setEnabled(true);
98         if (active == def) {
99             ui.useDefault->setChecked(true);
100             ui.keySequenceWidget->setKeySequence(QKeySequence());
101         }
102         else {
103             ui.useCustom->setChecked(true);
104             ui.keySequenceWidget->setKeySequence(active);
105         }
106     }
107     else {
108         ui.defaultShortcut->setText(tr("None"));
109         ui.actionBox->setEnabled(false);
110         ui.useDefault->setChecked(true);
111         ui.keySequenceWidget->setKeySequence(QKeySequence());
112     }
113 }
114
115 void ShortcutsSettingsPage::on_searchEdit_textChanged(const QString& text)
116 {
117     _shortcutsFilter->setFilterString(text);
118 }
119
120 void ShortcutsSettingsPage::keySequenceChanged(const QKeySequence& seq, const QModelIndex& conflicting)
121 {
122     if (conflicting.isValid())
123         _shortcutsModel->setData(conflicting, QKeySequence(), ShortcutsModel::ActiveShortcutRole);
124
125     QModelIndex rowIdx = _shortcutsFilter->mapToSource(ui.shortcutsView->currentIndex());
126     Q_ASSERT(rowIdx.isValid());
127     _shortcutsModel->setData(rowIdx, seq, ShortcutsModel::ActiveShortcutRole);
128     setWidgetStates();
129 }
130
131 void ShortcutsSettingsPage::toggledCustomOrDefault()
132 {
133     if (!ui.shortcutsView->currentIndex().isValid())
134         return;
135
136     QModelIndex index = _shortcutsFilter->mapToSource(ui.shortcutsView->currentIndex());
137     Q_ASSERT(index.isValid());
138
139     if (ui.useDefault->isChecked()) {
140         _shortcutsModel->setData(index, index.data(ShortcutsModel::DefaultShortcutRole));
141     }
142     else {
143         _shortcutsModel->setData(index, QKeySequence());
144     }
145     setWidgetStates();
146 }
147
148 void ShortcutsSettingsPage::save()
149 {
150     _shortcutsModel->commit();
151     QtUi::saveShortcuts();
152     SettingsPage::save();
153 }
154
155 void ShortcutsSettingsPage::load()
156 {
157     _shortcutsModel->load();
158
159     SettingsPage::load();
160 }
161
162 void ShortcutsSettingsPage::defaults()
163 {
164     _shortcutsModel->defaults();
165
166     SettingsPage::defaults();
167 }