📄 qsettings.cpp
字号:
return QVariant(s.toLatin1().mid(11, s.size() - 12)); } else if (s.startsWith(QLatin1String("@Variant("))) {#ifndef QT_NO_DATASTREAM QByteArray a(s.toLatin1().mid(9)); QDataStream stream(&a, QIODevice::ReadOnly); QVariant result; stream >> result; return result;#else Q_ASSERT("QSettings: Cannot load custom types without QDataStream support");#endif#ifndef QT_NO_GEOM_VARIANT } else if (s.startsWith(QLatin1String("@Rect("))) { QStringList args = QSettingsPrivate::splitArgs(s, 5); if (args.size() == 4) { return QVariant(QRect(args[0].toInt(), args[1].toInt(), args[2].toInt(), args[3].toInt())); } } else if (s.startsWith(QLatin1String("@Size("))) { QStringList args = QSettingsPrivate::splitArgs(s, 5); if (args.size() == 2) { return QVariant(QSize(args[0].toInt(), args[1].toInt())); } } else if (s.startsWith(QLatin1String("@Point("))) { QStringList args = QSettingsPrivate::splitArgs(s, 6); if (args.size() == 2) { return QVariant(QPoint(args[0].toInt(), args[1].toInt())); }#endif } else if (s == QLatin1String("@Invalid()")) { return QVariant(); } } QString tmp = s; return QVariant(unescapedLeadingAt(tmp));}static const char hexDigits[] = "0123456789ABCDEF";void QSettingsPrivate::iniEscapedKey(const QString &key, QByteArray &result){ for (int i = 0; i < key.size(); ++i) { uint ch = key.at(i).unicode(); if (ch == '/') { result += '\\'; } else if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9' || ch == '_' || ch == '-' || ch == '.') { result += (char)ch; } else if (ch <= 0xFF) { result += '%'; result += hexDigits[ch / 16]; result += hexDigits[ch % 16]; } else { result += "%U"; QByteArray hexCode; for (int i = 0; i < 4; ++i) { hexCode.prepend(hexDigits[ch % 16]); ch >>= 4; } result += hexCode; } }}bool QSettingsPrivate::iniUnescapedKey(const QByteArray &key, int from, int to, QString &result){ bool lowercaseOnly = true; int i = from; while (i < to) { int ch = (uchar)key.at(i); if (ch == '\\') { result += QLatin1Char('/'); ++i; continue; } if (ch != '%' || i == to - 1) { if (isupper((uchar)ch)) lowercaseOnly = false; result += QLatin1Char(ch); ++i; continue; } int numDigits = 2; int firstDigitPos = i + 1; ch = key.at(i + 1); if (ch == 'U') { ++firstDigitPos; numDigits = 4; } if (firstDigitPos + numDigits > to) { result += QLatin1Char('%'); ++i; continue; } bool ok; ch = key.mid(firstDigitPos, numDigits).toInt(&ok, 16); if (!ok) { result += QLatin1Char('%'); ++i; continue; } QChar qch(ch); if (qch.toLower() != qch) lowercaseOnly = false; result += qch; i = firstDigitPos + numDigits; } return lowercaseOnly;}void QSettingsPrivate::iniEscapedString(const QString &str, QByteArray &result){ bool needsQuotes = false; bool escapeNextIfDigit = false; int i; int startPos = result.size(); for (i = 0; i < str.size(); ++i) { uint ch = str.at(i).unicode(); if (ch == ';' || ch == ',' || ch == '=') needsQuotes = true; if (escapeNextIfDigit && ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F'))) { result += "\\x"; result += QByteArray::number(ch, 16); continue; } escapeNextIfDigit = false; switch (ch) { case '\0': result += "\\0"; escapeNextIfDigit = true; break; case '\a': result += "\\a"; break; case '\b': result += "\\b"; break; case '\f': result += "\\f"; break; case '\n': result += "\\n"; break; case '\r': result += "\\r"; break; case '\t': result += "\\t"; break; case '\v': result += "\\v"; break; case '"': case '\\': result += '\\'; result += (char)ch; break; default: if (ch <= 0x1F || ch >= 0x7F) { result += "\\x"; result += QByteArray::number(ch, 16); escapeNextIfDigit = true; } else { result += (char)ch; } } } if (needsQuotes || (startPos < result.size() && (result.at(startPos) == ' ' || result.at(result.size() - 1) == ' '))) { result.insert(startPos, '"'); result += '"'; }}void QSettingsPrivate::iniChopTrailingSpaces(QString *str){ int n = str->size(); while (n > 0 && (str->at(n - 1) == QLatin1Char(' ') || str->at(n - 1) == QLatin1Char('\t'))) str->truncate(--n);}void QSettingsPrivate::iniEscapedStringList(const QStringList &strs, QByteArray &result){ if (strs.isEmpty()) { /* We need to distinguish between empty lists and one-item lists that contain an empty string. Ideally, we'd have a @EmptyList() symbol but that would break compatibility with Qt 4.0. @Invalid() stands for QVariant(), and QVariant().toStringList() returns an empty QStringList, so we're in good shape. */ result += "@Invalid()"; } else { for (int i = 0; i < strs.size(); ++i) { if (i != 0) result += ", "; iniEscapedString(strs.at(i), result); } }}QStringList *QSettingsPrivate::iniUnescapedStringList(const QByteArray &str, int from, int to, QString &result){ static const char escapeCodes[][2] = { { 'a', '\a' }, { 'b', '\b' }, { 'f', '\f' }, { 'n', '\n' }, { 'r', '\r' }, { 't', '\t' }, { 'v', '\v' }, { '"', '"' }, { '?', '?' }, { '\'', '\'' }, { '\\', '\\' } }; static const int numEscapeCodes = sizeof(escapeCodes) / sizeof(escapeCodes[0]); QStringList *strList = 0; int i = from; enum State { StNormal, StSkipSpaces, StEscape, StHexEscapeFirstChar, StHexEscape, StOctEscape }; State state = StSkipSpaces; int escapeVal = 0; bool inQuotedString = false; bool currentValueIsQuoted = false; while (i < to) { char ch = str.at(i); switch (state) { case StNormal: switch (ch) { case '\\': state = StEscape; break; case '"': currentValueIsQuoted = true; inQuotedString = !inQuotedString; if (!inQuotedString) state = StSkipSpaces; break; case ',': if (!inQuotedString) { if (!currentValueIsQuoted) iniChopTrailingSpaces(&result); if (!strList) strList = new QStringList; strList->append(result); result.clear(); currentValueIsQuoted = false; state = StSkipSpaces; break; } // fallthrough default: result += QLatin1Char(ch); } ++i; break; case StSkipSpaces: if (ch == ' ' || ch == '\t') ++i; else state = StNormal; break; case StEscape: for (int j = 0; j < numEscapeCodes; ++j) { if (ch == escapeCodes[j][0]) { result += QLatin1Char(escapeCodes[j][1]); ++i; state = StNormal; goto end_of_switch; } } if (ch == 'x') { escapeVal = 0; state = StHexEscapeFirstChar; } else if (ch >= '0' && ch <= '7') { escapeVal = ch - '0'; state = StOctEscape; } else { state = StNormal; } ++i; break; case StHexEscapeFirstChar: if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f')) state = StHexEscape; else state = StNormal; break; case StHexEscape: if (ch >= 'a') ch -= 'a' - 'A'; if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F')) { escapeVal <<= 4; escapeVal += strchr(hexDigits, ch) - hexDigits; ++i; } else { result += QChar(escapeVal); state = StNormal; } break; case StOctEscape: if (ch >= '0' && ch <= '7') { escapeVal <<= 3; escapeVal += ch - '0'; ++i; } else { result += QChar(escapeVal); state = StNormal; } }end_of_switch: ; } if (state == StHexEscape || state == StOctEscape) result += QChar(escapeVal); if (!currentValueIsQuoted) iniChopTrailingSpaces(&result); if (strList) strList->append(result); return strList;}QStringList QSettingsPrivate::splitArgs(const QString &s, int idx){ int l = s.length(); Q_ASSERT(l > 0); Q_ASSERT(s.at(idx) == QLatin1Char('(')); Q_ASSERT(s.at(l - 1) == QLatin1Char(')')); QStringList result; QString item; for (++idx; idx < l; ++idx) { QChar c = s.at(idx); if (c == QLatin1Char(')')) { Q_ASSERT(idx == l - 1); result.append(item); } else if (c == QLatin1Char(' ')) { result.append(item); item.clear(); } else { item.append(c); } } return result;}// ************************************************************************// QConfFileSettingsPrivate/* If we don't have the permission to read the file, returns false. If the file doesn't exist, returns true.*/static bool checkAccess(const QString &name){ QFileInfo fileInfo(name); if (fileInfo.exists()) { QFile file(name); // if the file exists but we can't open it, report an error return file.open(QFile::ReadOnly); } else { QDir dir; if (QDir::isRelativePath(name)) dir = QDir::current(); else dir = QDir::root(); /* Create the directories to the file. */ QStringList pathElements = name.split(QLatin1Char('/'), QString::SkipEmptyParts); for (int i = 0; i < pathElements.size() - 1; ++i) { const QString &elt = pathElements.at(i); if (dir.cd(elt)) continue; if (dir.mkdir(elt) && dir.cd(elt)) continue; if (dir.cd(elt)) continue; // if the path can't be created/reached, report an error return false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -