From 4a1da7099f4add2933de7ba2044ba8936762c234 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Thu, 21 Jan 2016 02:50:51 -0800 Subject: [PATCH 01/12] Added markdown support. Underline, Italics, Strikethrough and Bold supported. --- src/chatlog/chatmessage.cpp | 55 +++++++++++++++++++++++++++++++++++++ src/chatlog/chatmessage.h | 1 + 2 files changed, 56 insertions(+) diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index d2600f2db..27b73acb0 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -54,6 +54,9 @@ ChatMessage::Ptr ChatMessage::createChatMessage(const QString &sender, const QSt //quotes (green text) text = detectQuotes(detectAnchors(text), type); + //markdown + text = detectMarkdown(text); + switch(type) { case ACTION: @@ -175,6 +178,58 @@ void ChatMessage::hideDate() c->hide(); } +QString ChatMessage::detectMarkdown(const QString &str) +{ + QString out; + + // Create regex for certain markdown syntax + QRegExp exp("(\\*\\*)([^\\*\\*]*)(\\*\\*)" // Bold **text** + "|(\\*)([^\\*]*)(\\*)" // Italics *text* + "|(\\_)([^\\_]*)(\\_)" // Italics _text_ + "|(\\_\\_)([^\\_\\_]*)(\\_\\_)" // Italics __text__ + "|(\\-)([^\\-]*)(\\-)" // Underline -text- + "|(\\~)([^\\~]*)(\\~)" // Strike ~text~ + "|(\\~~)([^\\~\\~]*)(\\~~)" // Strike ~~text~~ + ); + + // Support for multi-line text + QStringList messageLines = str.split("\n"); + QStringList outLines; + for (int i = 0; i < messageLines.size(); ++i) + { + out = messageLines.at(i); + int offset = 0; + while ((offset = exp.indexIn(out, offset)) != -1) + { + QString snippet = exp.cap(); + + QString htmledSnippet; + + // Match captured string to corresponding md format + if (exp.cap(1) == "**") // Bold **text** + htmledSnippet = QString("%1").arg(snippet.mid(2,snippet.length()-4)); + else if (exp.cap(4) == "*" && snippet.length() > 2) // Italics *text* + htmledSnippet = QString("%1").arg(snippet.mid(1,snippet.length()-2)); + else if (exp.cap(7) == "_" && snippet.length() > 2) // Italics _text_ + htmledSnippet = QString("%1").arg(snippet.mid(1,snippet.length()-2)); + else if (exp.cap(10) == "__"&& snippet.length() > 4) // Italics __text__ + htmledSnippet = QString("%1").arg(snippet.mid(2,snippet.length()-4)); + else if (exp.cap(13) == "-" && snippet.length() > 2) // Underline -text- + htmledSnippet = QString("%1").arg(snippet.mid(1,snippet.length()-2)); + else if (exp.cap(16) == "~" && snippet.length() > 2) // Strikethrough ~text~ + htmledSnippet = QString("%1").arg(snippet.mid(1,snippet.length()-2)); + else if (exp.cap(19) == "~~" && snippet.length() > 4) // Strikethrough ~~text~~ + htmledSnippet = QString("%1").arg(snippet.mid(2,snippet.length()-4)); + else + htmledSnippet = snippet; + out.replace(offset, exp.cap().length(), htmledSnippet); + offset += htmledSnippet.length(); + } + outLines.push_back(out); + } + return outLines.join("\n"); +} + QString ChatMessage::detectAnchors(const QString &str) { QString out; diff --git a/src/chatlog/chatmessage.h b/src/chatlog/chatmessage.h index c92150d76..2de1d668c 100644 --- a/src/chatlog/chatmessage.h +++ b/src/chatlog/chatmessage.h @@ -61,6 +61,7 @@ public: void hideDate(); protected: + static QString detectMarkdown(const QString& str); static QString detectAnchors(const QString& str); static QString detectQuotes(const QString& str, MessageType type); static QString wrapDiv(const QString& str, const QString& div); From e15315b6181e6dabee81dbe54f9e6f38167db55f Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Sat, 23 Jan 2016 00:06:17 -0800 Subject: [PATCH 02/12] Added markdown preference chooser to settings which chat abides by. Don't parse md if only one character is involved. Prevent things like ~3~ being caught --- src/chatlog/chatmessage.cpp | 44 ++++++++----- src/chatlog/createChatMessage | 0 src/persistence/settings.cpp | 21 ++++++- src/persistence/settings.h | 4 ++ src/widget/form/settings/generalform.cpp | 13 ++++ src/widget/form/settings/generalform.h | 1 + src/widget/form/settings/generalsettings.ui | 70 ++++++++++++++++++--- 7 files changed, 130 insertions(+), 23 deletions(-) create mode 100644 src/chatlog/createChatMessage diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index 27b73acb0..6b9e08e79 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -55,7 +55,8 @@ ChatMessage::Ptr ChatMessage::createChatMessage(const QString &sender, const QSt text = detectQuotes(detectAnchors(text), type); //markdown - text = detectMarkdown(text); + if (Settings::getInstance().getMarkdownPreference() != 0) + text = detectMarkdown(text); switch(type) { @@ -183,13 +184,13 @@ QString ChatMessage::detectMarkdown(const QString &str) QString out; // Create regex for certain markdown syntax - QRegExp exp("(\\*\\*)([^\\*\\*]*)(\\*\\*)" // Bold **text** - "|(\\*)([^\\*]*)(\\*)" // Italics *text* - "|(\\_)([^\\_]*)(\\_)" // Italics _text_ - "|(\\_\\_)([^\\_\\_]*)(\\_\\_)" // Italics __text__ - "|(\\-)([^\\-]*)(\\-)" // Underline -text- - "|(\\~)([^\\~]*)(\\~)" // Strike ~text~ - "|(\\~~)([^\\~\\~]*)(\\~~)" // Strike ~~text~~ + QRegExp exp("(\\*\\*)([^\\*\\*]{2,})(\\*\\*)" // Bold **text** + "|(\\*)([^\\*]{2,})(\\*)" // Italics *text* + "|(\\_)([^\\_]{2,})(\\_)" // Italics _text_ + "|(\\_\\_)([^\\_\\_]{2,})(\\_\\_)" // Italics __text__ + "|(\\-)([^\\-]{2,})(\\-)" // Underline -text- + "|(\\~)([^\\~]{2,})(\\~)" // Strike ~text~ + "|(\\~~)([^\\~\\~]{2,})(\\~~)" // Strike ~~text~~ ); // Support for multi-line text @@ -205,21 +206,34 @@ QString ChatMessage::detectMarkdown(const QString &str) QString htmledSnippet; + // Check for surrounding spaces and/or beginning/end of line + if (!((snipCheck.startsWith(' ') || offset == 0) && (snipCheck.endsWith(' ') || offset + snipCheck.trimmed().length() == out.length()))) + { + offset += snippet.length(); + continue; + } + + int mul = 0; // Determines how many characters to strip from markdown text + + // Set mul depending on markdownPreference + if (Settings::getInstance().getMarkdownPreference() == 2) + mul = 2; + // Match captured string to corresponding md format if (exp.cap(1) == "**") // Bold **text** - htmledSnippet = QString("%1").arg(snippet.mid(2,snippet.length()-4)); + htmledSnippet = QString("%1").arg(snippet.mid(mul,snippet.length()-2*mul)); else if (exp.cap(4) == "*" && snippet.length() > 2) // Italics *text* - htmledSnippet = QString("%1").arg(snippet.mid(1,snippet.length()-2)); + htmledSnippet = QString("%1").arg(snippet.mid(mul/2,snippet.length()-mul)); else if (exp.cap(7) == "_" && snippet.length() > 2) // Italics _text_ - htmledSnippet = QString("%1").arg(snippet.mid(1,snippet.length()-2)); + htmledSnippet = QString("%1").arg(snippet.mid(mul/2,snippet.length()-mul)); else if (exp.cap(10) == "__"&& snippet.length() > 4) // Italics __text__ - htmledSnippet = QString("%1").arg(snippet.mid(2,snippet.length()-4)); + htmledSnippet = QString("%1").arg(snippet.mid(mul,snippet.length()-2*mul)); else if (exp.cap(13) == "-" && snippet.length() > 2) // Underline -text- - htmledSnippet = QString("%1").arg(snippet.mid(1,snippet.length()-2)); + htmledSnippet = QString("%1").arg(snippet.mid(mul/2,snippet.length()-mul)); else if (exp.cap(16) == "~" && snippet.length() > 2) // Strikethrough ~text~ - htmledSnippet = QString("%1").arg(snippet.mid(1,snippet.length()-2)); + htmledSnippet = QString("%1").arg(snippet.mid(mul/2,snippet.length()-mul)); else if (exp.cap(19) == "~~" && snippet.length() > 4) // Strikethrough ~~text~~ - htmledSnippet = QString("%1").arg(snippet.mid(2,snippet.length()-4)); + htmledSnippet = QString("%1").arg(snippet.mid(mul,snippet.length()-2*mul)); else htmledSnippet = snippet; out.replace(offset, exp.cap().length(), htmledSnippet); diff --git a/src/chatlog/createChatMessage b/src/chatlog/createChatMessage new file mode 100644 index 000000000..e69de29bb diff --git a/src/persistence/settings.cpp b/src/persistence/settings.cpp index 0839e4303..72a7a1ecf 100644 --- a/src/persistence/settings.cpp +++ b/src/persistence/settings.cpp @@ -177,6 +177,7 @@ void Settings::loadGlobal() separateWindow = s.value("separateWindow", false).toBool(); dontGroupWindows = s.value("dontGroupWindows", true).toBool(); groupchatPosition = s.value("groupchatPosition", true).toBool(); + markdownPreference = s.value("markdownPreference", 1).toInt(); s.endGroup(); s.beginGroup("Advanced"); @@ -242,7 +243,7 @@ void Settings::loadGlobal() camVideoFPS = s.value("camVideoFPS", 0).toUInt(); s.endGroup(); - // Read the embedded DHT bootsrap nodes list if needed + // Read the embedded DHT bootstrap nodes list if needed if (dhtServerList.isEmpty()) { QSettings rcs(":/conf/settings.ini", QSettings::IniFormat); @@ -395,6 +396,7 @@ void Settings::saveGlobal() s.setValue("groupchatPosition", groupchatPosition); s.setValue("autoSaveEnabled", autoSaveEnabled); s.setValue("globalAutoAcceptDir", globalAutoAcceptDir); + s.setValue("markdownPreference", markdownPreference); s.endGroup(); s.beginGroup("Advanced"); @@ -1028,6 +1030,23 @@ void Settings::setDateFormat(const QString &format) dateFormat = format; } +int Settings::getMarkdownPreference() const +{ + QMutexLocker locker{&bigLock}; + return markdownPreference; +} + +void Settings::setMarkdownPreference(int newValue) +{ + QMutexLocker locker{&bigLock}; + if (newValue < 0) + newValue = 1; + else if (newValue > 2) + newValue = 2; + + markdownPreference = newValue; +} + QByteArray Settings::getWindowGeometry() const { QMutexLocker locker{&bigLock}; diff --git a/src/persistence/settings.h b/src/persistence/settings.h index 59b8cc87b..32709a20c 100644 --- a/src/persistence/settings.h +++ b/src/persistence/settings.h @@ -175,6 +175,9 @@ public: int getThemeColor() const; void setThemeColor(const int& value); + int getMarkdownPreference() const; + void setMarkdownPreference(int newValue); + bool isCurstomEmojiFont() const; void setCurstomEmojiFont(bool value); @@ -367,6 +370,7 @@ private: // ChatView int firstColumnHandlePos; int secondColumnHandlePosFromRight; + int markdownPreference; QString timestampFormat; QString dateFormat; bool statusChangeNotificationEnabled; diff --git a/src/widget/form/settings/generalform.cpp b/src/widget/form/settings/generalform.cpp index 851c3057b..fdf7252bf 100644 --- a/src/widget/form/settings/generalform.cpp +++ b/src/widget/form/settings/generalform.cpp @@ -82,6 +82,9 @@ static QStringList langs = {"Български", "Türkçe", "Українська", "简体中文"}; +static QStringList mdPrefs = {"None", + "Show Characters", + "No Characters"}; static QStringList timeFormats = {"hh:mm AP", "hh:mm", "hh:mm:ss AP", "hh:mm:ss"}; // http://doc.qt.io/qt-4.8/qdate.html#fromString @@ -103,6 +106,10 @@ GeneralForm::GeneralForm(SettingsWidget *myParent) : bodyUI->transComboBox->insertItem(i, langs[i]); bodyUI->transComboBox->setCurrentIndex(locales.indexOf(Settings::getInstance().getTranslation())); + for (int i = 0; i < mdPrefs.size(); i++) + bodyUI->markdownComboBox->insertItem(i, mdPrefs[i]); + + bodyUI->markdownComboBox->setCurrentIndex(Settings::getInstance().getMarkdownPreference()); bodyUI->cbAutorun->setChecked(Settings::getInstance().getAutorun()); bool showSystemTray = Settings::getInstance().getShowSystemTray(); @@ -201,6 +208,7 @@ GeneralForm::GeneralForm(SettingsWidget *myParent) : connect(bodyUI->showWindow, &QCheckBox::stateChanged, this, &GeneralForm::onShowWindowChanged); connect(bodyUI->showInFront, &QCheckBox::stateChanged, this, &GeneralForm::onSetShowInFront); connect(bodyUI->notifySound, &QCheckBox::stateChanged, this, &GeneralForm::onSetNotifySound); + connect(bodyUI->markdownComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onMarkdownUpdated())); connect(bodyUI->groupAlwaysNotify, &QCheckBox::stateChanged, this, &GeneralForm::onSetGroupAlwaysNotify); connect(bodyUI->autoacceptFiles, &QCheckBox::stateChanged, this, &GeneralForm::onAutoAcceptFileChange); connect(bodyUI->autoSaveFilesDir, SIGNAL(clicked()), this, SLOT(onAutoSaveDirChange())); @@ -361,6 +369,11 @@ void GeneralForm::onUseEmoticonsChange() bodyUI->smileyPackBrowser->setEnabled(bodyUI->useEmoticons->isChecked()); } +void GeneralForm::onMarkdownUpdated() +{ + Settings::getInstance().setMarkdownPreference(bodyUI->markdownComboBox->currentIndex()); +} + void GeneralForm::onSetStatusChange() { Settings::getInstance().setStatusChangeNotificationEnabled(bodyUI->statusChanges->isChecked()); diff --git a/src/widget/form/settings/generalform.h b/src/widget/form/settings/generalform.h index 1657eb06c..1c141e51f 100644 --- a/src/widget/form/settings/generalform.h +++ b/src/widget/form/settings/generalform.h @@ -53,6 +53,7 @@ private slots: void onStyleSelected(QString style); void onTimestampSelected(int index); void onDateFormatSelected(int index); + void onMarkdownUpdated(); void onSetStatusChange(); void onAutoAwayChanged(); void onUseEmoticonsChange(); diff --git a/src/widget/form/settings/generalsettings.ui b/src/widget/form/settings/generalsettings.ui index cc1e3ab96..41e7418a5 100644 --- a/src/widget/form/settings/generalsettings.ui +++ b/src/widget/form/settings/generalsettings.ui @@ -6,7 +6,7 @@ 0 0 - 671 + 1312 1098 @@ -14,7 +14,16 @@ Form - + + 9 + + + 9 + + + 9 + + 9 @@ -30,8 +39,8 @@ 0 0 - 631 - 1141 + 1280 + 2394 @@ -227,6 +236,9 @@ instead of closing itself. Set to 0 to disable + + true + min @@ -236,9 +248,6 @@ instead of closing itself. 2147483647 - - true - @@ -350,6 +359,46 @@ instead of closing itself. + + + + + + The translation may not load until qTox restarts. + + + Markdown: + + + + + + + + 0 + 0 + + + + Select Markdown preference + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + @@ -432,6 +481,13 @@ will be sent to them when they appear online to you. + + + + + + + From fd31dd816d5108f1ffc0d0afdab2a4bc24ff526b Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Sat, 23 Jan 2016 02:49:11 -0800 Subject: [PATCH 03/12] Added space detection for markdown #imdeadinside --- src/chatlog/chatmessage.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index 6b9e08e79..54f46562b 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -26,6 +26,8 @@ #include "content/image.h" #include "content/notificationicon.h" +#include + #include "src/persistence/settings.h" #include "src/persistence/smileypack.h" #include "src/widget/style.h" @@ -202,7 +204,8 @@ QString ChatMessage::detectMarkdown(const QString &str) int offset = 0; while ((offset = exp.indexIn(out, offset)) != -1) { - QString snippet = exp.cap(); + QString snipCheck = out.mid(offset-1,exp.cap(0).length()+2); + QString snippet = exp.cap(0).trimmed(); QString htmledSnippet; @@ -219,21 +222,26 @@ QString ChatMessage::detectMarkdown(const QString &str) if (Settings::getInstance().getMarkdownPreference() == 2) mul = 2; + if (snippet.length() > 0) + { + qDebug() << "Offset: " << offset << " Grabbed snippet: " << snippet << " exp.cap(7): " << exp.cap(7); + } + // Match captured string to corresponding md format if (exp.cap(1) == "**") // Bold **text** - htmledSnippet = QString("%1").arg(snippet.mid(mul,snippet.length()-2*mul)); + htmledSnippet = QString(" %1 ").arg(snippet.mid(mul,snippet.length()-2*mul)); else if (exp.cap(4) == "*" && snippet.length() > 2) // Italics *text* - htmledSnippet = QString("%1").arg(snippet.mid(mul/2,snippet.length()-mul)); + htmledSnippet = QString(" %1 ").arg(snippet.mid(mul/2,snippet.length()-mul)); else if (exp.cap(7) == "_" && snippet.length() > 2) // Italics _text_ - htmledSnippet = QString("%1").arg(snippet.mid(mul/2,snippet.length()-mul)); + htmledSnippet = QString(" %1 ").arg(snippet.mid(mul/2,snippet.length()-mul)); else if (exp.cap(10) == "__"&& snippet.length() > 4) // Italics __text__ - htmledSnippet = QString("%1").arg(snippet.mid(mul,snippet.length()-2*mul)); + htmledSnippet = QString(" %1 ").arg(snippet.mid(mul,snippet.length()-2*mul)); else if (exp.cap(13) == "-" && snippet.length() > 2) // Underline -text- - htmledSnippet = QString("%1").arg(snippet.mid(mul/2,snippet.length()-mul)); + htmledSnippet = QString(" %1 ").arg(snippet.mid(mul/2,snippet.length()-mul)); else if (exp.cap(16) == "~" && snippet.length() > 2) // Strikethrough ~text~ - htmledSnippet = QString("%1").arg(snippet.mid(mul/2,snippet.length()-mul)); + htmledSnippet = QString(" %1 ").arg(snippet.mid(mul/2,snippet.length()-mul)); else if (exp.cap(19) == "~~" && snippet.length() > 4) // Strikethrough ~~text~~ - htmledSnippet = QString("%1").arg(snippet.mid(mul,snippet.length()-2*mul)); + htmledSnippet = QString(" %1 ").arg(snippet.mid(mul,snippet.length()-2*mul)); else htmledSnippet = snippet; out.replace(offset, exp.cap().length(), htmledSnippet); From aa5d0f660c8f5d6fd470043ddfd75616dcee0b63 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Sat, 23 Jan 2016 03:41:55 -0800 Subject: [PATCH 04/12] Changed markdown settings titles --- src/widget/form/settings/generalform.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/widget/form/settings/generalform.cpp b/src/widget/form/settings/generalform.cpp index fdf7252bf..158b935ad 100644 --- a/src/widget/form/settings/generalform.cpp +++ b/src/widget/form/settings/generalform.cpp @@ -82,9 +82,9 @@ static QStringList langs = {"Български", "Türkçe", "Українська", "简体中文"}; -static QStringList mdPrefs = {"None", - "Show Characters", - "No Characters"}; +static QStringList mdPrefs = {"Plaintext", + "Show Formatting Characters", + "Don't Show Formatting Characters"}; static QStringList timeFormats = {"hh:mm AP", "hh:mm", "hh:mm:ss AP", "hh:mm:ss"}; // http://doc.qt.io/qt-4.8/qdate.html#fromString From a5f9e77a6b8c7ade92d51601fbf30fe2b4e95e22 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Thu, 28 Jan 2016 14:08:12 -0800 Subject: [PATCH 05/12] Changed asterisk rule to bold instead of italics. Fixed extraneous container in settings. --- src/chatlog/chatmessage.cpp | 6 +++--- src/widget/form/settings/generalsettings.ui | 11 ++--------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index 54f46562b..0f5ae94b5 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -187,7 +187,7 @@ QString ChatMessage::detectMarkdown(const QString &str) // Create regex for certain markdown syntax QRegExp exp("(\\*\\*)([^\\*\\*]{2,})(\\*\\*)" // Bold **text** - "|(\\*)([^\\*]{2,})(\\*)" // Italics *text* + "|(\\*)([^\\*]{2,})(\\*)" // Bold *text* "|(\\_)([^\\_]{2,})(\\_)" // Italics _text_ "|(\\_\\_)([^\\_\\_]{2,})(\\_\\_)" // Italics __text__ "|(\\-)([^\\-]{2,})(\\-)" // Underline -text- @@ -230,8 +230,8 @@ QString ChatMessage::detectMarkdown(const QString &str) // Match captured string to corresponding md format if (exp.cap(1) == "**") // Bold **text** htmledSnippet = QString(" %1 ").arg(snippet.mid(mul,snippet.length()-2*mul)); - else if (exp.cap(4) == "*" && snippet.length() > 2) // Italics *text* - htmledSnippet = QString(" %1 ").arg(snippet.mid(mul/2,snippet.length()-mul)); + else if (exp.cap(4) == "*" && snippet.length() > 2) // Bold *text* + htmledSnippet = QString(" %1 ").arg(snippet.mid(mul/2,snippet.length()-mul)); else if (exp.cap(7) == "_" && snippet.length() > 2) // Italics _text_ htmledSnippet = QString(" %1 ").arg(snippet.mid(mul/2,snippet.length()-mul)); else if (exp.cap(10) == "__"&& snippet.length() > 4) // Italics __text__ diff --git a/src/widget/form/settings/generalsettings.ui b/src/widget/form/settings/generalsettings.ui index 41e7418a5..c92316da3 100644 --- a/src/widget/form/settings/generalsettings.ui +++ b/src/widget/form/settings/generalsettings.ui @@ -39,8 +39,8 @@ 0 0 - 1280 - 2394 + 1277 + 1272 @@ -481,13 +481,6 @@ will be sent to them when they appear online to you. - - - - - - - From 518a398ca0ffd1ac3a3dee0dd48ede6c2095172e Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Thu, 28 Jan 2016 16:43:41 -0800 Subject: [PATCH 06/12] Added tooltip to warn user markdown preference will not change until restart. --- src/widget/form/settings/generalsettings.ui | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/widget/form/settings/generalsettings.ui b/src/widget/form/settings/generalsettings.ui index c92316da3..b7285387d 100644 --- a/src/widget/form/settings/generalsettings.ui +++ b/src/widget/form/settings/generalsettings.ui @@ -364,7 +364,7 @@ instead of closing itself. - The translation may not load until qTox restarts. + New markdown preference may not load until qTox restarts. Markdown: @@ -380,7 +380,7 @@ instead of closing itself. - Select Markdown preference + Select Markdown preference. From a8098978507f7b7117985d4716adbcf08aee34d2 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Thu, 28 Jan 2016 16:57:34 -0800 Subject: [PATCH 07/12] Removed leftover debug logging. --- src/chatlog/chatmessage.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index 0f5ae94b5..3eef85519 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -222,11 +222,6 @@ QString ChatMessage::detectMarkdown(const QString &str) if (Settings::getInstance().getMarkdownPreference() == 2) mul = 2; - if (snippet.length() > 0) - { - qDebug() << "Offset: " << offset << " Grabbed snippet: " << snippet << " exp.cap(7): " << exp.cap(7); - } - // Match captured string to corresponding md format if (exp.cap(1) == "**") // Bold **text** htmledSnippet = QString(" %1 ").arg(snippet.mid(mul,snippet.length()-2*mul)); From 4c51be9a6b6c5d94526b54187e601d3eae336b02 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 29 Jan 2016 15:17:41 -0800 Subject: [PATCH 08/12] Changed rules to keep in line with actual markdown. Although Tox is marketed somewhat as a Skype-replacement, that doesn't mean we have to break compatibility with the rest of the web. --- src/chatlog/chatmessage.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index 3eef85519..5a24b0ae8 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -187,9 +187,9 @@ QString ChatMessage::detectMarkdown(const QString &str) // Create regex for certain markdown syntax QRegExp exp("(\\*\\*)([^\\*\\*]{2,})(\\*\\*)" // Bold **text** - "|(\\*)([^\\*]{2,})(\\*)" // Bold *text* + "|(\\*)([^\\*]{2,})(\\*)" // Italics *text* "|(\\_)([^\\_]{2,})(\\_)" // Italics _text_ - "|(\\_\\_)([^\\_\\_]{2,})(\\_\\_)" // Italics __text__ + "|(\\_\\_)([^\\_\\_]{2,})(\\_\\_)" // Bold __text__ "|(\\-)([^\\-]{2,})(\\-)" // Underline -text- "|(\\~)([^\\~]{2,})(\\~)" // Strike ~text~ "|(\\~~)([^\\~\\~]{2,})(\\~~)" // Strike ~~text~~ @@ -225,12 +225,12 @@ QString ChatMessage::detectMarkdown(const QString &str) // Match captured string to corresponding md format if (exp.cap(1) == "**") // Bold **text** htmledSnippet = QString(" %1 ").arg(snippet.mid(mul,snippet.length()-2*mul)); - else if (exp.cap(4) == "*" && snippet.length() > 2) // Bold *text* - htmledSnippet = QString(" %1 ").arg(snippet.mid(mul/2,snippet.length()-mul)); + else if (exp.cap(4) == "*" && snippet.length() > 2) // Italics *text* + htmledSnippet = QString(" %1 ").arg(snippet.mid(mul/2,snippet.length()-mul)); else if (exp.cap(7) == "_" && snippet.length() > 2) // Italics _text_ htmledSnippet = QString(" %1 ").arg(snippet.mid(mul/2,snippet.length()-mul)); - else if (exp.cap(10) == "__"&& snippet.length() > 4) // Italics __text__ - htmledSnippet = QString(" %1 ").arg(snippet.mid(mul,snippet.length()-2*mul)); + else if (exp.cap(10) == "__"&& snippet.length() > 4) // Bold __text__ + htmledSnippet = QString(" %1 ").arg(snippet.mid(mul,snippet.length()-2*mul)); else if (exp.cap(13) == "-" && snippet.length() > 2) // Underline -text- htmledSnippet = QString(" %1 ").arg(snippet.mid(mul/2,snippet.length()-mul)); else if (exp.cap(16) == "~" && snippet.length() > 2) // Strikethrough ~text~ From db840749263a1bde09ce14978ef61e6d41df9418 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Sat, 30 Jan 2016 21:43:58 -0800 Subject: [PATCH 09/12] Markdown Preference now uses enumeration type instead of integer. --- src/chatlog/chatmessage.cpp | 4 ++-- src/chatlog/chatmessage.h | 7 +++++++ src/persistence/settings.cpp | 13 ++++--------- src/persistence/settings.h | 8 +++++--- src/widget/form/settings/generalform.cpp | 2 +- 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index 3eef85519..7ef043a56 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -57,7 +57,7 @@ ChatMessage::Ptr ChatMessage::createChatMessage(const QString &sender, const QSt text = detectQuotes(detectAnchors(text), type); //markdown - if (Settings::getInstance().getMarkdownPreference() != 0) + if (Settings::getInstance().getMarkdownPreference() != MarkdownType::NONE) text = detectMarkdown(text); switch(type) @@ -187,7 +187,7 @@ QString ChatMessage::detectMarkdown(const QString &str) // Create regex for certain markdown syntax QRegExp exp("(\\*\\*)([^\\*\\*]{2,})(\\*\\*)" // Bold **text** - "|(\\*)([^\\*]{2,})(\\*)" // Bold *text* + "|(\\*)([^\\*]{2,})(\\*)" // Bold *text* "|(\\_)([^\\_]{2,})(\\_)" // Italics _text_ "|(\\_\\_)([^\\_\\_]{2,})(\\_\\_)" // Italics __text__ "|(\\-)([^\\-]{2,})(\\-)" // Underline -text- diff --git a/src/chatlog/chatmessage.h b/src/chatlog/chatmessage.h index 2de1d668c..0cb133563 100644 --- a/src/chatlog/chatmessage.h +++ b/src/chatlog/chatmessage.h @@ -45,6 +45,13 @@ public: ALERT, }; + enum MarkdownType + { + NONE, + WITH_CHARS, + WITHOUT_CHARS, + }; + ChatMessage(); static ChatMessage::Ptr createChatMessage(const QString& sender, const QString& rawMessage, MessageType type, bool isMe, const QDateTime& date = QDateTime()); diff --git a/src/persistence/settings.cpp b/src/persistence/settings.cpp index 72a7a1ecf..84b9bdc02 100644 --- a/src/persistence/settings.cpp +++ b/src/persistence/settings.cpp @@ -177,7 +177,7 @@ void Settings::loadGlobal() separateWindow = s.value("separateWindow", false).toBool(); dontGroupWindows = s.value("dontGroupWindows", true).toBool(); groupchatPosition = s.value("groupchatPosition", true).toBool(); - markdownPreference = s.value("markdownPreference", 1).toInt(); + markdownPreference = static_cast(s.value("markdownPreference", 1).toInt()); s.endGroup(); s.beginGroup("Advanced"); @@ -396,7 +396,7 @@ void Settings::saveGlobal() s.setValue("groupchatPosition", groupchatPosition); s.setValue("autoSaveEnabled", autoSaveEnabled); s.setValue("globalAutoAcceptDir", globalAutoAcceptDir); - s.setValue("markdownPreference", markdownPreference); + s.setValue("markdownPreference", static_cast(markdownPreference)); s.endGroup(); s.beginGroup("Advanced"); @@ -1030,20 +1030,15 @@ void Settings::setDateFormat(const QString &format) dateFormat = format; } -int Settings::getMarkdownPreference() const +MarkdownType Settings::getMarkdownPreference() const { QMutexLocker locker{&bigLock}; return markdownPreference; } -void Settings::setMarkdownPreference(int newValue) +void Settings::setMarkdownPreference(MarkdownType newValue) { QMutexLocker locker{&bigLock}; - if (newValue < 0) - newValue = 1; - else if (newValue > 2) - newValue = 2; - markdownPreference = newValue; } diff --git a/src/persistence/settings.h b/src/persistence/settings.h index 32709a20c..e0ae85d4f 100644 --- a/src/persistence/settings.h +++ b/src/persistence/settings.h @@ -34,6 +34,8 @@ namespace Db { enum class syncType; } enum ProxyType {ptNone, ptSOCKS5, ptHTTP}; +enum MarkdownType {NONE, WITH_CHARS, WITHOUT_CHARS}; + class Settings : public QObject { Q_OBJECT @@ -175,8 +177,8 @@ public: int getThemeColor() const; void setThemeColor(const int& value); - int getMarkdownPreference() const; - void setMarkdownPreference(int newValue); + MarkdownType getMarkdownPreference() const; + void setMarkdownPreference(MarkdownType newValue); bool isCurstomEmojiFont() const; void setCurstomEmojiFont(bool value); @@ -368,9 +370,9 @@ private: bool showSystemTray; // ChatView + MarkdownType markdownPreference; int firstColumnHandlePos; int secondColumnHandlePosFromRight; - int markdownPreference; QString timestampFormat; QString dateFormat; bool statusChangeNotificationEnabled; diff --git a/src/widget/form/settings/generalform.cpp b/src/widget/form/settings/generalform.cpp index 158b935ad..196c20ce0 100644 --- a/src/widget/form/settings/generalform.cpp +++ b/src/widget/form/settings/generalform.cpp @@ -371,7 +371,7 @@ void GeneralForm::onUseEmoticonsChange() void GeneralForm::onMarkdownUpdated() { - Settings::getInstance().setMarkdownPreference(bodyUI->markdownComboBox->currentIndex()); + Settings::getInstance().setMarkdownPreference(static_cast(bodyUI->markdownComboBox->currentIndex())); } void GeneralForm::onSetStatusChange() From ee4ccf1f68b4a93264257dbf22f4ee623f15aa16 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 1 Feb 2016 11:22:29 -0800 Subject: [PATCH 10/12] Added message styling section to user manual --- doc/user_manual_en.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/doc/user_manual_en.md b/doc/user_manual_en.md index 98736115f..0d507256c 100644 --- a/doc/user_manual_en.md +++ b/doc/user_manual_en.md @@ -4,6 +4,7 @@ * [User Profile](#user-profile) * [Settings](#settings) * [Groupchats](#groupchats) +* [Message Styling](#message-styling) * [Multi Window Mode](#multi-window-mode) * [Keyboard Shortcuts](#keyboard-shortcuts) @@ -119,6 +120,23 @@ NoSpam is a feature of Tox that prevents a malicious user from spamming you with Groupchats are a way to talk with multiple friends at the same time, like when you are standing together in a group. To create a groupchat click the groupchat icon in the bottom left corner and set a name. Now you can invite your contacts by right-clicking on the contact and selecting "Invite to group". Currently, if the last person leaves the chat, it is closed and you have to create a new one. Videochats and file transfers are currently unsupported in groupchats. +## Message Styling + +Similar to other messaging applications, qTox supports stylized text formatting. Formatting follows [Markdown syntax](), thus: + +* For **Bold**, surround text in double asterisks or underscores: `**text**` or `__text__` +* For **Italics**, surround text in single asterisks or underscores: `*text*` or `_text_` +* For **Strikethrough**, surround text in single tilde's: `~text~` +* For **Underline**, surround text in single dashes: `-text-` + +Additionally, qTox supports three modes of Markdown parsing: + +* `Plaintext`: No text is stylized +* `Show Formatting Characters`: Stylize text while showing formatting characters (Default) +* `Don't Show Formatting Characters`: Stylize text without showing formatting characters + +*Note that any change in Markdown preference will require a restart.* + ## Multi Window Mode In this mode, qTox will separate its main window into a single contact list and one or multiple chat windows, which allows you to have multiple conversations on your screen at the same time. Additionally you can manually group chats into a window by dragging and dropping them onto each other. This mode can be activated and configured in [settings](#settings). From 08e9f0b8858a6e803ed386857c7db5ae3742d18b Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 1 Feb 2016 11:50:21 -0800 Subject: [PATCH 11/12] Use new connection syntax --- src/widget/form/settings/generalform.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/widget/form/settings/generalform.cpp b/src/widget/form/settings/generalform.cpp index 196c20ce0..7cceb0127 100644 --- a/src/widget/form/settings/generalform.cpp +++ b/src/widget/form/settings/generalform.cpp @@ -208,7 +208,7 @@ GeneralForm::GeneralForm(SettingsWidget *myParent) : connect(bodyUI->showWindow, &QCheckBox::stateChanged, this, &GeneralForm::onShowWindowChanged); connect(bodyUI->showInFront, &QCheckBox::stateChanged, this, &GeneralForm::onSetShowInFront); connect(bodyUI->notifySound, &QCheckBox::stateChanged, this, &GeneralForm::onSetNotifySound); - connect(bodyUI->markdownComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onMarkdownUpdated())); + connect(bodyUI->markdownComboBox, &QComboBox::currentTextChanged, this, &GeneralForm::onMarkdownUpdated); connect(bodyUI->groupAlwaysNotify, &QCheckBox::stateChanged, this, &GeneralForm::onSetGroupAlwaysNotify); connect(bodyUI->autoacceptFiles, &QCheckBox::stateChanged, this, &GeneralForm::onAutoAcceptFileChange); connect(bodyUI->autoSaveFilesDir, SIGNAL(clicked()), this, SLOT(onAutoSaveDirChange())); @@ -235,7 +235,7 @@ GeneralForm::GeneralForm(SettingsWidget *myParent) : // prevent stealing mouse wheel scroll // scrolling event won't be transmitted to comboboxes or qspinboxes when scrolling - // you can scroll through general settings without accidentially chaning theme/skin/icons etc. + // you can scroll through general settings without accidentially changing theme/skin/icons etc. // @see GeneralForm::eventFilter(QObject *o, QEvent *e) at the bottom of this file for more for (QComboBox *cb : findChildren()) { From e04bd912b93c4cc476d38ca13223f29fcf113438 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 1 Feb 2016 14:46:54 -0800 Subject: [PATCH 12/12] Fixed link to Markdown syntax in user manual --- doc/user_manual_en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/user_manual_en.md b/doc/user_manual_en.md index 0d507256c..146d9aee7 100644 --- a/doc/user_manual_en.md +++ b/doc/user_manual_en.md @@ -122,7 +122,7 @@ Groupchats are a way to talk with multiple friends at the same time, like when y ## Message Styling -Similar to other messaging applications, qTox supports stylized text formatting. Formatting follows [Markdown syntax](), thus: +Similar to other messaging applications, qTox supports stylized text formatting. Formatting follows [Markdown syntax](https://daringfireball.net/projects/markdown/syntax), thus: * For **Bold**, surround text in double asterisks or underscores: `**text**` or `__text__` * For **Italics**, surround text in single asterisks or underscores: `*text*` or `_text_`