• qsettings 中文键值 注释 支持


    #ifndef SETTINGS_H
    #define SETTINGS_H

    #include <QString>
    #include <QVariant>

    class QSettings;

    class Settings
    {
    public:
        Settings(const QString & fileName);
        ~Settings();
        void setValue ( const QString & key, const QVariant & value );
        QVariant value ( const QString & key, const QVariant & defaultValue = QVariant() ) const;
    private:
        QSettings *d;
    };

    #endif // SETTINGS_H

    #include "settings.h"
    #include <QtGui>

    QMap<int, QString> comments;

    //#define LZM_DEBUG

    bool readIniComment(QString fileName)
    {
        QFile file(fileName);
        if (!file.open(QIODevice::ReadOnly))
        {
            qDebug()<<"readIniComment open"<<fileName<<"failed!: error"<<file.error();
            return false;
        }

        QTextStream inStream(&file);
        inStream.setCodec("UTF-8");

        QString data;
        bool ok = true;

        int line=-1;
        while (!inStream.atEnd())
        {
            data = inStream.readLine();
            line++;
            QString trimmed = data.trimmed();
            if(trimmed.isEmpty())
            {
                continue;
            }
            else if(trimmed[0]== QChar('#') || trimmed[0]== QChar(';'))
            {
                comments[line] = data;
    #ifdef LZM_DEBUG
                qDebug()<<"line"<<line<<"text"<<data;
    #endif

            }
            else
            {
                continue;
            }
        }

        return ok;
    }

    bool WriteIniComment(QString fileName)
    {
        QFile inFile(fileName);
        if (!inFile.open(QIODevice::ReadOnly))
        {
            qDebug()<<"WriteIniComment open"<<fileName<<"failed!";
            return false;
        }

        QString outFileName = fileName+".out";
        QFile outfile(outFileName);
        if (!outfile.open(QIODevice::WriteOnly))
        {
            qDebug()<<"open"<<outFileName<<"failed!";
            return false;
        }

        QTextStream inStream(&inFile);
        inStream.setCodec("UTF-8");

        QTextStream outStream(&outfile);
        outStream.setCodec("UTF-8");

        QString data;
        bool ok = true;

        int line=-1;

        while (!inStream.atEnd())
        {
            data = inStream.readLine();
            line++;
            QString trimmed = data.trimmed();
            //add comments
            while(comments.contains(line))
            {
                outStream <<comments[line]<<"\n";
    #ifdef LZM_DEBUG
                qDebug()<<"line"<<line<<"text"<<comments[line];
    #endif
                line++;
            }

            if(trimmed.isEmpty())
            {
                outStream <<data<<"\n";
                continue;
            }
            else
            {
                outStream <<data<<"\n";
            }
        }

        inFile.close();
        outfile.close();
    //

        QFile::remove(fileName);
        qDebug()<<"remove"<<fileName;
        QFile::rename(outFileName, fileName);
        qDebug()<<"rename"<<outFileName<<"to"<<fileName;

        return ok;
    }

    QStringList 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;
    }

    QVariant stringToVariant(const QString &s)
    {
        if (s.startsWith(QLatin1Char('@'))) {
            if (s.endsWith(QLatin1Char(')'))) {
                if (s.startsWith(QLatin1String("@ByteArray("))) {
                    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);
                    stream.setVersion(QDataStream::Qt_4_0);
                    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 = ::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 = ::splitArgs(s, 5);
                    if (args.size() == 2)
                        return QVariant(QSize(args[0].toInt(), args[1].toInt()));
                } else if (s.startsWith(QLatin1String("@Point("))) {
                    QStringList args = ::splitArgs(s, 6);
                    if (args.size() == 2)
                        return QVariant(QPoint(args[0].toInt(), args[1].toInt()));
    #endif
                } else if (s == QLatin1String("@Invalid()")) {
                    return QVariant();
                }

            }
            if (s.startsWith(QLatin1String("@@")))
                return QVariant(s.mid(1));
        }

        return QVariant(s);
    }

    bool myReadFunc(QIODevice &device, QSettings::SettingsMap &settingsMap)
    {
            QString currentSection;
            QTextStream stream(&device);
            stream.setCodec("UTF-8");
            QString data;
            bool ok = true;
            while (!stream.atEnd())
            {

                data = stream.readLine();
                if (data.trimmed().isEmpty())
                {
                    continue;
                }
                if (data[0] == QChar('['))
                {
                    QString iniSection;
                    int inx = data.indexOf(QChar(']'));
                    if (inx == -1){
                        ok = false;
                        iniSection = data.mid(1);
                    }
                    else
                    {
                        iniSection = data.mid(1, inx - 1);
                    }
                    iniSection = iniSection.trimmed();
                    if (iniSection.compare(QString("general"), Qt::CaseInsensitive) == 0)
                    {
                        currentSection.clear();
                    }
                    else
                    {
                        if (iniSection.compare(QString("%general"), Qt::CaseInsensitive) == 0)
                        {
                            currentSection = QString("general");
                        }
                        else
                        {
                            currentSection = iniSection;
                        }
                        currentSection += QChar('/');

                    }
                }
                else
                {
                    bool inQuotes = false;
                    int equalsPos = -1;
                    QList<int> commaPos;
                    int i = 0;
                    while (i < data.size())
                    {
                        QChar ch = data.at(i);
                        if (ch == QChar('='))
                        {
                            if (!inQuotes && equalsPos == -1)
                            {
                                equalsPos = i;
                            }
                        }
                        else if (ch == QChar('"'))
                        {
                            inQuotes = !inQuotes;
                        }
                        else if (ch == QChar(','))
                        {
                            if (!inQuotes && equalsPos != -1)
                            {
                                commaPos.append(i);
                            }
                        }
                        else if (ch == QChar(';') || ch == QChar('#'))
                        {
                            if (!inQuotes)
                            {
                                data.resize(i);
                                break;
                            }
                        }
                        else if (ch == QChar('\\'))
                        {
                            if (++i < data.size())
                            {
                            }
                            else
                            {
                                ok = false;
                                break;
                            }
                        }
                        i++;
                    }
                    if (equalsPos == -1)
                    {
                        break;
                    }
                    else
                    {
                        QString key = data.mid(0, equalsPos).trimmed();
                        if (key.isEmpty())
                        {
                            break;
                        }
                        else
                        {
                            key = currentSection + key;
                        }
                        if (commaPos.isEmpty())
                        {
                            //value
                            QString v = data.mid(equalsPos+1).trimmed();
                            if (v.startsWith("\"") && v.endsWith("\"") && v.length()>1)
                            {
                                v = v.mid(1, v.length()-2);
                            }
                            settingsMap[key] = stringToVariant(v);
                        }
                        else
                        { //value list
                            commaPos.prepend(equalsPos);
                            commaPos.append(-1);
                            QVariantList vals;
                            for (int i=1; i<commaPos.size(); ++i)
                            {
                                QString d = data.mid(commaPos.at(i-1)+1, commaPos.at(i)-commaPos.at(i-1)-1);
                                QString v = d.trimmed();
                                if (v.startsWith("\"") && v.endsWith("\"") && v.length()>1)
                                {
                                    v = v.mid(1, v.length()-2);
                                }
                                vals.append(stringToVariant(v) /*stringToVariant(unescapedString(v))*/);
                            }
                            settingsMap[key] = vals;
                        }
                    }
                }
            }

            return ok;
    }

    QString variantToString(const QVariant &v)
    {
         QString result;

         switch (v.type()) {
             case QVariant::Invalid:
                 result = QLatin1String("@Invalid()");
                 break;

             case QVariant::ByteArray: {
                 QByteArray a = v.toByteArray();
                 result = QLatin1String("@ByteArray(");
                 result += QString::fromLatin1(a.constData(), a.size());
                 result += QLatin1Char(')');
                 break;
             }

             case QVariant::String:
             case QVariant::LongLong:
             case QVariant::ULongLong:
             case QVariant::Int:
             case QVariant::UInt:
             case QVariant::Bool:
             case QVariant::Double:
             case QVariant::KeySequence: {
                 result = v.toString();
                 if (result.startsWith(QLatin1Char('@')))
                     result.prepend(QLatin1Char('@'));
                 break;
             }
    #ifndef QT_NO_GEOM_VARIANT
             case QVariant::Rect: {
                 QRect r = qvariant_cast<QRect>(v);
                 result += QLatin1String("@Rect(");
                 result += QString::number(r.x());
                 result += QLatin1Char(' ');
                 result += QString::number(r.y());
                 result += QLatin1Char(' ');
                 result += QString::number(r.width());
                 result += QLatin1Char(' ');
                 result += QString::number(r.height());
                 result += QLatin1Char(')');
                 break;
             }
             case QVariant::Size: {
                 QSize s = qvariant_cast<QSize>(v);
                 result += QLatin1String("@Size(");
                 result += QString::number(s.width());
                 result += QLatin1Char(' ');
                 result += QString::number(s.height());
                 result += QLatin1Char(')');
                 break;
             }
             case QVariant::Point: {
                 QPoint p = qvariant_cast<QPoint>(v);
                 result += QLatin1String("@Point(");
                 result += QString::number(p.x());
                 result += QLatin1Char(' ');
                 result += QString::number(p.y());
                 result += QLatin1Char(')');
                 break;
             }
    #endif // !QT_NO_GEOM_VARIANT

             default: {
    #ifndef QT_NO_DATASTREAM
                 QByteArray a;
                 {
                     QDataStream s(&a, QIODevice::WriteOnly);
                     s.setVersion(QDataStream::Qt_4_0);
                     s << v;
                 }

                 result = QLatin1String("@Variant(");
                 result += QString::fromLatin1(a.constData(), a.size());
                 result += QLatin1Char(')');
    #else
                 Q_ASSERT(!"QSettings: Cannot save custom types without QDataStream support");
    #endif
                 break;
             }
         }

         return result;
    }

    bool myWriteFunc(QIODevice &device, const QSettings::SettingsMap &settingsMap)
    {
    #ifdef Q_OS_WIN
        const char * const eol = "\r\n";
    #else
        const char *eol = "\n";
    #endif
        bool writeError = false;
        QString lastSection;
        QMapIterator<QString,QVariant> it(settingsMap);
        while(it.hasNext() && !writeError)
        {
            it.next();
            QString key = it.key();
            QString section;
            qDebug()<<"key: "<<key;
            int idx = key.lastIndexOf(QChar('/'));
            if (idx == -1)
            {
                section = QString("[General]");
            }
            else
            {
                section = key.left(idx);
                key = key.mid(idx+1);
                if (section.compare(QString("General"), Qt::CaseInsensitive) == 0)
                {
                    section = QString("[%General]");
                }
                else
                {
                    section.prepend(QChar('['));
                    section.append(QChar(']'));
                }
            }
            if (section.compare(lastSection, Qt::CaseInsensitive))
            {
                if (!lastSection.isEmpty())
                {
                    device.write(eol);
                }
                lastSection = section;
                if (device.write(section.toUtf8() + eol) == -1)
                {
                    writeError = true;
                }
            }
            QByteArray block = key.toUtf8();
            block += " = ";
            if (it.value().type() == QVariant::StringList)
            {
    //            foreach (QString s, it.value().toStringList())
    //            {
    //                block += /*escapedString(s)*/ s;
    //                block += ", ";
    //            }
    //            if (block.endsWith(", "))
    //            {
    //                block.chop(2);
    //            }
                qDebug()<< "no support QVariant::StringList";
            }
            else if (it.value().type() == QVariant::List)
            {
    //            foreach (QVariant v, it.value().toList())
    //            {
    //                block += /*escapedString(variantToString(v))*/ v.toString();
    //                block += ", ";
    //            }
    //            if (block.endsWith(", "))
    //            {
    //                block.chop(2);
    //            }
                qDebug()<< "no support QVariant::List";
            }
            else
            {
    //            block += /*escapedString*/(variantToString(it.value()));
    //            block += it.value().toString();
                block += variantToString(it.value());
            }
            block += eol;
            if (device.write(block) == -1)
            {
                writeError = true;
            }
        }
        return writeError;

    }

    Settings::Settings(const QString & fileName)
    {
        readIniComment(fileName);
        const QSettings::Format MyIniFormat = QSettings::registerFormat("ini", myReadFunc, myWriteFunc);
        d= new QSettings(fileName, MyIniFormat);
        d->setIniCodec("UTF-8");
    }

    Settings::~Settings()
    {
        if(d)
        {
            QString fileName = d->fileName();

            delete d;
            WriteIniComment(fileName);
        }

    }

    void Settings::setValue(const QString &key, const QVariant &value)
    {
        d->setValue(key, value);
    }

    QVariant Settings::value(const QString &key, const QVariant &defaultValue) const
    {
        return d->value(key, defaultValue);
    }

  • 相关阅读:
    使用jetty部署配置solr服务
    solr 与 MySQL(二)
    学习solr(一)
    FormData 上传文件
    node.js cannot find module 'mysql'
    select2 ajax 无法选中
    jenkins持续集成文件冲突的问题
    Inno Setup 实现每次jenkins自动构建时版本号自动+1
    jenkins 配置slave节点(win10系统)
    Jenkins+Gradle实现android开发持续集成和打包
  • 原文地址:https://www.cnblogs.com/cute/p/1968010.html
Copyright © 2020-2023  润新知