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 expected = QVariant(metaEnum.keysToValue(d->value.toString().toLatin1()));
00216 }
00217
00218 if (d->compOperator==Mask) {
00219 bool v_ok;
00220 int v = value.toInt(&v_ok);
00221 bool e_ok;
00222 int e = expected.toInt(&e_ok);
00223
00224 return (e_ok && v_ok && (v &e));
00225 } else {
00226 return (value == expected);
00227 }
00228 }
00229 break;
00230 }
00231 case Private::IsType:
00232 return device.isDeviceInterface(d->ifaceType);
00233 }
00234
00235 return false;
00236 }
00237
00238 QSet<Solid::DeviceInterface::Type> Solid::Predicate::usedTypes() const
00239 {
00240 QSet<DeviceInterface::Type> res;
00241
00242 if (d->isValid) {
00243
00244 switch(d->type)
00245 {
00246 case Private::OrType:
00247 case Private::AndType:
00248 res+= d->operand1->usedTypes();
00249 res+= d->operand2->usedTypes();
00250 break;
00251 case Private::AtomType:
00252 case Private::IsType:
00253 res << d->ifaceType;
00254 break;
00255 }
00256
00257 }
00258
00259 return res;
00260 }
00261
00262
00263 QString Solid::Predicate::toString() const
00264 {
00265 if (!d->isValid) return "False";
00266
00267 if (d->type!=Private::AtomType && d->type!=Private::IsType)
00268 {
00269 QString op = " AND ";
00270 if (d->type==Private::OrType) op = " OR ";
00271
00272 return '['+d->operand1->toString()+op+d->operand2->toString()+']';
00273 }
00274 else
00275 {
00276 QString ifaceName = DeviceInterface::typeToString(d->ifaceType);
00277
00278 if (ifaceName.isEmpty()) ifaceName = "Unknown";
00279
00280 if (d->type==Private::IsType) {
00281 return "IS "+ifaceName;
00282 }
00283
00284 QString value;
00285
00286 switch (d->value.type())
00287 {
00288 case QVariant::StringList:
00289 {
00290 value = "{";
00291
00292 const QStringList list = d->value.toStringList();
00293
00294 QStringList::ConstIterator it = list.begin();
00295 QStringList::ConstIterator end = list.end();
00296
00297 for (; it!=end; ++it)
00298 {
00299 value+= '\''+ *it+'\'';
00300
00301 if (it+1!=end)
00302 {
00303 value+= ", ";
00304 }
00305 }
00306
00307 value+= '}';
00308 break;
00309 }
00310 case QVariant::Bool:
00311 value = (d->value.toBool()?"true":"false");
00312 break;
00313 case QVariant::Int:
00314 case QVariant::UInt:
00315 case QVariant::LongLong:
00316 case QVariant::ULongLong:
00317 value = d->value.toString();
00318 break;
00319 default:
00320 value = '\''+d->value.toString()+'\'';
00321 break;
00322 }
00323
00324 QString str_operator = "==";
00325 if (d->compOperator!=Equals) str_operator = " &";
00326
00327
00328 return ifaceName+'.'+d->property+' '+str_operator+' '+value;
00329 }
00330 }
00331
00332
00333
00334