static QByteArray getWinLocaleName(LCID id) { QByteArray result; if (id == LOCALE_USER_DEFAULT) { static QByteArray langEnvVar = qgetenv("LANG"); result = langEnvVar; QString lang, script, cntry; if ( result == "C" || (!result.isEmpty() && qt_splitLocaleName(QString::fromLocal8Bit(result), lang, script, cntry)) ) { long id = 0; bool ok = false; id = qstrtoll(result.data(), 0, 0, &ok); if ( !ok || id == 0 || id < INT_MIN || id > INT_MAX ) return result; else return winLangCodeToIsoName( (int)id ); } } #if defined(Q_OS_WINCE) result = winLangCodeToIsoName(id != LOCALE_USER_DEFAULT ? id : GetUserDefaultLCID()); #else if (id == LOCALE_USER_DEFAULT) id = GetUserDefaultLCID(); QString resultuage = winIso639LangName(id); QString country = winIso3116CtryName(id); result = resultuage.toLatin1(); if (!country.isEmpty()) { result += '_'; result += country.toLatin1(); } #endif return result; }
/*! Compares a string using a natural comparison algorithm. In other words, it sorts the numbers in value order and the remaining characters in ASCII order. The code is based on the LGPL C++ implementation found at http://www.davekoelle.com/alphanum.html See this header file for license details. */ int Movida::naturalCompare(const QString &string_a, const QString &string_b, Qt::CaseSensitivity cs) { if (string_a.unicode() == string_b.unicode()) return 0; if (string_a.isEmpty()) return -1; if (string_b.isEmpty()) return +1; const bool _cs = cs == Qt::CaseSensitive; enum Mode { String, Number } mode = String; const QChar* a_begin = string_a.unicode(); const QChar* a_end = a_begin + string_a.length(); const QChar* a = a_begin; const QChar* b_begin = string_b.unicode(); const QChar* b_end = b_begin + string_b.length(); const QChar* b = b_begin; bool mode_change = false; int last_num_compare = 0; while (a != a_end && b != b_end) { last_num_compare = 0; switch (mode) { case String: { while (a != a_end && b != b_end) { // Check if this are digit characters const bool a_digit = a->isDigit(); const bool b_digit = b->isDigit(); // If both characters are digits, we continue in Number mode if (a_digit && b_digit) { mode = Number; mode_change = true; break; } // If only the left character is a digit, we have a result if (a_digit) return -1; // If only the right character is a digit, we have a result if (b_digit) return +1; // Compute the difference of both characters const quint16 u_a = a->unicode(); const quint16 u_b = b->unicode(); const quint16 diff = _cs ? (u_a - u_b) : (QChar::toCaseFolded(u_a) - QChar::toCaseFolded(u_b)); // If they differ we have a result if (diff != 0) return diff; // Otherwise process the next characters ++a; ++b; } } break; case Number: { // Get the left number CharBuff a_buff; qMemSet(a_buff.data(), 0, a_buff.capacity()); a = extractNumber(a, a_end, a_buff); quint64 a_num = qstrtoll(a_buff.constData(), 0, 10, 0); // Get the right number CharBuff b_buff; qMemSet(b_buff.data(), 0, b_buff.capacity()); b = extractNumber(b, b_end, b_buff); quint64 b_num = qstrtoll(b_buff.constData(), 0, 10, 0); // If the difference is not equal to zero, we have a comparison result const long diff = a_num - b_num; if (diff != 0) return diff; // If the strings differ only by the number of padding zeros // in the current number, we should take it into account and // simulate a lexical comparison by comparing the number of // digits. last_num_compare = a_buff.size() - b_buff.size(); // Otherwise we process the next substring in String mode mode = String; } break; } if (!mode_change && a != a_end && b != b_end) { ++a; ++b; } else mode_change = false; } if (a == a_end && b == b_end) return last_num_compare; if (a == a_end) return -1; if (b == b_end) return +1; return last_num_compare; }