/************************************************************************** ** ** This file is part of Qt Simulator ** ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). ** ** Contact: Nokia Corporation (info@qt.nokia.com) ** ** ** GNU Lesser General Public License Usage ** ** This file may be used under the terms of the GNU Lesser General Public ** License version 2.1 as published by the Free Software Foundation and ** appearing in the file LICENSE.LGPL included in the packaging of this file. ** Please review the following information to ensure the GNU Lesser General ** Public License version 2.1 requirements will be met: ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** Other Usage ** ** Alternatively, this file may be used in accordance with the terms and ** conditions contained in a signed written agreement between you and Nokia. ** ** If you have questions regarding the use of this file, please contact ** Nokia at info@qt.nokia.com. ** **************************************************************************/ #include "configurationreader.h" #include #include #include #include bool ConfigurationReader::processDir(QDir *dir, QList& deviceDataList) { mErrorMessages.clear(); mCurrentDir = dir; bool noErrors = true; foreach (const QString& modelDirName, dir->entryList(QDir::Dirs | QDir::NoDotAndDotDot)) { if (!dir->cd(modelDirName)) continue; foreach(const QString& fileName, dir->entryList(QStringList() << "*.config", QDir::Files)) { mCurrentConfigFile = dir->filePath(fileName); QFile file(mCurrentConfigFile); DeviceData data; if (processFile(&file, &data)) deviceDataList.append(data); else noErrors = false; } dir->cdUp(); } return noErrors; } bool ConfigurationReader::processFile(QFile *file, DeviceData *data) { if (!file->open(QIODevice::ReadOnly | QIODevice::Text)) return false; QString errorMsg; QString fileName = file->fileName(); int start = fileName.lastIndexOf('/'); int end = fileName.lastIndexOf('.'); data->name = fileName.mid(start + 1, end - start - 1); int lineNr=0; while (!file->atEnd()) { lineNr++; QByteArray line = file->readLine(); if (!processLine(line, data, errorMsg)) { error(tr("Error in line %1: %2").arg(lineNr).arg(errorMsg)); errorMsg.clear(); return false; } } return true; } bool ConfigurationReader::processLine(const QByteArray &line, DeviceData *deviceData, QString& errorMsg) { int colonIndex = line.indexOf(':'); if (colonIndex == -1) { errorMsg = "ConfigurationReader: Invalid property. Syntax is name:value"; return false; } QByteArray parameter = line.mid(0, colonIndex).trimmed(); QByteArray value = line.mid(colonIndex + 1).trimmed(); if (parameter == "name") deviceData->name = value; else if (parameter == "resolutionWidth") deviceData->resolution.setWidth(value.toInt()); else if (parameter == "resolutionHeight") deviceData->resolution.setHeight(value.toInt()); else if (parameter == "diagonalInInch") deviceData->diagonalInInch = value.toFloat(); else if (parameter == "mockup") { deviceData->mockupPath = mCurrentDir->filePath(value); if (!mCurrentDir->exists(value)) { errorMsg = tr("Mockup file %1 does not exist.").arg(deviceData->mockupPath); return false; } } else if (parameter == "offsetX") deviceData->offset.setX(value.toInt()); else if (parameter == "offsetY") deviceData->offset.setY(value.toInt()); else if (parameter == "defaultFontSize") deviceData->defaultFontSize = value.toInt(); else if (parameter == "forceDpi") deviceData->forceDpi = value.toInt(); else if (parameter == "style") { QList values = splitByUnescaped(value, ','); if (values.size() > 2) { errorMsg = tr("ConfigurationReader: style property requires one or two comma separated values\n" " style:name,theme"); return false; } deviceData->style = values.at(0); if (values.size() == 2) deviceData->styleTheme = values.at(1); } else if (parameter == "button") { QList values = splitByUnescaped(value, ','); if (values.count() != 6) { errorMsg = tr("ConfigurationReader: button property requires six comma separated values\n" " button:keycode,keytext,x,y,width,height"); return false; } Button b; const QMetaObject &qtMetaObject(QObject::staticQtMetaObject); QMetaEnum keyEnum = qtMetaObject.enumerator(qtMetaObject.indexOfEnumerator("Key")); int keyCode = keyEnum.keyToValue(values[0].constData()); if (keyCode == -1) { errorMsg = tr("ConfigurationReader: Not a valid Qt::Key name: %1").arg(values[0].data()); return false; } b.key = static_cast(keyCode); b.text = values[1]; b.area = QRectF(values[2].toFloat(), values[3].toFloat(), values[4].toFloat(), values[5].toFloat()); deviceData->buttons.append(b); } else if (parameter == "maemoNavigationButtonPortrait" || parameter == "maemoNavigationButtonLandscape") { QList values = value.split(','); if (values.count() != 2) { errorMsg = tr("ConfigurationReader: maemoNavigationButton property requires two comma separated values\n" " maemoNavigationButton:x,y"); return false; } QPointF toSet = QPointF(values[0].toFloat(), values[1].toFloat()); if (parameter == "maemoNavigationButtonPortrait") deviceData->maemoNavigationButtonPortrait = toSet; else deviceData->maemoNavigationButtonLandscape = toSet; } else if (parameter == "maemoNavigationButtonBack") { deviceData->maemoNavigationBackButton = mCurrentDir->filePath(value); if (!mCurrentDir->exists(value)) { errorMsg = tr("Image file %1 does not exist.").arg(deviceData->maemoNavigationBackButton); return false; } } else if (parameter == "maemoNavigationButtonClose") { deviceData->maemoNavigationCloseButton = mCurrentDir->filePath(value); if (!mCurrentDir->exists(value)) { errorMsg = tr("Image file %1 does not exist.").arg(deviceData->maemoNavigationCloseButton); return false; } } else if (parameter == "symbianSoftKeyButton") { QList values = value.split(','); if (values.count() != 6) { errorMsg = tr("ConfigurationReader: symbianSoftKeyButton property requires six comma separated values\n" " symbianSoftKeyButton:orientation,buttonnr,x,y,width,height\n" " where buttonnr: 0: positive, 1: negative, 2: middle, 3: middle, 4: middle"); return false; } SymbianSoftKeyButtonData key; key.buttonNumber = values[1].toInt(); key.area = QRectF(values[2].toFloat(), values[3].toFloat(), values[4].toFloat(), values[5].toFloat()); bool orientationOk = false; Orientation orientation = stringToOrientation(values[0], &orientationOk); if (!orientationOk) { errorMsg = tr("ConfigurationReader: unknown orientation: %1").arg(QString(values[0])); return false; } else { key.orientation = orientation; } deviceData->symbianSoftKeys.append(key); } else if (parameter == "availableGeometry") { QList values = value.split(','); if (values.count() != 5) { errorMsg = tr("ConfigurationReader: availableGeometryPortrait/Landscape property requires" "five comma separated values\n" " availableGeometry:orientation,x,y,width,height"); return false; } QRect geometry = QRect(values[1].toInt(), values[2].toInt(), values[3].toInt(), values[4].toInt()); bool orientationOk = false; Orientation orientation = stringToOrientation(values[0], &orientationOk); if (!orientationOk) { errorMsg = tr("ConfigurationReader: unknown parameter: %1").arg(QString(values[0])); return false; } else { deviceData->menus[orientation].availableGeometry = geometry; deviceData->supportedOrientations |= orientation; } } else if (parameter == "menuImage") { QList values = value.split(','); if (values.count() != 2) { errorMsg = tr("ConfigurationReader: menuImage property requires" "two comma separated values\n" " menuImage:orientation,pixmapPath"); return false; } if (!mCurrentDir->exists(values[1])) { errorMsg = tr("Menu file %1 does not exist.").arg(mCurrentDir->filePath(value)); return false; } bool orientationOk = false; Orientation orientation = stringToOrientation(values[0], &orientationOk); if (!orientationOk) { errorMsg = tr("ConfigurationReader: unknown orientation: %1").arg(QString(values[0])); return false; } deviceData->menus[orientation].pixmapPath = mCurrentDir->filePath(values[1]); deviceData->supportedOrientations |= orientation; } else if (parameter == "landscapeOrientation" || parameter == "portraitOrientation"){ bool orientationOk = false; Orientation orientation = stringToOrientation(value, &orientationOk); if (!orientationOk) { errorMsg = tr("ConfigurationReader: unknown orientation: %1").arg(QString(value)); return false; } if (parameter == "landscapeOrientation") deviceData->landscapeOrientation = orientation; else deviceData->portraitOrientation = orientation; } else return false; return true; } void ConfigurationReader::error(const QString& msg) { mErrorMessages.append(mCurrentConfigFile + ": " + msg); } QString ConfigurationReader::errorMessageLines() const { QString msg; foreach (const QString& str, mErrorMessages) msg.append(str + '\n'); return msg; } QList ConfigurationReader::splitByUnescaped(const QByteArray &arrayToSplit, QChar splitChar) { QList returnList; QByteArray arrayToAdd; for(int i = 0; i < arrayToSplit.length(); i++) { if (arrayToSplit.at(i) == QLatin1Char('\\') && i < arrayToSplit.length() - 1) { arrayToAdd.append(arrayToSplit.at(i + 1)); i++; } else if (arrayToSplit.at(i) == splitChar) { returnList.append(arrayToAdd); arrayToAdd.clear(); } else { arrayToAdd.append(arrayToSplit.at(i)); } } if (!arrayToAdd.isEmpty()) returnList.append(arrayToAdd); return returnList; } Orientation ConfigurationReader::stringToOrientation(const QString &orientationString, bool *ok) { if (ok) *ok = true; if (orientationString == "topUp") { return topUp; } else if (orientationString == "topDown") { return topDown; } else if (orientationString == "leftUp") { return leftUp; } else if (orientationString == "rightUp") { return rightUp; } else { if (ok) *ok = false; return topUp; } }