]> git.sesse.net Git - kdenlive/blobdiff - src/unicodedialog.cpp
Const'ref
[kdenlive] / src / unicodedialog.cpp
index 53e1a9695bdbe1e46111e70f3b332971733ccc1e..d55c30dfaffe1edca32bda5b06fdb1b642d9e0f0 100644 (file)
@@ -9,66 +9,96 @@
 
 #include "unicodedialog.h"
 
+#include <QWheelEvent>
+
 /// CONSTANTS
 
 const int MAX_LENGTH_HEX = 4;
 const uint MAX_UNICODE_V1 = 65535;
 
 
+UnicodeDialog::UnicodeDialog(InputMethod inputMeth, QWidget *parent)
+    : KDialog(parent)
+{
+    setCaption( i18n("Details") );
+    setButtons( Ok|Cancel );
+    mUnicodeWidget = new UnicodeWidget(inputMeth);
+    connect(mUnicodeWidget, SIGNAL(charSelected(QString)), SIGNAL(charSelected(QString)));
+    setMainWidget(mUnicodeWidget);
+    connect(this, SIGNAL(okClicked()), SLOT(slotAccept()));
+}
+
+UnicodeDialog::~UnicodeDialog()
+{
+}
+
+void UnicodeDialog::slotAccept()
+{
+    mUnicodeWidget->slotReturnPressed();
+    accept();
+}
+
+
 /// CONSTRUCTORS/DECONSTRUCTORS
 
-UnicodeDialog::UnicodeDialog(InputMethod inputMeth) : inputMethod(inputMeth), lastCursorPos(0), lastUnicodeNumber("")
+UnicodeWidget::UnicodeWidget(UnicodeDialog::InputMethod inputMeth, QWidget *parent)
+    : QWidget(parent),
+        inputMethod(inputMeth),
+        m_lastCursorPos(0)
 {
     setupUi(this);
+    readChoices();
+    showLastUnicode();
     connect(unicodeNumber, SIGNAL(textChanged(QString)), this, SLOT(slotTextChanged(QString)));
     connect(unicodeNumber, SIGNAL(returnPressed()), this, SLOT(slotReturnPressed()));
-    connect(arrowUp, SIGNAL(clicked()), this, SLOT(slotNextUnicode()));
-    connect(arrowDown, SIGNAL(clicked()), this, SLOT(slotPrevUnicode()));
+    connect(arrowUp, SIGNAL(clicked()), this, SLOT(slotPrevUnicode()));
+    connect(arrowDown, SIGNAL(clicked()), this, SLOT(slotNextUnicode()));
 
     switch (inputMethod) {
-    case InputHex:
+    case UnicodeDialog::InputHex:
         unicodeNumber->setMaxLength(MAX_LENGTH_HEX);
         break;
 
-    case InputDec:
+    case UnicodeDialog::InputDec:
         break;
     }
 
     arrowUp->setShortcut(Qt::Key_Up);
     arrowDown->setShortcut(Qt::Key_Down);
-
-    arrowUp->setToolTip(i18n("Next Unicode character (Arrow Up)"));
-    arrowDown->setToolTip(i18n("Previous Unicode character (Arrow Down)"));
+    unicode_link->setText(i18n("Information about unicode characters: <a href=\"http://decodeunicode.org\">http://decodeunicode.org</a>"));
+    arrowUp->setToolTip(i18n("Previous Unicode character (Arrow Up)"));
+    arrowDown->setToolTip(i18n("Next Unicode character (Arrow Down)"));
     unicodeNumber->setToolTip(i18n("Enter your Unicode number here. Allowed characters: [0-9] and [a-f]."));
+    unicodeNumber->selectAll(); // Selection will be reset by setToolTip and similar, so set it here
 }
 
-UnicodeDialog::~UnicodeDialog()
+UnicodeWidget::~UnicodeWidget()
 {
 }
-
-
 /// METHODS
 
