123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623 |
- /*=============================================================================
- Library: CTK
- Copyright (c) German Cancer Research Center,
- Division of Medical and Biological Informatics
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- =============================================================================*/
- #include "ctkMTDataParser_p.h"
- #include "ctkAttributeDefinitionImpl_p.h"
- #include "ctkMTMsg_p.h"
- #include <service/log/ctkLogService.h>
- #include <QCoreApplication>
- #include <QDebug>
- const QString ctkMTDataParser::METADATA = "MetaData";
- const QString ctkMTDataParser::LOCALIZATION = "localization";
- const QString ctkMTDataParser::CONTEXT = "context";
- const QString ctkMTDataParser::OCD = "OCD";
- const QString ctkMTDataParser::ICON = "Icon";
- const QString ctkMTDataParser::AD = "AD";
- const QString ctkMTDataParser::CARDINALITY = "cardinality";
- const QString ctkMTDataParser::OPTION = "Option";
- const QString ctkMTDataParser::LABEL = "label";
- const QString ctkMTDataParser::VALUE = "value";
- const QString ctkMTDataParser::MIN = "min";
- const QString ctkMTDataParser::MAX = "max";
- const QString ctkMTDataParser::TYPE = "type";
- const QString ctkMTDataParser::SIZE = "size";
- const QString ctkMTDataParser::ID = "id";
- const QString ctkMTDataParser::NAME = "name";
- const QString ctkMTDataParser::DESCRIPTION = "description";
- const QString ctkMTDataParser::RESOURCE = "resource";
- const QString ctkMTDataParser::PID = "pid";
- const QString ctkMTDataParser::DEFAULT = "default";
- const QString ctkMTDataParser::ADREF = "adref";
- const QString ctkMTDataParser::CONTENT = "content";
- const QString ctkMTDataParser::FACTORY = "factoryPid";
- const QString ctkMTDataParser::PLUGIN = "plugin";
- const QString ctkMTDataParser::OPTIONAL = "optional";
- const QString ctkMTDataParser::OBJECT = "Object";
- const QString ctkMTDataParser::OCDREF = "ocdref";
- const QString ctkMTDataParser::ATTRIBUTE = "Attribute";
- const QString ctkMTDataParser::DESIGNATE = "Designate";
- const QString ctkMTDataParser::MERGE = "merge";
- const QString ctkMTDataParser::REQUIRED = "required";
- const QString ctkMTDataParser::INTEGER = "Integer";
- const QString ctkMTDataParser::STRING = "String";
- const QString ctkMTDataParser::DOUBLE = "Double";
- const QString ctkMTDataParser::LONG = "Long";
- const QString ctkMTDataParser::CHAR = "Char";
- const QString ctkMTDataParser::BOOLEAN = "Boolean";
- const QString ctkMTDataParser::PASSWORD = "Password";
- ctkMTDataParser::ctkMTDataParser(const QSharedPointer<ctkPlugin>& plugin, QIODevice* device, ctkLogService* logger)
- : _dp_plugin(plugin), _dp_xmlReader(device), logger(logger)
- {
- }
- QHash<QString, ctkObjectClassDefinitionImplPtr> ctkMTDataParser::doParse()
- {
- CTK_DEBUG(logger) << "Starting to parse metadata";
- while (_dp_xmlReader.readNextStartElement())
- {
- QStringRef name = _dp_xmlReader.name();
- if (name.compare(METADATA, Qt::CaseInsensitive) == 0)
- {
- metaDataHandler();
- }
- else
- {
- CTK_WARN(logger) << QCoreApplication::translate(ctkMTMsg::CONTEXT, ctkMTMsg::UNEXPECTED_ELEMENT).arg(name.toString());
- _dp_xmlReader.skipCurrentElement();
- }
- }
- if (_dp_xmlReader.hasError() &&
- !(_dp_xmlReader.atEnd() && _dp_xmlReader.error() == QXmlStreamReader::PrematureEndOfDocumentError))
- {
- errorHandler();
- return QHash<QString, ctkObjectClassDefinitionImplPtr>();
- }
- return _dp_pid_to_OCDs;
- }
- void ctkMTDataParser::metaDataHandler()
- {
- Q_ASSERT(_dp_xmlReader.isStartElement() && _dp_xmlReader.name().compare(METADATA, Qt::CaseInsensitive) == 0);
- QXmlStreamAttributes attributes = _dp_xmlReader.attributes();
- _dp_localization = attributes.value(LOCALIZATION).toString();
- _dp_context = attributes.value(CONTEXT).toString();
- // The variables "_dp_localization" and "_dp_context" will be used within
- // ocdHandler() and attributeDefinitionHandler() later.
- _dp_xmlReader.readNext();
- while(!_dp_xmlReader.hasError() && _dp_xmlReader.readNextStartElement())
- {
- QStringRef name = _dp_xmlReader.name();
- if (name.compare(DESIGNATE, Qt::CaseInsensitive) == 0)
- {
- designateHandler();
- }
- else if (name.compare(OCD, Qt::CaseInsensitive) == 0)
- {
- ocdHandler();
- }
- else
- {
- CTK_WARN(logger) << QCoreApplication::translate(ctkMTMsg::CONTEXT, ctkMTMsg::UNEXPECTED_ELEMENT).arg(name.toString());
- _dp_xmlReader.skipCurrentElement();
- }
- }
- if (_dp_xmlReader.hasError()) return;
- if (_dp_designateInfos.isEmpty())
- {
- // Schema defines at least one DESIGNATE is required.
- QString msg = QCoreApplication::translate(ctkMTMsg::CONTEXT, ctkMTMsg::MISSING_ELEMENT).arg(DESIGNATE);
- _dp_xmlReader.raiseError(msg);
- return;
- }
- for (int i = 0; i < _dp_designateInfos.size(); ++i)
- {
- const DesignateInfo& designateInfo = _dp_designateInfos[i];
- ctkObjectClassDefinitionImplPtr ocd = _dp_OCDs.value(designateInfo._ocdref);
- if (ocd)
- {
- if (designateInfo._factory_val.isEmpty())
- {
- ocd->setType(ctkObjectClassDefinitionImpl::PID);
- _dp_pid_to_OCDs.insert(designateInfo._pid_val, ocd);
- }
- else
- {
- ocd->setType(ctkObjectClassDefinitionImpl::FPID);
- _dp_pid_to_OCDs.insert(designateInfo._factory_val, ocd);
- }
- }
- else
- {
- QString msg = QCoreApplication::translate(ctkMTMsg::CONTEXT, ctkMTMsg::OCD_ID_NOT_FOUND).arg(designateInfo._ocdref);
- _dp_xmlReader.raiseError(msg);
- return;
- }
- }
- }
- void ctkMTDataParser::designateHandler()
- {
- Q_ASSERT(_dp_xmlReader.isStartElement() && _dp_xmlReader.name().compare(DESIGNATE, Qt::CaseInsensitive) == 0);
- DesignateInfo info;
- QXmlStreamAttributes atts = _dp_xmlReader.attributes();
- info._pid_val = atts.value(PID).toString();
- if (info._pid_val.isNull())
- {
- QString msg = QCoreApplication::translate(ctkMTMsg::CONTEXT, ctkMTMsg::MISSING_ATTRIBUTE).arg(PID).arg(_dp_xmlReader.name().toString());
- _dp_xmlReader.raiseError(msg);
- return;
- }
- info._factory_val = atts.value(FACTORY).toString();
- info._plugin_val = atts.value(PLUGIN).toString();
- if (info._plugin_val.isNull())
- {
- // Not a problem because PLUGIN is an optional attribute.
- }
- QString optional_str = atts.value(OPTIONAL).toString();
- if (optional_str.isNull())
- {
- // Not a problem, because OPTIONAL is an optional attribute.
- // The default value is "false".
- info._optional_val = false;
- }
- else
- {
- info._optional_val = toBool(optional_str);
- }
- QString merge_str = atts.value(MERGE).toString();
- if (merge_str.isNull())
- {
- // Not a problem, because MERGE is an optional attribute.
- // The default value is "false".
- info._merge_val = false;
- }
- else
- {
- info._merge_val = toBool(merge_str);
- }
- while (!_dp_xmlReader.hasError() && _dp_xmlReader.readNextStartElement())
- {
- QStringRef name = _dp_xmlReader.name();
- if (name.compare(OBJECT, Qt::CaseInsensitive) == 0)
- {
- objectHandler(info);
- }
- else
- {
- CTK_WARN(logger) << QCoreApplication::translate(ctkMTMsg::CONTEXT, ctkMTMsg::UNEXPECTED_ELEMENT).arg(name.toString());
- _dp_xmlReader.skipCurrentElement();
- }
- }
- if (_dp_xmlReader.hasError()) return;
- if (info._ocdref.isEmpty())
- {
- // Schema defines at least one OBJECT is required.
- QString msg = QCoreApplication::translate(ctkMTMsg::CONTEXT, ctkMTMsg::MISSING_ELEMENT).arg(OBJECT).arg(info._pid_val);
- _dp_xmlReader.raiseError(msg);
- return;
- }
- _dp_designateInfos.push_back(info);
- }
- void ctkMTDataParser::ocdHandler()
- {
- Q_ASSERT(_dp_xmlReader.isStartElement() && _dp_xmlReader.name().compare(OCD, Qt::CaseInsensitive) == 0);
- QStringRef name = _dp_xmlReader.name();
- QXmlStreamAttributes atts = _dp_xmlReader.attributes();
- QString ocd_name_val = atts.value(NAME).toString();
- if (ocd_name_val.isNull())
- {
- QString msg = QCoreApplication::translate(ctkMTMsg::CONTEXT, ctkMTMsg::MISSING_ATTRIBUTE).arg(NAME).arg(name.toString());
- _dp_xmlReader.raiseError(msg);
- return;
- }
- QString ocd_description_val = atts.value(DESCRIPTION).toString();
- if (ocd_description_val.isNull())
- {
- // Not a problem, because DESCRIPTION is an optional attribute.
- }
- QString refID = atts.value(ID).toString();
- if (refID.isNull())
- {
- QString msg = QCoreApplication::translate(ctkMTMsg::CONTEXT, ctkMTMsg::MISSING_ATTRIBUTE).arg(ID).arg(name.toString());
- _dp_xmlReader.raiseError(msg);
- return;
- }
- ctkObjectClassDefinitionImplPtr ocd(new ctkObjectClassDefinitionImpl(
- ocd_name_val, ocd_description_val,
- refID, _dp_localization, _dp_context));
- QList<ctkAttributeDefinitionImplPtr> ad_list;
- while (!_dp_xmlReader.hasError() && _dp_xmlReader.readNextStartElement())
- {
- QStringRef name2 = _dp_xmlReader.name();
- if (name2.compare(AD, Qt::CaseInsensitive) == 0)
- {
- attributeDefinitionHandler(ad_list);
- }
- else if (name2.compare(ICON, Qt::CaseInsensitive) == 0)
- {
- ctkMTIcon icon = iconHandler();
- if (!_dp_xmlReader.hasError())
- {
- // Because XML schema allows at most one icon for
- // one OCD, if more than one icons are read from
- // MetaData, then only the final icon will be kept.
- ocd->setIcon(icon);
- }
- }
- else
- {
- CTK_WARN(logger) << QCoreApplication::translate(ctkMTMsg::CONTEXT, ctkMTMsg::UNEXPECTED_ELEMENT).arg(name2.toString());
- _dp_xmlReader.skipCurrentElement();
- }
- }
- if (_dp_xmlReader.hasError()) return;
- if (ad_list.isEmpty())
- {
- // Schema defines at least one AD is required.
- QString msg = QCoreApplication::translate(ctkMTMsg::CONTEXT, ctkMTMsg::MISSING_ELEMENT).arg(AD).arg(refID);
- _dp_xmlReader.raiseError(msg);
- return;
- }
- // OCD gets all parsed ADs.
- foreach (ctkAttributeDefinitionImplPtr ad, ad_list)
- {
- ocd->addAttributeDefinition(ad, ad->isRequired());
- }
- _dp_OCDs.insert(refID, ocd);
- }
- void ctkMTDataParser::objectHandler(DesignateInfo& designateInfo)
- {
- Q_ASSERT(_dp_xmlReader.isStartElement() && _dp_xmlReader.name().compare(OBJECT, Qt::CaseInsensitive) == 0);
- designateInfo._ocdref = _dp_xmlReader.attributes().value(OCDREF).toString();
- if (designateInfo._ocdref.isNull())
- {
- QString msg = QCoreApplication::translate(ctkMTMsg::CONTEXT, ctkMTMsg::MISSING_ATTRIBUTE).arg(OCDREF).arg(_dp_xmlReader.name().toString());
- _dp_xmlReader.raiseError(msg);
- return;
- }
- while (!_dp_xmlReader.hasError() && _dp_xmlReader.readNextStartElement())
- {
- QStringRef name = _dp_xmlReader.name();
- if (name.compare(ATTRIBUTE, Qt::CaseInsensitive) == 0)
- {
- attributeHandler();
- }
- else
- {
- CTK_WARN(logger) << QCoreApplication::translate(ctkMTMsg::CONTEXT, ctkMTMsg::UNEXPECTED_ELEMENT).arg(name.toString());
- _dp_xmlReader.skipCurrentElement();
- }
- }
- }
- void ctkMTDataParser::attributeHandler()
- {
- Q_ASSERT(_dp_xmlReader.isStartElement() && _dp_xmlReader.name().compare(ATTRIBUTE, Qt::CaseInsensitive) == 0);
- while (_dp_xmlReader.readNextStartElement()) _dp_xmlReader.skipCurrentElement();
- }
- void ctkMTDataParser::attributeDefinitionHandler(QList<ctkAttributeDefinitionImplPtr>& ad_list)
- {
- Q_ASSERT(_dp_xmlReader.isStartElement() && _dp_xmlReader.name().compare(AD, Qt::CaseInsensitive) == 0);
- QString name = _dp_xmlReader.name().toString();
- QXmlStreamAttributes atts = _dp_xmlReader.attributes();
- QString ad_name_val = atts.value(NAME).toString();
- if (ad_name_val.isNull())
- {
- // Not a problem, because NAME is an optional attribute.
- }
- QString ad_description_val = atts.value(DESCRIPTION).toString();
- if (ad_description_val.isNull())
- {
- // Not a problem, because DESCRIPTION is an optional attribute.
- }
- QString ad_id_val = atts.value(ID).toString();
- if (ad_id_val.isNull())
- {
- QString msg = QCoreApplication::translate(ctkMTMsg::CONTEXT, ctkMTMsg::MISSING_ATTRIBUTE).arg(ID).arg(name);
- _dp_xmlReader.raiseError(msg);
- return;
- }
- int dataType;
- QStringRef ad_type_val = atts.value("", TYPE);
- if (ad_type_val.compare(STRING, Qt::CaseInsensitive) == 0)
- {
- dataType = QVariant::String;
- }
- else if (ad_type_val.compare(LONG, Qt::CaseInsensitive) == 0)
- {
- dataType = QVariant::LongLong;
- }
- else if (ad_type_val.compare(DOUBLE, Qt::CaseInsensitive) == 0)
- {
- dataType = QVariant::Double;
- }
- else if (ad_type_val.compare(INTEGER, Qt::CaseInsensitive) == 0)
- {
- dataType = QVariant::Int;
- }
- else if (ad_type_val.compare(CHAR, Qt::CaseInsensitive) == 0)
- {
- dataType = QVariant::Char;
- }
- else if (ad_type_val.compare(BOOLEAN, Qt::CaseInsensitive) == 0)
- {
- dataType = QVariant::Bool;
- }
- else if (ad_type_val.compare(PASSWORD, Qt::CaseInsensitive) == 0)
- {
- dataType = ctkAttributeDefinition::PASSWORD;
- }
- else
- {
- QString msg = QCoreApplication::translate(ctkMTMsg::CONTEXT, ctkMTMsg::MISSING_ATTRIBUTE).arg(TYPE).arg(name);
- _dp_xmlReader.raiseError(msg);
- return;
- }
- QString ad_cardinality_str = atts.value(CARDINALITY).toString();
- int ad_cardinality_val = 0;
- if (ad_cardinality_str.isNull())
- {
- // Not a problem, because CARDINALITY is an optional attribute.
- // And the default value is 0.
- }
- else
- {
- ad_cardinality_val = ad_cardinality_str.toInt();
- }
- QString ad_min_val = atts.value(MIN).toString();
- if (ad_min_val.isNull())
- {
- // Not a problem, because MIN is an optional attribute.
- }
- QString ad_max_val = atts.value(MAX).toString();
- if (ad_max_val.isNull())
- {
- // Not a problem, because MAX is an optional attribute.
- }
- QString ad_defaults_str = atts.value(DEFAULT).toString();
- if (ad_defaults_str.isNull())
- {
- // Not a problem, because DEFAULT is an optional attribute.
- if (ad_cardinality_val == 0)
- {
- // But when it is not assigned, CARDINALITY cannot be '0'.
- QString msg = QCoreApplication::translate(ctkMTMsg::CONTEXT, ctkMTMsg::NULL_DEFAULTS);
- _dp_xmlReader.raiseError(msg);
- return;
- }
- }
- QString ad_required_val = atts.value(REQUIRED).toString();
- if (ad_required_val.isNull())
- {
- // Not a problem, because REQUIRED is an optional attribute.
- // And the default value is 'true'.
- ad_required_val = "true";
- }
- ctkAttributeDefinitionImplPtr ad(new ctkAttributeDefinitionImpl(
- ad_id_val, ad_name_val, ad_description_val, dataType,
- ad_cardinality_val, convert(ad_min_val, dataType), convert(ad_max_val, dataType),
- toBool(ad_required_val), _dp_localization, _dp_context, logger));
- if (ad_cardinality_val == 0)
- {
- // Attribute DEFAULT has one and only one occurance.
- ad->setDefaultValue(QStringList(ad_defaults_str), false);
- }
- else
- {
- // Attribute DEFAULT is a comma delimited list.
- ad->setDefaultValue(ad_defaults_str, false);
- }
- QStringList optionLabels;
- QStringList optionValues;
- while (!_dp_xmlReader.hasError() && _dp_xmlReader.readNextStartElement())
- {
- QStringRef name2 = _dp_xmlReader.name();
- if (name2.compare(OPTION, Qt::CaseInsensitive) == 0)
- {
- OptionInfo optionInfo;
- optionHandler(optionInfo);
- if (!_dp_xmlReader.hasError())
- {
- optionLabels.push_back(optionInfo._label_val);
- optionValues.push_back(optionInfo._value_val);
- }
- }
- else
- {
- CTK_WARN(logger) << QCoreApplication::translate(ctkMTMsg::CONTEXT, ctkMTMsg::UNEXPECTED_ELEMENT).arg(name2.toString());
- _dp_xmlReader.skipCurrentElement();
- }
- }
- if (_dp_xmlReader.hasError()) return;
- ad->setOption(optionLabels, optionValues, true);
- ad_list.push_back(ad);
- }
- ctkMTIcon ctkMTDataParser::iconHandler()
- {
- Q_ASSERT(_dp_xmlReader.isStartElement() && _dp_xmlReader.name().compare(ICON, Qt::CaseInsensitive) == 0);
- QXmlStreamAttributes atts = _dp_xmlReader.attributes();
- QString icon_resource_val = atts.value(RESOURCE).toString();
- if (icon_resource_val.isNull())
- {
- QString msg = QCoreApplication::translate(ctkMTMsg::CONTEXT, ctkMTMsg::MISSING_ATTRIBUTE).arg(RESOURCE).arg(_dp_xmlReader.name().toString());
- _dp_xmlReader.raiseError(msg);
- return ctkMTIcon();
- }
- QString icon_size_val = atts.value(SIZE).toString();
- if (icon_size_val.isNull())
- {
- // Not a problem, because SIZE is an optional attribute.
- icon_size_val = "0";
- }
- while (_dp_xmlReader.readNextStartElement()) _dp_xmlReader.skipCurrentElement();
- return ctkMTIcon(icon_resource_val, icon_size_val.toInt(), _dp_plugin);
- }
- void ctkMTDataParser::optionHandler(OptionInfo& optionInfo)
- {
- Q_ASSERT(_dp_xmlReader.isStartElement() && _dp_xmlReader.name().compare(OPTION, Qt::CaseInsensitive) == 0);
- QXmlStreamAttributes atts = _dp_xmlReader.attributes();
- optionInfo._label_val = atts.value(LABEL).toString();
- if (optionInfo._label_val.isNull())
- {
- QString msg = QCoreApplication::translate(ctkMTMsg::CONTEXT, ctkMTMsg::MISSING_ATTRIBUTE).arg(LABEL).arg(_dp_xmlReader.name().toString());
- _dp_xmlReader.raiseError(msg);
- return;
- }
- optionInfo._value_val = atts.value(VALUE).toString();
- if (optionInfo._value_val.isNull())
- {
- QString msg = QCoreApplication::translate(ctkMTMsg::CONTEXT, ctkMTMsg::MISSING_ATTRIBUTE).arg(VALUE).arg(_dp_xmlReader.name().toString());
- _dp_xmlReader.raiseError(msg);
- return;
- }
- while (_dp_xmlReader.readNextStartElement()) _dp_xmlReader.skipCurrentElement();
- }
- void ctkMTDataParser::errorHandler()
- {
- switch (_dp_xmlReader.error())
- {
- case QXmlStreamReader::NotWellFormedError:
- CTK_WARN(logger) << "XML Document not well formed at line " << _dp_xmlReader.lineNumber() << ", col " << _dp_xmlReader.columnNumber();
- break;
- case QXmlStreamReader::PrematureEndOfDocumentError:
- CTK_WARN(logger) << "Premature end of XML Document at line " << _dp_xmlReader.lineNumber() << ", col " << _dp_xmlReader.columnNumber();
- break;
- case QXmlStreamReader::UnexpectedElementError:
- CTK_WARN(logger) << "Unexpected element at line " << _dp_xmlReader.lineNumber() << ", col " << _dp_xmlReader.columnNumber();
- break;
- case QXmlStreamReader::CustomError:
- CTK_ERROR(logger) << _dp_xmlReader.errorString() << "at line" << _dp_xmlReader.lineNumber() << ", col " << _dp_xmlReader.columnNumber();
- break;
- default:
- break;
- }
- }
- bool ctkMTDataParser::toBool(const QString& str)
- {
- if (str.isEmpty()) return false;
- if (str.trimmed().compare("true", Qt::CaseInsensitive)) return true;
- if (str.trimmed().compare("1")) return true;
- return false;
- }
- QVariant ctkMTDataParser::convert(const QString& value, int type)
- {
- if (value.isNull())
- {
- return QVariant();
- }
- if (type == ctkAttributeDefinition::PASSWORD || type == QVariant::String)
- {
- // PASSWORD should be treated like STRING.
- // Both the min and max of STRING are Integers.
- return QVariant::fromValue<int>(value.toInt());
- }
- else if (type == QVariant::LongLong)
- {
- return QVariant::fromValue<qlonglong>(value.toLongLong());
- }
- else if (type == QVariant::Int)
- {
- return QVariant::fromValue<int>(value.toInt());
- }
- else if (type == QVariant::Char)
- {
- return QVariant::fromValue<QChar>(value.at(0));
- }
- else if (type == QVariant::Double)
- {
- return QVariant::fromValue<double>(value.toDouble());
- }
- else if (type == QVariant::Bool)
- {
- return QVariant::fromValue<bool>(toBool(value));
- }
- else
- {
- // Unknown data type
- return QVariant();
- }
- }
|