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 d->operand1 = new Predicate(*(other.d->operand1));
00131 d->operand2 = new Predicate(*(other.d->operand2));
00132 }
00133 else
00134 {
00135 d->ifaceType = other.d->ifaceType;
00136 d->property = other.d->property;
00137 d->value = other.d->value;
00138 d->compOperator = other.d->compOperator;
00139 }
00140
00141 return *this;
00142 }
00143
00144 Solid::Predicate Solid::Predicate::operator &(const Predicate &other)
00145 {
00146 Predicate result;
00147
00148 result.d->isValid = true;
00149 result.d->type = Private::AndType;
00150 result.d->operand1 = new Predicate(*this);
00151 result.d->operand2 = new Predicate(other);
00152
00153 return result;
00154 }
00155
00156 Solid::Predicate Solid::Predicate::operator|(const Predicate &other)
00157 {
00158 Predicate result;
00159
00160 result.d->isValid = true;
00161 result.d->type = Private::OrType;
00162 result.d->operand1 = new Predicate(*this);
00163 result.d->operand2 = new Predicate(other);
00164
00165 return result;
00166 }
00167
00168 bool Solid::Predicate::isValid() const
00169 {
00170 return d->isValid;
00171 }
00172
00173 bool Solid::Predicate::matches(const Device &device) const
00174 {
00175 if (!d->isValid) return false;
00176
00177 switch(d->type)
00178 {
00179 case Private::OrType:
00180 return d->operand1->matches(device)
00181 || d->operand2->matches(device);
00182 case Private::AndType:
00183 return d->operand1->matches(device)
00184 && d->operand2->matches(device);
00185 case Private::AtomType:
00186 {
00187 const DeviceInterface *iface = device.asDeviceInterface(d->ifaceType);
00188
00189 if (iface!=0)
00190 {
00191 QVariant value = iface->property(d->property.toLatin1());
00192 QVariant expected = d->value;
00193
00194 int index = iface->metaObject()->indexOfProperty(d->property.toLatin1());
00195 QMetaProperty metaProp = iface->metaObject()->property(index);
00196
00197 if (metaProp.isEnumType() && expected.type()==QVariant::String) {
00198 QMetaEnum metaEnum = metaProp.enumerator();
00199 expected = QVariant(metaEnum.keysToValue(d->value.toString().toLatin1()));
00200 }
00201
00202 if (d->compOperator==Mask) {
00203 bool v_ok;
00204 int v = value.toInt(&v_ok);
00205 bool e_ok;
00206 int e = expected.toInt(&e_ok);
00207
00208 return (e_ok && v_ok && (v &e));
00209 } else {
00210 return (value == expected);
00211 }
00212 }
00213 break;
00214 }
00215 case Private::IsType:
00216 return device.isDeviceInterface(d->ifaceType);
00217 }
00218
00219 return false;
00220 }
00221
00222 QSet<Solid::DeviceInterface::Type> Solid::Predicate::usedTypes() const
00223 {
00224 QSet<DeviceInterface::Type> res;
00225
00226 if (d->isValid) {
00227
00228 switch(d->type)
00229 {
00230 case Private::OrType:
00231 case Private::AndType:
00232 res+= d->operand1->usedTypes();
00233 res+= d->operand2->usedTypes();
00234 break;
00235 case Private::AtomType:
00236 case Private::IsType:
00237 res << d->ifaceType;
00238 break;
00239 }
00240
00241 }
00242
00243 return res;
00244 }
00245
00246
00247 QString Solid::Predicate::toString() const
00248 {
00249 if (!d->isValid) return "False";
00250
00251 if (d->type!=Private::AtomType && d->type!=Private::IsType)
00252 {
00253 QString op = " AND ";
00254 if (d->type==Private::OrType) op = " OR ";
00255
00256 return '['+d->operand1->toString()+op+d->operand2->toString()+']';
00257 }
00258 else
00259 {
00260 QString ifaceName = DeviceInterface::typeToString(d->ifaceType);
00261
00262 if (ifaceName.isEmpty()) ifaceName = "Unknown";
00263
00264 if (d->type==Private::IsType) {
00265 return "IS "+ifaceName;
00266 }
00267
00268 QString value;
00269
00270 switch (d->value.type())
00271 {
00272 case QVariant::StringList:
00273 {
00274 value = "{";
00275
00276 QStringList list = d->value.toStringList();
00277
00278 QStringList::ConstIterator it = list.begin();
00279 QStringList::ConstIterator end = list.end();
00280
00281 for (; it!=end; ++it)
00282 {
00283 value+= '\''+ *it+'\'';
00284
00285 if (it+1!=end)
00286 {
00287 value+= ", ";
00288 }
00289 }
00290
00291 value+= '}';
00292 break;
00293 }
00294 case QVariant::Bool:
00295 value = (d->value.toBool()?"true":"false");
00296 break;
00297 case QVariant::Int:
00298 case QVariant::UInt:
00299 case QVariant::LongLong:
00300 case QVariant::ULongLong:
00301 value = d->value.toString();
00302 break;
00303 default:
00304 value = '\''+d->value.toString()+'\'';
00305 break;
00306 }
00307
00308 QString str_operator = "==";
00309 if (d->compOperator!=Equals) str_operator = " &";
00310
00311
00312 return ifaceName+'.'+d->property+' '+str_operator+' '+value;
00313 }
00314 }
00315
00316
00317
00318