summaryrefslogtreecommitdiff
path: root/src/plugins/remotelinux/maemoqemumanager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/remotelinux/maemoqemumanager.cpp')
-rw-r--r--src/plugins/remotelinux/maemoqemumanager.cpp621
1 files changed, 621 insertions, 0 deletions
diff --git a/src/plugins/remotelinux/maemoqemumanager.cpp b/src/plugins/remotelinux/maemoqemumanager.cpp
new file mode 100644
index 0000000000..dbb2158291
--- /dev/null
+++ b/src/plugins/remotelinux/maemoqemumanager.cpp
@@ -0,0 +1,621 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** 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 "maemoqemumanager.h"
+
+#include "maemoglobal.h"
+#include "maemoqemuruntimeparser.h"
+#include "maemosettingspages.h"
+#include "maemorunconfiguration.h"
+#include "qt4maemotarget.h"
+#include "maemoqtversion.h"
+
+#include <coreplugin/actionmanager/actionmanager.h>
+#include <coreplugin/actionmanager/command.h>
+#include <coreplugin/uniqueidmanager.h>
+#include <coreplugin/coreconstants.h>
+#include <coreplugin/icore.h>
+#include <coreplugin/icontext.h>
+#include <coreplugin/modemanager.h>
+
+#include <projectexplorer/projectexplorer.h>
+#include <projectexplorer/project.h>
+#include <projectexplorer/session.h>
+#include <qtsupport/qtversionmanager.h>
+#include <utils/filesystemwatcher.h>
+
+#include <QtCore/QDebug>
+#include <QtCore/QDir>
+#include <QtCore/QList>
+#include <QtCore/QSet>
+#include <QtCore/QStringBuilder>
+
+#include <QtGui/QAction>
+#include <QtGui/QDesktopServices>
+#include <QtGui/QMessageBox>
+
+#include <limits.h>
+
+using namespace ProjectExplorer;
+using namespace Qt4ProjectManager;
+using namespace RemoteLinux;
+using namespace RemoteLinux::Internal;
+
+MaemoQemuManager *MaemoQemuManager::m_instance = 0;
+
+const QSize iconSize = QSize(24, 20);
+
+MaemoQemuManager::MaemoQemuManager(QObject *parent)
+ : QObject(parent)
+ , m_qemuAction(0)
+ , m_qemuProcess(new QProcess(this))
+ , m_runningQtId(INT_MIN)
+ , m_userTerminated(false)
+ , m_runtimeRootWatcher(0)
+ , m_runtimeFolderWatcher(0)
+{
+ m_qemuStarterIcon.addFile(":/qt-maemo/images/qemu-run.png", iconSize);
+ m_qemuStarterIcon.addFile(":/qt-maemo/images/qemu-stop.png", iconSize,
+ QIcon::Normal, QIcon::On);
+
+ m_qemuAction = new QAction("Maemo Emulator", this);
+ m_qemuAction->setIcon(m_qemuStarterIcon.pixmap(iconSize));
+ m_qemuAction->setToolTip(tr("Start Maemo Emulator"));
+ connect(m_qemuAction, SIGNAL(triggered()), this, SLOT(startRuntime()));
+
+ Core::ICore *core = Core::ICore::instance();
+ Core::ActionManager *actionManager = core->actionManager();
+ Core::Command *qemuCommand = actionManager->registerAction(m_qemuAction,
+ "MaemoEmulator", Core::Context(Core::Constants::C_GLOBAL));
+ qemuCommand->setAttribute(Core::Command::CA_UpdateText);
+ qemuCommand->setAttribute(Core::Command::CA_UpdateIcon);
+
+ Core::ModeManager *modeManager = core->modeManager();
+ modeManager->addAction(qemuCommand->action(), 1);
+ m_qemuAction->setEnabled(false);
+ m_qemuAction->setVisible(false);
+
+ // listen to qt version changes to update the start button
+ connect(QtSupport::QtVersionManager::instance(), SIGNAL(qtVersionsChanged(QList<int>)),
+ this, SLOT(qtVersionsChanged(QList<int>)));
+
+ // listen to project add, remove and startup changes to udate start button
+ SessionManager *session = ProjectExplorerPlugin::instance()->session();
+ connect(session, SIGNAL(projectAdded(ProjectExplorer::Project*)), this,
+ SLOT(projectAdded(ProjectExplorer::Project*)));
+ connect(session, SIGNAL(projectRemoved(ProjectExplorer::Project*)), this,
+ SLOT(projectRemoved(ProjectExplorer::Project*)));
+ connect(session, SIGNAL(startupProjectChanged(ProjectExplorer::Project*)),
+ this, SLOT(projectChanged(ProjectExplorer::Project*)));
+
+ connect(m_qemuProcess, SIGNAL(error(QProcess::ProcessError)), this,
+ SLOT(qemuProcessError(QProcess::ProcessError)));
+ connect(m_qemuProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this,
+ SLOT(qemuProcessFinished()));
+ connect(m_qemuProcess, SIGNAL(readyReadStandardOutput()), this,
+ SLOT(qemuOutput()));
+ connect(m_qemuProcess, SIGNAL(readyReadStandardError()), this,
+ SLOT(qemuOutput()));
+ connect(this, SIGNAL(qemuProcessStatus(QemuStatus, QString)),
+ this, SLOT(qemuStatusChanged(QemuStatus, QString)));
+}
+
+Utils::FileSystemWatcher *MaemoQemuManager::runtimeRootWatcher()
+{
+ if (!m_runtimeRootWatcher) {
+ m_runtimeRootWatcher = new Utils::FileSystemWatcher(this);
+ m_runtimeRootWatcher->setObjectName(QLatin1String("MaemoQemuRuntimeRootWatcher"));
+ connect(m_runtimeRootWatcher, SIGNAL(directoryChanged(QString)), this,
+ SLOT(runtimeRootChanged(QString)));
+ }
+ return m_runtimeRootWatcher;
+}
+
+Utils::FileSystemWatcher *MaemoQemuManager::runtimeFolderWatcher()
+{
+ if (!m_runtimeFolderWatcher) {
+ m_runtimeFolderWatcher = new Utils::FileSystemWatcher(this);
+ m_runtimeFolderWatcher->setObjectName(QLatin1String("MaemoQemuRuntimeFolderWatcher"));
+ connect(m_runtimeFolderWatcher, SIGNAL(directoryChanged(QString)), this,
+ SLOT(runtimeFolderChanged(QString)));
+ }
+ return m_runtimeFolderWatcher;
+}
+
+MaemoQemuManager::~MaemoQemuManager()
+{
+ terminateRuntime();
+ m_instance = 0;
+}
+
+MaemoQemuManager &MaemoQemuManager::instance(QObject *parent)
+{
+ if (m_instance == 0)
+ m_instance = new MaemoQemuManager(parent);
+ return *m_instance;
+}
+
+bool MaemoQemuManager::runtimeForQtVersion(int uniqueId, MaemoQemuRuntime *rt) const
+{
+ *rt = m_runtimes.value(uniqueId, MaemoQemuRuntime());
+ return rt->isValid();
+}
+
+bool MaemoQemuManager::qemuIsRunning() const
+{
+ return m_runningQtId != INT_MIN;
+}
+
+void MaemoQemuManager::qtVersionsChanged(const QList<int> &uniqueIds)
+{
+ QtSupport::QtVersionManager *manager = QtSupport::QtVersionManager::instance();
+ foreach (int uniqueId, uniqueIds) {
+ if (manager->isValidId(uniqueId)) {
+ MaemoQtVersion *version = dynamic_cast<MaemoQtVersion *>(manager->version(uniqueId));
+
+ if (version) {
+ MaemoQemuRuntime runtime
+ = MaemoQemuRuntimeParser::parseRuntime(version);
+ if (runtime.isValid()) {
+ m_runtimes.insert(uniqueId, runtime);
+ if (!runtimeRootWatcher()->watchesDirectory(runtime.m_watchPath))
+ runtimeRootWatcher()->addDirectory(runtime.m_watchPath,
+ Utils::FileSystemWatcher::WatchAllChanges);
+ } else {
+ m_runtimes.remove(uniqueId);
+ }
+ }
+ } else {
+ // this qt version has been removed from the settings
+ m_runtimes.remove(uniqueId);
+ if (uniqueId == m_runningQtId) {
+ terminateRuntime();
+ emit qemuProcessStatus(QemuUserReason, tr("Qemu has been shut "
+ "down, because you removed the corresponding Qt version."));
+ }
+ }
+ }
+
+ showOrHideQemuButton();
+}
+
+void MaemoQemuManager::projectAdded(ProjectExplorer::Project *project)
+{
+ // handle all target related changes, add, remove, etc...
+ connect(project, SIGNAL(addedTarget(ProjectExplorer::Target*)), this,
+ SLOT(targetAdded(ProjectExplorer::Target*)));
+ connect(project, SIGNAL(removedTarget(ProjectExplorer::Target*)), this,
+ SLOT(targetRemoved(ProjectExplorer::Target*)));
+ connect(project, SIGNAL(activeTargetChanged(ProjectExplorer::Target*)),
+ this, SLOT(targetChanged(ProjectExplorer::Target*)));
+
+ foreach (Target *target, project->targets())
+ targetAdded(target);
+}
+
+void MaemoQemuManager::projectRemoved(ProjectExplorer::Project *project)
+{
+ disconnect(project, SIGNAL(addedTarget(ProjectExplorer::Target*)), this,
+ SLOT(targetAdded(ProjectExplorer::Target*)));
+ disconnect(project, SIGNAL(removedTarget(ProjectExplorer::Target*)), this,
+ SLOT(targetRemoved(ProjectExplorer::Target*)));
+ disconnect(project, SIGNAL(activeTargetChanged(ProjectExplorer::Target*)),
+ this, SLOT(targetChanged(ProjectExplorer::Target*)));
+
+ foreach (Target *target, project->targets())
+ targetRemoved(target);
+ showOrHideQemuButton();
+}
+
+void MaemoQemuManager::projectChanged(ProjectExplorer::Project *project)
+{
+ if (project) {
+ toggleStarterButton(project->activeTarget());
+ deviceConfigurationChanged(project->activeTarget());
+ }
+}
+
+void MaemoQemuManager::targetAdded(ProjectExplorer::Target *target)
+{
+ if (!target || !MaemoGlobal::isMaemoTargetId(target->id()))
+ return;
+
+ // handle all run configuration changes, add, remove, etc...
+ connect(target, SIGNAL(addedRunConfiguration(ProjectExplorer::RunConfiguration*)),
+ this, SLOT(runConfigurationAdded(ProjectExplorer::RunConfiguration*)));
+ connect(target, SIGNAL(removedRunConfiguration(ProjectExplorer::RunConfiguration*)),
+ this, SLOT(runConfigurationRemoved(ProjectExplorer::RunConfiguration*)));
+ connect(target, SIGNAL(activeRunConfigurationChanged(ProjectExplorer::RunConfiguration*)),
+ this, SLOT(runConfigurationChanged(ProjectExplorer::RunConfiguration*)));
+
+ // handle all build configuration changes, add, remove, etc...
+ connect(target, SIGNAL(removedBuildConfiguration(ProjectExplorer::BuildConfiguration*)),
+ this, SLOT(buildConfigurationAdded(ProjectExplorer::BuildConfiguration*)));
+ connect(target, SIGNAL(removedBuildConfiguration(ProjectExplorer::BuildConfiguration*)),
+ this, SLOT(buildConfigurationRemoved(ProjectExplorer::BuildConfiguration*)));
+ connect(target, SIGNAL(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)),
+ this, SLOT(buildConfigurationChanged(ProjectExplorer::BuildConfiguration*)));
+
+ // handle the qt version changes the build configuration uses
+ connect(target, SIGNAL(environmentChanged()), this, SLOT(environmentChanged()));
+
+ foreach (RunConfiguration *rc, target->runConfigurations())
+ toggleDeviceConnections(qobject_cast<MaemoRunConfiguration*> (rc), true);
+ toggleStarterButton(target);
+}
+
+void MaemoQemuManager::targetRemoved(ProjectExplorer::Target *target)
+{
+ if (!target || !MaemoGlobal::isMaemoTargetId(target->id()))
+ return;
+
+ disconnect(target, SIGNAL(addedRunConfiguration(ProjectExplorer::RunConfiguration*)),
+ this, SLOT(runConfigurationAdded(ProjectExplorer::RunConfiguration*)));
+ disconnect(target, SIGNAL(removedRunConfiguration(ProjectExplorer::RunConfiguration*)),
+ this, SLOT(runConfigurationRemoved(ProjectExplorer::RunConfiguration*)));
+ disconnect(target, SIGNAL(activeRunConfigurationChanged(ProjectExplorer::RunConfiguration*)),
+ this, SLOT(runConfigurationChanged(ProjectExplorer::RunConfiguration*)));
+
+ disconnect(target, SIGNAL(removedBuildConfiguration(ProjectExplorer::BuildConfiguration*)),
+ this, SLOT(buildConfigurationAdded(ProjectExplorer::BuildConfiguration*)));
+ disconnect(target, SIGNAL(removedBuildConfiguration(ProjectExplorer::BuildConfiguration*)),
+ this, SLOT(buildConfigurationRemoved(ProjectExplorer::BuildConfiguration*)));
+ disconnect(target, SIGNAL(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)),
+ this, SLOT(buildConfigurationChanged(ProjectExplorer::BuildConfiguration*)));
+
+ disconnect(target, SIGNAL(environmentChanged()), this, SLOT(environmentChanged()));
+
+ foreach (RunConfiguration *rc, target->runConfigurations())
+ toggleDeviceConnections(qobject_cast<MaemoRunConfiguration*> (rc), false);
+ showOrHideQemuButton();
+}
+
+void MaemoQemuManager::targetChanged(ProjectExplorer::Target *target)
+{
+ if (target) {
+ toggleStarterButton(target);
+ deviceConfigurationChanged(target);
+ }
+}
+
+void MaemoQemuManager::runConfigurationAdded(ProjectExplorer::RunConfiguration *rc)
+{
+ if (!rc || !MaemoGlobal::isMaemoTargetId(rc->target()->id()))
+ return;
+ toggleDeviceConnections(qobject_cast<MaemoRunConfiguration*> (rc), true);
+}
+
+void MaemoQemuManager::runConfigurationRemoved(ProjectExplorer::RunConfiguration *rc)
+{
+ if (!rc || !MaemoGlobal::isMaemoTargetId(rc->target()->id()))
+ return;
+ toggleDeviceConnections(qobject_cast<MaemoRunConfiguration*> (rc), false);
+}
+
+void MaemoQemuManager::runConfigurationChanged(ProjectExplorer::RunConfiguration *rc)
+{
+ if (rc)
+ m_qemuAction->setEnabled(targetUsesMatchingRuntimeConfig(rc->target()));
+}
+
+void MaemoQemuManager::buildConfigurationAdded(ProjectExplorer::BuildConfiguration *bc)
+{
+ if (!bc || !MaemoGlobal::isMaemoTargetId(bc->target()->id()))
+ return;
+
+ connect(bc, SIGNAL(environmentChanged()), this, SLOT(environmentChanged()));
+}
+
+void MaemoQemuManager::buildConfigurationRemoved(ProjectExplorer::BuildConfiguration *bc)
+{
+ if (!bc || !MaemoGlobal::isMaemoTargetId(bc->target()->id()))
+ return;
+
+ disconnect(bc, SIGNAL(environmentChanged()), this, SLOT(environmentChanged()));
+}
+
+void MaemoQemuManager::buildConfigurationChanged(ProjectExplorer::BuildConfiguration *bc)
+{
+ if (bc)
+ toggleStarterButton(bc->target());
+}
+
+void MaemoQemuManager::environmentChanged()
+{
+ // likely to happen when the qt version changes the build config is using
+ if (ProjectExplorerPlugin *explorer = ProjectExplorerPlugin::instance()) {
+ if (Project *project = explorer->session()->startupProject())
+ toggleStarterButton(project->activeTarget());
+ }
+}
+
+void MaemoQemuManager::deviceConfigurationChanged(ProjectExplorer::Target *target)
+{
+ m_qemuAction->setEnabled(targetUsesMatchingRuntimeConfig(target));
+}
+
+void MaemoQemuManager::startRuntime()
+{
+ m_userTerminated = false;
+ Project *p = ProjectExplorerPlugin::instance()->session()->startupProject();
+ if (!p)
+ return;
+ QtSupport::BaseQtVersion *version;
+ if (!targetUsesMatchingRuntimeConfig(p->activeTarget(), &version)) {
+ qWarning("Strange: Qemu button was enabled, but target does not match.");
+ return;
+ }
+
+ m_runningQtId = version->uniqueId();
+ const MaemoQemuRuntime rt = m_runtimes.value(version->uniqueId());
+ m_qemuProcess->setProcessEnvironment(rt.environment());
+ m_qemuProcess->setWorkingDirectory(rt.m_root);
+ m_qemuProcess->start(rt.m_bin % QLatin1Char(' ') % rt.m_args);
+ if (!m_qemuProcess->waitForStarted())
+ return;
+
+ emit qemuProcessStatus(QemuStarting);
+ connect(m_qemuAction, SIGNAL(triggered()), this, SLOT(terminateRuntime()));
+ disconnect(m_qemuAction, SIGNAL(triggered()), this, SLOT(startRuntime()));
+}
+
+void MaemoQemuManager::terminateRuntime()
+{
+ m_userTerminated = true;
+
+ if (m_qemuProcess->state() != QProcess::NotRunning) {
+ m_qemuProcess->terminate();
+ m_qemuProcess->kill();
+ }
+
+ connect(m_qemuAction, SIGNAL(triggered()), this, SLOT(startRuntime()));
+ disconnect(m_qemuAction, SIGNAL(triggered()), this, SLOT(terminateRuntime()));
+}
+
+void MaemoQemuManager::qemuProcessFinished()
+{
+ m_runningQtId = INT_MIN;
+ QemuStatus status = QemuFinished;
+ QString error;
+
+ if (!m_userTerminated) {
+ if (m_qemuProcess->exitStatus() == QProcess::CrashExit) {
+ status = QemuCrashed;
+ error = m_qemuProcess->errorString();
+ } else if (m_qemuProcess->exitCode() != 0) {
+ error = tr("Qemu finished with error: Exit code was %1.")
+ .arg(m_qemuProcess->exitCode());
+ }
+ }
+
+ m_userTerminated = false;
+ emit qemuProcessStatus(status, error);
+}
+
+void MaemoQemuManager::qemuProcessError(QProcess::ProcessError error)
+{
+ if (error == QProcess::FailedToStart)
+ emit qemuProcessStatus(QemuFailedToStart, m_qemuProcess->errorString());
+}
+
+void MaemoQemuManager::qemuStatusChanged(QemuStatus status, const QString &error)
+{
+ bool running = false;
+ switch (status) {
+ case QemuStarting:
+ running = true;
+ break;
+ case QemuFailedToStart:
+ QMessageBox::warning(0, tr("Qemu error"),
+ tr("Qemu failed to start: %1"));
+ break;
+ case QemuCrashed:
+ MaemoQemuSettingsPage::showQemuCrashDialog();
+ break;
+ case QemuFinished:
+ case QemuUserReason:
+ if (!error.isEmpty())
+ QMessageBox::warning(0, tr("Qemu error"), error);
+ break;
+ default:
+ Q_ASSERT(!"Missing handling of Qemu status");
+ }
+
+ updateStarterIcon(running);
+}
+
+void MaemoQemuManager::qemuOutput()
+{
+ qDebug("%s", m_qemuProcess->readAllStandardOutput().data());
+ qDebug("%s", m_qemuProcess->readAllStandardError().data());
+}
+
+void MaemoQemuManager::runtimeRootChanged(const QString &directory)
+{
+ QList<int> uniqueIds;
+ QMap<int, MaemoQemuRuntime>::const_iterator it;
+ for (it = m_runtimes.constBegin(); it != m_runtimes.constEnd(); ++it) {
+ if (QDir(it.value().m_watchPath) == QDir(directory))
+ uniqueIds.append(it.key());
+ }
+
+ foreach (int uniqueId, uniqueIds) {
+ MaemoQemuRuntime runtime = m_runtimes.value(uniqueId, MaemoQemuRuntime());
+ if (runtime.isValid()) {
+ if (QFile::exists(runtime.m_root)) {
+ // nothing changed, so we can remove it
+ uniqueIds.removeAll(uniqueId);
+ }
+ } else {
+ if (QFile::exists(runtime.m_root)) {
+ if (!QFile::exists(runtime.m_root + QLatin1String("/information"))) {
+ // install might be still in progress
+ uniqueIds.removeAll(uniqueId);
+ runtimeFolderWatcher()->addDirectory(runtime.m_root,
+ Utils::FileSystemWatcher::WatchAllChanges);
+ }
+ }
+ }
+ }
+ notify(uniqueIds);
+}
+
+void MaemoQemuManager::runtimeFolderChanged(const QString &directory)
+{
+ if (QFile::exists(directory + QLatin1String("/information"))) {
+ QList<int> uniqueIds;
+ QMap<int, MaemoQemuRuntime>::const_iterator it;
+ for (it = m_runtimes.constBegin(); it != m_runtimes.constEnd(); ++it) {
+ if (QDir(it.value().m_root) == QDir(directory))
+ uniqueIds.append(it.key());
+ }
+ notify(uniqueIds);
+ if (m_runtimeFolderWatcher)
+ m_runtimeFolderWatcher->removeDirectory(directory);
+ }
+}
+
+// -- private
+
+void MaemoQemuManager::updateStarterIcon(bool running)
+{
+ QIcon::State state;
+ QString toolTip;
+ if (running) {
+ state = QIcon::On;
+ toolTip = tr("Stop Maemo Emulator");
+ } else {
+ state = QIcon::Off;
+ toolTip = tr("Start Maemo Emulator");
+ }
+
+ m_qemuAction->setToolTip(toolTip);
+ m_qemuAction->setIcon(m_qemuStarterIcon.pixmap(iconSize, QIcon::Normal,
+ state));
+}
+
+void MaemoQemuManager::toggleStarterButton(Target *target)
+{
+ int uniqueId = -1;
+ if (target) {
+ if (AbstractQt4MaemoTarget *qt4Target = qobject_cast<AbstractQt4MaemoTarget*>(target)) {
+ if (Qt4BuildConfiguration *bc = qt4Target->activeBuildConfiguration()) {
+ if (QtSupport::BaseQtVersion *version = bc->qtVersion())
+ uniqueId = version->uniqueId();
+ }
+ }
+ }
+
+ if (uniqueId >= 0 && (m_runtimes.isEmpty() || !m_runtimes.contains(uniqueId)))
+ qtVersionsChanged(QList<int>() << uniqueId);
+
+ bool isRunning = m_qemuProcess->state() != QProcess::NotRunning;
+ if (m_runningQtId == uniqueId)
+ isRunning = false;
+
+ const Project * const p
+ = ProjectExplorerPlugin::instance()->session()->startupProject();
+ const bool qemuButtonEnabled
+ = p && p->activeTarget() && MaemoGlobal::isMaemoTargetId(p->activeTarget()->id())
+ && m_runtimes.value(uniqueId, MaemoQemuRuntime()).isValid()
+ && targetUsesMatchingRuntimeConfig(target) && !isRunning;
+ m_qemuAction->setEnabled(qemuButtonEnabled);
+ showOrHideQemuButton();
+}
+
+bool MaemoQemuManager::sessionHasMaemoTarget() const
+{
+ ProjectExplorerPlugin *explorer = ProjectExplorerPlugin::instance();
+ const QList<Project*> &projects = explorer->session()->projects();
+ foreach (const Project *p, projects) {
+ foreach (const Target * const target, p->targets()) {
+ if (MaemoGlobal::isMaemoTargetId(target->id()))
+ return true;
+ }
+ }
+ return false;
+}
+
+bool MaemoQemuManager::targetUsesMatchingRuntimeConfig(Target *target,
+ QtSupport::BaseQtVersion **qtVersion)
+{
+ if (!target)
+ return false;
+ if (target != target->project()->activeTarget())
+ return false;
+
+ MaemoRunConfiguration *mrc =
+ qobject_cast<MaemoRunConfiguration *> (target->activeRunConfiguration());
+ if (!mrc)
+ return false;
+ Qt4BuildConfiguration *bc
+ = qobject_cast<Qt4BuildConfiguration *>(target->activeBuildConfiguration());
+ if (!bc)
+ return false;
+ QtSupport::BaseQtVersion *version = bc->qtVersion();
+ if (!version || !m_runtimes.value(version->uniqueId(), MaemoQemuRuntime()).isValid())
+ return false;
+
+ if (qtVersion)
+ *qtVersion = version;
+ const MaemoDeviceConfig::ConstPtr &config = mrc->deviceConfig();
+ return config && config->type() == MaemoDeviceConfig::Emulator;
+}
+
+void MaemoQemuManager::notify(const QList<int> uniqueIds)
+{
+ qtVersionsChanged(uniqueIds);
+ environmentChanged(); // to toggle the start button
+}
+
+void MaemoQemuManager::toggleDeviceConnections(MaemoRunConfiguration *mrc,
+ bool _connect)
+{
+ if (!mrc)
+ return;
+
+ if (_connect) { // handle device configuration changes
+ connect(mrc, SIGNAL(deviceConfigurationChanged(ProjectExplorer::Target*)),
+ this, SLOT(deviceConfigurationChanged(ProjectExplorer::Target*)));
+ } else {
+ disconnect(mrc, SIGNAL(deviceConfigurationChanged(ProjectExplorer::Target*)),
+ this, SLOT(deviceConfigurationChanged(ProjectExplorer::Target*)));
+ }
+}
+
+void MaemoQemuManager::showOrHideQemuButton()
+{
+ const bool showButton = !m_runtimes.isEmpty() && sessionHasMaemoTarget();
+ if (!showButton)
+ terminateRuntime();
+ m_qemuAction->setVisible(showButton);
+}