Skip to content

Commit

Permalink
Merge pull request #3 from veddan/master
Browse files Browse the repository at this point in the history
Natural sorting of files
  • Loading branch information
stolowski committed Dec 1, 2012
2 parents 2b09ce7 + dd650d7 commit 12b67b2
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 11 deletions.
25 changes: 14 additions & 11 deletions src/DirReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
* WITHOUT ANY WARRANTY. See GPL for more details.
*/

#include <algorithm>
#include "DirReader.h"
#include "NaturalComparator.h"

DirReader::DirReader(QDir::SortFlags sortFlags, int maxDepth): flags(sortFlags), maxDirDepth(maxDepth)
{
Expand All @@ -22,30 +24,31 @@ DirReader::~DirReader()

void DirReader::recurseDir(const QString &path, int curDepth)
{
QDir dir(path);
dir.setSorting(flags);
dir.setFilter(QDir::AllDirs|QDir::Files);
QDir dir(path);
dir.setSorting(flags);
dir.setFilter(QDir::AllDirs|QDir::Files);
QStringList files = dir.entryList();
std::sort(files.begin(), files.end(), NaturalComparator());

const QStringList files = dir.entryList();
foreach (QString f, files)
{
if (f == "." || f == "..")
continue;
{
if (f == "." || f == "..")
continue;

QFileInfo finf(dir, f);
QFileInfo finf(dir, f);
fileHandler(finf);
if (finf.isDir()) // && (finf.absoluteFilePath() != path))
if (finf.isDir()) // && (finf.absoluteFilePath() != path))
{
if (curDepth < maxDirDepth)
{
recurseDir(finf.absoluteFilePath(), curDepth+1);
}
}
}
}
}

void DirReader::visit(const QString &path)
{
recurseDir(path, 0);
recurseDir(path, 0);
}

67 changes: 67 additions & 0 deletions src/NaturalComparator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* This file is a part of QComicBook.
*
* Copyright (C) 2005-2009 Pawel Stolowski <stolowski@gmail.com>
*
* QComicBook is free software; you can redestribute it and/or modify it
* under terms of GNU General Public License by Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY. See GPL for more details.
*/

#include <QString>
#include "NaturalComparator.h"

static unsigned toInt(QString const& s, int *idx)
{
int res = 0;
int i = *idx;
while (i != s.size() && s[i].isDigit())
{
res *= 10;
res += s[i].digitValue();
++i;
}
*idx = i;
return res;
}

bool NaturalComparator::cmpLetters(QChar l, QChar r) const
{
return this->caseSenitive ? l < r : l.toLower() < r.toLower();
}

// Adapted from Dave Koelle's Alphanum (http://www.davekoelle.com/alphanum.html)
// The idea is to split the string into "chunks" of letters or digits
bool NaturalComparator::operator()(QString const& l, QString const& r) const
{
enum Mode { String, Number } mode = String;
for (int il = 0, ir = 0; il != l.size() && ir != r.size();)
{
if (mode == String)
{
for (; il != l.size() && ir != r.size(); ++il, ++ir)
{
const bool digitL = l[il].isDigit(), digitR = r[ir].isDigit();
if (digitL && digitR)
{
mode = Number;
break;
}
if (digitL) return true;
if (digitR) return false;
if (l[il] != r[ir]) return l[il] < r[ir];
}
}
else
{
// At least the current character is a digit in both strings
unsigned lNum = toInt(l, &il);
unsigned rNum = toInt(r, &ir);
if (lNum != rNum) return lNum < rNum;
mode = String;
}
}
return l.size() < r.size();
}
26 changes: 26 additions & 0 deletions src/NaturalComparator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* This file is a part of QComicBook.
*
* Copyright (C) 2005-2009 Pawel Stolowski <stolowski@gmail.com>
*
* QComicBook is free software; you can redestribute it and/or modify it
* under terms of GNU General Public License by Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY. See GPL for more details.
*/

#include <QString>

class NaturalComparator
{
private:
const bool caseSenitive;
bool cmpLetters(QChar l, QChar r) const;

public:
NaturalComparator(bool caseSens = false) : caseSenitive(caseSens)
{}

bool operator()(QString const& l, QString const& r) const;
};

0 comments on commit 12b67b2

Please sign in to comment.