/************************************************************************** ** ** 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 #include "viewui.h" #include "viewconfiguration.h" #include "ui_inspector.h" #include "configurationreader.h" #include #include #include #include #include #include #include Q_DECLARE_METATYPE(Orientation); ViewUi::ViewUi(const DeviceItem *deviceItem, QWidget *parent) : ToolBoxPage(parent) , mCorrectionFactor(1) , mViewConfiguration(0) , ui_inspector(new Ui_Inspector) , mScriptInterface(0) , mDeviceItem(deviceItem) , mOrientationLocked(false) { qRegisterMetaType(); QDesktopWidget *desktop = QApplication::desktop(); mLogicalDpi.setWidth(desktop->logicalDpiX()); mLogicalDpi.setHeight(desktop->logicalDpiY()); mScriptInterface = new ViewScriptInterface(this); QStringList tags; QList optionsList; OptionsItem *item; QWidget *target = new QWidget(); ui_inspector->setupUi(target); item = new OptionsItem(QString(),target, true); item->setTags(QStringList() << tr("models") << tr("rotation") << tr("size") << tr("scale")); optionsList << item; mOrientationButtons = new QButtonGroup; mOrientationButtons->setParent(ui_inspector->topUp->parent()); mOrientationButtons->addButton(ui_inspector->topUp, static_cast(topUp)); mOrientationButtons->addButton(ui_inspector->rightUp, static_cast(rightUp)); mOrientationButtons->addButton(ui_inspector->topDown, static_cast(topDown)); mOrientationButtons->addButton(ui_inspector->leftUp, static_cast(leftUp)); connect(mOrientationButtons, SIGNAL(buttonClicked(int)), this, SLOT(changeOrientation(int))); updateOrientationsButtonsIcons(false); QPushButton *dpiButton = new QPushButton(tr("Configure DPI Correction")); item = new OptionsItem(QString(), dpiButton, true); item->setTags(QStringList() << tr("dpi")); optionsList << item; connect(dpiButton, SIGNAL(clicked()), SLOT(showViewConfiguration())); connect(ui_inspector->scaleSlider, SIGNAL(valueChanged(int)), this, SLOT(changeScaleFactor(int))); connect(ui_inspector->deviceListView, SIGNAL(currentIndexChanged(int)), this, SLOT(changeDeviceSelection(int))); connect(ui_inspector->rotateScreen, SIGNAL(toggled(bool)), this, SLOT(rotateScreenToggled())); connect(this, SIGNAL(deviceSelectionChanged(const DeviceData &)), mDeviceItem, SLOT(changeDevice(const DeviceData &))); connect(this, SIGNAL(scaleFactorChanged(qreal)), mDeviceItem, SLOT(changeScaleFactor(qreal))); connect(this, SIGNAL(orientationChangeRequested(Orientation, bool)), mDeviceItem, SLOT(changeOrientation(Orientation, bool))); connect(mDeviceItem, SIGNAL(orientationChanged(Orientation)), this, SLOT(updateOrientationButtonsState(Orientation))); connect(mDeviceItem, SIGNAL(deviceChanged(bool)), this, SLOT(updateOrientationsButtonsIcons(bool))); setTitle(tr("Model")); setOptions(optionsList); } int ViewUi::currentDeviceIndex() const { return ui_inspector->deviceListView->currentIndex(); } QString ViewUi::currentDeviceName() const { return ui_inspector->deviceListView->currentText(); } void ViewUi::changeDeviceSelection(int newIndex) { ui_inspector->deviceListView->setCurrentIndex(newIndex); const DeviceData &newData = deviceList.at(newIndex); emit deviceSelectionChanged(newData); updateOrientationButtons(newData); changeScaleFactor(ui_inspector->scaleSlider->value()); } void ViewUi::updateOrientationButtonsState(Orientation orientation) { mOrientationButtons->button(orientation)->setChecked(true); } void ViewUi::updateOrientationsButtonsIcons(bool standardOrientationPortrait) { if (standardOrientationPortrait) { ui_inspector->topUp->setIcon(QIcon(":/ui/icons/topup.png")); ui_inspector->topDown->setIcon(QIcon(":/ui/icons/topdown.png")); ui_inspector->leftUp->setIcon(QIcon(":/ui/icons/leftup.png")); ui_inspector->rightUp->setIcon(QIcon(":/ui/icons/rightup.png")); } else { ui_inspector->topUp->setIcon(QIcon(":/ui/icons/topup_landscape.png")); ui_inspector->topDown->setIcon(QIcon(":/ui/icons/topdown_landscape.png")); ui_inspector->leftUp->setIcon(QIcon(":/ui/icons/leftup_landscape.png")); ui_inspector->rightUp->setIcon(QIcon(":/ui/icons/rightup_landscape.png")); } } void ViewUi::updateOrientationButtons(const DeviceData &data) { const bool rotateScreen = ui_inspector->rotateScreen->isChecked(); if (!rotateScreen || mOrientationLocked) { ui_inspector->topUp->setEnabled(true); ui_inspector->leftUp->setEnabled(true); ui_inspector->rightUp->setEnabled(true); ui_inspector->topDown->setEnabled(true); } else { ui_inspector->topUp->setEnabled(data.supportedOrientations & topUp); ui_inspector->leftUp->setEnabled(data.supportedOrientations & leftUp); ui_inspector->rightUp->setEnabled(data.supportedOrientations & rightUp); ui_inspector->topDown->setEnabled(data.supportedOrientations & topDown); } if (!mOrientationButtons->checkedButton()->isEnabled() && !data.menus.isEmpty() && !mOrientationLocked) { Orientation fallback = data.menus.begin().key(); if (data.supportedOrientations & fallback) mOrientationButtons->button(fallback)->click(); } } void ViewUi::rotateScreenToggled() { updateOrientationButtons(deviceList.at(currentDeviceIndex())); emit orientationChangeRequested(static_cast(mOrientationButtons->checkedId()), ui_inspector->rotateScreen->isChecked()); } void ViewUi::initializeSelection() { if (deviceList.count() == 0) return; ui_inspector->deviceListView->setCurrentIndex(0); changeDeviceSelection(0); } void ViewUi::changeScaleFactor(int sliderPosition) { int index = currentDeviceIndex(); if (index < 0 || index >= deviceList.size()) return; const DeviceData &data = deviceList.at(index); qreal pixelDiagonal = sqrt(pow((qreal)data.resolution.width(), 2) + pow((qreal)data.resolution.height(), 2)); qreal displayWidthInInch = data.diagonalInInch / pixelDiagonal * data.resolution.width(); qreal minimalScale = mLogicalDpi.width() * displayWidthInInch / data.resolution.width() * mCorrectionFactor; emit scaleFactorChanged((minimalScale + qreal(sliderPosition) / 100. * (1. - minimalScale))); } void ViewUi::changeCorrectionFactor(qreal newFactor) { mCorrectionFactor = newFactor; changeScaleFactor(ui_inspector->scaleSlider->value()); } void ViewUi::writeSettings(QSettings &settings) const { ToolBoxPage::writeSettings(settings); settings.beginGroup("ViewUiWidget"); settings.setValue("scale", ui_inspector->scaleSlider->value()); settings.setValue("corrfactor", mCorrectionFactor); settings.setValue("viewPageVisible", isContentVisible()); settings.setValue("rotateScreen", ui_inspector->rotateScreen->isChecked()); int index = currentDeviceIndex(); if (index >= 0 && index < deviceList.size()) settings.setValue("device", deviceList.at(index).name); settings.endGroup(); } void ViewUi::readSettings(QSettings &settings) { ToolBoxPage::readSettings(settings); settings.beginGroup("ViewUiWidget"); bool deviceFound = false; if (settings.contains("device")) { QString deviceName = settings.value("device").toString(); for (int i = 0; i < deviceList.size(); ++i) { if (deviceList.at(i).name == deviceName) { ui_inspector->deviceListView->setCurrentIndex(i); changeDeviceSelection(i); deviceFound = true; break; } } } if (!deviceFound) initializeSelection(); if (settings.contains("scale")) ui_inspector->scaleSlider->setValue(settings.value("scale").toInt()); if (settings.contains("corrfactor")) { changeCorrectionFactor(settings.value("corrfactor").toDouble()); } if (settings.contains("viewPageVisible")) { bool viewPageVisible = settings.value("viewPageVisible").toBool(); if (viewPageVisible) showContent(true); else showContent(false); } if (settings.contains("rotateScreen")) ui_inspector->rotateScreen->setChecked(settings.value("rotateScreen").toBool()); settings.endGroup(); } void ViewUi::changeOrientation(int orientation) { emit orientationChangeRequested(static_cast(orientation), ui_inspector->rotateScreen->isChecked()); } QObject *ViewUi::scriptInterface() const { return mScriptInterface; } bool ViewUi::initializeDeviceList() { QDir modelsDir("models"); if (!modelsDir.exists()) { QMessageBox errorMsg; errorMsg.setWindowTitle(tr("Folder Does Not Exist")); errorMsg.setText(tr("Cannot find the \"%1\" folder in the installation directory.").arg(modelsDir.dirName())); errorMsg.setIcon(QMessageBox::Critical); errorMsg.exec(); return false; } ConfigurationReader confReader; deviceList.clear(); bool noErrors = confReader.processDir(&modelsDir, deviceList); if (!noErrors && !deviceList.isEmpty()) { QMessageBox msgbox; msgbox.setWindowTitle(tr("Errors Occurred While Reading Device Configurations")); msgbox.setText(confReader.errorMessageLines()); msgbox.setIcon(QMessageBox::Critical); msgbox.exec(); } if (deviceList.isEmpty()) { QMessageBox errorMsg; errorMsg.setWindowTitle(tr("Cannot Find Devices")); QString msg; if (!noErrors) { msg = confReader.errorMessageLines(); } msg += tr("No valid device configuration files (.config) could be found in the \"%1\" folder.").arg(modelsDir.dirName()); errorMsg.setText(msg); errorMsg.setIcon(QMessageBox::Critical); errorMsg.exec(); return false; } foreach (const DeviceData &data, deviceList) ui_inspector->deviceListView->addItem(data.name); return true; } void ViewUi::showViewConfiguration() { if (!mViewConfiguration) { mViewConfiguration = new ViewConfiguration(mCorrectionFactor, this); connect(mViewConfiguration, SIGNAL(correctionFactorChanged(qreal)), SLOT(changeCorrectionFactor(qreal))); } mViewConfiguration->exec(); } void ViewUi::setOrientationLocked(bool locked) { mOrientationLocked = locked; ui_inspector->rotateScreen->setDisabled(locked); updateOrientationButtons(deviceList.at(currentDeviceIndex())); if (!locked) { emit orientationChangeRequested(static_cast(mOrientationButtons->checkedId()), ui_inspector->rotateScreen->isChecked()); } } QIcon ViewUi::icon() const { return QIcon(":/ui/icons/view.png"); } /*! \class ViewScriptInterface \brief Exposed as simulator. */ /*! \property ViewScriptInterface::zoom \brief the device scaling The value can be between between 0 for real-world size and 100 for pixel equivalence. */ ViewScriptInterface::ViewScriptInterface(ViewUi *ui) : QObject(ui), ui(ui) { int enumIndex = metaObject()->indexOfEnumerator("Orientation"); QMetaEnum metaEnum = metaObject()->enumerator(enumIndex); for (int i = 0; i < metaEnum.keyCount(); ++i) setProperty(metaEnum.key(i), metaEnum.key(i)); } ViewScriptInterface::~ViewScriptInterface() { } int ViewScriptInterface::zoom() const { return ui->ui_inspector->scaleSlider->value(); } void ViewScriptInterface::setZoom(int z) { if (z < 0) z = 0; else if (z > 100) z = 100; ui->ui_inspector->scaleSlider->setValue(z); } /*! Returns the index of the current device. \sa setDevice(), deviceCount() */ int ViewScriptInterface::currentDeviceIndex() const { return ui->currentDeviceIndex(); } /*! Returns the name of the current device. \sa setDevice() */ QString ViewScriptInterface::currentDeviceName() const { return ui->currentDeviceName(); } /*! Returns the number of available device models. \sa setDevice(), currentDeviceIndex() */ int ViewScriptInterface::deviceCount() const { return ui->deviceList.size(); } /*! Sets the current device to the one with \a index. \sa deviceCount(), currentDeviceIndex() */ void ViewScriptInterface::setDevice(int index) { ui->changeDeviceSelection(index); } /*! Sets the current device to be the one identified by \a dev. \sa currentDeviceName() */ void ViewScriptInterface::setDevice(const QString &dev) { const QList &devices = ui->deviceList; for (int i = 0; i < devices.size(); ++i) { if (devices.at(i).name == dev) { ui->changeDeviceSelection(i); break; } } } /*! Rotates the current device, and - optionally - the screen. Returns true on success. */ bool ViewScriptInterface::setDeviceOrientation(QString newOrientation, bool rotateScreen) { const int enumIndex = metaObject()->indexOfEnumerator("Orientation"); const QMetaEnum metaEnum = metaObject()->enumerator(enumIndex); int orientation = metaEnum.keyToValue(newOrientation.toLatin1()); if (QAbstractButton *button = ui->mOrientationButtons->button(orientation)) { ui->ui_inspector->rotateScreen->setChecked(rotateScreen); if (!button->isEnabled()) return false; button->click(); return true; } return false; } /*! Returns the current device orientation. */ QString ViewScriptInterface::deviceOrientation() const { const int enumIndex = metaObject()->indexOfEnumerator("Orientation"); const QMetaEnum metaEnum = metaObject()->enumerator(enumIndex); return metaEnum.valueToKey(ui->mDeviceItem->deviceOrientation()); } /*! Returns the current screen orientation. */ QString ViewScriptInterface::screenOrientation() const { const int enumIndex = metaObject()->indexOfEnumerator("Orientation"); const QMetaEnum metaEnum = metaObject()->enumerator(enumIndex); return metaEnum.valueToKey(ui->mDeviceItem->screenOrientation()); } /*! Returns the list of screen orientations. */ QStringList ViewScriptInterface::supportedScreenOrientations() const { const int enumIndex = metaObject()->indexOfEnumerator("Orientation"); const QMetaEnum metaEnum = metaObject()->enumerator(enumIndex); QStringList ret; foreach (::Orientation o, ui->mDeviceItem->supportedScreenOrientations()) ret.append(metaEnum.valueToKey(o)); return ret; } int ViewScriptInterface::availableGeometryX() const { return ui->mDeviceItem->availableGeometry().x(); } int ViewScriptInterface::availableGeometryY() const { return ui->mDeviceItem->availableGeometry().y(); } int ViewScriptInterface::availableGeometryWidth() const { return ui->mDeviceItem->availableGeometry().width(); } int ViewScriptInterface::availableGeometryHeight() const { return ui->mDeviceItem->availableGeometry().height(); }