-void UnicodeDialog::showLastUnicode()
+void UnicodeWidget::showLastUnicode()
 {
-    unicodeNumber->setText(lastUnicodeNumber);
+    unicodeNumber->setText(m_lastUnicodeNumber);
+    unicodeNumber->selectAll();
+    slotTextChanged(m_lastUnicodeNumber);
 }
 
-bool UnicodeDialog::controlCharacter(QString text)
+bool UnicodeWidget::controlCharacter(const QString &text)
 {
     bool isControlCharacter = false;
     QString t = text.toLower();
 
     switch (inputMethod) {
-    case InputHex:
-        if (t == ""
+    case UnicodeDialog::InputHex:
+        if (t.isEmpty()
                 || (t.length() == 1 && !(t == "9" || t == "a" || t == "d"))
                 || (t.length() == 2 && t.at(0) == QChar('1'))) {
             isControlCharacter = true;
         }
         break;
 
-    case InputDec:
+    case UnicodeDialog::InputDec:
         bool ok;
         isControlCharacter = controlCharacter(text.toUInt(&ok, 16));
         break;
@@ -77,7 +107,7 @@ bool UnicodeDialog::controlCharacter(QString text)
     return isControlCharacter;
 }
 
-bool UnicodeDialog::controlCharacter(uint value)
+bool UnicodeWidget::controlCharacter(uint value)
 {
     bool isControlCharacter = false;
 
@@ -88,29 +118,31 @@ bool UnicodeDialog::controlCharacter(uint value)
 
 }
 
-QString UnicodeDialog::trimmedUnicodeNumber(QString text)
+QString UnicodeWidget::trimmedUnicodeNumber(QString text)
 {
-    while (text.length() > 0 && text.at(0) == QChar('0')) {
+    while (!text.isEmpty() && text.at(0) == QChar('0')) {
         text = text.remove(0, 1);
     }
     return text;
 }
 
-QString UnicodeDialog::unicodeInfo(QString unicode_number)
+QString UnicodeWidget::unicodeInfo(const QString &unicode)
 {
     QString infoText(i18n("<small>(no character selected)</small>"));
-    if (unicode_number.length() == 0) return infoText;
+    if (unicode.length() == 0) return infoText;
 
-    QString u = trimmedUnicodeNumber(unicode_number).toLower();
+    QString u = trimmedUnicodeNumber(unicode).toLower();
 
     if (controlCharacter(u)) {
         infoText = i18n("Control character. Cannot be inserted/printed. See <a href=\"http://en.wikipedia.org/wiki/Control_character\">Wikipedia:Control_character</a>");
     } else if (u == "a") {
         infoText = i18n("Line Feed (newline character, \\\\n)");
     } else if (u == "20") {
-        infoText = i18n("Standard space character. (See U+00a0 and U+2000&#x2013;200b)");
+        infoText = i18n("Standard space character. (Other space characters: U+00a0, U+2000&#x2013;200b, U+202f)");
     } else if (u == "a0") {
-        infoText = i18n("No-break space. &amp;nbsp; in HTML. See U+0020.");
+        infoText = i18n("No-break space. &amp;nbsp; in HTML. See U+2009 and U+0020.");
+    } else if (u == "ab" || u == "bb" || u == "2039" || u == "203a") {
+        infoText = i18n("<p><strong>&laquo;</strong> (u+00ab, <code>&amp;lfquo;</code> in HTML) and <strong>&raquo;</strong> (u+00bb, <code>&amp;rfquo;</code> in HTML) are called Guillemets or angle quotes. Usage in different countries: France (with non-breaking Space 0x00a0), Switzerland, Germany, Finland and Sweden.</p><p><strong>&lsaquo;</strong> and <strong>&rsaquo;</strong> (U+2039/203a, <code>&amp;lsaquo;/&amp;rsaquo;</code>) are their single quote equivalents.</p><p>See <a href=\"http://en.wikipedia.org/wiki/Guillemets\">Wikipedia:Guillemets</a></p>");
     } else if (u == "2002") {
         infoText = i18n("En Space (width of an n)");
     } else if (u == "2003") {
@@ -126,17 +158,31 @@ QString UnicodeDialog::unicodeInfo(QString unicode_number)
     } else if (u == "2008") {
         infoText = i18n("Punctuation Space. Width the same as between a punctuation character and the next character.");
     } else if (u == "2009") {
-        infoText = i18n("Thin space, in HTML also &amp;thinsp;. See <a href=\"http://en.wikipedia.org/wiki/Space_(punctuation)\">Wikipedia:Space_(punctuation)</a>");
+        infoText = i18n("Thin space, in HTML also &amp;thinsp;. See U+202f and <a href=\"http://en.wikipedia.org/wiki/Space_(punctuation)\">Wikipedia:Space_(punctuation)</a>");
     } else if (u == "200a") {
         infoText = i18n("Hair Space. Thinner than U+2009.");
     } else if (u == "2019") {
         infoText = i18n("Punctuation Apostrophe. Should be used instead of U+0027. See <a href=\"http://en.wikipedia.org/wiki/Apostrophe\">Wikipedia:Apostrophe</a>");
     } else if (u == "2013") {
-        infoText = i18n("An en Dash (dash of the width of an n). See <a href=\"http://en.wikipedia.org/wiki/Dash\">Wikipedia:Dash</a>");
+        infoText = i18n("<p>An en Dash (dash of the width of an n).</p><p>Usage examples: In English language for value ranges (1878&#x2013;1903), for relationships/connections (Zurich&#x2013;Dublin). In the German language it is also used (with spaces!) for showing thoughts: &ldquo;Es war &#x2013; wie immer in den Ferien &#x2013; ein regnerischer Tag.</p> <p>See <a href=\"http://en.wikipedia.org/wiki/Dash\">Wikipedia:Dash</a></p>");
     } else if (u == "2014") {
-        infoText = i18n("An em Dash (dash of the widht of an m). See <a href=\"http://en.wikipedia.org/wiki/Dash\">Wikipedia:Dash</a>");
+        infoText = i18n("<p>An em Dash (dash of the width of an m).</p><p>Usage examples: In English language to mark&#x2014;like here&#x2014;thoughts. Traditionally without spaces. </p><p>See <a href=\"http://en.wikipedia.org/wiki/Dash\">Wikipedia:Dash</a></p>");
+    } else if (u == "202f") {
+        infoText = i18n("<p>Narrow no-break space. Has the same width as U+2009.</p><p>Usage: For units (spaces are marked with U+2423, &#x2423;): 230&#x2423;V, &#x2212;21&#x2423;&deg;C, 50&#x2423;lb, <em>but</em> 90&deg; (no space). In German for abbreviations (like: i.&#x202f;d.&#x202f;R. instead of i.&#xa0;d.&#xa0;R. with U+00a0).</p><p>See <a href=\"http://de.wikipedia.org/wiki/Schmales_Leerzeichen\">Wikipedia:de:Schmales_Leerzeichen</a></p>");
     } else if (u == "2026") {
-        infoText = i18n("Ellipsis: If text has been left out. See <a href=\"http://en.wikipedia.org/wiki/Ellipsis\">Wikipedia:Ellipsis</a>");
+        infoText = i18n("Ellipsis: If text has been left o&#x2026; See <a href=\"http://en.wikipedia.org/wiki/Ellipsis\">Wikipedia:Ellipsis</a>");
+    } else if (u == "2212") {
+        infoText = i18n("Minus sign. For numbers: &#x2212;42");
+    } else if (u == "2423") {
+        infoText = i18n("Open box; stands for a space.");
+    } else if (u == "2669") {
+        infoText = i18n("Quarter note (Am.) or crochet (Brit.). See <a href=\"http://en.wikipedia.org/wiki/Quarter_note\">Wikipedia:Quarter_note</a>");
+    } else if (u == "266a" || u == "266b") {
+        infoText = i18n("Eighth note (Am.) or quaver (Brit.). Half as long as a quarter note (U+2669). See <a href=\"http://en.wikipedia.org/wiki/Eighth_note\">Wikipedia:Eighth_note</a>");
+    } else if (u == "266c") {
+        infoText = i18n("Sixteenth note (Am.) or semiquaver (Brit.). Half as long as an eighth note (U+266a). See <a href=\"http://en.wikipedia.org/wiki/Sixteenth_note\">Wikipedia:Sixteenth_note</a>");
+    } else if (u == "1D162") {
+        infoText = i18n("Thirty-second note (Am.) or demisemiquaver (Brit.). Half as long as a sixteenth note (U+266b). See <a href=\"http://en.wikipedia.org/wiki/Thirty-second_note\">Wikipedia:Thirty-second_note</a>");
     } else {
         infoText = i18n("<small>No additional information available for this character.</small>");
     }
@@ -144,14 +190,14 @@ QString UnicodeDialog::unicodeInfo(QString unicode_number)
     return infoText;
 }
 
-QString UnicodeDialog::validateText(QString text)
+QString UnicodeWidget::validateText(const QString &text)
 {
     QRegExp regex("([0-9]|[a-f])", Qt::CaseInsensitive, QRegExp::RegExp2);
-    QString newText = "";
+    QString newText;
     int pos = 0;
 
     switch (inputMethod) {
-    case InputHex:
+    case UnicodeDialog::InputHex:
         // Remove all characters we don't want
         while ((pos = regex.indexIn(text, pos)) != -1) {
             newText += regex.cap(1);
@@ -159,7 +205,7 @@ QString UnicodeDialog::validateText(QString text)
         }
         break;
 
-    case InputDec:
+    case UnicodeDialog::InputDec:
         // TODO
         break;
     }
@@ -167,23 +213,23 @@ QString UnicodeDialog::validateText(QString text)
     return newText;
 }
 
-void UnicodeDialog::updateOverviewChars(uint unicode)
+void UnicodeWidget::updateOverviewChars(uint unicode)
 {
-    QString left = "";
-    QString right = "";
+    QString left;
+    QString right;
     uint i;
 
-    for (i = 1; i <= 4; i++) {
+    for (i = 1; i <= 4; ++i) {
         if (unicode > i && !controlCharacter(unicode - i)) {
-            left = " " + left;
+            left = ' ' + left;
             left = QChar(unicode - i) + left;
         }
     }
 
-    for (i = 1; i <= 8; i++) {
+    for (i = 1; i <= 8; ++i) {
         if (unicode + i <= MAX_UNICODE_V1 && !controlCharacter(unicode + i)) {
             right += QChar(unicode + i);
-            right += " ";
+            right += ' ';
         }
     }
 
@@ -192,20 +238,20 @@ void UnicodeDialog::updateOverviewChars(uint unicode)
 
 }
 
-void UnicodeDialog::clearOverviewChars()
+void UnicodeWidget::clearOverviewChars()
 {
     leftChars->setText("");
     rightChars->setText("");
 }
 
-QString UnicodeDialog::nextUnicode(QString text, Direction direction)
+QString UnicodeWidget::nextUnicode(const QString &text, Direction direction)
 {
     uint value = 0;
-    QString newText = "";
+    QString newText;
     bool ok;
 
     switch (inputMethod) {
-    case InputHex:
+    case UnicodeDialog::InputHex:
         value = text.toUInt(&ok, 16);
         switch (direction) {
         case Backward:
@@ -222,20 +268,39 @@ QString UnicodeDialog::nextUnicode(QString text, Direction direction)
         newText.setNum(value, 16);
         break;
 
-    case InputDec:
+    case UnicodeDialog::InputDec:
         break;
     }
 
     return newText;
 }
 
+void UnicodeWidget::readChoices()
+{
+    // Get a pointer to a shared configuration instance, then get the TitleWidget group.
+    KSharedConfigPtr config = KGlobal::config();
+    KConfigGroup titleConfig(config, "TitleWidget");
+
+    // Default is 2013 because there is also (perhaps interesting) information.
+    m_lastUnicodeNumber = titleConfig.readEntry("unicode_number", QString("2013"));
+}
+
+void UnicodeWidget::writeChoices()
+{
+    // Get a pointer to a shared configuration instance, then get the TitleWidget group.
+    KSharedConfigPtr config = KGlobal::config();
+    KConfigGroup titleConfig(config, "TitleWidget");
+
+    titleConfig.writeEntry("unicode_number", m_lastUnicodeNumber);
+}
+
 
 /// SLOTS
 
 /**
  * \brief Validates the entered Unicode number and displays its Unicode character.
  */
-void UnicodeDialog::slotTextChanged(QString text)
+void UnicodeWidget::slotTextChanged(const QString &text)
 {
     unicodeNumber->blockSignals(true);
 
@@ -244,8 +309,8 @@ void UnicodeDialog::slotTextChanged(QString text)
         unicodeChar->setText("");
         unicodeNumber->setText("");
         clearOverviewChars();
-        lastCursorPos = 0;
-        lastUnicodeNumber = "";
+        m_lastCursorPos = 0;
+        m_lastUnicodeNumber = "";
         labelInfoText->setText(unicodeInfo(""));
 
     } else {
@@ -259,10 +324,10 @@ void UnicodeDialog::slotTextChanged(QString text)
         bool ok;
         uint value = 0;
         switch (inputMethod) {
-        case InputHex:
+        case UnicodeDialog::InputHex:
             value = newText.toUInt(&ok, 16);
             break;
-        case InputDec:
+        case UnicodeDialog::InputDec:
             value = newText.toUInt(&ok, 10);
             break;
         }
@@ -274,12 +339,12 @@ void UnicodeDialog::slotTextChanged(QString text)
 
         // If an invalid character has been entered:
         // Reset the cursor position because the entered char has been deleted.
-        if (text != newText && newText == lastUnicodeNumber) {
-            unicodeNumber->setCursorPosition(lastCursorPos);
+        if (text != newText && newText == m_lastUnicodeNumber) {
+            unicodeNumber->setCursorPosition(m_lastCursorPos);
         }
 
-        lastCursorPos = unicodeNumber->cursorPosition();
-        lastUnicodeNumber = newText;
+        m_lastCursorPos = unicodeNumber->cursorPosition();
+        m_lastUnicodeNumber = newText;
 
         labelInfoText->setText(unicodeInfo(newText));
         unicodeChar->setText(QChar(value));
@@ -292,25 +357,36 @@ void UnicodeDialog::slotTextChanged(QString text)
  * When return pressed, we return the selected unicode character
  * if it was not a control character.
  */
-void UnicodeDialog::slotReturnPressed()
+void UnicodeWidget::slotReturnPressed()
 {
-    QString text = trimmedUnicodeNumber(unicodeNumber->text());
+    unicodeNumber->setFocus();
+    const QString text = trimmedUnicodeNumber(unicodeNumber->text());
     if (!controlCharacter(text)) {
         emit charSelected(unicodeChar->text());
+        writeChoices();
     }
-    emit accept();
 }
 
-void UnicodeDialog::slotNextUnicode()
+void UnicodeWidget::slotNextUnicode()
 {
-    QString text = unicodeNumber->text();
+    const QString text = unicodeNumber->text();
     unicodeNumber->setText(nextUnicode(text, Forward));
 }
 
-void UnicodeDialog::slotPrevUnicode()
+void UnicodeWidget::slotPrevUnicode()
 {
-    QString text = unicodeNumber->text();
+    const QString text = unicodeNumber->text();
     unicodeNumber->setText(nextUnicode(text, Backward));
 }
 
+void UnicodeWidget::wheelEvent(QWheelEvent * event)
+{
+    if (frame->underMouse()) {
+        if (event->delta() > 0)
+            slotNextUnicode();
+        else
+            slotPrevUnicode();
+    }
+}
+
 #include "unicodedialog.moc"