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

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

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

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