]> git.sesse.net Git - kdenlive/blob - src/unicodedialog.cpp
clean up reindentation
[kdenlive] / src / unicodedialog.cpp
1 /***************************************************************************
2  *   Copyright (C) 2008 by Simon Andreas Eugster (simon.eu@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
10 #include "unicodedialog.h"
11
12 /// CONSTANTS
13
14 const int MAX_LENGTH_HEX = 4;
15 const uint MAX_UNICODE_V1 = 65535;
16
17
18 /// CONSTRUCTORS/DECONSTRUCTORS
19
20 UnicodeDialog::UnicodeDialog(InputMethod inputMeth) : inputMethod(inputMeth), lastCursorPos(0), lastUnicodeNumber("")
21 {
22     setupUi(this);
23     connect(unicodeNumber, SIGNAL(textChanged(QString)), this, SLOT(slotTextChanged(QString)));
24     connect(unicodeNumber, SIGNAL(returnPressed()), this, SLOT(slotReturnPressed()));
25     connect(arrowUp, SIGNAL(clicked()), this, SLOT(slotNextUnicode()));
26     connect(arrowDown, SIGNAL(clicked()), this, SLOT(slotPrevUnicode()));
27
28     switch (inputMethod) {
29     case InputHex:
30         unicodeNumber->setMaxLength(MAX_LENGTH_HEX);
31         break;
32
33     case InputDec:
34         break;
35     }
36
37     arrowUp->setShortcut(Qt::Key_Up);
38     arrowDown->setShortcut(Qt::Key_Down);
39
40     arrowUp->setToolTip(i18n("Next Unicode character (Arrow Up)"));
41     arrowDown->setToolTip(i18n("Previous Unicode character (Arrow Down)"));
42     unicodeNumber->setToolTip(i18n("Enter your Unicode number here. Allowed characters: [0-9] and [a-f]."));
43 }
44
45 UnicodeDialog::~UnicodeDialog()
46 {
47 }
48
49
50 /// METHODS
51
52 void UnicodeDialog::showLastUnicode()
53 {
54     unicodeNumber->setText(lastUnicodeNumber);
55 }
56
57 bool UnicodeDialog::controlCharacter(QString text)
58 {
59     bool isControlCharacter = false;
60     QString t = text.toLower();
61
62     switch (inputMethod) {
63     case InputHex:
64         if (t == ""
65                 || (t.length() == 1 && !(t == "9" || t == "a" || t == "d"))
66                 || (t.length() == 2 && t.at(0) == QChar('1'))) {
67             isControlCharacter = true;
68         }
69         break;
70
71     case InputDec:
72         bool ok;
73         isControlCharacter = controlCharacter(text.toUInt(&ok, 16));
74         break;
75     }
76
77     return isControlCharacter;
78 }
79
80 bool UnicodeDialog::controlCharacter(uint value)
81 {
82     bool isControlCharacter = false;
83
84     if (value < 32 && !(value == 9 || value == 10 || value == 13)) {
85         isControlCharacter = true;
86     }
87     return isControlCharacter;
88
89 }
90
91 QString UnicodeDialog::trimmedUnicodeNumber(QString text)
92 {
93     while (text.length() > 0 && text.at(0) == QChar('0')) {
94         text = text.remove(0, 1);
95     }
96     return text;
97 }
98
99 QString UnicodeDialog::unicodeInfo(QString unicode_number)
100 {
101     QString infoText(i18n("<small>(no character selected)</small>"));
102     if (unicode_number.length() == 0) return infoText;
103
104     QString u = trimmedUnicodeNumber(unicode_number).toLower();
105
106     if (controlCharacter(u)) {
107         infoText = i18n("Control character. Cannot be inserted/printed. See <a href=\"http://en.wikipedia.org/wiki/Control_character\">Wikipedia:Control_character</a>");
108     } else if (u == "a") {
109         infoText = i18n("Line Feed (newline character, \\\\n)");
110     } else if (u == "20") {
111         infoText = i18n("Standard space character. (See U+00a0 and U+2000&#x2013;200b)");
112     } else if (u == "a0") {
113         infoText = i18n("No-break space. &amp;nbsp; in HTML. See U+0020.");
114     } else if (u == "2002") {
115         infoText = i18n("En Space (width of an n)");
116     } else if (u == "2003") {
117         infoText = i18n("Em Space (width of an m)");
118     } else if (u == "2004") {
119         infoText = i18n("Three-Per-Em Space. Width: 1/3 of one <em>em</em>");
120     } else if (u == "2005") {
121         infoText = i18n("Four-Per-Em Space. Width: 1/4 of one <em>em</em>");
122     } else if (u == "2006") {
123         infoText = i18n("Six-Per-Em Space. Width: 1/6 of one <em>em</em>");
124     } else if (u == "2007") {
125         infoText = i18n("Figure space (non-breaking). Width of a digit if digits have fixed width in this font.");
126     } else if (u == "2008") {
127         infoText = i18n("Punctuation Space. Width the same as between a punctuation character and the next character.");
128     } else if (u == "2009") {
129         infoText = i18n("Thin space, in HTML also &amp;thinsp;. See <a href=\"http://en.wikipedia.org/wiki/Space_(punctuation)\">Wikipedia:Space_(punctuation)</a>");
130     } else if (u == "200a") {
131         infoText = i18n("Hair Space. Thinner than U+2009.");
132     } else if (u == "2019") {
133         infoText = i18n("Punctuation Apostrophe. Should be used instead of U+0027. See <a href=\"http://en.wikipedia.org/wiki/Apostrophe\">Wikipedia:Apostrophe</a>");
134     } else if (u == "2013") {
135         infoText = i18n("An en Dash (dash of the width of an n). See <a href=\"http://en.wikipedia.org/wiki/Dash\">Wikipedia:Dash</a>");
136     } else if (u == "2014") {
137         infoText = i18n("An em Dash (dash of the widht of an m). See <a href=\"http://en.wikipedia.org/wiki/Dash\">Wikipedia:Dash</a>");
138     } else if (u == "2026") {
139         infoText = i18n("Ellipsis: If text has been left out. See <a href=\"http://en.wikipedia.org/wiki/Ellipsis\">Wikipedia:Ellipsis</a>");
140     } else {
141         infoText = i18n("<small>No additional information available for this character.</small>");
142     }
143
144     return infoText;
145 }
146
147 QString UnicodeDialog::validateText(QString text)
148 {
149     QRegExp regex("([0-9]|[a-f])", Qt::CaseInsensitive, QRegExp::RegExp2);
150     QString newText = "";
151     int pos = 0;
152
153     switch (inputMethod) {
154     case InputHex:
155         // Remove all characters we don't want
156         while ((pos = regex.indexIn(text, pos)) != -1) {
157             newText += regex.cap(1);
158             pos++;
159         }
160         break;
161
162     case InputDec:
163         // TODO
164         break;
165     }
166
167     return newText;
168 }
169
170 void UnicodeDialog::updateOverviewChars(uint unicode)
171 {
172     QString left = "";
173     QString right = "";
174     uint i;
175
176     for (i = 1; i <= 4; i++) {
177         if (unicode > i && !controlCharacter(unicode - i)) {
178             left = " " + left;
179             left = QChar(unicode - i) + left;
180         }
181     }
182
183     for (i = 1; i <= 8; i++) {
184         if (unicode + i <= MAX_UNICODE_V1 && !controlCharacter(unicode + i)) {
185             right += QChar(unicode + i);
186             right += " ";
187         }
188     }
189
190     leftChars->setText(left);
191     rightChars->setText(right);
192
193 }
194
195 void UnicodeDialog::clearOverviewChars()
196 {
197     leftChars->setText("");
198     rightChars->setText("");
199 }
200
201 QString UnicodeDialog::nextUnicode(QString text, Direction direction)
202 {
203     uint value = 0;
204     QString newText = "";
205     bool ok;
206
207     switch (inputMethod) {
208     case InputHex:
209         value = text.toUInt(&ok, 16);
210         switch (direction) {
211         case Backward:
212             value--;
213             break;
214         default:
215             value++;
216             break;
217         }
218         // Wrapping
219         if (value == (uint) - 1) value = MAX_UNICODE_V1;
220         if (value > MAX_UNICODE_V1) value = 0;
221
222         newText.setNum(value, 16);
223         break;
224
225     case InputDec:
226         break;
227     }
228
229     return newText;
230 }
231
232
233 /// SLOTS
234
235 /**
236  * \brief Validates the entered Unicode number and displays its Unicode character.
237  */
238 void UnicodeDialog::slotTextChanged(QString text)
239 {
240     unicodeNumber->blockSignals(true);
241
242     QString newText = validateText(text);
243     if (newText.length() == 0) {
244         unicodeChar->setText("");
245         unicodeNumber->setText("");
246         clearOverviewChars();
247         lastCursorPos = 0;
248         lastUnicodeNumber = "";
249         labelInfoText->setText(unicodeInfo(""));
250
251     } else {
252
253         int cursorPos = unicodeNumber->cursorPosition();
254
255         unicodeNumber->setText(newText);
256         unicodeNumber->setCursorPosition(cursorPos);
257
258         // Get the decimal number as uint to create the QChar from
259         bool ok;
260         uint value = 0;
261         switch (inputMethod) {
262         case InputHex:
263             value = newText.toUInt(&ok, 16);
264             break;
265         case InputDec:
266             value = newText.toUInt(&ok, 10);
267             break;
268         }
269         updateOverviewChars(value);
270
271         if (!ok) {
272             // Impossible! validateText never fails!
273         }
274
275         // If an invalid character has been entered:
276         // Reset the cursor position because the entered char has been deleted.
277         if (text != newText && newText == lastUnicodeNumber) {
278             unicodeNumber->setCursorPosition(lastCursorPos);
279         }
280
281         lastCursorPos = unicodeNumber->cursorPosition();
282         lastUnicodeNumber = newText;
283
284         labelInfoText->setText(unicodeInfo(newText));
285         unicodeChar->setText(QChar(value));
286     }
287
288     unicodeNumber->blockSignals(false);
289 }
290
291 /**
292  * When return pressed, we return the selected unicode character
293  * if it was not a control character.
294  */
295 void UnicodeDialog::slotReturnPressed()
296 {
297     QString text = trimmedUnicodeNumber(unicodeNumber->text());
298     if (!controlCharacter(text)) {
299         emit charSelected(unicodeChar->text());
300     }
301     emit accept();
302 }
303
304 void UnicodeDialog::slotNextUnicode()
305 {
306     QString text = unicodeNumber->text();
307     unicodeNumber->setText(nextUnicode(text, Forward));
308 }
309
310 void UnicodeDialog::slotPrevUnicode()
311 {
312     QString text = unicodeNumber->text();
313     unicodeNumber->setText(nextUnicode(text, Backward));
314 }
315
316 #include "unicodedialog.moc"