util/qdesktopservices.cpp

Source codeSwitch to Preprocessed file
LineSource CodeCoverage
1/**************************************************************************** -
2** -
3** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -
4** Contact: http://www.qt-project.org/legal -
5** -
6** This file is part of the QtGui module of the Qt Toolkit. -
7** -
8** $QT_BEGIN_LICENSE:LGPL$ -
9** Commercial License Usage -
10** Licensees holding valid commercial Qt licenses may use this file in -
11** accordance with the commercial license agreement provided with the -
12** Software or, alternatively, in accordance with the terms contained in -
13** a written agreement between you and Digia. For licensing terms and -
14** conditions see http://qt.digia.com/licensing. For further information -
15** use the contact form at http://qt.digia.com/contact-us. -
16** -
17** GNU Lesser General Public License Usage -
18** Alternatively, this file may be used under the terms of the GNU Lesser -
19** General Public License version 2.1 as published by the Free Software -
20** Foundation and appearing in the file LICENSE.LGPL included in the -
21** packaging of this file. Please review the following information to -
22** ensure the GNU Lesser General Public License version 2.1 requirements -
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -
24** -
25** In addition, as a special exception, Digia gives you certain additional -
26** rights. These rights are described in the Digia Qt LGPL Exception -
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -
28** -
29** GNU General Public License Usage -
30** Alternatively, this file may be used under the terms of the GNU -
31** General Public License version 3.0 as published by the Free Software -
32** Foundation and appearing in the file LICENSE.GPL included in the -
33** packaging of this file. Please review the following information to -
34** ensure the GNU General Public License version 3.0 requirements will be -
35** met: http://www.gnu.org/copyleft/gpl.html. -
36** -
37** -
38** $QT_END_LICENSE$ -
39** -
40****************************************************************************/ -
41 -
42#include "qdesktopservices.h" -
43 -
44#ifndef QT_NO_DESKTOPSERVICES -
45 -
46#include <qdebug.h> -
47 -
48#include <qstandardpaths.h> -
49#include <qhash.h> -
50#include <qobject.h> -
51#include <qcoreapplication.h> -
52#include <private/qguiapplication_p.h> -
53#include <qurl.h> -
54#include <qmutex.h> -
55#include <qpa/qplatformservices.h> -
56#include <qpa/qplatformintegration.h> -
57#include <qdir.h> -
58 -
59QT_BEGIN_NAMESPACE -
60 -
61class QOpenUrlHandlerRegistry : public QObject -
62{ -
63 Q_OBJECT -
64public: -
65 inline QOpenUrlHandlerRegistry() : mutex(QMutex::Recursive) {}
executed: }
Execution Count:1
1
66 -
67 QMutex mutex; -
68 -
69 struct Handler -
70 { -
71 QObject *receiver; -
72 QByteArray name; -
73 }; -
74 typedef QHash<QString, Handler> HandlerHash; -
75 HandlerHash handlers; -
76 -
77public Q_SLOTS: -
78 void handlerDestroyed(QObject *handler); -
79 -
80}; -
81 -
82Q_GLOBAL_STATIC(QOpenUrlHandlerRegistry, handlerRegistry)
never executed: delete x;
executed: return thisGlobalStatic.pointer.load();
Execution Count:5
partially evaluated: !thisGlobalStatic.pointer.testAndSetOrdered(0, x)
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:1
evaluated: !thisGlobalStatic.pointer.load()
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:4
partially evaluated: !thisGlobalStatic.destroyed
TRUEFALSE
yes
Evaluation Count:1
no
Evaluation Count:0
0-5
83 -
84void QOpenUrlHandlerRegistry::handlerDestroyed(QObject *handler) -
85{ -
86 HandlerHash::Iterator it = handlers.begin();
executed (the execution status of this line is deduced): HandlerHash::Iterator it = handlers.begin();
-
87 while (it != handlers.end()) {
evaluated: it != handlers.end()
TRUEFALSE
yes
Evaluation Count:3
yes
Evaluation Count:2
2-3
88 if (it->receiver == handler) {
evaluated: it->receiver == handler
TRUEFALSE
yes
Evaluation Count:2
yes
Evaluation Count:1
1-2
89 it = handlers.erase(it);
executed (the execution status of this line is deduced): it = handlers.erase(it);
-
90 } else {
executed: }
Execution Count:2
2
91 ++it;
executed (the execution status of this line is deduced): ++it;
-
92 }
executed: }
Execution Count:1
1
93 } -
94}
executed: }
Execution Count:2
2
95 -
96/*! -
97 \class QDesktopServices -
98 \brief The QDesktopServices class provides methods for accessing common desktop services. -
99 \since 4.2 -
100 \ingroup desktop -
101 \inmodule QtGui -
102 -
103 Many desktop environments provide services that can be used by applications to -
104 perform common tasks, such as opening a web page, in a way that is both consistent -
105 and takes into account the user's application preferences. -
106 -
107 This class contains functions that provide simple interfaces to these services -
108 that indicate whether they succeeded or failed. -
109 -
110 The openUrl() function is used to open files located at arbitrary URLs in external -
111 applications. For URLs that correspond to resources on the local filing system -
112 (where the URL scheme is "file"), a suitable application will be used to open the -
113 file; otherwise, a web browser will be used to fetch and display the file. -
114 -
115 The user's desktop settings control whether certain executable file types are -
116 opened for browsing, or if they are executed instead. Some desktop environments -
117 are configured to prevent users from executing files obtained from non-local URLs, -
118 or to ask the user's permission before doing so. -
119 -
120 \section1 URL Handlers -
121 -
122 The behavior of the openUrl() function can be customized for individual URL -
123 schemes to allow applications to override the default handling behavior for -
124 certain types of URLs. -
125 -
126 The dispatch mechanism allows only one custom handler to be used for each URL -
127 scheme; this is set using the setUrlHandler() function. Each handler is -
128 implemented as a slot which accepts only a single QUrl argument. -
129 -
130 The existing handlers for each scheme can be removed with the -
131 unsetUrlHandler() function. This returns the handling behavior for the given -
132 scheme to the default behavior. -
133 -
134 This system makes it easy to implement a help system, for example. Help could be -
135 provided in labels and text browsers using \uicontrol{help://myapplication/mytopic} -
136 URLs, and by registering a handler it becomes possible to display the help text -
137 inside the application: -
138 -
139 \snippet code/src_gui_util_qdesktopservices.cpp 0 -
140 -
141 If inside the handler you decide that you can't open the requested -
142 URL, you can just call QDesktopServices::openUrl() again with the -
143 same argument, and it will try to open the URL using the -
144 appropriate mechanism for the user's desktop environment. -
145 -
146 \sa QSystemTrayIcon, QProcess -
147*/ -
148 -
149/*! -
150 Opens the given \a url in the appropriate Web browser for the user's desktop -
151 environment, and returns true if successful; otherwise returns false. -
152 -
153 If the URL is a reference to a local file (i.e., the URL scheme is "file") then -
154 it will be opened with a suitable application instead of a Web browser. -
155 -
156 The following example opens a file on the Windows file system residing on a path -
157 that contains spaces: -
158 -
159 \snippet code/src_gui_util_qdesktopservices.cpp 2 -
160 -
161 If a \c mailto URL is specified, the user's e-mail client will be used to open a -
162 composer window containing the options specified in the URL, similar to the way -
163 \c mailto links are handled by a Web browser. -
164 -
165 For example, the following URL contains a recipient (\c{user@foo.com}), a -
166 subject (\c{Test}), and a message body (\c{Just a test}): -
167 -
168 \snippet code/src_gui_util_qdesktopservices.cpp 1 -
169 -
170 \warning Although many e-mail clients can send attachments and are -
171 Unicode-aware, the user may have configured their client without these features. -
172 Also, certain e-mail clients (e.g., Lotus Notes) have problems with long URLs. -
173 -
174 \sa setUrlHandler() -
175*/ -
176bool QDesktopServices::openUrl(const QUrl &url) -
177{ -
178 QOpenUrlHandlerRegistry *registry = handlerRegistry();
executed (the execution status of this line is deduced): QOpenUrlHandlerRegistry *registry = handlerRegistry();
-
179 QMutexLocker locker(&registry->mutex);
executed (the execution status of this line is deduced): QMutexLocker locker(&registry->mutex);
-
180 static bool insideOpenUrlHandler = false; -
181 -
182 if (!insideOpenUrlHandler) {
partially evaluated: !insideOpenUrlHandler
TRUEFALSE
yes
Evaluation Count:3
no
Evaluation Count:0
0-3
183 QOpenUrlHandlerRegistry::HandlerHash::ConstIterator handler = registry->handlers.constFind(url.scheme());
executed (the execution status of this line is deduced): QOpenUrlHandlerRegistry::HandlerHash::ConstIterator handler = registry->handlers.constFind(url.scheme());
-
184 if (handler != registry->handlers.constEnd()) {
evaluated: handler != registry->handlers.constEnd()
TRUEFALSE
yes
Evaluation Count:2
yes
Evaluation Count:1
1-2
185 insideOpenUrlHandler = true;
executed (the execution status of this line is deduced): insideOpenUrlHandler = true;
-
186 bool result = QMetaObject::invokeMethod(handler->receiver, handler->name.constData(), Qt::DirectConnection, Q_ARG(QUrl, url));
executed (the execution status of this line is deduced): bool result = QMetaObject::invokeMethod(handler->receiver, handler->name.constData(), Qt::DirectConnection, QArgument<QUrl >("QUrl", url));
-
187 insideOpenUrlHandler = false;
executed (the execution status of this line is deduced): insideOpenUrlHandler = false;
-
188 return result; // ### support bool slot return type
executed: return result;
Execution Count:2
2
189 } -
190 }
executed: }
Execution Count:1
1
191 if (!url.isValid())
partially evaluated: !url.isValid()
TRUEFALSE
yes
Evaluation Count:1
no
Evaluation Count:0
0-1
192 return false;
executed: return false;
Execution Count:1
1
193 QPlatformServices *platformServices = QGuiApplicationPrivate::platformIntegration()->services();
never executed (the execution status of this line is deduced): QPlatformServices *platformServices = QGuiApplicationPrivate::platformIntegration()->services();
-
194 if (!platformServices) {
never evaluated: !platformServices
0
195 qWarning("%s: The platform plugin does not support services.", Q_FUNC_INFO);
never executed (the execution status of this line is deduced): QMessageLogger("util/qdesktopservices.cpp", 195, __PRETTY_FUNCTION__).warning("%s: The platform plugin does not support services.", __PRETTY_FUNCTION__);
-
196 return false;
never executed: return false;
0
197 } -
198 return url.scheme() == QStringLiteral("file") ?
never executed: return url.scheme() == QString::fromUtf8("" "file" "", sizeof("file") - 1) ? platformServices->openDocument(url) : platformServices->openUrl(url);
0
199 platformServices->openDocument(url) : platformServices->openUrl(url);
never executed: return url.scheme() == QString::fromUtf8("" "file" "", sizeof("file") - 1) ? platformServices->openDocument(url) : platformServices->openUrl(url);
0
200} -
201 -
202/*! -
203 Sets the handler for the given \a scheme to be the handler \a method provided by -
204 the \a receiver object. -
205 -
206 This function provides a way to customize the behavior of openUrl(). If openUrl() -
207 is called with a URL with the specified \a scheme then the given \a method on the -
208 \a receiver object is called instead of QDesktopServices launching an external -
209 application. -
210 -
211 The provided method must be implemented as a slot that only accepts a single QUrl -
212 argument. -
213 -
214 If setUrlHandler() is used to set a new handler for a scheme which already -
215 has a handler, the existing handler is simply replaced with the new one. -
216 Since QDesktopServices does not take ownership of handlers, no objects are -
217 deleted when a handler is replaced. -
218 -
219 Note that the handler will always be called from within the same thread that -
220 calls QDesktopServices::openUrl(). -
221 -
222 \sa openUrl(), unsetUrlHandler() -
223*/ -
224void QDesktopServices::setUrlHandler(const QString &scheme, QObject *receiver, const char *method) -
225{ -
226 QOpenUrlHandlerRegistry *registry = handlerRegistry();
executed (the execution status of this line is deduced): QOpenUrlHandlerRegistry *registry = handlerRegistry();
-
227 QMutexLocker locker(&registry->mutex);
executed (the execution status of this line is deduced): QMutexLocker locker(&registry->mutex);
-
228 if (!receiver) {
partially evaluated: !receiver
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:2
0-2
229 registry->handlers.remove(scheme);
never executed (the execution status of this line is deduced): registry->handlers.remove(scheme);
-
230 return;
never executed: return;
0
231 } -
232 QOpenUrlHandlerRegistry::Handler h;
executed (the execution status of this line is deduced): QOpenUrlHandlerRegistry::Handler h;
-
233 h.receiver = receiver;
executed (the execution status of this line is deduced): h.receiver = receiver;
-
234 h.name = method;
executed (the execution status of this line is deduced): h.name = method;
-
235 registry->handlers.insert(scheme, h);
executed (the execution status of this line is deduced): registry->handlers.insert(scheme, h);
-
236 QObject::connect(receiver, SIGNAL(destroyed(QObject*)),
executed (the execution status of this line is deduced): QObject::connect(receiver, "2""destroyed(QObject*)",
-
237 registry, SLOT(handlerDestroyed(QObject*)));
executed (the execution status of this line is deduced): registry, "1""handlerDestroyed(QObject*)");
-
238}
executed: }
Execution Count:2
2
239 -
240/*! -
241 Removes a previously set URL handler for the specified \a scheme. -
242 -
243 \sa setUrlHandler() -
244*/ -
245void QDesktopServices::unsetUrlHandler(const QString &scheme) -
246{ -
247 setUrlHandler(scheme, 0, 0);
never executed (the execution status of this line is deduced): setUrlHandler(scheme, 0, 0);
-
248}
never executed: }
0
249 -
250/*! -
251 \enum QDesktopServices::StandardLocation -
252 \since 4.4 -
253 \obsolete -
254 Use QStandardPaths::StandardLocation -
255 -
256 This enum describes the different locations that can be queried by -
257 QDesktopServices::storageLocation and QDesktopServices::displayName. -
258 -
259 \value DesktopLocation Returns the user's desktop directory. -
260 \value DocumentsLocation Returns the user's document. -
261 \value FontsLocation Returns the user's fonts. -
262 \value ApplicationsLocation Returns the user's applications. -
263 \value MusicLocation Returns the users music. -
264 \value MoviesLocation Returns the user's movies. -
265 \value PicturesLocation Returns the user's pictures. -
266 \value TempLocation Returns the system's temporary directory. -
267 \value HomeLocation Returns the user's home directory. -
268 \value DataLocation Returns a directory location where persistent -
269 application data can be stored. QCoreApplication::applicationName -
270 and QCoreApplication::organizationName should work on all -
271 platforms. -
272 \value CacheLocation Returns a directory location where user-specific -
273 non-essential (cached) data should be written. -
274 -
275 \sa storageLocation(), displayName() -
276*/ -
277 -
278/*! -
279 \fn QString QDesktopServices::storageLocation(StandardLocation type) -
280 \obsolete -
281 Use QStandardPaths::writableLocation() -
282*/ -
283 -
284/*! -
285 \fn QString QDesktopServices::displayName(StandardLocation type) -
286 \obsolete -
287 Use QStandardPaths::displayName() -
288*/ -
289 -
290extern Q_CORE_EXPORT QString qt_applicationName_noFallback(); -
291 -
292QString QDesktopServices::storageLocationImpl(QStandardPaths::StandardLocation type) -
293{ -
294 if (type == QStandardPaths::DataLocation) {
partially evaluated: type == QStandardPaths::DataLocation
TRUEFALSE
yes
Evaluation Count:2
no
Evaluation Count:0
0-2
295 // Preserve Qt 4 compatibility: -
296 // * QCoreApplication::applicationName() must default to empty -
297 // * Unix data location is under the "data/" subdirectory -
298 const QString compatAppName = qt_applicationName_noFallback();
executed (the execution status of this line is deduced): const QString compatAppName = qt_applicationName_noFallback();
-
299 const QString baseDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
executed (the execution status of this line is deduced): const QString baseDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
-
300#if defined(Q_OS_WIN) || defined(Q_OS_MAC) -
301 QString result = baseDir; -
302 if (!QCoreApplication::organizationName().isEmpty()) -
303 result += QLatin1Char('/') + QCoreApplication::organizationName(); -
304 if (!compatAppName.isEmpty()) -
305 result += QLatin1Char('/') + compatAppName; -
306 return result; -
307#elif defined(Q_OS_UNIX) -
308 return baseDir + QLatin1String("/data/")
executed: return baseDir + QLatin1String("/data/") + QCoreApplication::organizationName() + QLatin1Char('/') + compatAppName;
Execution Count:2
2
309 + QCoreApplication::organizationName() + QLatin1Char('/')
executed: return baseDir + QLatin1String("/data/") + QCoreApplication::organizationName() + QLatin1Char('/') + compatAppName;
Execution Count:2
2
310 + compatAppName;
executed: return baseDir + QLatin1String("/data/") + QCoreApplication::organizationName() + QLatin1Char('/') + compatAppName;
Execution Count:2
2
311#endif -
312 } -
313 return QStandardPaths::writableLocation(type);
never executed: return QStandardPaths::writableLocation(type);
0
314} -
315 -
316QT_END_NAMESPACE -
317 -
318#include "qdesktopservices.moc" -
319 -
320#endif // QT_NO_DESKTOPSERVICES -
321 -
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial