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