1 /*
2 * Stellarium
3 * Copyright (C) 2012 Anton Samoylov
4 * Copyright (C) 2012 Bogdan Marinov
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
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 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
19 */
20
21 #include <QDebug>
22 #include <QKeyEvent>
23
24 #include "ShortcutLineEdit.hpp"
25
ShortcutLineEdit(QWidget * parent)26 ShortcutLineEdit::ShortcutLineEdit(QWidget *parent) :
27 QLineEdit(parent)
28 {
29 // call clear for setting up private fields
30 clear();
31 }
32
getKeySequence() const33 QKeySequence ShortcutLineEdit::getKeySequence() const
34 {
35 return QKeySequence(keys.value(0, 0), keys.value(1, 0),
36 keys.value(2, 0), keys.value(3, 0));
37 }
38
isEmpty() const39 bool ShortcutLineEdit::isEmpty() const
40 {
41 return (keys.isEmpty());
42 }
43
clear()44 void ShortcutLineEdit::clear()
45 {
46 keys.clear();
47 QLineEdit::setText(""); // https://wiki.qt.io/Technical_FAQ#Why_does_the_memory_keep_increasing_when_repeatedly_pasting_text_and_calling_clear.28.29_in_a_QLineEdit.3F
48 emit contentsChanged();
49 }
50
backspace()51 void ShortcutLineEdit::backspace()
52 {
53 if (keys.isEmpty())
54 return;
55 keys.removeLast();
56 setContents(getKeySequence());
57 }
58
setContents(QKeySequence ks)59 void ShortcutLineEdit::setContents(QKeySequence ks)
60 {
61 // Avoiding infinite loop of same signal-slot emitting/calling
62 if (ks.toString(QKeySequence::NativeText) == text())
63 return;
64
65 // Set the keys from the given key sequence
66 clear();
67 for (int i = 0; i < ks.count(); ++i)
68 {
69 keys.append(ks[i]);
70 }
71
72 // Show Ctrl button as Cmd on Mac
73 setText(ks.toString(QKeySequence::NativeText));
74 emit contentsChanged();
75 }
76
keyPressEvent(QKeyEvent * e)77 void ShortcutLineEdit::keyPressEvent(QKeyEvent *e)
78 {
79 int nextKey = e->key();
80 if ( keys.count() > 3 || // too long shortcut
81 nextKey == Qt::Key_Control || // don't count modifier keys
82 nextKey == Qt::Key_Shift ||
83 nextKey == Qt::Key_Meta ||
84 nextKey == Qt::Key_Alt )
85 return;
86
87 // applying current modifiers to key
88 nextKey |= getModifiers(e->modifiers(), e->text());
89
90 // If there is selected text, replace *all* instead of appending.
91 if (hasSelectedText())
92 {
93 keys.clear();
94 }
95 keys.append(nextKey);
96
97 // set displaying information
98 setText(getKeySequence().toString(QKeySequence::NativeText));
99 emit contentsChanged();
100
101 // not call QLineEdit's event because we already changed contents
102 e->accept();
103 }
104
focusInEvent(QFocusEvent * e)105 void ShortcutLineEdit::focusInEvent(QFocusEvent *e)
106 {
107 // Select the contents so that they are replaced on the next edit
108 selectAll();
109 emit focusChanged(false);
110 QLineEdit::focusInEvent(e);
111 }
112
focusOutEvent(QFocusEvent * e)113 void ShortcutLineEdit::focusOutEvent(QFocusEvent *e)
114 {
115 emit focusChanged(true);
116 QLineEdit::focusOutEvent(e);
117 }
118
119
getModifiers(Qt::KeyboardModifiers state,const QString & text)120 int ShortcutLineEdit::getModifiers(Qt::KeyboardModifiers state, const QString &text)
121 {
122 int result = 0;
123 // The shift modifier only counts when it is not used to type a symbol
124 // that is only reachable using the shift key anyway
125 if ((state & Qt::ShiftModifier) && (text.size() == 0
126 || !text.at(0).isPrint()
127 || text.at(0).isLetterOrNumber()
128 || text.at(0).isSpace()))
129 result |= Qt::SHIFT;
130 if (state & Qt::ControlModifier)
131 result |= Qt::CTRL;
132 // META key is the same as WIN key on non-MACs
133 if (state & Qt::MetaModifier)
134 result |= Qt::META;
135 if (state & Qt::AltModifier)
136 result |= Qt::ALT;
137 return result;
138 }
139