Fix bug 9030 except for windows

The format entries should be sorted according to the culture selected for the
UI. This was not the case previously, resulting in unexpected sorting of small
and capital letters. This is now fixed by using the standard C function
strcoll(). Qt does only offer similar functionality in Qt5, and this is not
mature enough yet to depend on it.
Unfortunately we have a report that strcoll() does not work on MSVC, however
this partial fix is better than nothing. The MSVC issue might also be a
configuration problem, since MS claims that strcoll() is supported. This
still needs to be checked.
This commit is contained in:
Georg Baum 2014-05-19 22:37:14 +02:00
parent 2acd00fc17
commit afc34c7a60
3 changed files with 30 additions and 2 deletions

View File

@ -104,12 +104,12 @@ private:
bool Format::formatSorter(Format const * lhs, Format const * rhs) bool Format::formatSorter(Format const * lhs, Format const * rhs)
{ {
return _(lhs->prettyname()) < _(rhs->prettyname()); return compare_locale(_(lhs->prettyname()), _(rhs->prettyname())) < 0;
} }
bool operator<(Format const & a, Format const & b) bool operator<(Format const & a, Format const & b)
{ {
return _(a.prettyname()) < _(b.prettyname()); return compare_locale(_(a.prettyname()), _(b.prettyname())) < 0;
} }

View File

@ -15,6 +15,7 @@
#include "support/lstrings.h" #include "support/lstrings.h"
#include "support/convert.h" #include "support/convert.h"
#include "support/debug.h"
#include "support/qstring_helpers.h" #include "support/qstring_helpers.h"
#include "support/lassert.h" #include "support/lassert.h"
@ -22,6 +23,7 @@
#include <QString> #include <QString>
#include <cstdio> #include <cstdio>
#include <cstring>
#include <algorithm> #include <algorithm>
using namespace std; using namespace std;
@ -200,6 +202,29 @@ int compare_no_case(docstring const & s, docstring const & s2)
} }
int compare_locale(docstring const & s, docstring const & s2)
{
// FIXME We have a report that this does not work on windows (bug 9030)
try
{
string const l = to_local8bit(s);
string const r = to_local8bit(s2);
return strcoll(l.c_str(), r.c_str());
}
catch (bad_cast & e)
{
// fall back to builtin sorting
LYXERR0("Could not compare using the current locale: "
<< e.what() << ", using fallback.");
if (s < s2)
return -1;
if (s > s2)
return 1;
return 0;
}
}
namespace { namespace {
template<typename Char> template<typename Char>

View File

@ -28,6 +28,9 @@ namespace support {
/// Does not depend on the locale. /// Does not depend on the locale.
int compare_no_case(docstring const & s, docstring const & s2); int compare_no_case(docstring const & s, docstring const & s2);
/// Compare \p s and \p s2 using the collating rules of the current locale.
int compare_locale(docstring const & s, docstring const & s2);
/// Compare \p s and \p s2, ignoring the case of ASCII characters only. /// Compare \p s and \p s2, ignoring the case of ASCII characters only.
int compare_ascii_no_case(std::string const & s, std::string const & s2); int compare_ascii_no_case(std::string const & s, std::string const & s2);