aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOrgad Shaneh <orgad.shaneh@audiocodes.com>2013-03-11 18:15:49 +0200
committerOrgad Shaneh <orgads@gmail.com>2013-03-15 12:24:52 +0100
commit14e35b5dc4d4cc346e65d3b87940d6f584b69bb3 (patch)
tree42b4eaf7c642ba72d0196de80b682fd6717f01b4
parent225c21a0f22cbba2b2dc6a4d647bea93918e3134 (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.cpp14
-rw-r--r--src/libs/extensionsystem/iplugin.cpp13
-rw-r--r--src/libs/extensionsystem/iplugin.h2
-rw-r--r--src/libs/extensionsystem/pluginmanager.cpp15
-rw-r--r--src/libs/extensionsystem/pluginmanager.h2
-rw-r--r--src/plugins/coreplugin/coreplugin.cpp6
-rw-r--r--src/plugins/coreplugin/coreplugin.h2
-rw-r--r--src/plugins/coreplugin/mainwindow.cpp40
-rw-r--r--src/plugins/coreplugin/mainwindow.h3
-rw-r--r--src/plugins/debugger/debuggerplugin.cpp3
-rw-r--r--src/plugins/debugger/debuggerplugin.h2
-rw-r--r--src/shared/qtsingleapplication/qtlocalpeer.cpp7
-rw-r--r--src/shared/qtsingleapplication/qtlocalpeer.h4
-rw-r--r--src/shared/qtsingleapplication/qtsingleapplication.cpp22
-rw-r--r--src/shared/qtsingleapplication/qtsingleapplication.h4
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