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

Last change on this file since 1168 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 11.4 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this 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 have questions regarding the use of this file, please contact
37** Nokia 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#elif defined(Q_OS_SYMBIAN)
59#include "qdesktopservices_s60.cpp"
60#endif
61
62#include <qhash.h>
63#include <qobject.h>
64#include <qcoreapplication.h>
65#include <qurl.h>
66#include <qmutex.h>
67
68QT_BEGIN_NAMESPACE
69
70class QOpenUrlHandlerRegistry : public QObject
71{
72 Q_OBJECT
73public:
74 inline QOpenUrlHandlerRegistry() : mutex(QMutex::Recursive) {}
75
76 QMutex mutex;
77
78 struct Handler
79 {
80 QObject *receiver;
81 QByteArray name;
82 };
83 typedef QHash<QString, Handler> HandlerHash;
84 HandlerHash handlers;
85
86public Q_SLOTS:
87 void handlerDestroyed(QObject *handler);
88
89};
90
91Q_GLOBAL_STATIC(QOpenUrlHandlerRegistry, handlerRegistry)
92
93void QOpenUrlHandlerRegistry::handlerDestroyed(QObject *handler)
94{
95 HandlerHash::Iterator it = handlers.begin();
96 while (it != handlers.end()) {
97 if (it->receiver == handler) {
98 it = handlers.erase(it);
99 } else {
100 ++it;
101 }
102 }
103}
104
105/*!
106 \class QDesktopServices
107 \brief The QDesktopServices class provides methods for accessing common desktop services.
108 \since 4.2
109 \ingroup desktop
110
111 Many desktop environments provide services that can be used by applications to
112 perform common tasks, such as opening a web page, in a way that is both consistent
113 and takes into account the user's application preferences.
114
115 This class contains functions that provide simple interfaces to these services
116 that indicate whether they succeeded or failed.
117
118 The openUrl() function is used to open files located at arbitrary URLs in external
119 applications. For URLs that correspond to resources on the local filing system
120 (where the URL scheme is "file"), a suitable application will be used to open the
121 file; otherwise, a web browser will be used to fetch and display the file.
122
123 The user's desktop settings control whether certain executable file types are
124 opened for browsing, or if they are executed instead. Some desktop environments
125 are configured to prevent users from executing files obtained from non-local URLs,
126 or to ask the user's permission before doing so.
127
128 \section1 URL Handlers
129
130 The behavior of the openUrl() function can be customized for individual URL
131 schemes to allow applications to override the default handling behavior for
132 certain types of URLs.
133
134 The dispatch mechanism allows only one custom handler to be used for each URL
135 scheme; this is set using the setUrlHandler() function. Each handler is
136 implemented as a slot which accepts only a single QUrl argument.
137
138 The existing handlers for each scheme can be removed with the
139 unsetUrlHandler() function. This returns the handling behavior for the given
140 scheme to the default behavior.
141
142 This system makes it easy to implement a help system, for example. Help could be
143 provided in labels and text browsers using \gui{help://myapplication/mytopic}
144 URLs, and by registering a handler it becomes possible to display the help text
145 inside the application:
146
147 \snippet doc/src/snippets/code/src_gui_util_qdesktopservices.cpp 0
148
149 If inside the handler you decide that you can't open the requested
150 URL, you can just call QDesktopServices::openUrl() again with the
151 same argument, and it will try to open the URL using the
152 appropriate mechanism for the user's desktop environment.
153
154 \sa QSystemTrayIcon, QProcess
155*/
156
157/*!
158 Opens the given \a url in the appropriate Web browser for the user's desktop
159 environment, and returns true if successful; otherwise returns false.
160
161 If the URL is a reference to a local file (i.e., the URL scheme is "file") then
162 it will be opened with a suitable application instead of a Web browser.
163
164 The following example opens a file on the Windows file system residing on a path
165 that contains spaces:
166
167 \snippet doc/src/snippets/code/src_gui_util_qdesktopservices.cpp 2
168
169 If a \c mailto URL is specified, the user's e-mail client will be used to open a
170 composer window containing the options specified in the URL, similar to the way
171 \c mailto links are handled by a Web browser.
172
173 For example, the following URL contains a recipient (\c{[email protected]}), a
174 subject (\c{Test}), and a message body (\c{Just a test}):
175
176 \snippet doc/src/snippets/code/src_gui_util_qdesktopservices.cpp 1
177
178 \warning Although many e-mail clients can send attachments and are
179 Unicode-aware, the user may have configured their client without these features.
180 Also, certain e-mail clients (e.g., Lotus Notes) have problems with long URLs.
181
182 \sa setUrlHandler()
183*/
184bool QDesktopServices::openUrl(const QUrl &url)
185{
186 QOpenUrlHandlerRegistry *registry = handlerRegistry();
187 QMutexLocker locker(&registry->mutex);
188 static bool insideOpenUrlHandler = false;
189
190 if (!insideOpenUrlHandler) {
191 QOpenUrlHandlerRegistry::HandlerHash::ConstIterator handler = registry->handlers.constFind(url.scheme());
192 if (handler != registry->handlers.constEnd()) {
193 insideOpenUrlHandler = true;
194 bool result = QMetaObject::invokeMethod(handler->receiver, handler->name.constData(), Qt::DirectConnection, Q_ARG(QUrl, url));
195 insideOpenUrlHandler = false;
196 return result; // ### support bool slot return type
197 }
198 }
199
200 bool result;
201 if (url.scheme() == QLatin1String("file"))
202 result = openDocument(url);
203 else
204 result = launchWebBrowser(url);
205
206 return result;
207}
208
209/*!
210 Sets the handler for the given \a scheme to be the handler \a method provided by
211 the \a receiver object.
212
213 This function provides a way to customize the behavior of openUrl(). If openUrl()
214 is called with a URL with the specified \a scheme then the given \a method on the
215 \a receiver object is called instead of QDesktopServices launching an external
216 application.
217
218 The provided method must be implemented as a slot that only accepts a single QUrl
219 argument.
220
221 If setUrlHandler() is used to set a new handler for a scheme which already
222 has a handler, the existing handler is simply replaced with the new one.
223 Since QDesktopServices does not take ownership of handlers, no objects are
224 deleted when a handler is replaced.
225
226 Note that the handler will always be called from within the same thread that
227 calls QDesktopServices::openUrl().
228
229 \sa openUrl(), unsetUrlHandler()
230*/
231void QDesktopServices::setUrlHandler(const QString &scheme, QObject *receiver, const char *method)
232{
233 QOpenUrlHandlerRegistry *registry = handlerRegistry();
234 QMutexLocker locker(&registry->mutex);
235 if (!receiver) {
236 registry->handlers.remove(scheme);
237 return;
238 }
239 QOpenUrlHandlerRegistry::Handler h;
240 h.receiver = receiver;
241 h.name = method;
242 registry->handlers.insert(scheme, h);
243 QObject::connect(receiver, SIGNAL(destroyed(QObject*)),
244 registry, SLOT(handlerDestroyed(QObject*)));
245}
246
247/*!
248 Removes a previously set URL handler for the specified \a scheme.
249
250 \sa setUrlHandler()
251*/
252void QDesktopServices::unsetUrlHandler(const QString &scheme)
253{
254 setUrlHandler(scheme, 0, 0);
255}
256
257/*!
258 \enum QDesktopServices::StandardLocation
259 \since 4.4
260
261 This enum describes the different locations that can be queried by
262 QDesktopServices::storageLocation and QDesktopServices::displayName.
263
264 \value DesktopLocation Returns the user's desktop directory.
265 \value DocumentsLocation Returns the user's document.
266 \value FontsLocation Returns the user's fonts.
267 \value ApplicationsLocation Returns the user's applications.
268 \value MusicLocation Returns the users music.
269 \value MoviesLocation Returns the user's movies.
270 \value PicturesLocation Returns the user's pictures.
271 \value TempLocation Returns the system's temporary directory.
272 \value HomeLocation Returns the user's home directory.
273 \value DataLocation Returns a directory location where persistent
274 application data can be stored. QCoreApplication::applicationName
275 and QCoreApplication::organizationName should work on all
276 platforms.
277 \value CacheLocation Returns a directory location where user-specific
278 non-essential (cached) data should be written.
279
280 \sa storageLocation() displayName()
281*/
282
283/*!
284 \fn QString QDesktopServices::storageLocation(StandardLocation type)
285 \since 4.4
286
287 Returns the default system directory where files of \a type belong, or an empty string
288 if the location cannot be determined.
289
290 \note The storage location returned can be a directory that does not exist; i.e., it
291 may need to be created by the system or the user.
292
293 \note On Symbian OS, ApplicationsLocation always point /sys/bin folder on the same drive
294 with executable. FontsLocation always points to folder on ROM drive. Symbian OS does not
295 have desktop concept, DesktopLocation returns same path as DocumentsLocation.
296 Rest of the standard locations point to folder on same drive with executable, except
297 that if executable is in ROM the folder from C drive is returned.
298*/
299
300/*!
301 \fn QString QDesktopServices::displayName(StandardLocation type)
302
303 Returns a localized display name for the given location \a type or
304 an empty QString if no relevant location can be found.
305*/
306
307QT_END_NAMESPACE
308
309#include "qdesktopservices.moc"
310
311#endif // QT_NO_DESKTOPSERVICES
Note: See TracBrowser for help on using the repository browser.