Solid
predicate.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "predicate.h"
00021
00022 #include <solid/device.h>
00023 #include <solid/deviceinterface.h>
00024 #include <QtCore/QStringList>
00025 #include <QtCore/QMetaEnum>
00026
00027 namespace Solid
00028 {
00029 class Predicate::Private
00030 {
00031 public:
00032 enum OperatorType { AtomType, AndType, OrType, IsType };
00033
00034 Private() : isValid(false), type(AtomType),
00035 compOperator(Predicate::Equals),
00036 operand1(0), operand2(0) {}
00037
00038 bool isValid;
00039 OperatorType type;
00040
00041 DeviceInterface::Type ifaceType;
00042 QString property;
00043 QVariant value;
00044 Predicate::ComparisonOperator compOperator;
00045
00046 Predicate *operand1;
00047 Predicate *operand2;
00048 };
00049 }
00050
00051
00052 Solid::Predicate::Predicate()
00053 : d(new Private())
00054 {
00055 }
00056
00057 Solid::Predicate::Predicate(const Predicate &other)
00058 : d(new Private())
00059 {
00060 *this = other;
00061 }
00062
00063 Solid::Predicate::Predicate(const DeviceInterface::Type &ifaceType,
00064 const QString &property, const QVariant &value,
00065 ComparisonOperator compOperator)
00066 : d(new Private())
00067 {
00068 d->isValid = true;
00069 d->ifaceType = ifaceType;
00070 d->property = property;
00071 d->value = value;
00072 d->compOperator = compOperator;
00073 }
00074
00075 Solid::Predicate::Predicate(const QString &ifaceName,
00076 const QString &property, const QVariant &value,
00077 ComparisonOperator compOperator)
00078 : d(new Private())
00079 {
00080 DeviceInterface::Type ifaceType = DeviceInterface::stringToType(ifaceName);
00081
00082 if (((int)ifaceType)!=-1)
00083 {
00084 d->isValid = true;
00085 d->ifaceType = ifaceType;
00086 d->property = property;
00087 d->value = value;
00088 d->compOperator = compOperator;
00089 }
00090 }
00091
00092 Solid::Predicate::Predicate(const DeviceInterface::Type &ifaceType)
00093 : d(new Private())
00094 {
00095 d->isValid = true;
00096 d->type = Private::IsType;
00097 d->ifaceType = ifaceType;
00098 }
00099
00100 Solid::Predicate::Predicate(const QString &ifaceName)
00101 : d(new Private())
00102 {
00103 DeviceInterface::Type ifaceType = DeviceInterface::stringToType(ifaceName);
00104
00105 if (((int)ifaceType)!=-1)
00106 {
00107 d->isValid = true;
00108 d->type = Private::IsType;
00109 d->ifaceType = ifaceType;
00110 }
00111 }
00112
00113 Solid::Predicate::~Predicate()
00114 {
00115 if (d->type!=Private::AtomType && d->type!=Private::IsType) {
00116 delete d->operand1;
00117 delete d->operand2;
00118 }
00119
00120 delete d;
00121 }
00122
00123 Solid::Predicate &Solid::Predicate::operator=(const Predicate &other)
00124 {
00125 d->isValid = other.d->isValid;
00126 d->type = other.d->type;
00127
00128 if (d->type!=Private::AtomType && d->type!=Private::IsType)
00129 {
00130 Predicate* operand1 = new Predicate(*(other.d->operand1));
00131 delete d->operand1;
00132 d->operand1 = operand1;
00133 Predicate* operand2 = new Predicate(*(other.d->operand2));
00134 delete d->operand2;
00135 d->operand2 = operand2;
00136 }
00137 else
00138 {
00139 d->ifaceType = other.d->ifaceType;
00140 d->property = other.d->property;
00141 d->value = other.d->value;
00142 d->compOperator = other.d->compOperator;
00143 }
00144
00145 return *this;
00146 }
00147
00148 Solid::Predicate Solid::Predicate::operator &(const Predicate &other)
00149 {
00150 Predicate result;
00151
00152 result.d->isValid = true;
00153 result.d->type = Private::AndType;
00154 result.d->operand1 = new Predicate(*this);
00155 result.d->operand2 = new Predicate(other);
00156
00157 return result;
00158 }
00159
00160 Solid::Predicate &Solid::Predicate::operator &=(const Predicate &other)
00161 {
00162 *this = *this & other;
00163 return *this;
00164 }
00165
00166 Solid::Predicate Solid::Predicate::operator|(const Predicate &other)
00167 {
00168 Predicate result;
00169
00170 result.d->isValid = true;
00171 result.d->type = Private::OrType;
00172 result.d->operand1 = new Predicate(*this);
00173 result.d->operand2 = new Predicate(other);
00174
00175 return result;
00176 }
00177
00178 Solid::Predicate &Solid::Predicate::operator |=(const Predicate &other)
00179 {
00180 *this = *this | other;
00181 return *this;
00182 }
00183
00184 bool Solid::Predicate::isValid() const
00185 {
00186 return d->isValid;
00187 }
00188
00189 bool Solid::Predicate::matches(const Device &device) const
00190 {
00191 if (!d->isValid) return false;
00192
00193 switch(d->type)
00194 {
00195 case Private::OrType:
00196 return d->operand1->matches(device)
00197 || d->operand2->matches(device);
00198 case Private::AndType:
00199 return d->operand1->matches(device)
00200 && d->operand2->matches(device);
00201 case Private::AtomType:
00202 {
00203 const DeviceInterface *iface = device.asDeviceInterface(d->ifaceType);
00204
00205 if (iface!=0)
00206 {
00207 QVariant value = iface->property(d->property.toLatin1());
00208 QVariant expected = d->value;
00209
00210 int index = iface->metaObject()->indexOfProperty(d->property.toLatin1());
00211 QMetaProperty metaProp = iface->metaObject()->property(index);
00212
00213 if (metaProp.isEnumType() && expected.type()==QVariant::String) {
00214 QMetaEnum metaEnum = metaProp.enumerator();
00215 int value = metaEnum.keysToValue(d->value.toString().toLatin1());
00216 if (value>=0) {
00217 expected = value;
00218 } else {
00219 expected = QVariant();
00220 }
00221 }
00222
00223 if (d->compOperator==Mask) {
00224 bool v_ok;
00225 int v = value.toInt(&v_ok);
00226 bool e_ok;
00227 int e = expected.toInt(&e_ok);
00228
00229 return (e_ok && v_ok && (v &e));
00230 } else {
00231 return (value == expected);
00232 }
00233 }
00234 break;
00235 }
00236 case Private::IsType:
00237 return device.isDeviceInterface(d->ifaceType);
00238 }
00239
00240 return false;
00241 }
00242
00243 QSet<Solid::DeviceInterface::Type> Solid::Predicate::usedTypes() const
00244 {
00245 QSet<DeviceInterface::Type> res;
00246
00247 if (d->isValid) {
00248
00249 switch(d->type)
00250 {
00251 case Private::OrType:
00252 case Private::AndType:
00253 res+= d->operand1->usedTypes();
00254 res+= d->operand2->usedTypes();
00255 break;
00256 case Private::AtomType:
00257 case Private::IsType:
00258 res << d->ifaceType;
00259 break;
00260 }
00261
00262 }
00263
00264 return res;
00265 }
00266
00267
00268 QString Solid::Predicate::toString() const
00269 {
00270 if (!d->isValid) return "False";
00271
00272 if (d->type!=Private::AtomType && d->type!=Private::IsType)
00273 {
00274 QString op = " AND ";
00275 if (d->type==Private::OrType) op = " OR ";
00276
00277 return '['+d->operand1->toString()+op+d->operand2->toString()+']';
00278 }
00279 else
00280 {
00281 QString ifaceName = DeviceInterface::typeToString(d->ifaceType);
00282
00283 if (ifaceName.isEmpty()) ifaceName = "Unknown";
00284
00285 if (d->type==Private::IsType) {
00286 return "IS "+ifaceName;
00287 }
00288
00289 QString value;
00290
00291 switch (d->value.type())
00292 {
00293 case QVariant::StringList:
00294 {
00295 value = "{";
00296
00297 const QStringList list = d->value.toStringList();
00298
00299 QStringList::ConstIterator it = list.begin();
00300 QStringList::ConstIterator end = list.end();
00301
00302 for (; it!=end; ++it)
00303 {
00304 value+= '\''+ *it+'\'';
00305
00306 if (it+1!=end)
00307 {
00308 value+= ", ";
00309 }
00310 }
00311
00312 value+= '}';
00313 break;
00314 }
00315 case QVariant::Bool:
00316 value = (d->value.toBool()?"true":"false");
00317 break;
00318 case QVariant::Int:
00319 case QVariant::UInt:
00320 case QVariant::LongLong:
00321 case QVariant::ULongLong:
00322 value = d->value.toString();
00323 break;
00324 default:
00325 value = '\''+d->value.toString()+'\'';
00326 break;
00327 }
00328
00329 QString str_operator = "==";
00330 if (d->compOperator!=Equals) str_operator = " &";
00331
00332
00333 return ifaceName+'.'+d->property+' '+str_operator+' '+value;
00334 }
00335 }
00336
00337
00338
00339