diff options
author | Orgad Shaneh <orgad.shaneh@audiocodes.com> | 2013-03-11 18:15:49 +0200 |
---|---|---|
committer | Orgad Shaneh <orgads@gmail.com> | 2013-03-15 12:24:52 +0100 |
commit | 14e35b5dc4d4cc346e65d3b87940d6f584b69bb3 (patch) | |
tree | 42b4eaf7c642ba72d0196de80b682fd6717f01b4 | |
parent | 225c21a0f22cbba2b2dc6a4d647bea93918e3134 (diff) |
Client: Block until editor is closed
Change-Id: I06bd4425008103be3a4c8f64b6dff8f7df30c552
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@digia.com>
Reviewed-by: Eike Ziller <eike.ziller@digia.com>
-rw-r--r-- | src/app/main.cpp | 14 | ||||
-rw-r--r-- | src/libs/extensionsystem/iplugin.cpp | 13 | ||||
-rw-r--r-- | src/libs/extensionsystem/iplugin.h | 2 | ||||
-rw-r--r-- | src/libs/extensionsystem/pluginmanager.cpp | 15 | ||||
-rw-r--r-- | src/libs/extensionsystem/pluginmanager.h | 2 | ||||
-rw-r--r-- | src/plugins/coreplugin/coreplugin.cpp | 6 | ||||
-rw-r--r-- | src/plugins/coreplugin/coreplugin.h | 2 | ||||
-rw-r--r-- | src/plugins/coreplugin/mainwindow.cpp | 40 | ||||
-rw-r--r-- | src/plugins/coreplugin/mainwindow.h | 3 | ||||
-rw-r--r-- | src/plugins/debugger/debuggerplugin.cpp | 3 | ||||
-rw-r--r-- | src/plugins/debugger/debuggerplugin.h | 2 | ||||
-rw-r--r-- | src/shared/qtsingleapplication/qtlocalpeer.cpp | 7 | ||||
-rw-r--r-- | src/shared/qtsingleapplication/qtlocalpeer.h | 4 | ||||
-rw-r--r-- | src/shared/qtsingleapplication/qtsingleapplication.cpp | 22 | ||||
-rw-r--r-- | src/shared/qtsingleapplication/qtsingleapplication.h | 4 |
15 files changed, 100 insertions, 39 deletions
diff --git a/src/app/main.cpp b/src/app/main.cpp index 71d00d320b..1db6fc2bda 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -71,7 +71,8 @@ static const char fixedOptionsC[] = " -version Display program version\n" " -client Attempt to connect to already running first instance\n" " -settingspath <path> Override the default path where user settings are stored\n" -" -pid <pid> Attempt to connect to instance given by pid\n"; +" -pid <pid> Attempt to connect to instance given by pid\n" +" -block Block until editor is closed\n"; static const char HELP_OPTION1[] = "-h"; @@ -82,6 +83,7 @@ static const char VERSION_OPTION[] = "-version"; static const char CLIENT_OPTION[] = "-client"; static const char SETTINGS_OPTION[] = "-settingspath"; static const char PID_OPTION[] = "-pid"; +static const char BLOCK_OPTION[] = "-block"; typedef QList<PluginSpec *> PluginSpecSet; @@ -409,6 +411,7 @@ int main(int argc, char **argv) appOptions.insert(QLatin1String(VERSION_OPTION), false); appOptions.insert(QLatin1String(CLIENT_OPTION), false); appOptions.insert(QLatin1String(PID_OPTION), true); + appOptions.insert(QLatin1String(BLOCK_OPTION), false); QString errorMessage; if (!PluginManager::parseOptions(arguments, appOptions, &foundAppOptions, &errorMessage)) { displayError(errorMessage); @@ -456,7 +459,10 @@ int main(int argc, char **argv) pid = tmpPid; } - if (app.isRunning() && (pid != -1 || foundAppOptions.contains(QLatin1String(CLIENT_OPTION)))) { + bool isBlock = foundAppOptions.contains(QLatin1String(BLOCK_OPTION)); + if (app.isRunning() && (pid != -1 || isBlock + || foundAppOptions.contains(QLatin1String(CLIENT_OPTION)))) { + app.setBlock(isBlock); if (app.sendMessage(PluginManager::serializedArguments(), 5000 /*timeout*/, pid)) return 0; @@ -489,8 +495,8 @@ int main(int argc, char **argv) // Set up lock and remote arguments. app.initialize(); - QObject::connect(&app, SIGNAL(messageReceived(QString)), - &pluginManager, SLOT(remoteArguments(QString))); + QObject::connect(&app, SIGNAL(messageReceived(QString,QObject*)), + &pluginManager, SLOT(remoteArguments(QString,QObject*))); QObject::connect(&app, SIGNAL(fileOpenRequest(QString)), coreplugin->plugin(), SLOT(fileOpenRequest(QString))); diff --git a/src/libs/extensionsystem/iplugin.cpp b/src/libs/extensionsystem/iplugin.cpp index 062e9efdee..b3cda5f508 100644 --- a/src/libs/extensionsystem/iplugin.cpp +++ b/src/libs/extensionsystem/iplugin.cpp @@ -158,6 +158,19 @@ */ /*! + \fn QObject *IPlugin::remoteCommand(const QStringList &options, const QStringList &arguments) + \brief When \QC is executed with the -client argument while already another instance of \QC + is running, this method of plugins is called in the running instance. + + Plugin-specific arguments are passed in \a options, while the rest of the + arguments are passed in \a arguments. + + \returns a QObject that blocks the command until it is destroyed, if -block is used. + + \sa PluginManager::serializedArguments() +*/ + +/*! \fn void IPlugin::asynchronousShutdownFinished() Sent by the plugin implementation after a asynchronous shutdown is ready to proceed with the shutdown sequence. diff --git a/src/libs/extensionsystem/iplugin.h b/src/libs/extensionsystem/iplugin.h index 1a49e351ac..1b3e537b24 100644 --- a/src/libs/extensionsystem/iplugin.h +++ b/src/libs/extensionsystem/iplugin.h @@ -64,7 +64,7 @@ public: virtual void extensionsInitialized() = 0; virtual bool delayedInitialize() { return false; } virtual ShutdownFlag aboutToShutdown() { return SynchronousShutdown; } - virtual void remoteCommand(const QStringList & /* options */, const QStringList & /* arguments */) { } + virtual QObject *remoteCommand(const QStringList & /* options */, const QStringList & /* arguments */) { return 0; } PluginSpec *pluginSpec() const; diff --git a/src/libs/extensionsystem/pluginmanager.cpp b/src/libs/extensionsystem/pluginmanager.cpp index 8829f757e7..63208da057 100644 --- a/src/libs/extensionsystem/pluginmanager.cpp +++ b/src/libs/extensionsystem/pluginmanager.cpp @@ -532,13 +532,16 @@ static QStringList subList(const QStringList &in, const QString &key) } /*! - \fn PluginManager::remoteArguments(const QString &argument) + \fn PluginManager::remoteArguments(const QString &argument, QObject *socket) Parses the options encoded by serializedArguments() const and passes them on to the respective plugins along with the arguments. + + \a socket is passed for disconnecting the peer when the operation is done (for example, + document is closed) for supporting the -block flag. */ -void PluginManager::remoteArguments(const QString &serializedArgument) +void PluginManager::remoteArguments(const QString &serializedArgument, QObject *socket) { if (serializedArgument.isEmpty()) return; @@ -547,9 +550,15 @@ void PluginManager::remoteArguments(const QString &serializedArgument) foreach (const PluginSpec *ps, plugins()) { if (ps->state() == PluginSpec::Running) { const QStringList pluginOptions = subList(serializedArguments, QLatin1Char(':') + ps->name()); - ps->plugin()->remoteCommand(pluginOptions, arguments); + QObject *socketParent = ps->plugin()->remoteCommand(pluginOptions, arguments); + if (socketParent && socket) { + socket->setParent(socketParent); + socket = 0; + } } } + if (socket) + delete socket; } /*! diff --git a/src/libs/extensionsystem/pluginmanager.h b/src/libs/extensionsystem/pluginmanager.h index 41de4c5591..e20159abfc 100644 --- a/src/libs/extensionsystem/pluginmanager.h +++ b/src/libs/extensionsystem/pluginmanager.h @@ -137,7 +137,7 @@ signals: void initializationDone(); public slots: - void remoteArguments(const QString &serializedArguments); + void remoteArguments(const QString &serializedArguments, QObject *socket); void shutdown(); private slots: diff --git a/src/plugins/coreplugin/coreplugin.cpp b/src/plugins/coreplugin/coreplugin.cpp index 25ebd22851..d170ddb648 100644 --- a/src/plugins/coreplugin/coreplugin.cpp +++ b/src/plugins/coreplugin/coreplugin.cpp @@ -119,10 +119,12 @@ bool CorePlugin::delayedInitialize() return true; } -void CorePlugin::remoteCommand(const QStringList & /* options */, const QStringList &args) +QObject *CorePlugin::remoteCommand(const QStringList & /* options */, const QStringList &args) { - m_mainWindow->openFiles(args, Core::ICore::OpenFilesFlags(ICore::SwitchMode | ICore::CanContainLineNumbers)); + IDocument *res = m_mainWindow->openFiles( + args, ICore::OpenFilesFlags(ICore::SwitchMode | ICore::CanContainLineNumbers)); m_mainWindow->activateWindow(); + return res; } void CorePlugin::fileOpenRequest(const QString &f) diff --git a/src/plugins/coreplugin/coreplugin.h b/src/plugins/coreplugin/coreplugin.h index d7fbef0f2a..b9ca64b855 100644 --- a/src/plugins/coreplugin/coreplugin.h +++ b/src/plugins/coreplugin/coreplugin.h @@ -52,7 +52,7 @@ public: void extensionsInitialized(); bool delayedInitialize(); ShutdownFlag aboutToShutdown(); - void remoteCommand(const QStringList & /* options */, const QStringList &args); + QObject *remoteCommand(const QStringList & /* options */, const QStringList &args); public slots: void fileOpenRequest(const QString&); diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp index e7e2abc6f9..862e6e77d3 100644 --- a/src/plugins/coreplugin/mainwindow.cpp +++ b/src/plugins/coreplugin/mainwindow.cpp @@ -831,31 +831,51 @@ static IDocumentFactory *findDocumentFactory(const QList<IDocumentFactory*> &fil return 0; } -// opens either an editor or loads a project -void MainWindow::openFiles(const QStringList &fileNames, ICore::OpenFilesFlags flags) +/*! Either opens \a fileNames with editors or loads a project. + * + * \a flags can be used to stop on first failure, indicate that a file name + * might include line numbers and/or switch mode to edit mode. + * + * \returns the first opened document. Required to support the -block flag + * for client mode. + * + * \sa IPlugin::remoteArguments() + */ +IDocument *MainWindow::openFiles(const QStringList &fileNames, ICore::OpenFilesFlags flags) { QList<IDocumentFactory*> nonEditorFileFactories = getNonEditorDocumentFactories(); + IDocument *res = 0; foreach (const QString &fileName, fileNames) { const QFileInfo fi(fileName); const QString absoluteFilePath = fi.absoluteFilePath(); if (IDocumentFactory *documentFactory = findDocumentFactory(nonEditorFileFactories, mimeDatabase(), fi)) { - Core::IDocument *document = documentFactory->open(absoluteFilePath); - if (!document && (flags & ICore::StopOnLoadFail)) - return; - if (document && (flags & ICore::SwitchMode)) - ModeManager::activateMode(Id(Core::Constants::MODE_EDIT)); + IDocument *document = documentFactory->open(absoluteFilePath); + if (!document) { + if (flags & ICore::StopOnLoadFail) + return res; + } else { + if (!res) + res = document; + if (flags & ICore::SwitchMode) + ModeManager::activateMode(Id(Core::Constants::MODE_EDIT)); + } } else { QFlags<EditorManager::OpenEditorFlag> emFlags; if (flags & ICore::SwitchMode) emFlags = EditorManager::ModeSwitch; if (flags & ICore::CanContainLineNumbers) emFlags |= EditorManager::CanContainLineNumber; - Core::IEditor *editor = EditorManager::openEditor(absoluteFilePath, Id(), emFlags); - if (!editor && (flags & ICore::StopOnLoadFail)) - return; + IEditor *editor = EditorManager::openEditor(absoluteFilePath, Id(), emFlags); + if (!editor) { + if (flags & ICore::StopOnLoadFail) + return res; + } else if (!res) { + res = editor->document(); + } } } + return res; } void MainWindow::setFocusToEditor() diff --git a/src/plugins/coreplugin/mainwindow.h b/src/plugins/coreplugin/mainwindow.h index 97a4447d9d..0fc5c4172d 100644 --- a/src/plugins/coreplugin/mainwindow.h +++ b/src/plugins/coreplugin/mainwindow.h @@ -53,6 +53,7 @@ class EditorManager; class ExternalToolManager; class DocumentManager; class HelpManager; +class IDocument; class IWizard; class MessageManager; class MimeDatabase; @@ -95,7 +96,7 @@ public: void removeContextObject(IContext *contex); void resetContext(); - void openFiles(const QStringList &fileNames, ICore::OpenFilesFlags flags); + Core::IDocument *openFiles(const QStringList &fileNames, ICore::OpenFilesFlags flags); Core::ActionManager *actionManager() const; Core::MessageManager *messageManager() const; diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 3a2a9175e4..8227d42683 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -3441,10 +3441,11 @@ IPlugin::ShutdownFlag DebuggerPlugin::aboutToShutdown() return SynchronousShutdown; } -void DebuggerPlugin::remoteCommand(const QStringList &options, +QObject *DebuggerPlugin::remoteCommand(const QStringList &options, const QStringList &list) { theDebuggerCore->remoteCommand(options, list); + return 0; } DebuggerRunControl *DebuggerPlugin::createDebugger diff --git a/src/plugins/debugger/debuggerplugin.h b/src/plugins/debugger/debuggerplugin.h index 73e221a999..1c3925486b 100644 --- a/src/plugins/debugger/debuggerplugin.h +++ b/src/plugins/debugger/debuggerplugin.h @@ -71,7 +71,7 @@ public: private: // IPlugin implementation. bool initialize(const QStringList &arguments, QString *errorMessage); - void remoteCommand(const QStringList &options, const QStringList &arguments); + QObject *remoteCommand(const QStringList &options, const QStringList &arguments); ShutdownFlag aboutToShutdown(); void extensionsInitialized(); diff --git a/src/shared/qtsingleapplication/qtlocalpeer.cpp b/src/shared/qtsingleapplication/qtlocalpeer.cpp index 6410db3195..c1c68938af 100644 --- a/src/shared/qtsingleapplication/qtlocalpeer.cpp +++ b/src/shared/qtsingleapplication/qtlocalpeer.cpp @@ -99,7 +99,7 @@ bool QtLocalPeer::isClient() return false; } -bool QtLocalPeer::sendMessage(const QString &message, int timeout) +bool QtLocalPeer::sendMessage(const QString &message, int timeout, bool block) { if (!isClient()) return false; @@ -129,6 +129,8 @@ bool QtLocalPeer::sendMessage(const QString &message, int timeout) bool res = socket.waitForBytesWritten(timeout); res &= socket.waitForReadyRead(timeout); // wait for ack res &= (socket.read(qstrlen(ack)) == ack); + if (block) // block until peer disconnects + socket.waitForDisconnected(-1); return res; } @@ -168,8 +170,7 @@ void QtLocalPeer::receiveConnection() QString message = QString::fromUtf8(uMsg.constData(), uMsg.size()); socket->write(ack, qstrlen(ack)); socket->waitForBytesWritten(1000); - delete socket; - emit messageReceived(message); // ##(might take a long time to return) + emit messageReceived(message, socket); // ##(might take a long time to return) } } // namespace SharedTools diff --git a/src/shared/qtsingleapplication/qtlocalpeer.h b/src/shared/qtsingleapplication/qtlocalpeer.h index 14d2d14806..e721a05de9 100644 --- a/src/shared/qtsingleapplication/qtlocalpeer.h +++ b/src/shared/qtsingleapplication/qtlocalpeer.h @@ -42,12 +42,12 @@ class QtLocalPeer : public QObject public: explicit QtLocalPeer(QObject *parent = 0, const QString &appId = QString()); bool isClient(); - bool sendMessage(const QString &message, int timeout); + bool sendMessage(const QString &message, int timeout, bool block); QString applicationId() const { return id; } Q_SIGNALS: - void messageReceived(const QString &message); + void messageReceived(const QString &message, QObject *socket); protected Q_SLOTS: void receiveConnection(); diff --git a/src/shared/qtsingleapplication/qtsingleapplication.cpp b/src/shared/qtsingleapplication/qtsingleapplication.cpp index 8fcf215279..f00ebea53c 100644 --- a/src/shared/qtsingleapplication/qtsingleapplication.cpp +++ b/src/shared/qtsingleapplication/qtsingleapplication.cpp @@ -38,10 +38,11 @@ namespace SharedTools { void QtSingleApplication::sysInit(const QString &appId) { actWin = 0; + block = false; firstPeer = new QtLocalPeer(this, appId); - connect(firstPeer, SIGNAL(messageReceived(QString)), SIGNAL(messageReceived(QString))); + connect(firstPeer, SIGNAL(messageReceived(QString,QObject*)), SIGNAL(messageReceived(QString,QObject*))); pidPeer = new QtLocalPeer(this, appId + QLatin1Char('-') + QString::number(QCoreApplication::applicationPid(), 10)); - connect(pidPeer, SIGNAL(messageReceived(QString)), SIGNAL(messageReceived(QString))); + connect(pidPeer, SIGNAL(messageReceived(QString,QObject*)), SIGNAL(messageReceived(QString,QObject*))); } @@ -87,10 +88,10 @@ void QtSingleApplication::initialize(bool) bool QtSingleApplication::sendMessage(const QString &message, int timeout, qint64 pid) { if (pid == -1) - return firstPeer->sendMessage(message, timeout); + return firstPeer->sendMessage(message, timeout, block); QtLocalPeer peer(this, appId + QLatin1Char('-') + QString::number(pid, 10)); - return peer.sendMessage(message, timeout); + return peer.sendMessage(message, timeout, block); } QString QtSingleApplication::id() const @@ -103,15 +104,20 @@ QString QtSingleApplication::applicationId() const return appId; } +void QtSingleApplication::setBlock(bool value) +{ + block = value; +} + void QtSingleApplication::setActivationWindow(QWidget *aw, bool activateOnMessage) { actWin = aw; if (activateOnMessage) { - connect(firstPeer, SIGNAL(messageReceived(QString)), this, SLOT(activateWindow())); - connect(pidPeer, SIGNAL(messageReceived(QString)), this, SLOT(activateWindow())); + connect(firstPeer, SIGNAL(messageReceived(QString,QObject*)), this, SLOT(activateWindow())); + connect(pidPeer, SIGNAL(messageReceived(QString,QObject*)), this, SLOT(activateWindow())); } else { - disconnect(firstPeer, SIGNAL(messageReceived(QString)), this, SLOT(activateWindow())); - disconnect(pidPeer, SIGNAL(messageReceived(QString)), this, SLOT(activateWindow())); + disconnect(firstPeer, SIGNAL(messageReceived(QString,QObject*)), this, SLOT(activateWindow())); + disconnect(pidPeer, SIGNAL(messageReceived(QString,QObject*)), this, SLOT(activateWindow())); } } diff --git a/src/shared/qtsingleapplication/qtsingleapplication.h b/src/shared/qtsingleapplication/qtsingleapplication.h index 5baebd5c9a..47f290a925 100644 --- a/src/shared/qtsingleapplication/qtsingleapplication.h +++ b/src/shared/qtsingleapplication/qtsingleapplication.h @@ -50,6 +50,7 @@ public: bool event(QEvent *event); QString applicationId() const; + void setBlock(bool value); public Q_SLOTS: bool sendMessage(const QString &message, int timeout = 5000, qint64 pid = -1); @@ -61,7 +62,7 @@ public: // end obsolete methods Q_SIGNALS: - void messageReceived(const QString &message); + void messageReceived(const QString &message, QObject *socket); void fileOpenRequest(const QString &file); private: @@ -70,6 +71,7 @@ private: QtLocalPeer *pidPeer; QWidget *actWin; QString appId; + bool block; }; } // namespace SharedTools |