Salome HOME
bos #18834 [CEA] Restore object browser state when switching from light module to...
[modules/gui.git] / src / HelpBrowser / qtsingleapplication.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the Qt Solutions component.
7 **
8 ** $QT_BEGIN_LICENSE:BSD$
9 ** You may use this file under the terms of the BSD license as follows:
10 **
11 ** "Redistribution and use in source and binary forms, with or without
12 ** modification, are permitted provided that the following conditions are
13 ** met:
14 **   * Redistributions of source code must retain the above copyright
15 **     notice, this list of conditions and the following disclaimer.
16 **   * Redistributions in binary form must reproduce the above copyright
17 **     notice, this list of conditions and the following disclaimer in
18 **     the documentation and/or other materials provided with the
19 **     distribution.
20 **   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
21 **     of its contributors may be used to endorse or promote products derived
22 **     from this software without specific prior written permission.
23 **
24 **
25 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40
41
42 #include "qtsingleapplication.h"
43 #include "qtlocalpeer.h"
44 #include <QWidget>
45
46
47 /*!
48     \class QtSingleApplication qtsingleapplication.h
49     \brief The QtSingleApplication class provides an API to detect and
50     communicate with running instances of an application.
51
52     This class allows you to create applications where only one
53     instance should be running at a time. I.e., if the user tries to
54     launch another instance, the already running instance will be
55     activated instead. Another usecase is a client-server system,
56     where the first started instance will assume the role of server,
57     and the later instances will act as clients of that server.
58
59     By default, the full path of the executable file is used to
60     determine whether two processes are instances of the same
61     application. You can also provide an explicit identifier string
62     that will be compared instead.
63
64     The application should create the QtSingleApplication object early
65     in the startup phase, and call isRunning() to find out if another
66     instance of this application is already running. If isRunning()
67     returns false, it means that no other instance is running, and
68     this instance has assumed the role as the running instance. In
69     this case, the application should continue with the initialization
70     of the application user interface before entering the event loop
71     with exec(), as normal.
72
73     The messageReceived() signal will be emitted when the running
74     application receives messages from another instance of the same
75     application. When a message is received it might be helpful to the
76     user to raise the application so that it becomes visible. To
77     facilitate this, QtSingleApplication provides the
78     setActivationWindow() function and the activateWindow() slot.
79
80     If isRunning() returns true, another instance is already
81     running. It may be alerted to the fact that another instance has
82     started by using the sendMessage() function. Also data such as
83     startup parameters (e.g. the name of the file the user wanted this
84     new instance to open) can be passed to the running instance with
85     this function. Then, the application should terminate (or enter
86     client mode).
87
88     If isRunning() returns true, but sendMessage() fails, that is an
89     indication that the running instance is frozen.
90
91     Here's an example that shows how to convert an existing
92     application to use QtSingleApplication. It is very simple and does
93     not make use of all QtSingleApplication's functionality (see the
94     examples for that).
95
96     \code
97     // Original
98     int main(int argc, char **argv)
99     {
100         QApplication app(argc, argv);
101
102         MyMainWidget mmw;
103         mmw.show();
104         return app.exec();
105     }
106
107     // Single instance
108     int main(int argc, char **argv)
109     {
110         QtSingleApplication app(argc, argv);
111
112         if (app.isRunning())
113             return !app.sendMessage(someDataString);
114
115         MyMainWidget mmw;
116         app.setActivationWindow(&mmw);
117         mmw.show();
118         return app.exec();
119     }
120     \endcode
121
122     Once this QtSingleApplication instance is destroyed (normally when
123     the process exits or crashes), when the user next attempts to run the
124     application this instance will not, of course, be encountered. The
125     next instance to call isRunning() or sendMessage() will assume the
126     role as the new running instance.
127
128     For console (non-GUI) applications, QtSingleCoreApplication may be
129     used instead of this class, to avoid the dependency on the QtGui
130     library.
131
132     \sa QtSingleCoreApplication
133 */
134
135
136 void QtSingleApplication::sysInit(const QString &appId)
137 {
138     actWin = 0;
139     peer = new QtLocalPeer(this, appId);
140     connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&)));
141 }
142
143
144 /*!
145     Creates a QtSingleApplication object. The application identifier
146     will be QCoreApplication::applicationFilePath(). \a argc, \a
147     argv, and \a GUIenabled are passed on to the QAppliation constructor.
148
149     If you are creating a console application (i.e. setting \a
150     GUIenabled to false), you may consider using
151     QtSingleCoreApplication instead.
152 */
153
154 QtSingleApplication::QtSingleApplication(int &argc, char **argv, bool GUIenabled)
155     : QApplication(argc, argv, GUIenabled)
156 {
157     sysInit();
158 }
159
160
161 /*!
162     Creates a QtSingleApplication object with the application
163     identifier \a appId. \a argc and \a argv are passed on to the
164     QAppliation constructor.
165 */
166
167 QtSingleApplication::QtSingleApplication(const QString &appId, int &argc, char **argv)
168     : QApplication(argc, argv)
169 {
170     sysInit(appId);
171 }
172
173 /*!
174     Returns true if another instance of this application is running;
175     otherwise false.
176
177     This function does not find instances of this application that are
178     being run by a different user (on Windows: that are running in
179     another session).
180
181     \sa sendMessage()
182 */
183
184 bool QtSingleApplication::isRunning()
185 {
186     return peer->isClient();
187 }
188
189
190 /*!
191     Tries to send the text \a message to the currently running
192     instance. The QtSingleApplication object in the running instance
193     will emit the messageReceived() signal when it receives the
194     message.
195
196     This function returns true if the message has been sent to, and
197     processed by, the current instance. If there is no instance
198     currently running, or if the running instance fails to process the
199     message within \a timeout milliseconds, this function return false.
200
201     \sa isRunning(), messageReceived()
202 */
203 bool QtSingleApplication::sendMessage(const QString &message, int timeout)
204 {
205     return peer->sendMessage(message, timeout);
206 }
207
208
209 /*!
210     Returns the application identifier. Two processes with the same
211     identifier will be regarded as instances of the same application.
212 */
213 QString QtSingleApplication::id() const
214 {
215     return peer->applicationId();
216 }
217
218
219 /*!
220   Sets the activation window of this application to \a aw. The
221   activation window is the widget that will be activated by
222   activateWindow(). This is typically the application's main window.
223
224   If \a activateOnMessage is true (the default), the window will be
225   activated automatically every time a message is received, just prior
226   to the messageReceived() signal being emitted.
227
228   \sa activateWindow(), messageReceived()
229 */
230
231 void QtSingleApplication::setActivationWindow(QWidget* aw, bool activateOnMessage)
232 {
233     actWin = aw;
234     if (activateOnMessage)
235         connect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow()));
236     else
237         disconnect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow()));
238 }
239
240
241 /*!
242     Returns the applications activation window if one has been set by
243     calling setActivationWindow(), otherwise returns 0.
244
245     \sa setActivationWindow()
246 */
247 QWidget* QtSingleApplication::activationWindow() const
248 {
249     return actWin;
250 }
251
252
253 /*!
254   De-minimizes, raises, and activates this application's activation window.
255   This function does nothing if no activation window has been set.
256
257   This is a convenience function to show the user that this
258   application instance has been activated when he has tried to start
259   another instance.
260
261   This function should typically be called in response to the
262   messageReceived() signal. By default, that will happen
263   automatically, if an activation window has been set.
264
265   \sa setActivationWindow(), messageReceived(), initialize()
266 */
267 void QtSingleApplication::activateWindow()
268 {
269     if (actWin) {
270         actWin->setWindowState(actWin->windowState() & ~Qt::WindowMinimized);
271         actWin->raise();
272         actWin->activateWindow();
273     }
274 }
275
276
277 /*!
278     \fn void QtSingleApplication::messageReceived(const QString& message)
279
280     This signal is emitted when the current instance receives a \a
281     message from another instance of this application.
282
283     \sa sendMessage(), setActivationWindow(), activateWindow()
284 */
285
286
287 /*!
288     \fn void QtSingleApplication::initialize(bool dummy = true)
289
290     \obsolete
291 */