Browse Source

Move number-aware comparison logic into misc class.

adaptive-webui-19844
Nick Tiskov 12 years ago
parent
commit
89e3500a8e
  1. 63
      src/misc.cpp
  2. 4
      src/misc.h
  3. 59
      src/transferlistsortmodel.h

63
src/misc.cpp

@ -521,3 +521,66 @@ QString misc::toQString(time_t t) @@ -521,3 +521,66 @@ QString misc::toQString(time_t t)
return QDateTime::fromTime_t(t).toString(Qt::DefaultLocaleLongDate);
}
#endif
#ifndef DISABLE_GUI
bool misc::naturalSort(QString left, QString right, bool &result) { // uses lessThan comparison
// Return value indicates if functions was successful
// result argument will contain actual comparison result if function was successful
do {
int posL = left.indexOf(QRegExp("[0-9]"));
int posR = right.indexOf(QRegExp("[0-9]"));
if (posL == -1 || posR == -1)
break; // No data
else if (posL != posR)
break; // Digit positions mismatch
else if (left.left(posL) != right.left(posR))
break; // Strings' subsets before digit do not match
bool second_digit = false;
if (left.size() > posL + 1)
second_digit = left.at(posL + 1).isDigit();
if (right.size() > posR + 1)
second_digit = second_digit ?
second_digit :
right.at(posR + 1).isDigit();
if (!second_digit)
break; // Single digit in both, normal sort could handle this
QString temp;
while (posL < left.size()) {
if (left.at(posL).isDigit())
temp += left.at(posL);
else
break;
posL++;
}
int numL = temp.toInt();
temp.clear();
while (posR < right.size()) {
if (right.at(posR).isDigit())
temp += right.at(posR);
else
break;
posR++;
}
int numR = temp.toInt();
if (numL != numR) {
result = (numL < numR);
return true;
}
// Strings + digits do match and we haven't hit string end
// Do another round
left.remove(0, posL);
right.remove(0, posR);
continue;
} while (true);
return false;
}
#endif

4
src/misc.h

@ -119,6 +119,10 @@ public: @@ -119,6 +119,10 @@ public:
#else
static QString toQString(time_t t);
#endif
#ifndef DISABLE_GUI
static bool naturalSort(QString left, QString right, bool& result);
#endif
};
// Trick to get a portable sleep() function

59
src/transferlistsortmodel.h

@ -33,6 +33,7 @@ @@ -33,6 +33,7 @@
#include <QSortFilterProxyModel>
#include "torrentmodel.h"
#include "misc.h"
class TransferListSortModel : public QSortFilterProxyModel {
Q_OBJECT
@ -50,61 +51,9 @@ protected: @@ -50,61 +51,9 @@ protected:
Q_ASSERT(vL.isValid());
Q_ASSERT(vR.isValid());
QString nameLeft = vL.toString();
QString nameRight = vR.toString();
do {
int posL = nameLeft.indexOf(QRegExp("[0-9]"));
int posR = nameRight.indexOf(QRegExp("[0-9]"));
if (posL == -1 || posR == -1)
break; // No data
else if (posL != posR)
break; // Digit positions mismatch
else if (nameLeft.left(posL) != nameRight.left(posR))
break; // Strings' subsets before digit do not match
bool second_digit = false;
if (nameLeft.size() > posL + 1)
second_digit = nameLeft.at(posL + 1).isDigit();
if (nameRight.size() > posR + 1)
second_digit = second_digit ?
second_digit :
nameRight.at(posR + 1).isDigit();
if (!second_digit)
break; // Single digit in both, normal sort could handle this
QString temp;
while (posL < nameLeft.size()) {
if (nameLeft.at(posL).isDigit())
temp += nameLeft.at(posL);
else
break;
posL++;
}
int numL = temp.toInt();
temp.clear();
while (posR < nameRight.size()) {
if (nameRight.at(posR).isDigit())
temp += nameRight.at(posR);
else
break;
posR++;
}
int numR = temp.toInt();
if (numL != numR)
return numL < numR;
// Strings + digits do match and we haven't hit string end
// Do another round
nameLeft.remove(0, posL);
nameRight.remove(0, posR);
continue;
} while (true);
bool res = false;
if (misc::naturalSort(vL.toString(), vR.toString(), res))
return res;
return QSortFilterProxyModel::lessThan(left, right);
}

Loading…
Cancel
Save