Pencil2D  ff90c0872e88be3bf81c548cd60f01983012ec49
Pencil2D is an animation software for both bitmap and vector graphics. It is free, multi-platform, and open source.
 All Classes Functions
shortcutspage.cpp
1 /*
2 
3 Pencil - Traditional Animation Software
4 Copyright (C) 2005-2007 Patrick Corrieri & Pascal Naidon
5 Copyright (C) 2013-2017 Matt Chiawen Chang
6 
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; version 2 of the License.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15 
16 */
17 #include <QDebug>
18 #include <QMap>
19 #include <QStringRef>
20 #include <QSettings>
21 #include <QGroupBox>
22 #include <QVBoxLayout>
23 #include <QLabel>
24 #include <QLineEdit>
25 #include <QTreeView>
26 #include <QStandardItemModel>
27 #include <QKeyEvent>
28 #include <QKeySequence>
29 #include <QMessageBox>
30 #include "pencilsettings.h"
31 #include "shortcutspage.h"
32 #include "keycapturelineedit.h"
33 #include "ui_shortcutspage.h"
34 
35 static const int ACT_NAME_COLUMN = 0;
36 static const int KEY_SEQ_COLUMN = 1;
37 
38 ShortcutsPage::ShortcutsPage( QWidget* parent ) : QWidget(parent),
39  m_treeModel( NULL ),
40  ui( new Ui::ShortcutsPage )
41 {
42  ui->setupUi(this);
43  m_treeModel = new QStandardItemModel(this);
44 
45  treeModelLoadShortcutsSetting();
46 
47  ui->treeView->setModel(m_treeModel);
48  ui->treeView->resizeColumnToContents(0);
49 
50  connect( ui->treeView, &QTreeView::clicked, this, &ShortcutsPage::tableItemClicked );
51  connect( ui->keySeqLineEdit, &KeyCaptureLineEdit::keyCaptured, this, &ShortcutsPage::keyCapLineEditTextChanged );
52  connect( ui->restoreShortcutsButton, &QPushButton::clicked, this, &ShortcutsPage::restoreShortcutsButtonClicked );
53  connect( ui->clearButton, &QPushButton::clicked, this, &ShortcutsPage::clearButtonClicked );
54 }
55 
56 void ShortcutsPage::tableItemClicked( const QModelIndex& modelIndex )
57 {
58  int row = modelIndex.row();
59 
60  // extract action name
61  QStandardItem* actionItem = m_treeModel->item(row, ACT_NAME_COLUMN);
62  ui->actionNameLabel->setText(actionItem->text());
63 
64  // extract key sequence
65  QStandardItem* keyseqItem = m_treeModel->item(row, KEY_SEQ_COLUMN);
66  ui->keySeqLineEdit->setText(keyseqItem->text());
67 
68  qDebug() << "Command Selected:" << actionItem->text();
69 
70  m_currentItemIndex = modelIndex;
71 
72  ui->keySeqLineEdit->setFocus();
73 }
74 
75 void ShortcutsPage::keyCapLineEditTextChanged(QKeySequence keySeqence)
76 {
77  if ( !m_currentItemIndex.isValid() )
78  {
79  return;
80  }
81 
82  int row = m_currentItemIndex.row();
83  QStandardItem* actionItem = m_treeModel->item(row, ACT_NAME_COLUMN);
84  QStandardItem* keyseqItem = m_treeModel->item(row, KEY_SEQ_COLUMN);
85 
86  QString strCmdName = QString("Cmd%1").arg( actionItem->text() );
87  QString strKeySeq = keySeqence.toString( QKeySequence::PortableText );
88 
89  QSettings setting( PENCIL2D, PENCIL2D );
90  setting.beginGroup("shortcuts");
91 
92  if (isKeySequenceExist(setting, strCmdName, keySeqence))
93  {
94  QMessageBox msgBox;
95  msgBox.setText( tr("Shortcut Conflict!"));
96  msgBox.setInformativeText( tr("%1 is already used, overwrite?").arg(keySeqence.toString(QKeySequence::NativeText)) );
97  msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
98  msgBox.setDefaultButton(QMessageBox::No);
99  msgBox.setIcon( QMessageBox::Warning );
100 
101  int result = msgBox.exec();
102 
103  if ( result != QMessageBox::Yes )
104  {
105  ui->keySeqLineEdit->setText( keyseqItem->text() );
106  return;
107  }
108  removeDuplicateKeySequence(&setting, keySeqence);
109  }
110 
111  setting.setValue(strCmdName, strKeySeq);
112  setting.endGroup();
113  setting.sync();
114 
115  treeModelLoadShortcutsSetting();
116 
117  qDebug() << "Shortcut " << strCmdName << " = " << strKeySeq;
118 }
119 
120 void ShortcutsPage::restoreShortcutsButtonClicked()
121 {
122  restoreShortcutsToDefault();
123  treeModelLoadShortcutsSetting();
124 }
125 
126 bool ShortcutsPage::isKeySequenceExist(const QSettings& settings, QString strTargetCmdName, QKeySequence targetkeySeq)
127 {
128  foreach (QString strCmdName, settings.allKeys())
129  {
130  if (strTargetCmdName == strCmdName)
131  {
132  continue;
133  }
134 
135  QString strCmdKeySeq = settings.value(strCmdName).toString();
136  /*
137  qDebug() << "Compare:"
138  << QKeySequence(strCmdKeySeq).toString()
139  << "|"
140  << targetkeySeq.toString();
141  */
142  if (QKeySequence(strCmdKeySeq) == targetkeySeq)
143  {
144  return true;
145  }
146  }
147  return false;
148 }
149 
150 void ShortcutsPage::removeDuplicateKeySequence(QSettings* settings, QKeySequence keySeq)
151 {
152  foreach(QString strCmdName, settings->allKeys())
153  {
154  QString strCmdKeySeq = settings->value(strCmdName).toString();
155 
156  if ( strCmdKeySeq == keySeq.toString(QKeySequence::PortableText))
157  {
158  settings->setValue(strCmdName, "");
159  }
160  }
161 }
162 
163 void ShortcutsPage::treeModelLoadShortcutsSetting()
164 {
165  // Load shortcuts from settings
166  QSettings settings( PENCIL2D, PENCIL2D );
167  settings.beginGroup("shortcuts");
168 
169  m_treeModel->clear(); // release all existing items.
170 
171  m_treeModel->setRowCount( settings.allKeys().size() );
172  m_treeModel->setColumnCount( 2 );
173 
174  int row = 0;
175  foreach (QString strCmdName, settings.allKeys())
176  {
177  QString strKeySequence = settings.value(strCmdName).toString();
178 
179  //convert to native format
180  strKeySequence = QKeySequence(strKeySequence).toString( QKeySequence::NativeText );
181 
182  // strip the first 3 chars "Cmd"
183  QStringRef strHumanReadCmdName (&strCmdName, 3, strCmdName.size() - 3);
184 
185  QStandardItem* nameItem = new QStandardItem(strHumanReadCmdName.toString());
186  QStandardItem* keyseqItem = new QStandardItem(strKeySequence);
187 
188  m_treeModel->setItem(row, 0, nameItem);
189  m_treeModel->setItem(row, 1, keyseqItem);
190 
191  m_treeModel->item(row, 0)->setEditable(false);
192  m_treeModel->item(row, 1)->setEditable(false);
193 
194  row++;
195  }
196  settings.endGroup();
197 
198  ui->treeView->resizeColumnToContents( 0 );
199 }
200 
201 void ShortcutsPage::clearButtonClicked()
202 {
203  if ( !m_currentItemIndex.isValid() )
204  {
205  return;
206  }
207 
208  int row = m_currentItemIndex.row();
209  QStandardItem* actionItem = m_treeModel->item(row, ACT_NAME_COLUMN);
210 
211  QString strCmdName = QString("shortcuts/Cmd%1").arg( actionItem->text() );
212 
213  QSettings setting( PENCIL2D, PENCIL2D );
214  setting.setValue( strCmdName, "" );
215  setting.sync();
216 
217  ui->keySeqLineEdit->setText("");
218 
219  treeModelLoadShortcutsSetting();
220 }