1 /*
2  *  Copyright (c) 2020 Anna Medonosová <anna.medonosova@gmail.com>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 #include "KisSPenSettings.h"
20 
21 #include <QAction>
22 #include <QStandardItem>
23 #include <QStandardItemModel>
24 #include <QList>
25 #include <QMap>
26 #include <QModelIndex>
27 
28 #include <kactioncollection.h>
29 #include <KisPart.h>
30 #include <kactioncategory.h>
31 #include <kconfiggroup.h>
32 #include <ksharedconfig.h>
33 #include <klocalizedstring.h>
34 #include <KisActionsSnapshot.h>
35 #include <kis_icon_utils.h>
36 
KisSPenSettings(QWidget * parent)37 KisSPenSettings::KisSPenSettings(QWidget *parent)
38     : KisPreferenceSet(parent)
39     , m_model(new QStandardItemModel())
40 {
41     mUi = new WdgSPenSettings(this);
42 
43     m_model->setColumnCount(2);
44 
45     // TODO - popup palette is different action mechanism, thus is missing in this list; maybe we could create a fake KisAction for it
46     // Thanks to the KisActionSnapshot, we can list all actions even when no document is open
47     QScopedPointer<KisActionsSnapshot> actionsSnapshot(new KisActionsSnapshot());
48 
49     KActionCollection *actionCollection = KisPart::instance()->currentMainwindow()->actionCollection();
50     for (QAction *action: actionCollection->actions()) {
51         actionsSnapshot->addAction(action->objectName(), action);
52     }
53 
54     QMap<QString, KActionCollection*> sortedCollections = actionsSnapshot->actionCollections();
55     for (KActionCollection* collection: sortedCollections) {
56         for (QAction* action: collection->actions()) {
57             QString actionName = KLocalizedString::removeAcceleratorMarker(action->text());
58             QStandardItem* item = new QStandardItem(action->icon(), actionName);
59             QStandardItem* actionNameItem = new QStandardItem(action->objectName());
60             m_model->appendRow(QList<QStandardItem*>() << item << actionNameItem);
61         }
62     }
63 
64     m_model->sort(m_ACTION_TEXT_COLUMN);
65     m_model->insertRow(0, new QStandardItem(i18n("Do nothing")));
66 
67     mUi->cmbClickAction->setModel(m_model);
68     mUi->cmbDoubleClickAction->setModel(m_model);
69     mUi->cmbGestureSwipeUp->setModel(m_model);
70     mUi->cmbGestureSwipeDown->setModel(m_model);
71     mUi->cmbGestureSwipeLeft->setModel(m_model);
72     mUi->cmbGestureSwipeRight->setModel(m_model);
73     mUi->cmbGestureCircleCW->setModel(m_model);
74     mUi->cmbGestureCircleCCW->setModel(m_model);
75 
76     loadPreferences();
77 }
78 
~KisSPenSettings()79 KisSPenSettings::~KisSPenSettings()
80 {
81     delete mUi;
82     delete m_model;
83 }
84 
id()85 QString KisSPenSettings::id()
86 {
87     return QString("SPenSettings");
88 }
89 
name()90 QString KisSPenSettings::name()
91 {
92     return header();
93 }
94 
header()95 QString KisSPenSettings::header()
96 {
97     return QString(i18n("S-Pen Actions"));
98 }
99 
icon()100 QIcon KisSPenSettings::icon()
101 {
102     return KisIconUtils::loadIcon("spen-remote");
103 }
104 
savePreferences() const105 void KisSPenSettings::savePreferences() const
106 {
107     KConfigGroup cfg = KSharedConfig::openConfig()->group("SPenSettings");
108 
109     cfg.writeEntry("actionButtonClick", actionNameForIndex(mUi->cmbClickAction->currentIndex()));
110     cfg.writeEntry("actionButtonDoubleClick", actionNameForIndex(mUi->cmbDoubleClickAction->currentIndex()));
111     cfg.writeEntry("actionGestureSwipeUp", actionNameForIndex(mUi->cmbGestureSwipeUp->currentIndex()));
112     cfg.writeEntry("actionGestureSwipeDown", actionNameForIndex(mUi->cmbGestureSwipeDown->currentIndex()));
113     cfg.writeEntry("actionGestureSwipeLeft", actionNameForIndex(mUi->cmbGestureSwipeLeft->currentIndex()));
114     cfg.writeEntry("actionGestureSwipeRight", actionNameForIndex(mUi->cmbGestureSwipeRight->currentIndex()));
115     cfg.writeEntry("actionGestureCircleCW", actionNameForIndex(mUi->cmbGestureCircleCW->currentIndex()));
116     cfg.writeEntry("actionGestureCircleCCW", actionNameForIndex(mUi->cmbGestureCircleCCW->currentIndex()));
117 
118     emit settingsChanged();
119 }
120 
loadPreferences()121 void KisSPenSettings::loadPreferences()
122 {
123     KConfigGroup cfg = KSharedConfig::openConfig()->group("SPenSettings");
124 
125     mUi->cmbClickAction->setCurrentIndex(indexFromActionName(cfg.readEntry("actionButtonClick", QString())));
126     mUi->cmbDoubleClickAction->setCurrentIndex(indexFromActionName(cfg.readEntry("actionButtonDoubleClick", QString())));
127     mUi->cmbGestureSwipeUp->setCurrentIndex(indexFromActionName(cfg.readEntry("actionGestureSwipeUp", QString())));
128     mUi->cmbGestureSwipeDown->setCurrentIndex(indexFromActionName(cfg.readEntry("actionGestureSwipeDown", QString())));
129     mUi->cmbGestureSwipeLeft->setCurrentIndex(indexFromActionName(cfg.readEntry("actionGestureSwipeLeft", QString())));
130     mUi->cmbGestureSwipeRight->setCurrentIndex(indexFromActionName(cfg.readEntry("actionGestureSwipeRight", QString())));
131     mUi->cmbGestureCircleCW->setCurrentIndex(indexFromActionName(cfg.readEntry("actionGestureCircleCW", QString())));
132     mUi->cmbGestureCircleCCW->setCurrentIndex(indexFromActionName(cfg.readEntry("actionGestureCircleCCW", QString())));
133 
134 }
135 
loadDefaultPreferences()136 void KisSPenSettings::loadDefaultPreferences()
137 {
138     mUi->cmbClickAction->setCurrentIndex(indexFromActionName(QString("fake_show_popup_palette")));
139     mUi->cmbDoubleClickAction->setCurrentIndex(indexFromActionName(QString("erase_action")));
140     mUi->cmbGestureSwipeUp->setCurrentIndex(indexFromActionName(QString("make_brush_color_lighter")));
141     mUi->cmbGestureSwipeDown->setCurrentIndex(indexFromActionName(QString("make_brush_color_darker")));
142     mUi->cmbGestureSwipeLeft->setCurrentIndex(indexFromActionName(QString("KritaShape/KisToolBrush")));
143     mUi->cmbGestureSwipeRight->setCurrentIndex(indexFromActionName(QString("KritaSelected/KisToolColorPicker")));
144     mUi->cmbGestureCircleCW->setCurrentIndex(indexFromActionName(QString("shift_brush_color_clockwise")));
145     mUi->cmbGestureCircleCCW->setCurrentIndex(indexFromActionName(QString("shift_brush_color_counter_clockwise")));
146 }
147 
actionNameForIndex(int index) const148 QString KisSPenSettings::actionNameForIndex(int index) const
149 {
150     QModelIndex modelIndex = m_model->index(index, m_ACTION_NAME_COLUMN);
151     QString actionName = m_model->itemFromIndex(modelIndex)->data(Qt::DisplayRole).toString();
152     return actionName;
153 }
154 
indexFromActionName(QString actionName) const155 int KisSPenSettings::indexFromActionName(QString actionName) const
156 {
157     if (actionName.isEmpty()) {
158         return 0;
159     } else {
160         QList<QStandardItem*> itemsFound = m_model->findItems(actionName, Qt::MatchExactly, m_ACTION_NAME_COLUMN);
161         if (itemsFound.size() == 0) {
162             return 1;
163         } else {
164             return itemsFound[0]->index().row();
165         }
166     }
167 }
168