util/qdesktopservices.cpp

Source codeSwitch to Preprocessed file
LineSource CodeCoverage
1/**************************************************************************** -
2** -
3** Copyright (C) 2013 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 \note Since Qt 5, storageLocation() and displayName() are replaced by functionality -
147 provided by the QStandardPaths class. -
148 -
149 \sa QSystemTrayIcon, QProcess, QStandardPaths -
150*/ -
151 -
152/*! -
153 Opens the given \a url in the appropriate Web browser for the user's desktop -
154 environment, and returns true if successful; otherwise returns false. -
155 -
156 If the URL is a reference to a local file (i.e., the URL scheme is "file") then -
157 it will be opened with a suitable application instead of a Web browser. -
158 -
159 The following example opens a file on the Windows file system residing on a path -
160 that contains spaces: -
161 -
162 \snippet code/src_gui_util_qdesktopservices.cpp 2 -
163 -
164 If a \c mailto URL is specified, the user's e-mail client will be used to open a -
165 composer window containing the options specified in the URL, similar to the way -
166 \c mailto links are handled by a Web browser. -
167 -
168 For example, the following URL contains a recipient (\c{user@foo.com}), a -
169 subject (\c{Test}), and a message body (\c{Just a test}): -
170 -
171 \snippet code/src_gui_util_qdesktopservices.cpp 1 -
172 -
173 \warning Although many e-mail clients can send attachments and are -
174 Unicode-aware, the user may have configured their client without these features. -
175 Also, certain e-mail clients (e.g., Lotus Notes) have problems with long URLs. -
176 -
177 \sa setUrlHandler() -
178*/ -
179bool QDesktopServices::openUrl(const QUrl &url) -
180{ -
181 QOpenUrlHandlerRegistry *registry = handlerRegistry();
executed (the execution status of this line is deduced): QOpenUrlHandlerRegistry *registry = handlerRegistry();
-
182 QMutexLocker locker(&registry->mutex);
executed (the execution status of this line is deduced): QMutexLocker locker(&registry->mutex);
-
183 static bool insideOpenUrlHandler = false; -
184 -
185 if (!insideOpenUrlHandler) {
partially evaluated: !insideOpenUrlHandler
TRUEFALSE
yes
Evaluation Count:3
no
Evaluation Count:0
0-3
186 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());
-
187 if (handler != registry->handlers.constEnd()) {
evaluated: handler != registry->handlers.constEnd()
TRUEFALSE
yes
Evaluation Count:2
yes
Evaluation Count:1
1-2
188 insideOpenUrlHandler = true;
executed (the execution status of this line is deduced): insideOpenUrlHandler = true;
-
189 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));
-
190 insideOpenUrlHandler = false;
executed (the execution status of this line is deduced): insideOpenUrlHandler = false;
-
191 return result; // ### support bool slot return type
executed: return result;
Execution Count:2
2
192 } -
193 }
executed: }
Execution Count:1
1
194 if (!url.isValid())
partially evaluated: !url.isValid()
TRUEFALSE
yes
Evaluation Count:1
no
Evaluation Count:0
0-1
195 return false;
executed: return false;
Execution Count:1
1
196 QPlatformServices *platformServices = QGuiApplicationPrivate::platformIntegration()->services();
never executed (the execution status of this line is deduced): QPlatformServices *platformServices = QGuiApplicationPrivate::platformIntegration()->services();
-
197 if (!platformServices) {
never evaluated: !platformServices
0
198 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", 198, __PRETTY_FUNCTION__).warning("%s: The platform plugin does not support services.", __PRETTY_FUNCTION__);
-
199 return false;
never executed: return false;
0
200 } -
201 return url.scheme() == QStringLiteral("file") ?
never executed: return url.scheme() == QString::fromUtf8("" "file" "", sizeof("file") - 1) ? platformServices->openDocument(url) : platformServices->openUrl(url);
0
202 platformServices->openDocument(url) : platformServices->openUrl(url);
never executed: return url.scheme() == QString::fromUtf8("" "file" "", sizeof("file") - 1) ? platformServices->openDocument(url) : platformServices->openUrl(url);
0
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();
executed (the execution status of this line is deduced): QOpenUrlHandlerRegistry *registry = handlerRegistry();
-
230 QMutexLocker locker(&registry->mutex);
executed (the execution status of this line is deduced): QMutexLocker locker(&registry->mutex);
-
231 if (!receiver) {
partially evaluated: !receiver
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:2
0-2
232 registry->handlers.remove(scheme);
never executed (the execution status of this line is deduced): registry->handlers.remove(scheme);
-
233 return;
never executed: return;
0
234 } -
235 QOpenUrlHandlerRegistry::Handler h;
executed (the execution status of this line is deduced): QOpenUrlHandlerRegistry::Handler h;
-
236 h.receiver = receiver;
executed (the execution status of this line is deduced): h.receiver = receiver;
-
237 h.name = method;
executed (the execution status of this line is deduced): h.name = method;
-
238 registry->handlers.insert(scheme, h);
executed (the execution status of this line is deduced): registry->handlers.insert(scheme, h);
-
239 QObject::connect(receiver, SIGNAL(destroyed(QObject*)),
executed (the execution status of this line is deduced): QObject::connect(receiver, "2""destroyed(QObject*)",
-
240 registry, SLOT(handlerDestroyed(QObject*)));
executed (the execution status of this line is deduced): registry, "1""handlerDestroyed(QObject*)");
-
241}
executed: }
Execution Count:2
2
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);
never executed (the execution status of this line is deduced): setUrlHandler(scheme, 0, 0);
-
251}
never executed: }
0
252 -
253/*! -
254 \enum QDesktopServices::StandardLocation -
255 \since 4.4 -
256 \obsolete -
257 Use QStandardPaths::StandardLocation -
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. -
263 \value DocumentsLocation Returns the user's document. -
264 \value FontsLocation Returns the user's fonts. -
265 \value ApplicationsLocation Returns the user's applications. -
266 \value MusicLocation Returns the users music. -
267 \value MoviesLocation Returns the user's movies. -
268 \value PicturesLocation Returns the user's pictures. -
269 \value TempLocation Returns the system's temporary directory. -
270 \value HomeLocation Returns the user's home directory. -
271 \value DataLocation Returns a directory location where persistent -
272 application data can be stored. QCoreApplication::applicationName -
273 and QCoreApplication::organizationName should work on all -
274 platforms. -
275 \value CacheLocation Returns a directory location where user-specific -
276 non-essential (cached) data should be written. -
277 -
278 \sa storageLocation(), displayName() -
279*/ -
280 -
281/*! -
282 \fn QString QDesktopServices::storageLocation(StandardLocation type) -
283 \obsolete -
284 Use QStandardPaths::writableLocation() -
285*/ -
286 -
287/*! -
288 \fn QString QDesktopServices::displayName(StandardLocation type) -
289 \obsolete -
290 Use QStandardPaths::displayName() -
291*/ -
292 -
293extern Q_CORE_EXPORT QString qt_applicationName_noFallback(); -
294 -
295QString QDesktopServices::storageLocationImpl(QStandardPaths::StandardLocation type) -
296{ -
297 if (type == QStandardPaths::DataLocation) {
partially evaluated: type == QStandardPaths::DataLocation
TRUEFALSE
yes
Evaluation Count:2
no
Evaluation Count:0
0-2
298 // Preserve Qt 4 compatibility: -
299 // * QCoreApplication::applicationName() must default to empty -
300 // * Unix data location is under the "data/" subdirectory -
301 const QString compatAppName = qt_applicationName_noFallback();
executed (the execution status of this line is deduced): const QString compatAppName = qt_applicationName_noFallback();
-
302 const QString baseDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
executed (the execution status of this line is deduced): const QString baseDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
-
303#if defined(Q_OS_WIN) || defined(Q_OS_MAC) -
304 QString result = baseDir; -
305 if (!QCoreApplication::organizationName().isEmpty()) -
306 result += QLatin1Char('/') + QCoreApplication::organizationName(); -
307 if (!compatAppName.isEmpty()) -
308 result += QLatin1Char('/') + compatAppName; -
309 return result; -
310#elif defined(Q_OS_UNIX) -
311 return baseDir + QLatin1String("/data/")
executed: return baseDir + QLatin1String("/data/") + QCoreApplication::organizationName() + QLatin1Char('/') + compatAppName;
Execution Count:2
2
312 + QCoreApplication::organizationName() + QLatin1Char('/')
executed: return baseDir + QLatin1String("/data/") + QCoreApplication::organizationName() + QLatin1Char('/') + compatAppName;
Execution Count:2
2
313 + compatAppName;
executed: return baseDir + QLatin1String("/data/") + QCoreApplication::organizationName() + QLatin1Char('/') + compatAppName;
Execution Count:2
2
314#endif -
315 } -
316 return QStandardPaths::writableLocation(type);
never executed: return QStandardPaths::writableLocation(type);
0
317} -
318 -
319QT_END_NAMESPACE -
320 -
321#include "qdesktopservices.moc" -
322 -
323#endif // QT_NO_DESKTOPSERVICES -
324 -
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial