source: trunk/src/gui/util/qdesktopservices.cpp@ 139

Last change on this file since 139 was 132, checked in by Dmitry A. Kuminov, 16 years ago

gui: Enabled dummy QDesktopServices and FreeType by default.

File size: 11.4 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qdesktopservices.h"
43
44#ifndef QT_NO_DESKTOPSERVICES
45
46#include <qdebug.h>
47
48#if defined(Q_WS_QWS)
49#include "qdesktopservices_qws.cpp"
50#elif defined(Q_WS_X11)
51#include "qdesktopservices_x11.cpp"
52#elif defined(Q_WS_WIN)
53#include "qdesktopservices_win.cpp"
54#elif defined(Q_WS_PM)
55#include "qdesktopservices_pm.cpp"
56#elif defined(Q_WS_MAC)
57#include "qdesktopservices_mac.cpp"
58#endif
59
60#include <qhash.h>
61#include <qobject.h>
62#include <qcoreapplication.h>
63#include <qurl.h>
64#include <qmutex.h>
65
66QT_BEGIN_NAMESPACE
67
68class QOpenUrlHandlerRegistry : public QObject
69{
70 Q_OBJECT
71public:
72 inline QOpenUrlHandlerRegistry() : mutex(QMutex::Recursive) {}
73
74 QMutex mutex;
75
76 struct Handler
77 {
78 QObject *receiver;
79 QByteArray name;
80 };
81 typedef QHash<QString, Handler> HandlerHash;
82 HandlerHash handlers;
83
84public Q_SLOTS:
85 void handlerDestroyed(QObject *handler);
86
87};
88
89Q_GLOBAL_STATIC(QOpenUrlHandlerRegistry, handlerRegistry)
90
91void QOpenUrlHandlerRegistry::handlerDestroyed(QObject *handler)
92{
93 HandlerHash::Iterator it = handlers.begin();
94 while (it != handlers.end()) {
95 if (it->receiver == handler) {
96 it = handlers.erase(it);
97 } else {
98 ++it;
99 }
100 }
101}
102
103/*!
104 \class QDesktopServices
105 \brief The QDesktopServices class provides methods for accessing common desktop services.
106 \since 4.2
107 \ingroup desktop
108
109 Many desktop environments provide services that can be used by applications to
110 perform common tasks, such as opening a web page, in a way that is both consistent
111 and takes into account the user's application preferences.
112
113 This class contains functions that provide simple interfaces to these services
114 that indicate whether they succeeded or failed.
115
116 The openUrl() function is used to open files located at arbitrary URLs in external
117 applications. For URLs that correspond to resources on the local filing system
118 (where the URL scheme is "file"), a suitable application will be used to open the
119 file; otherwise, a web browser will be used to fetch and display the file.
120
121 The user's desktop settings control whether certain executable file types are
122 opened for browsing, or if they are executed instead. Some desktop environments
123 are configured to prevent users from executing files obtained from non-local URLs,
124 or to ask the user's permission before doing so.
125
126 \section1 URL Handlers
127
128 The behavior of the openUrl() function can be customized for individual URL
129 schemes to allow applications to override the default handling behavior for
130 certain types of URLs.
131
132 The dispatch mechanism allows only one custom handler to be used for each URL
133 scheme; this is set using the setUrlHandler() function. Each handler is
134 implemented as a slot which accepts only a single QUrl argument.
135
136 The existing handlers for each scheme can be removed with the
137 unsetUrlHandler() function. This returns the handling behavior for the given
138 scheme to the default behavior.
139
140 This system makes it easy to implement a help system, for example. Help could be
141 provided in labels and text browsers using \gui{help://myapplication/mytopic}
142 URLs, and by registering a handler it becomes possible to display the help text
143 inside the application:
144
145 \snippet doc/src/snippets/code/src_gui_util_qdesktopservices.cpp 0
146
147 If inside the handler you decide that you can't open the requested
148 URL, you can just call QDesktopServices::openUrl() again with the
149 same argument, and it will try to open the URL using the
150 appropriate mechanism for the user's desktop environment.
151
152 \sa QSystemTrayIcon, QProcess
153*/
154
155/*!
156 Opens the given \a url in the appropriate Web browser for the user's desktop
157 environment, and returns true if successful; otherwise returns false.
158
159 If the URL is a reference to a local file (i.e., the URL scheme is "file") then
160 it will be opened with a suitable application instead of a Web browser.
161
162 The following example opens a file on the Windows file system residing on a path
163 that contains spaces:
164
165 \snippet doc/src/snippets/code/src_gui_util_qdesktopservices.cpp 2
166
167 If a \c mailto URL is specified, the user's e-mail client will be used to open a
168 composer window containing the options specified in the URL, similar to the way
169 \c mailto links are handled by a Web browser.
170
171 For example, the following URL contains a recipient (\c{[email protected]}), a
172 subject (\c{Test}), and a message body (\c{Just a test}):
173
174 \snippet doc/src/snippets/code/src_gui_util_qdesktopservices.cpp 1
175
176 \warning Although many e-mail clients can send attachments and are
177 Unicode-aware, the user may have configured their client without these features.
178 Also, certain e-mail clients (e.g., Lotus Notes) have problems with long URLs.
179
180 \sa setUrlHandler()
181*/
182bool QDesktopServices::openUrl(const QUrl &url)
183{
184 QOpenUrlHandlerRegistry *registry = handlerRegistry();
185 QMutexLocker locker(&registry->mutex);
186 static bool insideOpenUrlHandler = false;
187
188 if (!insideOpenUrlHandler) {
189 QOpenUrlHandlerRegistry::HandlerHash::ConstIterator handler = registry->handlers.constFind(url.scheme());
190 if (handler != registry->handlers.constEnd()) {
191 insideOpenUrlHandler = true;
192 bool result = QMetaObject::invokeMethod(handler->receiver, handler->name.constData(), Qt::DirectConnection, Q_ARG(QUrl, url));
193 insideOpenUrlHandler = false;
194 return result; // ### support bool slot return type
195 }
196 }
197
198 bool result;
199 if (url.scheme() == QLatin1String("file"))
200 result = openDocument(url);
201 else
202 result = launchWebBrowser(url);
203
204 return result;
205}
206
207/*!
208 Sets the handler for the given \a scheme to be the handler \a method provided by
209 the \a receiver object.
210
211 This function provides a way to customize the behavior of openUrl(). If openUrl()
212 is called with a URL with the specified \a scheme then the given \a method on the
213 \a receiver object is called instead of QDesktopServices launching an external
214 application.
215
216 The provided method must be implemented as a slot that only accepts a single QUrl
217 argument.
218
219 If setUrlHandler() is used to set a new handler for a scheme which already
220 has a handler, the existing handler is simply replaced with the new one.
221 Since QDesktopServices does not take ownership of handlers, no objects are
222 deleted when a handler is replaced.
223
224 Note that the handler will always be called from within the same thread that
225 calls QDesktopServices::openUrl().
226
227 \sa openUrl(), unsetUrlHandler()
228*/
229void QDesktopServices::setUrlHandler(const QString &scheme, QObject *receiver, const char *method)
230{
231 QOpenUrlHandlerRegistry *registry = handlerRegistry();
232 QMutexLocker locker(&registry->mutex);
233 if (!receiver) {
234 registry->handlers.remove(scheme);
235 return;
236 }
237 QOpenUrlHandlerRegistry::Handler h;
238 h.receiver = receiver;
239 h.name = method;
240 registry->handlers.insert(scheme, h);
241 QObject::connect(receiver, SIGNAL(destroyed(QObject*)),
242 registry, SLOT(handlerDestroyed(QObject*)));
243}
244
245/*!
246 Removes a previously set URL handler for the specified \a scheme.
247
248 \sa setUrlHandler()
249*/
250void QDesktopServices::unsetUrlHandler(const QString &scheme)
251{
252 setUrlHandler(scheme, 0, 0);
253}
254
255/*!
256 \enum QDesktopServices::StandardLocation
257 \since 4.4
258
259 This enum describes the different locations that can be queried by
260 QDesktopServices::storageLocation and QDesktopServices::displayName.
261
262 \value DesktopLocation Returns the user's desktop directory.