From a16c264aa30f56dc7116d62835df5c55eede24e3 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Sat, 20 Jun 2015 14:56:49 +0800 Subject: [PATCH 1/3] RSS Downloader dialog cleanup --- src/gui/rss/automatedrssdownloader.ui | 316 +++++++------------------- 1 file changed, 84 insertions(+), 232 deletions(-) diff --git a/src/gui/rss/automatedrssdownloader.ui b/src/gui/rss/automatedrssdownloader.ui index 41ce6742c..de73e49f4 100644 --- a/src/gui/rss/automatedrssdownloader.ui +++ b/src/gui/rss/automatedrssdownloader.ui @@ -7,11 +7,11 @@ 0 0 816 - 494 + 537 - Automated RSS Downloader + RSS Downloader @@ -49,27 +49,8 @@ - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 40 - 20 - - - - - - - 24 @@ -80,9 +61,6 @@ - - - 24 @@ -91,19 +69,6 @@ - - - - Qt::Horizontal - - - - 40 - 20 - - - - @@ -131,130 +96,67 @@ - + Must contain: - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - - 0 - 0 - - - - - 18 - 18 - - - - - 18 - 18 - - - - - - - - - Must not contain: - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + Episode Filter: - - - - - - - - - - 0 - 0 - - - - - 18 - 18 - - - - - 18 - 18 - - - - - - - - + + + + + 18 + 18 + + + + + + + + + 18 + 18 + + + + + + - - - - - - - - - 0 - 0 - - - - - 18 - 18 - - - - - 18 - 18 - - - - - - - - + - - - - Episode filter: + + + + + 18 + 18 + + + + @@ -265,18 +167,21 @@ - - + + + + + 0 + 0 + + Assign label: - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + true @@ -293,8 +198,8 @@ - - + + false @@ -302,31 +207,24 @@ Save to: - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + false - - - - - - false - - - - - - - false - - - ... - - - - + + + + false + + + ... + + @@ -339,19 +237,6 @@ - - - - Qt::Horizontal - - - - 40 - 20 - - - - @@ -368,36 +253,25 @@ - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - true - - - - - - - + + + true + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + 0 + 0 + + Add Paused: @@ -405,12 +279,6 @@ - - - 0 - 0 - - Use global setting @@ -491,35 +359,19 @@ - Import... + &Import... - Export... + &Export... - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - Qt::Horizontal - QDialogButtonBox::Close From 65d3ca8c3f034db7a9838af22940f1a5fbb22618 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Sat, 20 Jun 2015 14:57:43 +0800 Subject: [PATCH 2/3] Capitalize items --- src/gui/rss/automatedrssdownloader.cpp | 4 ++-- src/gui/rss/automatedrssdownloader.ui | 30 +++++++++++++------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/gui/rss/automatedrssdownloader.cpp b/src/gui/rss/automatedrssdownloader.cpp index 1fede2666..c92ff2578 100644 --- a/src/gui/rss/automatedrssdownloader.cpp +++ b/src/gui/rss/automatedrssdownloader.cpp @@ -260,9 +260,9 @@ void AutomatedRssDownloader::updateRuleDefinitionBox() QDateTime dateTime = rule->lastMatch(); QString lMatch; if (dateTime.isValid()) - lMatch = tr("Last match: %1 days ago").arg(dateTime.daysTo(QDateTime::currentDateTime())); + lMatch = tr("Last Match: %1 days ago").arg(dateTime.daysTo(QDateTime::currentDateTime())); else - lMatch = tr("Last match: Unknown"); + lMatch = tr("Last Match: Unknown"); ui->lblLastMatch->setText(lMatch); updateMustLineValidity(); updateMustNotLineValidity(); diff --git a/src/gui/rss/automatedrssdownloader.ui b/src/gui/rss/automatedrssdownloader.ui index de73e49f4..54a0fd32b 100644 --- a/src/gui/rss/automatedrssdownloader.ui +++ b/src/gui/rss/automatedrssdownloader.ui @@ -23,7 +23,7 @@ - Enable the automated RSS downloader + Enable Automated RSS Downloader @@ -45,7 +45,7 @@ - Download rules + Download Rules @@ -85,13 +85,13 @@ - Rule definition + Rule Definition - Use regular expressions + Use Regular Expressions @@ -100,14 +100,14 @@ - Must contain: + Must Contain: - Must not contain: + Must Not Contain: @@ -177,7 +177,7 @@ - Assign label: + Assign Label: @@ -193,7 +193,7 @@ - Save to a different directory + Save to a Different Directory @@ -233,7 +233,7 @@ - Ignore subsequent matches for (0 to disable) + Ignore Subsequent Matches for (0 to Disable) @@ -246,7 +246,7 @@ days - 360 + 365 @@ -281,17 +281,17 @@ - Use global setting + Use global settings - Always add paused + Always - Never add paused + Never @@ -312,7 +312,7 @@ - Apply rule to feeds: + Apply Rule to Feeds: @@ -334,7 +334,7 @@ - Matching RSS articles + Matching RSS Articles From cf91685f6f9cbeee93ee800948993ca9a7e83052 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Sat, 20 Jun 2015 15:06:49 +0800 Subject: [PATCH 3/3] Sort labels in RSS Downloader dialog, closes #3140. --- src/core/utils/string.cpp | 79 +++++++++++++++++++++++++- src/core/utils/string.h | 19 ++++++- src/gui/rss/automatedrssdownloader.cpp | 9 +-- 3 files changed, 101 insertions(+), 6 deletions(-) diff --git a/src/core/utils/string.cpp b/src/core/utils/string.cpp index 6dffa2615..d0c05329a 100644 --- a/src/core/utils/string.cpp +++ b/src/core/utils/string.cpp @@ -45,7 +45,7 @@ std::string Utils::String::toStdString(const QString &str) } // uses lessThan comparison -bool Utils::String::naturalSort(QString left, QString right, bool &result) +bool Utils::String::naturalSort(const QString &left, const QString &right, bool &result) { // Return value indicates if functions was successful // result argument will contain actual comparison result if function was successful @@ -106,6 +106,83 @@ bool Utils::String::naturalSort(QString left, QString right, bool &result) return false; } +Utils::String::NaturalCompare::NaturalCompare() +{ +#if (QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)) +#if defined(Q_OS_WIN) + // Without ICU library, QCollator doesn't support `setNumericMode(true)` on OS older than Win7 + if(SysInfo::windowsVersion() < QSysInfo::WV_WINDOWS7) + return; +#endif + m_collator.setNumericMode(true); + m_collator.setCaseSensitivity(Qt::CaseInsensitive); +#endif +} + +bool Utils::String::NaturalCompare::operator()(const QString &l, const QString &r) +{ +#if (QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)) +#if defined(Q_OS_WIN) + // Without ICU library, QCollator doesn't support `setNumericMode(true)` on OS older than Win7 + if(SysInfo::windowsVersion() < QSysInfo::WV_WINDOWS7) + return lessThan(l, r); +#endif + return (m_collator.compare(l, r) < 0); +#else + return lessThan(l, r); +#endif +} + +bool Utils::String::NaturalCompare::lessThan(const QString &left, const QString &right) +{ + // Return value `false` indicates `right` should go before `left`, otherwise, after + int posL = 0; + int posR = 0; + while (true) { + while (true) { + if (posL == left.size() || posR == right.size()) + return (left.size() < right.size()); // when a shorter string is another string's prefix, shorter string place before longer string + + QChar leftChar = left[posL].toLower(); + QChar rightChar = right[posR].toLower(); + if (leftChar == rightChar) + ; // compare next character + else if (leftChar.isDigit() && rightChar.isDigit()) + break; // Both are digits, break this loop and compare numbers + else + return leftChar < rightChar; + + ++posL; + ++posR; + } + + int startL = posL; + while ((posL < left.size()) && left[posL].isDigit()) + ++posL; +#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) + int numL = left.midRef(startL, posL - startL).toInt(); +#else + int numL = left.mid(startL, posL - startL).toInt(); +#endif + + int startR = posR; + while ((posR < right.size()) && right[posR].isDigit()) + ++posR; +#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) + int numR = right.midRef(startR, posR - startR).toInt(); +#else + int numR = right.mid(startR, posR - startR).toInt(); +#endif + + if (numL != numR) + return (numL < numR); + + // Strings + digits do match and we haven't hit string end + // Do another round + } + return false; +} + // to send numbers instead of strings with suffixes QString Utils::String::fromDouble(double n, int precision) { diff --git a/src/core/utils/string.h b/src/core/utils/string.h index d2863dc7c..36b34e979 100644 --- a/src/core/utils/string.h +++ b/src/core/utils/string.h @@ -31,6 +31,10 @@ #define UTILS_STRING_H #include +#include +#if (QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)) +#include +#endif class QString; class QByteArray; @@ -41,12 +45,25 @@ namespace Utils { QString fromStdString(const std::string &str); std::string toStdString(const QString &str); - bool naturalSort(QString left, QString right, bool &result); QString fromDouble(double n, int precision); // Implements constant-time comparison to protect against timing attacks // Taken from https://crackstation.net/hashing-security.htm bool slowEquals(const QByteArray &a, const QByteArray &b); + + bool naturalSort(const QString &left, const QString &right, bool &result); + + class NaturalCompare + { + public: + NaturalCompare(); + bool operator()(const QString &l, const QString &r); + bool lessThan(const QString &left, const QString &right); +#if (QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)) + private: + QCollator m_collator; +#endif + }; } } diff --git a/src/gui/rss/automatedrssdownloader.cpp b/src/gui/rss/automatedrssdownloader.cpp index c92ff2578..0898ca482 100644 --- a/src/gui/rss/automatedrssdownloader.cpp +++ b/src/gui/rss/automatedrssdownloader.cpp @@ -43,6 +43,7 @@ #include "guiiconprovider.h" #include "autoexpandabledialog.h" #include "core/utils/fs.h" +#include "core/utils/string.h" AutomatedRssDownloader::AutomatedRssDownloader(const QWeakPointer& manager, QWidget *parent) : QDialog(parent), @@ -308,10 +309,10 @@ RssDownloadRulePtr AutomatedRssDownloader::getCurrentRule() const void AutomatedRssDownloader::initLabelCombobox() { // Load custom labels - const QStringList customLabels = Preferences::instance()->getTorrentLabels(); - foreach (const QString& label, customLabels) { - ui->comboLabel->addItem(label); - } + QStringList customLabels = Preferences::instance()->getTorrentLabels(); + std::sort(customLabels.begin(), customLabels.end(), Utils::String::NaturalCompare()); + foreach (const QString& l, customLabels) + ui->comboLabel->addItem(l); } void AutomatedRssDownloader::saveEditedRule()