Fixed a superfluous "beep" sound that appeared on application startup
Fixed the Ogg Vorbis quality modes "-1" and "-2" (those were clipped to "0" before)
Fixed a bug that could cause the output directory to be reset mistakenly
+
Implemented "natural ordering" for sorting input files, using strnatcmp() by Martin Pool
Changes between v4.06 and v4.07 [2013-04-28]:
diff --git a/etc/Prerequisites/strnatcmp/include/strnatcmp.h b/etc/Prerequisites/strnatcmp/include/strnatcmp.h
new file mode 100644
index 00000000..7a5eff03
--- /dev/null
+++ b/etc/Prerequisites/strnatcmp/include/strnatcmp.h
@@ -0,0 +1,31 @@
+/* -*- mode: c; c-file-style: "k&r" -*-
+
+ strnatcmp.c -- Perform 'natural order' comparisons of strings in C.
+ Copyright (C) 2000, 2004 by Martin Pool
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+/* CUSTOMIZATION SECTION
+ *
+ * You can change this typedef, but must then also change the inline
+ * functions in strnatcmp.c */
+typedef wchar_t nat_char;
+
+int strnatcmp(nat_char const *a, nat_char const *b);
+int strnatcasecmp(nat_char const *a, nat_char const *b);
diff --git a/etc/Prerequisites/strnatcmp/readme.htm b/etc/Prerequisites/strnatcmp/readme.htm
new file mode 100644
index 00000000..c443f362
--- /dev/null
+++ b/etc/Prerequisites/strnatcmp/readme.htm
@@ -0,0 +1,196 @@
+
+
+
+ Natural Order String Comparison
+
+
+
+
Computer string sorting algorithms generally don't order strings
+containing numbers in the same way that a human would do. Consider:
+
+
rfc1.txt
+rfc2086.txt
+rfc822.txt
+
+
It would be more friendly if the program listed the files as
+
+
rfc1.txt
+rfc822.txt
+rfc2086.txt
+
+
+
Filenames sort properly if people insert leading zeros, but they
+don't always do that.
+
+
I've written a subroutine that compares strings according to this
+natural ordering. You can use this routine in your own software, or
+download a patch to add it to your favourite Unix program.
+
+
+
Sorting
+
+
Strings are sorted as usual, except that decimal integer substrings
+are compared on their numeric value. For example,
+
+
+ a < a0 < a1 < a1a < a1b < a2 < a10 < a20
+
+
+
Strings can contain several number parts:
+
+
+ x2-g8 < x2-y7 < x2-y08 < x8-y8
+
+
+in which case numeric fields are separated by nonnumeric characters.
+Leading spaces are ignored. This works very well for IP addresses
+from log files, for example.
+
+
+Leading zeros are not ignored, which tends to give more
+reasonable results on decimal fractions.
+
+
+
+ 1.001 < 1.002 < 1.010 < 1.02 < 1.1 < 1.3
+
+
+
Some applications may wish to change this by modifying the test
+ that calls isspace.
+
+
+
+ Performance is linear: each character of the string is scanned
+ at most once, and only as many characters as necessary to decide
+ are considered.
+
This software is copyright by Martin Pool, and made available under
+the same licence as zlib:
+
+
+
This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+
Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+
1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+
2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+
3. This notice may not be removed or altered from any source distribution.
+
+
+
This licence applies only to the C implementation. You are free to
+reimplement the idea fom scratch in any language.
+
+
Related Work
+
+
+
+ POSIX sort(1) has the -n option to sort numbers, but this doesn't
+ work if there is a non-numeric prefix.
+
+
+
+ GNU ls(1) has the --sort=version option, which works
+ the same way.
+
+
+
+ The PHP scripting language now has a
+ strnatcmp
+ function based on this code.
+ The PHP wrapper was done by Andrei Zimievsky.
+
+
+
+ Stuart
+ Cheshire has a Macintosh system extension to do natural ordering.
+ I indepdendently reinvented the algorithm, but Stuart had it
+ first. I borrowed the term natural sort from him.
+
+
+
+
+ Sort::Versions
+ in Perl. "The code has some special magic to deal with common
+conventions in program version numbers, like the difference between
+'decimal' versions (eg perl 5.005) and the Unix kind (eg perl 5.6.1)."
+
+
Sort::Naturally
+ is also in Perl, by Sean M. Burke. It uses locale-sensitive character classes to sort words and numeric substrings
+ in a way similar to natsort.
+
+
natsort.c - example driver program.
+ (Try ls -F /proc | natsort)
+
+
textutils.diff - patch to add
+ natural sort to sort(1) from GNU textutils-2.0; use the new
+ -N option.
+
+
Natural ordering is now in PHP4rc2, through the strnatcasecmp
+ and strnatcmp
+ functions.
+
+
+
+
To Do
+
+
+ Comparison of characters is purely numeric, without taking
+ character set or locale into account. So it is only correct for
+ ASCII. This should probably be a separate function because doing
+ the comparisons will probably introduce a dependency on the OS
+ mechanism for finding the locale and comparing characters.
+
+
+
+ It might be good to support multibyte character sets too.
+
+
+ If you fix either of these, please mail me. They should not be
+ very hard.
+
+
+
+
\ No newline at end of file
diff --git a/etc/Prerequisites/strnatcmp/src/strnatcmp.cpp b/etc/Prerequisites/strnatcmp/src/strnatcmp.cpp
new file mode 100644
index 00000000..1b04c11c
--- /dev/null
+++ b/etc/Prerequisites/strnatcmp/src/strnatcmp.cpp
@@ -0,0 +1,177 @@
+/* -*- mode: c; c-file-style: "k&r" -*-
+
+strnatcmp.c -- Perform 'natural order' comparisons of strings in C.
+Copyright (C) 2000, 2004 by Martin Pool
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+claim that you wrote the original software. If you use this software
+in a product, an acknowledgment in the product documentation would be
+appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+/* partial change history:
+*
+* 2004-10-10 mbp: Lift out character type dependencies into macros.
+*
+* Eric Sosman pointed out that ctype functions take a parameter whose
+* value must be that of an unsigned int, even on platforms that have
+* negative chars in their default char type.
+*/
+
+#include
+#include
+#include
+#include
+
+#include "strnatcmp.h"
+
+/* These are defined as macros to make it easier to adapt this code to
+* different characters types or comparison functions. */
+static inline int
+nat_isdigit(nat_char a)
+{
+ return iswdigit(a);
+}
+
+
+static inline int
+nat_isspace(nat_char a)
+{
+ return iswspace(a);
+}
+
+
+static inline nat_char
+nat_toupper(nat_char a)
+{
+ return towupper(a);
+}
+
+
+
+static int
+compare_right(nat_char const *a, nat_char const *b)
+{
+ int bias = 0;
+
+ /* The longest run of digits wins. That aside, the greatest
+ value wins, but we can't know that it will until we've scanned
+ both numbers to know that they have the same magnitude, so we
+ remember it in BIAS. */
+ for (;; a++, b++) {
+ if (!nat_isdigit(*a) && !nat_isdigit(*b))
+ return bias;
+ else if (!nat_isdigit(*a))
+ return -1;
+ else if (!nat_isdigit(*b))
+ return +1;
+ else if (*a < *b) {
+ if (!bias)
+ bias = -1;
+ } else if (*a > *b) {
+ if (!bias)
+ bias = +1;
+ } else if (!*a && !*b)
+ return bias;
+ }
+
+ return 0;
+}
+
+
+static int
+compare_left(nat_char const *a, nat_char const *b)
+{
+ /* Compare two left-aligned numbers: the first to have a
+ different value wins. */
+ for (;; a++, b++) {
+ if (!nat_isdigit(*a) && !nat_isdigit(*b))
+ return 0;
+ else if (!nat_isdigit(*a))
+ return -1;
+ else if (!nat_isdigit(*b))
+ return +1;
+ else if (*a < *b)
+ return -1;
+ else if (*a > *b)
+ return +1;
+ }
+
+ return 0;
+}
+
+
+static int strnatcmp0(nat_char const *a, nat_char const *b, int fold_case)
+{
+ int ai, bi;
+ nat_char ca, cb;
+ int fractional, result;
+
+ assert(a && b);
+ ai = bi = 0;
+ while (1) {
+ ca = a[ai]; cb = b[bi];
+
+ /* skip over leading spaces or zeros */
+ while (nat_isspace(ca))
+ ca = a[++ai];
+
+ while (nat_isspace(cb))
+ cb = b[++bi];
+
+ /* process run of digits */
+ if (nat_isdigit(ca) && nat_isdigit(cb)) {
+ fractional = (ca == '0' || cb == '0');
+
+ if (fractional) {
+ if ((result = compare_left(a+ai, b+bi)) != 0)
+ return result;
+ } else {
+ if ((result = compare_right(a+ai, b+bi)) != 0)
+ return result;
+ }
+ }
+
+ if (!ca && !cb) {
+ /* The strings compare the same. Perhaps the caller
+ will want to call strcmp to break the tie. */
+ return 0;
+ }
+
+ if (fold_case) {
+ ca = nat_toupper(ca);
+ cb = nat_toupper(cb);
+ }
+
+ if (ca < cb)
+ return -1;
+ else if (ca > cb)
+ return +1;
+
+ ++ai; ++bi;
+ }
+}
+
+
+
+int strnatcmp(nat_char const *a, nat_char const *b) {
+ return strnatcmp0(a, b, 0);
+}
+
+
+/* Compare, recognizing numeric string and ignoring case. */
+int strnatcasecmp(nat_char const *a, nat_char const *b) {
+ return strnatcmp0(a, b, 1);
+}
diff --git a/etc/Translation/Blank.ts b/etc/Translation/Blank.ts
index 1e0feeef..3598f25f 100644
--- a/etc/Translation/Blank.ts
+++ b/etc/Translation/Blank.ts
@@ -3312,23 +3312,23 @@
QApplication
-
+ Executable '%1' doesn't support Windows compatibility mode.
-
+ Executable '%1' requires Qt v%2, but found Qt v%3.
-
+ Executable '%1' was built for Qt '%2', but found Qt '%3'.
-
-
+
+ Executable '%1' requires Windows 2000 or later.
diff --git a/etc/Translation/LameXP_PL.ts b/etc/Translation/LameXP_PL.ts
index a0698450..56ea6dc7 100644
--- a/etc/Translation/LameXP_PL.ts
+++ b/etc/Translation/LameXP_PL.ts
@@ -3349,23 +3349,23 @@
QApplication
-
+ Executable '%1' doesn't support Windows compatibility mode.Plik wykonywalny '%1' nie działa w trybie kompatybilności z Windows.
-
+ Executable '%1' requires Qt v%2, but found Qt v%3.Plik wykonywalny '%1' wymaga Qt v%2, znaleziono jednak Qt v%3.
-
+ Executable '%1' was built for Qt '%2', but found Qt '%3'.Plik wykonywalny "%1" został skompilowany dla Qt "%2", znaleziono "%3".
-
-
+
+ Executable '%1' requires Windows 2000 or later.Plik wykonywalny '%1' wymaga do uruchomienia Windows 2000 lub nowszego.
diff --git a/src/Config.h b/src/Config.h
index 41fe7ed2..9857b8b5 100644
--- a/src/Config.h
+++ b/src/Config.h
@@ -33,8 +33,8 @@
#define VER_LAMEXP_MINOR_HI 0
#define VER_LAMEXP_MINOR_LO 8
#define VER_LAMEXP_TYPE RC
-#define VER_LAMEXP_PATCH 1
-#define VER_LAMEXP_BUILD 1328
+#define VER_LAMEXP_PATCH 2
+#define VER_LAMEXP_BUILD 1329
#define VER_LAMEXP_CONFG 1288
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/Global.cpp b/src/Global.cpp
index e3fa3046..ce886cf1 100644
--- a/src/Global.cpp
+++ b/src/Global.cpp
@@ -54,6 +54,7 @@
#include "Resource.h"
#include "Config.h"
#include "LockedFile.h"
+#include "strnatcmp.h"
//CRT includes
#include
@@ -2426,6 +2427,23 @@ QDate lamexp_current_date_safe(void)
return (currentDate >= processDate) ? currentDate : processDate;
}
+
+/*
+ * Natural Order String Comparison - the 'lessThan' helper function
+ */
+static bool lamexp_natural_string_sort_helper(const QString &str1, const QString &str2)
+{
+ return (strnatcmp(QWCHAR(str1), QWCHAR(str2)) < 0);
+}
+
+/*
+ * Natural Order String Comparison - the main sorting function
+ */
+void lamexp_natural_string_sort(QStringList &list)
+{
+ qSort(list.begin(), list.end(), lamexp_natural_string_sort_helper);
+}
+
/*
* Entry point checks
*/
diff --git a/src/Global.h b/src/Global.h
index 5f8fcad8..9624501d 100644
--- a/src/Global.h
+++ b/src/Global.h
@@ -162,6 +162,7 @@ const QString lamexp_clean_filepath(const QString &str);
void lamexp_seed_rand(void);
unsigned int lamexp_rand(void);
QDate lamexp_current_date_safe(void);
+void lamexp_natural_string_sort(QStringList &list);
void lamexp_fatal_exit(const wchar_t* exitMessage, const wchar_t* errorBoxMessage = NULL);
//Debug-only functions
diff --git a/src/Thread_FileAnalyzer.cpp b/src/Thread_FileAnalyzer.cpp
index 2374c60a..1f12f53e 100644
--- a/src/Thread_FileAnalyzer.cpp
+++ b/src/Thread_FileAnalyzer.cpp
@@ -119,7 +119,7 @@ void FileAnalyzer::run()
emit progressMaxChanged(nFiles);
emit progressValChanged(0);
- m_inputFiles.sort();
+ lamexp_natural_string_sort(m_inputFiles); //.sort();
if(!m_templateFile)
{
diff --git a/src/Thread_FileAnalyzer_ST.cpp b/src/Thread_FileAnalyzer_ST.cpp
index e125acb4..60e5600e 100644
--- a/src/Thread_FileAnalyzer_ST.cpp
+++ b/src/Thread_FileAnalyzer_ST.cpp
@@ -136,7 +136,8 @@ void FileAnalyzer_ST::run()
m_filesDummyCDDA = 0;
m_filesCueSheet = 0;
- m_inputFiles.sort();
+ lamexp_natural_string_sort(m_inputFiles); // .sort()
+
m_recentlyAdded.clear();
m_abortFlag = false;