libqutim 0.2.80.1
|
00001 /**************************************************************************** 00002 ** 00003 ** qutIM - instant messenger 00004 ** 00005 ** Copyright © 2011 Ruslan Nigmatullin <euroelessar@yandex.ru> 00006 ** 00007 ***************************************************************************** 00008 ** 00009 ** $QUTIM_BEGIN_LICENSE$ 00010 ** This program is free software: you can redistribute it and/or modify 00011 ** it under the terms of the GNU General Public License as published by 00012 ** the Free Software Foundation, either version 3 of the License, or 00013 ** (at your option) any later version. 00014 ** 00015 ** This program is distributed in the hope that it will be useful, 00016 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00018 ** See the GNU General Public License for more details. 00019 ** 00020 ** You should have received a copy of the GNU General Public License 00021 ** along with this program. If not, see http://www.gnu.org/licenses/. 00022 ** $QUTIM_END_LICENSE$ 00023 ** 00024 ****************************************************************************/ 00025 00026 #ifndef CONFIG_H 00027 #define CONFIG_H 00028 00029 #include "libqutim_global.h" 00030 #include <QVariant> 00031 #include <QSharedData> 00032 #include <QMetaTypeId> 00033 00034 namespace qutim_sdk_0_3 00035 { 00036 #ifndef Q_QDOC 00037 namespace EnumDetectorHelper 00038 { 00039 typedef quint8 Yes; 00040 typedef quint16 No; 00041 00042 // Check if type can be casted to int 00043 inline Yes is_int_type(int) { return Yes(); } 00044 inline No is_int_type(...) { return No(); } 00045 00046 template <int Defined, int Size> 00047 class Helper 00048 { 00049 public: 00050 static No value() { return No(); } 00051 }; 00052 00053 template <> 00054 class Helper<0, sizeof(Yes)> 00055 { 00056 public: 00057 static Yes value() { return Yes(); } 00058 }; 00059 00060 template <typename T, int IsEnum> 00061 class VariantCastHelper 00062 { 00063 public: 00064 static QVariant convertToVariant(const T &t) 00065 { return qVariantFromValue(t); } 00066 static T convertFromVariant(const QVariant &t) 00067 { return qVariantValue<T>(t); } 00068 }; 00069 00070 template <typename T> 00071 class VariantCastHelper <T, sizeof(Yes)> 00072 { 00073 public: 00074 static QVariant convertToVariant(const T &t) 00075 { return qVariantFromValue(int(t)); } 00076 static T convertFromVariant(const QVariant &v) 00077 { return static_cast<T>(v.toInt()); } 00078 }; 00079 00080 template <typename T, int Defined> 00081 class VariantCastHelper3 00082 { 00083 public: 00084 static QVariant convertToVariant(const T &t) 00085 { 00086 return VariantCastHelper<T, sizeof(No)>::convertToVariant(t); 00087 } 00088 static T convertFromVariant(const QVariant &v) 00089 { 00090 return VariantCastHelper<T, sizeof(No)>::convertFromVariant(v); 00091 } 00092 }; 00093 00094 // Enums are not registered in Qt meta system and they can be casted to int easily 00095 template <typename T> 00096 class VariantCastHelper3 <T, 0> 00097 { 00098 public: 00099 static QVariant convertToVariant(const T &t) 00100 { 00101 return VariantCastHelper<T, sizeof(Helper<QMetaTypeId2<T>::Defined, sizeof(is_int_type(*reinterpret_cast<T*>(0)))>::value())>::convertToVariant(t); 00102 } 00103 static T convertFromVariant(const QVariant &v) 00104 { 00105 return VariantCastHelper<T, sizeof(Helper<QMetaTypeId2<T>::Defined, sizeof(is_int_type(*reinterpret_cast<T*>(0)))>::value())>::convertFromVariant(v); 00106 } 00107 }; 00108 00109 // Enums are not registered in Qt meta system, so check it before possibility of cast to int 00110 // because QByteArray has "operator int()" in private section 00111 template <typename T> 00112 class VariantCastHelper2 00113 { 00114 public: 00115 static QVariant convertToVariant(const T &t) 00116 { 00117 return VariantCastHelper3<T, QMetaTypeId2<T>::Defined>::convertToVariant(t); 00118 } 00119 static T convertFromVariant(const QVariant &v) 00120 { 00121 return VariantCastHelper3<T, QMetaTypeId2<T>::Defined>::convertFromVariant(v); 00122 } 00123 }; 00124 } 00125 #endif 00126 class ConfigPrivate; 00127 class ConfigBackend; 00128 class ConfigBackendPrivate; 00129 00130 class LIBQUTIM_EXPORT Config 00131 { 00132 Q_DECLARE_PRIVATE(Config) 00133 public: 00134 enum ValueFlag { Normal = 0x00, Crypted = 0x01 }; 00135 Q_DECLARE_FLAGS(ValueFlags, ValueFlag) 00136 00137 Config(const QVariantList &list); 00138 Config(QVariantList *list); 00139 Config(const QVariantMap &map); 00140 Config(QVariantMap *map); 00141 Config(const QString &path = QString()); 00142 Config(const QString &path, ConfigBackend *backend); 00143 Config(const QStringList &paths); 00144 Config(const QString &path, const QVariantList &fallbacks); 00145 Config(const QString &path, const QVariant &fallback); 00146 Config(const Config &other); 00147 Config &operator =(const Config &other); 00148 virtual ~Config(); 00149 00150 Config group(const QString &name) Q_REQUIRED_RESULT; 00151 QStringList childGroups() const Q_REQUIRED_RESULT; 00152 QStringList childKeys() const Q_REQUIRED_RESULT; 00153 bool hasChildGroup(const QString &name) const Q_REQUIRED_RESULT; 00154 bool hasChildKey(const QString &name) const Q_REQUIRED_RESULT; 00155 void beginGroup(const QString &name); 00156 void endGroup(); 00157 void remove(const QString &name); 00158 00159 Config arrayElement(int index) Q_REQUIRED_RESULT; 00160 int beginArray(const QString &name); 00161 void endArray(); 00162 int arraySize() const Q_REQUIRED_RESULT; 00163 void setArrayIndex(int index); 00164 void remove(int index); 00165 00166 QVariant rootValue(const QVariant &def = QVariant(), ValueFlags type = Normal) const Q_REQUIRED_RESULT; 00167 template<typename T> 00168 T value(const QString &key, const T &def = T(), ValueFlags type = Normal) const Q_REQUIRED_RESULT; 00169 QVariant value(const QString &key, const QVariant &def = QVariant(), ValueFlags type = Normal) const Q_REQUIRED_RESULT; 00170 inline QString value(const QString &key, const QLatin1String &def, ValueFlags type = Normal) const Q_REQUIRED_RESULT; 00171 inline QString value(const QString &key, const char *def, ValueFlags type = Normal) const Q_REQUIRED_RESULT; 00172 template <int N> 00173 QString value(const QString &key, const char (&def)[N], ValueFlags type = Normal) const Q_REQUIRED_RESULT; 00174 template<typename T> 00175 void setValue(const QString &key, const T &value, ValueFlags type = Normal); 00176 void setValue(const QString &key, const QVariant &value, ValueFlags type = Normal); 00177 inline void setValue(const QString &key, const QLatin1String &value, ValueFlags type = Normal); 00178 inline void setValue(const QString &key, const char *value, ValueFlags type = Normal); 00179 template <int N> 00180 void setValue(const QString &key, const char (&value)[N], ValueFlags type = Normal); 00181 00182 void sync(); 00183 00184 typedef void (*SaveOperator)(QVariant &, const void *); 00185 typedef void (*LoadOperator)(const QVariant &, void *); 00186 static void registerType(int type, SaveOperator saveOp, LoadOperator loadOp); 00187 private: 00188 QExplicitlySharedDataPointer<ConfigPrivate> d_ptr; 00189 }; 00190 00191 template <typename T> 00192 void configSaveHelper(QVariant &var, const T *t) 00193 { 00194 var = qVariantFromValue(t); 00195 } 00196 00197 template <typename T> 00198 void configLoadHelper(const QVariant &var, T *t) 00199 { 00200 *t = var.value<T>(); 00201 } 00202 00203 template <typename T> 00204 void registerConfigType(T * /* dummy */ = 0) 00205 { 00206 typedef void (*SavePtr)(QVariant &, const T *); 00207 typedef void (*LoadPtr)(const QVariant &, T *); 00208 SavePtr sptr = configSaveHelper<T>(); 00209 LoadPtr lptr = configLoadHelper<T>(); 00210 00211 Config::registerType(qRegisterMetaType<T>(), 00212 reinterpret_cast<Config::SaveOperator>(sptr), 00213 reinterpret_cast<Config::LoadOperator>(lptr)); 00214 } 00215 00216 typedef Config ConfigBase; 00217 typedef Config ConfigGroup; 00218 00219 class LIBQUTIM_EXPORT ConfigBackend : public QObject 00220 { 00221 Q_OBJECT 00222 Q_DECLARE_PRIVATE(ConfigBackend) 00223 public: 00224 ConfigBackend(); 00225 virtual ~ConfigBackend(); 00226 00227 virtual QVariant load(const QString &file) = 0; 00228 virtual void save(const QString &file, const QVariant &entry) = 0; 00229 00230 QByteArray name() const; 00231 protected: 00232 virtual void virtual_hook(int id, void *data); 00233 private: 00234 QScopedPointer<ConfigBackendPrivate> d_ptr; 00235 }; 00236 00237 template<typename T> 00238 Q_INLINE_TEMPLATE T Config::value(const QString &key, const T &def, Config::ValueFlags type) const 00239 { 00240 QVariant defVar = EnumDetectorHelper::VariantCastHelper2<T>::convertToVariant(def); 00241 return EnumDetectorHelper::VariantCastHelper2<T>::convertFromVariant(value(key, defVar, type)); 00242 } 00243 00244 template<typename T> 00245 Q_INLINE_TEMPLATE void Config::setValue(const QString &key, const T &value, Config::ValueFlags type) 00246 { 00247 setValue(key, EnumDetectorHelper::VariantCastHelper2<T>::convertToVariant(value), type); 00248 } 00249 00250 QString Config::value(const QString &key, const QLatin1String &def, ValueFlags type) const 00251 { 00252 return value(key, QString(def), type); 00253 } 00254 00255 QString Config::value(const QString &key, const char *def, ValueFlags type) const 00256 { 00257 return value(key, QString::fromUtf8(def), type); 00258 } 00259 00260 template <int N> 00261 Q_INLINE_TEMPLATE QString Config::value(const QString &key, const char (&def)[N], ValueFlags type) const 00262 { 00263 return value(key, QString::fromUtf8(def, N-1), type); 00264 } 00265 00266 void Config::setValue(const QString &key, const QLatin1String &value, ValueFlags type) 00267 { 00268 setValue(key, QString(value), type); 00269 } 00270 00271 void Config::setValue(const QString &key, const char *value, ValueFlags type) 00272 { 00273 setValue(key, QString::fromUtf8(value), type); 00274 } 00275 00276 template <int N> 00277 Q_INLINE_TEMPLATE void Config::setValue(const QString &key, const char (&value)[N], ValueFlags type) 00278 { 00279 setValue(key, QString::fromUtf8(value, N-1), type); 00280 } 00281 } 00282 00283 // Config() is synonym for Config("profile"), so redefine construct method for it 00284 template <> 00285 Q_INLINE_TEMPLATE void *qMetaTypeConstructHelper<qutim_sdk_0_3::Config>(const qutim_sdk_0_3::Config *t) 00286 { 00287 if (!t) { 00288 return new qutim_sdk_0_3::Config(QVariantMap()); 00289 } 00290 return new qutim_sdk_0_3::Config(*t); 00291 } 00292 00293 Q_DECLARE_METATYPE(qutim_sdk_0_3::Config) 00294 00295 #endif // CONFIG_H 00296