File indexing completed on 2024-10-13 05:04:04
0001 // clang-format off 0002 /* 0003 * KDiff3 - Text Diff And Merge Tool 0004 0005 * SPDX-FileCopyrightText: 2002-2011 Joachim Eibl, joachim.eibl at gmx.de 0006 * SPDX-FileCopyrightText: 2018-2020 Michael Reeves reeves.87@gmail.com 0007 * SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 // clang-format on 0010 0011 #include "common.h" 0012 #include "TypeUtils.h" 0013 0014 #include <map> 0015 #include <utility> // for pair 0016 0017 #include <QColor> 0018 #include <QFont> 0019 #include <QLatin1String> 0020 #include <QPoint> 0021 #include <QSize> 0022 #include <QStringList> 0023 #include <QStringLiteral> 0024 #include <QTextStream> 0025 0026 ValueMap::ValueMap() = default; 0027 0028 ValueMap::~ValueMap() = default; 0029 0030 void ValueMap::save(QTextStream& ts) 0031 { 0032 for(const auto &entry: m_map) 0033 { 0034 const QString key = entry.first; 0035 const QString val = entry.second; 0036 ts << key << "=" << val << "\n"; 0037 } 0038 } 0039 0040 QString ValueMap::getAsString() 0041 { 0042 QString result; 0043 0044 for(const auto &entry: m_map) 0045 { 0046 const QString key = entry.first; 0047 const QString val = entry.second; 0048 result += key + '=' + val + '\n'; 0049 } 0050 return result; 0051 } 0052 0053 void ValueMap::load(QTextStream& ts) 0054 { 0055 while(!ts.atEnd()) 0056 { // until end of file... 0057 QString s = ts.readLine(); // line of text excluding '\n' 0058 QtSizeType pos = s.indexOf('='); 0059 if(pos > 0) // seems not to have a tag 0060 { 0061 QString key = s.left(pos); 0062 QString val = s.mid(pos + 1); 0063 m_map[key] = val; 0064 } 0065 } 0066 } 0067 0068 // safeStringJoin and safeStringSplit allow to convert a stringlist into a string and back 0069 // safely, even if the individual strings in the list contain the separator character. 0070 QString safeStringJoin(const QStringList& sl, char sepChar, char metaChar) 0071 { 0072 // Join the strings in the list, using the separator ',' 0073 // If a string contains the separator character, it will be replaced with "\,". 0074 // Any occurrences of "\" (one backslash) will be replaced with "\\" (2 backslashes) 0075 0076 assert(sepChar != metaChar); 0077 0078 QString sep; 0079 sep += sepChar; 0080 QString meta; 0081 meta += metaChar; 0082 0083 QString safeString; 0084 0085 QStringList::const_iterator i; 0086 for(i = sl.begin(); i != sl.end(); ++i) 0087 { 0088 QString s = *i; 0089 s.replace(meta, meta + meta); // "\" -> "\\" 0090 s.replace(sep, meta + sep); // "," -> "\," 0091 if(i == sl.begin()) 0092 safeString = s; 0093 else 0094 safeString += sep + s; 0095 } 0096 return safeString; 0097 } 0098 0099 // Split a string that was joined with safeStringJoin 0100 QStringList safeStringSplit(const QString& s, char sepChar, char metaChar) 0101 { 0102 assert(sepChar != metaChar); 0103 QStringList sl; 0104 // Miniparser 0105 QtSizeType i = 0; 0106 QtSizeType len = s.length(); 0107 QString b; 0108 for(i = 0; i < len; ++i) 0109 { 0110 if(i + 1 < len && s[i] == metaChar && s[i + 1] == metaChar) 0111 { 0112 b += metaChar; 0113 ++i; 0114 } 0115 else if(i + 1 < len && s[i] == metaChar && s[i + 1] == sepChar) 0116 { 0117 b += sepChar; 0118 ++i; 0119 } 0120 else if(s[i] == sepChar) // real separator 0121 { 0122 sl.push_back(b); 0123 b = ""; 0124 } 0125 else 0126 { 0127 b += s[i]; 0128 } 0129 } 0130 if(!b.isEmpty()) 0131 sl.push_back(b); 0132 0133 return sl; 0134 } 0135 0136 void ValueMap::writeEntry(const QString& k, const QFont& v) 0137 { 0138 m_map[k] = v.family() + u8"," + QString::number(v.pointSize()) + u8"," + (v.bold() ? QStringLiteral("bold") : QStringLiteral("normal")); 0139 } 0140 0141 void ValueMap::writeEntry(const QString& k, const QColor& v) 0142 { 0143 m_map[k].setNum(v.red()) + u8"," + QString().setNum(v.green()) + u8"," + QString().setNum(v.blue()); 0144 } 0145 0146 void ValueMap::writeEntry(const QString& k, const QSize& v) 0147 { 0148 m_map[k].setNum(v.width()) + u8"," + QString().setNum(v.height()); 0149 } 0150 0151 void ValueMap::writeEntry(const QString& k, const QPoint& v) 0152 { 0153 m_map[k].setNum(v.x()) + u8"," + QString().setNum(v.y()); 0154 } 0155 0156 void ValueMap::writeEntry(const QString& k, qint32 v) 0157 { 0158 m_map[k].setNum(v); 0159 } 0160 0161 void ValueMap::writeEntry(const QString& k, bool v) 0162 { 0163 m_map[k].setNum(v); 0164 } 0165 0166 void ValueMap::writeEntry(const QString& k, const QString& v) 0167 { 0168 m_map[k] = v; 0169 } 0170 0171 void ValueMap::writeEntry(const QString& k, const char* v) 0172 { 0173 m_map[k] = QLatin1String(v); 0174 } 0175 0176 void ValueMap::writeEntry(const QString& k, const QStringList& v) 0177 { 0178 m_map[k] = safeStringJoin(v); 0179 } 0180 0181 QFont ValueMap::readFontEntry(const QString& k, const QFont* defaultVal) 0182 { 0183 QFont f = *defaultVal; 0184 std::map<QString, QString>::iterator i = m_map.find(k); 0185 if(i != m_map.end()) 0186 { 0187 f.setFamily(i->second.split(',')[0]); 0188 f.setPointSize(i->second.split(',')[1].toInt()); 0189 f.setBold(i->second.split(',')[2] == "bold"); 0190 } 0191 return f; 0192 } 0193 0194 QColor ValueMap::readColorEntry(const QString& k, const QColor* defaultVal) 0195 { 0196 QColor c = *defaultVal; 0197 std::map<QString, QString>::iterator i = m_map.find(k); 0198 if(i != m_map.end()) 0199 { 0200 QString s = i->second; 0201 c = QColor(s.split(',')[0].toInt(), s.split(',')[1].toInt(), s.split(',')[2].toInt()); 0202 } 0203 0204 return c; 0205 } 0206 0207 QSize ValueMap::readSizeEntry(const QString& k, const QSize* defaultVal) 0208 { 0209 QSize size = defaultVal ? *defaultVal : QSize(600, 400); 0210 std::map<QString, QString>::iterator i = m_map.find(k); 0211 if(i != m_map.end()) 0212 { 0213 0214 QString s = i->second; 0215 size = QSize(s.split(',')[0].toInt(), s.split(',')[1].toInt()); 0216 } 0217 0218 return size; 0219 } 0220 0221 QPoint ValueMap::readPointEntry(const QString& k, const QPoint* defaultVal) 0222 { 0223 QPoint point = defaultVal ? *defaultVal : QPoint(0, 0); 0224 std::map<QString, QString>::iterator i = m_map.find(k); 0225 if(i != m_map.end()) 0226 { 0227 QString s = i->second; 0228 point = QPoint(s.split(',')[0].toInt(), s.split(',')[1].toInt()); 0229 } 0230 0231 return point; 0232 } 0233 0234 bool ValueMap::readBoolEntry(const QString& k, bool bDefault) 0235 { 0236 bool b = bDefault; 0237 std::map<QString, QString>::iterator i = m_map.find(k); 0238 if(i != m_map.end()) 0239 { 0240 QString s = i->second; 0241 b = (s.split(',')[0].toInt() == 1); 0242 } 0243 0244 return b; 0245 } 0246 0247 qint32 ValueMap::readNumEntry(const QString& k, qint32 iDefault) 0248 { 0249 qint32 ival = iDefault; 0250 std::map<QString, QString>::iterator i = m_map.find(k); 0251 if(i != m_map.end()) 0252 { 0253 QString s = i->second; 0254 ival = s.split(',')[0].toInt(); 0255 } 0256 0257 return ival; 0258 } 0259 0260 QString ValueMap::readStringEntry(const QString& k, const QString& sDefault) 0261 { 0262 QString sval = sDefault; 0263 std::map<QString, QString>::iterator i = m_map.find(k); 0264 if(i != m_map.end()) 0265 { 0266 sval = i->second; 0267 } 0268 0269 return sval; 0270 } 0271 0272 QStringList ValueMap::readListEntry(const QString& k, const QStringList& defaultVal) 0273 { 0274 QStringList strList; 0275 0276 std::map<QString, QString>::iterator i = m_map.find(k); 0277 if(i != m_map.end()) 0278 { 0279 strList = safeStringSplit(i->second); 0280 return strList; 0281 } 0282 else 0283 return defaultVal; 0284 } 0285 0286 QString ValueMap::readEntry(const QString& s, const QString& defaultVal) 0287 { 0288 return readStringEntry(s, defaultVal); 0289 } 0290 0291 QString ValueMap::readEntry(const QString& s, const char* defaultVal) 0292 { 0293 return readStringEntry(s, QString::fromLatin1(defaultVal)); 0294 } 0295 0296 QFont ValueMap::readEntry(const QString& s, const QFont& defaultVal) 0297 { 0298 return readFontEntry(s, &defaultVal); 0299 } 0300 0301 QColor ValueMap::readEntry(const QString& s, const QColor defaultVal) 0302 { 0303 return readColorEntry(s, &defaultVal); 0304 } 0305 0306 QSize ValueMap::readEntry(const QString& s, const QSize defaultVal) 0307 { 0308 return readSizeEntry(s, &defaultVal); 0309 } 0310 0311 QPoint ValueMap::readEntry(const QString& s, const QPoint defaultVal) 0312 { 0313 return readPointEntry(s, &defaultVal); 0314 } 0315 0316 bool ValueMap::readEntry(const QString& s, bool bDefault) 0317 { 0318 return readBoolEntry(s, bDefault); 0319 } 0320 0321 qint32 ValueMap::readEntry(const QString& s, qint32 iDefault) 0322 { 0323 return readNumEntry(s, iDefault); 0324 } 0325 0326 QStringList ValueMap::readEntry(const QString& s, const QStringList& defaultVal) 0327 { 0328 return readListEntry(s, defaultVal); 0329 }