1 
2 /*
3  Copyright (C) 2010-2014 Kristian Duske
4 
5  This file is part of TrenchBroom.
6 
7  TrenchBroom is free software: you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation, either version 3 of the License, or
10  (at your option) any later version.
11 
12  TrenchBroom is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with TrenchBroom. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #include "View/KeyboardShortcut.h"
22 #include <gtest/gtest.h>
23 
24 #include "StringUtils.h"
25 #include "TestUtils.h"
26 
27 namespace TrenchBroom {
28     namespace View {
29         void assertSortModifierKeys(int key1, int key2, int key3, const int exp1, const int exp2, const int exp3);
assertSortModifierKeys(int key1,int key2,int key3,const int exp1,const int exp2,const int exp3)30         void assertSortModifierKeys(int key1, int key2, int key3, const int exp1, const int exp2, const int exp3) {
31             KeyboardShortcut::sortModifierKeys(key1, key2, key3);
32             ASSERT_EQ(exp1, key1);
33             ASSERT_EQ(exp2, key2);
34             ASSERT_EQ(exp3, key3);
35         }
36 
TEST(KeyboardShortcutTest,sortModifierKeys)37         TEST(KeyboardShortcutTest, sortModifierKeys) {
38             assertSortModifierKeys(WXK_ALT, WXK_NONE, WXK_NONE,
39                                    WXK_ALT, WXK_NONE, WXK_NONE);
40             assertSortModifierKeys(WXK_SHIFT, WXK_NONE, WXK_NONE,
41                                    WXK_SHIFT, WXK_NONE, WXK_NONE);
42             assertSortModifierKeys(WXK_CONTROL, WXK_NONE, WXK_NONE,
43                                    WXK_CONTROL, WXK_NONE, WXK_NONE);
44 
45             assertSortModifierKeys(WXK_NONE, WXK_ALT, WXK_NONE,
46                                    WXK_ALT, WXK_NONE, WXK_NONE);
47             assertSortModifierKeys(WXK_NONE, WXK_SHIFT, WXK_NONE,
48                                    WXK_SHIFT, WXK_NONE, WXK_NONE);
49             assertSortModifierKeys(WXK_NONE, WXK_CONTROL, WXK_NONE,
50                                    WXK_CONTROL, WXK_NONE, WXK_NONE);
51 
52             assertSortModifierKeys(WXK_NONE, WXK_NONE, WXK_ALT,
53                                    WXK_ALT, WXK_NONE, WXK_NONE);
54             assertSortModifierKeys(WXK_NONE, WXK_NONE, WXK_SHIFT,
55                                    WXK_SHIFT, WXK_NONE, WXK_NONE);
56             assertSortModifierKeys(WXK_NONE, WXK_NONE, WXK_CONTROL,
57                                    WXK_CONTROL, WXK_NONE, WXK_NONE);
58 
59 #ifdef __APPLE__
60             assertSortModifierKeys(WXK_ALT, WXK_SHIFT, WXK_CONTROL,
61                                    WXK_ALT, WXK_SHIFT, WXK_CONTROL);
62             assertSortModifierKeys(WXK_ALT, WXK_CONTROL, WXK_SHIFT,
63                                    WXK_ALT, WXK_SHIFT, WXK_CONTROL);
64             assertSortModifierKeys(WXK_CONTROL, WXK_ALT, WXK_SHIFT,
65                                    WXK_ALT, WXK_SHIFT, WXK_CONTROL);
66             assertSortModifierKeys(WXK_SHIFT, WXK_ALT, WXK_CONTROL,
67                                    WXK_ALT, WXK_SHIFT, WXK_CONTROL);
68             assertSortModifierKeys(WXK_SHIFT, WXK_CONTROL, WXK_ALT,
69                                    WXK_ALT, WXK_SHIFT, WXK_CONTROL);
70 #else
71             assertSortModifierKeys(WXK_ALT, WXK_SHIFT, WXK_CONTROL,
72                                    WXK_CONTROL, WXK_ALT, WXK_SHIFT);
73             assertSortModifierKeys(WXK_ALT, WXK_CONTROL, WXK_SHIFT,
74                                    WXK_CONTROL, WXK_ALT, WXK_SHIFT);
75             assertSortModifierKeys(WXK_CONTROL, WXK_ALT, WXK_SHIFT,
76                                    WXK_CONTROL, WXK_ALT, WXK_SHIFT);
77             assertSortModifierKeys(WXK_SHIFT, WXK_ALT, WXK_CONTROL,
78                                    WXK_CONTROL, WXK_ALT, WXK_SHIFT);
79             assertSortModifierKeys(WXK_SHIFT, WXK_CONTROL, WXK_ALT,
80                                    WXK_CONTROL, WXK_ALT, WXK_SHIFT);
81 #endif
82         }
83 
84 #ifdef __linux__
TEST(KeyboardShortcutTest,isShortcutValid)85         TEST(KeyboardShortcutTest, isShortcutValid) {
86             ASSERT_FALSE(KeyboardShortcut::isShortcutValid(WXK_TAB));
87             ASSERT_FALSE(KeyboardShortcut::isShortcutValid(WXK_TAB, WXK_CONTROL));
88             ASSERT_FALSE(KeyboardShortcut::isShortcutValid(WXK_ESCAPE));
89             ASSERT_FALSE(KeyboardShortcut::isShortcutValid(WXK_ESCAPE, WXK_SHIFT));
90 
91             ASSERT_FALSE(KeyboardShortcut::isShortcutValid(WXK_LEFT));
92             ASSERT_TRUE(KeyboardShortcut::isShortcutValid(WXK_LEFT, WXK_SHIFT));
93             ASSERT_FALSE(KeyboardShortcut::isShortcutValid(WXK_RIGHT));
94             ASSERT_TRUE(KeyboardShortcut::isShortcutValid(WXK_RIGHT, WXK_CONTROL));
95             ASSERT_FALSE(KeyboardShortcut::isShortcutValid(WXK_UP));
96             ASSERT_TRUE(KeyboardShortcut::isShortcutValid(WXK_UP, WXK_ALT));
97             ASSERT_FALSE(KeyboardShortcut::isShortcutValid(WXK_DOWN));
98             ASSERT_TRUE(KeyboardShortcut::isShortcutValid(WXK_DOWN, WXK_CONTROL, WXK_ALT));
99         }
100 #endif
101 
TEST(KeyboardShortcutTest,staticModifierKeyMenuText)102         TEST(KeyboardShortcutTest, staticModifierKeyMenuText) {
103             ASSERT_WXSTR_EQ(wxString("Ctrl"), KeyboardShortcut::modifierMenuString(WXK_CONTROL));
104             ASSERT_WXSTR_EQ(wxString("Alt"), KeyboardShortcut::modifierMenuString(WXK_ALT));
105             ASSERT_WXSTR_EQ(wxString("Shift"), KeyboardShortcut::modifierMenuString(WXK_SHIFT));
106             ASSERT_WXSTR_EQ(wxString(""), KeyboardShortcut::modifierMenuString(WXK_TAB));
107         }
108 
TEST(KeyboardShortcutTest,modifierDisplayString)109         TEST(KeyboardShortcutTest, modifierDisplayString) {
110 #ifdef __APPLE__
111             ASSERT_WXSTR_EQ(wxString(L"\u2318"), KeyboardShortcut::modifierDisplayString(WXK_CONTROL));
112             ASSERT_WXSTR_EQ(wxString(L"\u2325"), KeyboardShortcut::modifierDisplayString(WXK_ALT));
113             ASSERT_WXSTR_EQ(wxString(L"\u21E7"), KeyboardShortcut::modifierDisplayString(WXK_SHIFT));
114             ASSERT_WXSTR_EQ(wxString(""), KeyboardShortcut::modifierDisplayString(WXK_TAB));
115 #else
116             ASSERT_WXSTR_EQ(wxString("Ctrl"), KeyboardShortcut::modifierDisplayString(WXK_CONTROL));
117             ASSERT_WXSTR_EQ(wxString("Alt"), KeyboardShortcut::modifierDisplayString(WXK_ALT));
118             ASSERT_WXSTR_EQ(wxString("Shift"), KeyboardShortcut::modifierDisplayString(WXK_SHIFT));
119             ASSERT_WXSTR_EQ(wxString(""), KeyboardShortcut::modifierDisplayString(WXK_TAB));
120 #endif
121         }
122 
TEST(KeyboardShortcutTest,staticShortcutDisplayText)123         TEST(KeyboardShortcutTest, staticShortcutDisplayText) {
124 #ifdef __APPLE__
125             ASSERT_WXSTR_EQ(wxString("C"), KeyboardShortcut::shortcutDisplayString('C', WXK_NONE, WXK_NONE, WXK_NONE));
126             ASSERT_WXSTR_EQ(wxString(L"\u238B"), KeyboardShortcut::shortcutDisplayString(WXK_ESCAPE, WXK_NONE, WXK_NONE, WXK_NONE));
127             ASSERT_WXSTR_EQ(wxString("F11"), KeyboardShortcut::shortcutDisplayString(WXK_F11, WXK_NONE, WXK_NONE, WXK_NONE));
128             ASSERT_WXSTR_EQ(wxString(L"\u2318D"), KeyboardShortcut::shortcutDisplayString('D', WXK_CONTROL, WXK_NONE, WXK_NONE));
129             ASSERT_WXSTR_EQ(wxString(L"\u2318D"), KeyboardShortcut::shortcutDisplayString('D', WXK_NONE, WXK_NONE, WXK_CONTROL));
130             ASSERT_WXSTR_EQ(wxString(L"\u2325\u2318S"), KeyboardShortcut::shortcutDisplayString('S', WXK_CONTROL, WXK_NONE, WXK_ALT));
131 #else
132             ASSERT_WXSTR_EQ(wxString("C"), KeyboardShortcut::shortcutDisplayString('C', WXK_NONE, WXK_NONE, WXK_NONE));
133             ASSERT_WXSTR_EQ(wxString("Esc"), KeyboardShortcut::shortcutDisplayString(WXK_ESCAPE, WXK_NONE, WXK_NONE, WXK_NONE));
134             ASSERT_WXSTR_EQ(wxString("F11"), KeyboardShortcut::shortcutDisplayString(WXK_F11, WXK_NONE, WXK_NONE, WXK_NONE));
135             ASSERT_WXSTR_EQ(wxString("Ctrl+D"), KeyboardShortcut::shortcutDisplayString('D', WXK_CONTROL, WXK_NONE, WXK_NONE));
136             ASSERT_WXSTR_EQ(wxString("Ctrl+D"), KeyboardShortcut::shortcutDisplayString('D', WXK_NONE, WXK_NONE, WXK_CONTROL));
137             ASSERT_WXSTR_EQ(wxString("Ctrl+Alt+S"), KeyboardShortcut::shortcutDisplayString('S', WXK_ALT, WXK_CONTROL, WXK_NONE));
138 #endif
139         }
140 
TEST(KeyboardShortcutTest,parseShortcut)141         TEST(KeyboardShortcutTest, parseShortcut) {
142             int m1, m2, m3, k;
143 
144             ASSERT_TRUE(KeyboardShortcut::parseShortcut("", k, m1, m2, m3));
145             ASSERT_EQ(WXK_NONE, m1);
146             ASSERT_EQ(WXK_NONE, m2);
147             ASSERT_EQ(WXK_NONE, m3);
148             ASSERT_EQ(WXK_NONE, k);
149 
150             ASSERT_FALSE(KeyboardShortcut::parseShortcut("asdf", k, m1, m2, m3));
151             ASSERT_FALSE(KeyboardShortcut::parseShortcut(" D", k, m1, m2, m3));
152             ASSERT_FALSE(KeyboardShortcut::parseShortcut("D ", k, m1, m2, m3));
153 
154             ASSERT_TRUE(KeyboardShortcut::parseShortcut("D", k, m1, m2, m3));
155             ASSERT_EQ(WXK_NONE, m1);
156             ASSERT_EQ(WXK_NONE, m2);
157             ASSERT_EQ(WXK_NONE, m3);
158             ASSERT_EQ('D', k);
159 
160 #ifdef __APPLE__
161             ASSERT_FALSE(KeyboardShortcut::parseShortcut("\u2318+D", k, m1, m2, m3));
162 
163             ASSERT_TRUE(KeyboardShortcut::parseShortcut("\u2318", k, m1, m2, m3));
164             ASSERT_EQ(WXK_CONTROL, m1);
165             ASSERT_EQ(WXK_NONE, m2);
166             ASSERT_EQ(WXK_NONE, m3);
167             ASSERT_EQ(WXK_NONE, k);
168 
169             ASSERT_TRUE(KeyboardShortcut::parseShortcut("\u2318D", k, m1, m2, m3));
170             ASSERT_EQ(WXK_CONTROL, m1);
171             ASSERT_EQ(WXK_NONE, m2);
172             ASSERT_EQ(WXK_NONE, m3);
173             ASSERT_EQ('D', k);
174 
175             ASSERT_TRUE(KeyboardShortcut::parseShortcut("\u2318\u2325D", k, m1, m2, m3));
176             ASSERT_EQ(WXK_ALT, m1);
177             ASSERT_EQ(WXK_CONTROL, m2);
178             ASSERT_EQ(WXK_NONE, m3);
179             ASSERT_EQ('D', k);
180 
181             ASSERT_TRUE(KeyboardShortcut::parseShortcut("\u2318\u2325\u21E7\u21E5", k, m1, m2, m3));
182             ASSERT_EQ(WXK_ALT, m1);
183             ASSERT_EQ(WXK_SHIFT, m2);
184             ASSERT_EQ(WXK_CONTROL, m3);
185             ASSERT_EQ(WXK_TAB, k);
186 #else
187             ASSERT_FALSE(KeyboardShortcut::parseShortcut("Ctrl D", k, m1, m2, m3));
188 
189             ASSERT_TRUE(KeyboardShortcut::parseShortcut("Ctrl", k, m1, m2, m3));
190             ASSERT_EQ(WXK_CONTROL, m1);
191             ASSERT_EQ(WXK_NONE, m2);
192             ASSERT_EQ(WXK_NONE, m3);
193             ASSERT_EQ(WXK_NONE, k);
194 
195             ASSERT_TRUE(KeyboardShortcut::parseShortcut("Ctrl+D", k, m1, m2, m3));
196             ASSERT_EQ(WXK_CONTROL, m1);
197             ASSERT_EQ(WXK_NONE, m2);
198             ASSERT_EQ(WXK_NONE, m3);
199             ASSERT_EQ('D', k);
200 
201             ASSERT_TRUE(KeyboardShortcut::parseShortcut("Alt+Ctrl+D", k, m1, m2, m3));
202             ASSERT_EQ(WXK_CONTROL, m1);
203             ASSERT_EQ(WXK_ALT, m2);
204             ASSERT_EQ(WXK_NONE, m3);
205             ASSERT_EQ('D', k);
206 
207             ASSERT_TRUE(KeyboardShortcut::parseShortcut("Alt+Ctrl+Shift+Tab", k, m1, m2, m3));
208             ASSERT_EQ(WXK_CONTROL, m1);
209             ASSERT_EQ(WXK_ALT, m2);
210             ASSERT_EQ(WXK_SHIFT, m3);
211             ASSERT_EQ(WXK_TAB, k);
212 #endif
213         }
214 
TEST(KeyboardShortcutTest,constructWithString)215         TEST(KeyboardShortcutTest, constructWithString) {
216             StringStream test;
217             test << static_cast<int>('D') << ":" << WXK_CONTROL << ":" << WXK_ALT << ":" << WXK_NONE;
218 
219             const KeyboardShortcut shortcut(test.str());
220 #ifdef __APPLE__
221             ASSERT_EQ(WXK_ALT, shortcut.modifier1());
222             ASSERT_EQ(WXK_CONTROL, shortcut.modifier2());
223 #else
224             ASSERT_EQ(WXK_CONTROL, shortcut.modifier1());
225             ASSERT_EQ(WXK_ALT, shortcut.modifier2());
226 #endif
227             ASSERT_EQ(WXK_NONE, shortcut.modifier3());
228             ASSERT_EQ('D', shortcut.key());
229         }
230 
TEST(KeyboardShortcutTest,matches)231         TEST(KeyboardShortcutTest, matches) {
232             const KeyboardShortcut shortcut('D', WXK_CONTROL, WXK_ALT);
233 
234             ASSERT_FALSE(shortcut.matches('S', WXK_CONTROL, WXK_ALT));
235             ASSERT_FALSE(shortcut.matches('D', WXK_CONTROL, WXK_SHIFT));
236             ASSERT_FALSE(shortcut.matches('D', WXK_SHIFT));
237             ASSERT_FALSE(shortcut.matches('D', WXK_NONE));
238             ASSERT_TRUE(shortcut.matches('D', WXK_CONTROL, WXK_ALT));
239             ASSERT_TRUE(shortcut.matches('D', WXK_ALT, WXK_CONTROL));
240             ASSERT_TRUE(shortcut.matches('D', WXK_ALT, WXK_NONE, WXK_CONTROL));
241             ASSERT_TRUE(shortcut.matches('D', WXK_NONE, WXK_ALT, WXK_CONTROL));
242         }
243 
TEST(KeyboardShortcutTest,modifierKeyMenuText)244         TEST(KeyboardShortcutTest, modifierKeyMenuText) {
245             const KeyboardShortcut shortcut('D', WXK_ALT, WXK_CONTROL);
246 #ifdef __APPLE__
247             ASSERT_WXSTR_EQ(wxString("Alt+Ctrl"), shortcut.modifierMenuString());
248 #else
249             ASSERT_WXSTR_EQ(wxString("Ctrl+Alt"), shortcut.modifierMenuString());
250 #endif
251         }
252     }
253 }
254