/************************************************************************** ** ** 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 "application.h" #include "applicationmanager.h" #include "displaywidget.h" #include "phononmanager.h" #include "widgetmanager.h" #include "widget.h" #include "deviceitem.h" #include #include #include #include #include Application::Application(const QString &name, int id, qint64 pid, QLocalSocket *s, ApplicationManager *m) : m_name(name) , m_id(id) , m_processId(pid) , receiveSocket(s) , sendSocket(0) , applicationManager(m) , mPhononManager(0) { readData(); // maybe there's already data to read connect(receiveSocket, SIGNAL(readyRead()), this, SLOT(readData())); connect(receiveSocket, SIGNAL(disconnected()), this, SLOT(disconnect())); sendSocket = new QLocalSocket(this); sendSocket->connectToServer(QtSimulatorPrivate::qt_applicationServerName(pid)); sendSocket->waitForConnected(); // don't check return value QtSimulatorPrivate::qt_registerUserTypes(); } Application::~Application() { receiveSocket->disconnectFromServer(); receiveSocket->deleteLater(); } void Application::readData() { readBuffer += receiveSocket->readAll(); forever { QtSimulatorPrivate::IncomingRemoteMetacall rpc; if (rpc.read(&readBuffer)) { bool callWasHandled = false; callWasHandled = rpc.call(receiveSocket, this) || rpc.call(receiveSocket, mWidgetManager); if (!callWasHandled) { mPhononManager->setCurrentApplication(this); callWasHandled = rpc.call(receiveSocket, mPhononManager); } if (callWasHandled) { continue; } qWarning("Ignoring a call to %s, No such slot in the receiving objects.", rpc.signature().data()); } break; } } /** * Tries hard to kill the application by regularly sending quit messages. */ void Application::kill() { QtSimulatorPrivate::RemoteMetacall::call(sendSocket, QtSimulatorPrivate::NoSync, "killApplication"); } void Application::setPhononManager(PhononManager *manager) { mPhononManager = manager; } void Application::setWidgetManager(WidgetManager *wm) { mWidgetManager = wm; } DisplayWidget* Application::display() const { return mWidgetManager->display(); } QtSimulatorPrivate::NewWindowInfo Application::createWidget(int parentId, QRect geometry, QString title) { return mWidgetManager->create( parentId, geometry, title, this); } QtSimulatorPrivate::DisplayInfo Application::displayInfo() { return applicationManager->displayInfo(); } QString Application::systemFontDirectory() { return applicationManager->fontDirectory(); } void Application::disconnect() { this->deleteLater(); applicationManager->unregisterApplication(m_id); } void Application::updateActionFromVariantList(QAction* action, const QVariantList& list) { action->setAutoRepeat(list.at(0).toBool()); QIcon icon = list.at(1).value(); // ### don't set icons for now. Something's wrong with it. //action->setIcon(icon); //action->setIconText(list.at(2).toString()); action->setCheckable(list.at(3).toBool()); action->setChecked(list.at(4).toBool()); action->setEnabled(list.at(5).toBool()); action->setIconVisibleInMenu(list.at(6).toBool()); action->setSeparator(list.at(7).toBool()); action->setVisible(list.at(8).toBool()); QString text = list.at(9).toString(); action->setText(text); action->setIconVisibleInMenu(list.at(10).toBool()); QtSimulatorPrivate::RemotePointer remoteMenu = list.at(11).value(); if (remoteMenu) { QMenu* menu = provideMenu(remoteMenu); action->setMenu(menu); } } Application::SimulatorActionData Application::variantListToSimulatorActionData(QVariantList& list, bool createAction) { SimulatorActionData item; QVariant remotePointerVariant = list.at(12); item.remotePointer = remotePointerVariant.value(); if (createAction) { item.action = new QAction(0); item.action->setProperty("remotePointer", remotePointerVariant); connect(item.action, SIGNAL(triggered()), SLOT(onMenuActionTriggered())); updateActionFromVariantList(item.action, list); } else { item.action = 0; } return item; } void Application::registerMenuBar(QtSimulatorPrivate::RemotePointer remoteMenuBar, int widgetId) { //qDebug("Application::registerMenuBar"); QMenuBar* menuBar = new QMenuBar(); mMenuBarHash.insert(remoteMenuBar, menuBar); menuBar->setNativeMenuBar(false); Widget* widget = mWidgetManager->widgetForId(widgetId); if (widget) widget->setMenuBar(menuBar); } void Application::unregisterMenuBar(QtSimulatorPrivate::RemotePointer remoteMenuBar, int widgetId) { Widget* widget = mWidgetManager->widgetForId(widgetId); if (widget) widget->setMenuBar(0); QMenuBar* menuBar = mMenuBarHash.value(remoteMenuBar, 0); delete menuBar; mMenuBarHash.remove(remoteMenuBar); } void Application::reparentMenuBar(QtSimulatorPrivate::RemotePointer remoteMenuBar, int oldWidgetId, int newWidgetId) { //qDebug("Application::reparentMenuBar from %d to %d", oldWidgetId, newWidgetId); QMenuBar* menuBar = mMenuBarHash.value(remoteMenuBar, 0); Widget* oldWidget = mWidgetManager->widgetForId(oldWidgetId); Widget* newWidget = mWidgetManager->widgetForId(newWidgetId); if (oldWidget) oldWidget->setMenuBar(0); if (newWidget) newWidget->setMenuBar(menuBar); } void Application::menuBarAddAction(QtSimulatorPrivate::RemotePointer remoteMenuBar, QVariantList actionData, QtSimulatorPrivate::RemotePointer remoteBeforeAction) { //qDebug("Application::menuBarAddAction %p", remoteMenuBar.ptr); QMenuBar* menuBar = mMenuBarHash.value(remoteMenuBar, 0); if (!menuBar) { qWarning("Application::menuBarAddAction can't find menuBar."); return; } QAction *beforeAction; beforeAction = mActionHash.value(remoteBeforeAction, 0); SimulatorActionData item = variantListToSimulatorActionData(actionData); mActionHash.insert(item.remotePointer, item.action); menuBar->insertAction(beforeAction, item.action); } void Application::menuBarSyncAction(QVariantList actionData) { //qDebug("Application::menuBarSyncAction"); SimulatorActionData item = variantListToSimulatorActionData(actionData, false); QAction* action = mActionHash.value(item.remotePointer, 0); if (!action) { qWarning("Application::menuBarSyncAction can't find action."); return; } updateActionFromVariantList(action, actionData); } void Application::menuBarRemoveAction(QtSimulatorPrivate::RemotePointer remoteMenuBar, QtSimulatorPrivate::RemotePointer remoteAction) { QMenuBar* menuBar = mMenuBarHash.value(remoteMenuBar, 0); if (!menuBar) { qWarning("Application::menuBarRemoveAction can't find menuBar."); return; } QAction* action = mActionHash.value(remoteAction, 0); if (!action) { qWarning("Application::menuBarRemoveAction can't find action."); return; } mActionHash.remove(remoteAction); menuBar->removeAction(action); delete action; } void Application::setSymbianSoftKeys(QtSimulatorPrivate::RemoteQAction positive, QtSimulatorPrivate::RemoteQAction negative) { mSymbianPositiveSoftKey = positive; mSymbianNegativeSoftKey = negative; mWidgetManager->updateSymbianSoftKeys(); } QMenu* Application::provideMenu(QtSimulatorPrivate::RemotePointer remoteMenu) { QMenu* menu = mMenuHash.value(remoteMenu, 0); if (!menu) { menu = new QMenu; mMenuHash.insert(remoteMenu, menu); } return menu; } void Application::destroyMenu(QtSimulatorPrivate::RemotePointer remoteMenu) { QMenu* menu = mMenuHash.value(remoteMenu, 0); if (!menu) { qWarning("Application::destroyMenu can't find menu."); return; } mMenuHash.remove(remoteMenu); delete menu; } void Application::menuAddAction(QtSimulatorPrivate::RemotePointer remoteMenu, QVariantList actionData, QtSimulatorPrivate::RemotePointer remoteBeforeAction) { QMenu* menu = provideMenu(remoteMenu); if (!menu) { qWarning("Application::menuAddAction can't find menu."); return; } QAction* beforeAction = mActionHash.value(remoteBeforeAction, 0); SimulatorActionData smi = variantListToSimulatorActionData(actionData); menu->insertAction(beforeAction, smi.action); mActionHash.insert(smi.remotePointer, smi.action); } void Application::menuSyncAction(QVariantList actionData) { SimulatorActionData smi = variantListToSimulatorActionData(actionData, false); QAction* action = mActionHash.value(smi.remotePointer, 0); if (!action) { qWarning("Application::menuSyncAction can't find action."); return; } updateActionFromVariantList(action, actionData); } void Application::menuRemoveAction(QtSimulatorPrivate::RemotePointer remoteMenu, QtSimulatorPrivate::RemotePointer remoteAction) { QMenu* menu = provideMenu(remoteMenu); if (!menu) { qWarning("Application::menuRemoveAction can't find menu."); return; } QAction* action = mActionHash.value(remoteAction, 0); if (!action) { qWarning("Application::menuRemoveAction can't find action."); return; } menu->removeAction(action); mActionHash.remove(remoteAction); delete action; } void Application::onMenuActionTriggered() { QAction* action = qobject_cast(sender()); Q_ASSERT(action); if (!action) return; QVariant v = action->property("remotePointer"); if (v.isNull()) return; QtSimulatorPrivate::RemoteMetacall::call(sendSocket, QtSimulatorPrivate::NoSync, "triggerAction", v); } QString Application::symbianSoftKeyText(int buttonNr) const { if (buttonNr == 0) return mSymbianPositiveSoftKey.text; else if (buttonNr == 1) return mSymbianNegativeSoftKey.text; else return QString(); } void Application::triggerSymbianSoftKeyAction(int buttonNr) { QtSimulatorPrivate::RemotePointer actionPtr; if (buttonNr == 0) actionPtr = mSymbianPositiveSoftKey.ptr; else if (buttonNr == 1) actionPtr = mSymbianNegativeSoftKey.ptr; if (!actionPtr) return; QtSimulatorPrivate::RemoteMetacall::call(sendSocket, QtSimulatorPrivate::NoSync, "triggerSymbianSoftKeyAction", actionPtr); }