Add QPlatformServices class.

- Add QPlatformServices as back-end for
  QDesktopServices.
- Bring back UNIX/Linux desktop detection in platformsupport
  as a generic implementation.
- Add Windows implementation.

Reviewed-by: Morten Johan Sorvig <morten.sorvig@nokia.com>
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
Reviewed-by: Anselmo Lacerda S. de Melo <anselmo.melo@openbossa.org>

Change-Id: If94bb65755df4f849edd83c57143ee2c73002137
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com>
This commit is contained in:
Friedemann Kleint 2012-02-08 08:40:48 +01:00 committed by Qt by Nokia
parent d43a01e149
commit c908fc4448
21 changed files with 585 additions and 463 deletions

View File

@ -55,7 +55,8 @@ HEADERS += \
kernel/qtouchdevice.h \
kernel/qtouchdevice_p.h \
kernel/qplatformsharedgraphicscache_qpa.h \
kernel/qplatformdialoghelper_qpa.h
kernel/qplatformdialoghelper_qpa.h \
kernel/qplatformservices_qpa.h
SOURCES += \
kernel/qclipboard_qpa.cpp \
@ -97,7 +98,8 @@ SOURCES += \
kernel/qstylehints.cpp \
kernel/qtouchdevice.cpp \
kernel/qplatformsharedgraphicscache_qpa.cpp \
kernel/qplatformdialoghelper_qpa.cpp
kernel/qplatformdialoghelper_qpa.cpp \
kernel/qplatformservices_qpa.cpp
contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles2)|contains(QT_CONFIG, egl) {
HEADERS += \

View File

@ -107,6 +107,11 @@ QPlatformNativeInterface * QPlatformIntegration::nativeInterface() const
return 0;
}
QPlatformServices *QPlatformIntegration::services() const
{
return 0;
}
/*!
\class QPlatformIntegration
\since 4.8

View File

@ -66,6 +66,7 @@ class QPlatformAccessibility;
class QPlatformTheme;
class QPlatformDialogHelper;
class QPlatformSharedGraphicsCache;
class QPlatformServices;
class Q_GUI_EXPORT QPlatformIntegration
{
@ -106,6 +107,8 @@ public:
// Access native handles. The window handle is already available from Wid;
virtual QPlatformNativeInterface *nativeInterface() const;
virtual QPlatformServices *services() const;
enum StyleHint {
CursorFlashTime,
KeyboardInputInterval,

View File

@ -0,0 +1,74 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qplatformservices_qpa.h"
#include <QtCore/QUrl>
#include <QtCore/QString>
#include <QtCore/QDebug>
QT_BEGIN_NAMESPACE
/*!
\class QPlatformServices
\since 5.0
\internal
\preliminary
\ingroup qpa
\brief The QPlatformServices provides the backend for desktop-related functionality.
*/
bool QPlatformServices::openUrl(const QUrl &url)
{
qWarning("This plugin does not support QPlatformServices::openUrl() for '%s'.",
qPrintable(url.toString()));
return false;
}
bool QPlatformServices::openDocument(const QUrl &url)
{
qWarning("This plugin does not support QPlatformServices::openDocument() for '%s'.",
qPrintable(url.toString()));
return false;
}
QT_END_NAMESPACE

View File

@ -39,23 +39,27 @@
**
****************************************************************************/
#include <qdebug.h>
#include <qurl.h>
#ifndef QPLATFORMSERVICES_QPA_H
#define QPLATFORMSERVICES_QPA_H
#include <QtCore/QtGlobal>
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
static bool launchWebBrowser(const QUrl &url)
{
Q_UNUSED(url);
qWarning("QDesktopServices::launchWebBrowser not implemented");
return false;
}
class QUrl;
static bool openDocument(const QUrl &file)
class Q_GUI_EXPORT QPlatformServices
{
Q_UNUSED(file);
qWarning("QDesktopServices::openDocument not implemented");
return false;
}
public:
virtual ~QPlatformServices() { }
virtual bool openUrl(const QUrl &url);
virtual bool openDocument(const QUrl &url);
};
QT_END_NAMESPACE
QT_END_HEADER
#endif // QPLATFORMSERVICES_QPA_H

View File

@ -45,14 +45,14 @@
#include <qdebug.h>
#include "qdesktopservices_qpa.cpp"
#include <qstandardpaths.h>
#include <qhash.h>
#include <qobject.h>
#include <qcoreapplication.h>
#include <private/qguiapplication_p.h>
#include <qurl.h>
#include <qmutex.h>
#include <qplatformservices_qpa.h>
QT_BEGIN_NAMESPACE
@ -185,14 +185,15 @@ bool QDesktopServices::openUrl(const QUrl &url)
return result; // ### support bool slot return type
}
}
bool result;
if (url.scheme() == QLatin1String("file"))
result = openDocument(url);
else
result = launchWebBrowser(url);
return result;
if (!url.isValid())
return false;
QPlatformServices *platformServices = QGuiApplicationPrivate::platformIntegration()->services();
if (!platformServices) {
qWarning("%s: The platform plugin does not support services.", Q_FUNC_INFO);
return false;
}
return url.scheme() == QStringLiteral("file") ?
platformServices->openDocument(url) : platformServices->openUrl(url);
}
/*!

View File

@ -1,127 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QT_NO_DESKTOPSERVICES
#include <qprocess.h>
#include <qstringlist.h>
#include <qdir.h>
#include <qurl.h>
#include <private/qcore_mac_p.h>
#include <qcoreapplication.h>
#include <ApplicationServices/ApplicationServices.h>
QT_BEGIN_NAMESPACE
/*
Translates a QDesktopServices::StandardLocation into the mac equivalent.
*/
OSType translateLocation(QDesktopServices::StandardLocation type)
{
switch (type) {
case QDesktopServices::DesktopLocation:
return kDesktopFolderType; break;
case QDesktopServices::DocumentsLocation:
return kDocumentsFolderType; break;
case QDesktopServices::FontsLocation:
// There are at least two different font directories on the mac: /Library/Fonts and ~/Library/Fonts.
// To select a specific one we have to specify a different first parameter when calling FSFindFolder.
return kFontsFolderType; break;
case QDesktopServices::ApplicationsLocation:
return kApplicationsFolderType; break;
case QDesktopServices::MusicLocation:
return kMusicDocumentsFolderType; break;
case QDesktopServices::MoviesLocation:
return kMovieDocumentsFolderType; break;
case QDesktopServices::PicturesLocation:
return kPictureDocumentsFolderType; break;
case QDesktopServices::TempLocation:
return kTemporaryFolderType; break;
case QDesktopServices::DataLocation:
return kApplicationSupportFolderType; break;
case QDesktopServices::CacheLocation:
return kCachedDataFolderType; break;
default:
return kDesktopFolderType; break;
}
}
static bool lsOpen(const QUrl &url)
{
if (!url.isValid() || url.scheme().isEmpty())
return false;
QCFType<CFURLRef> cfUrl = CFURLCreateWithString(0, QCFString(QString::fromLatin1(url.toEncoded())), 0);
if (cfUrl == 0)
return false;
const OSStatus err = LSOpenCFURLRef(cfUrl, 0);
return (err == noErr);
}
static bool launchWebBrowser(const QUrl &url)
{
return lsOpen(url);
}
static bool openDocument(const QUrl &file)
{
if (!file.isValid())
return false;
// LSOpen does not work in this case, use QProcess open instead.
return QProcess::startDetached(QLatin1String("open"), QStringList() << file.toLocalFile());
}
QT_END_NAMESPACE
#endif // QT_NO_DESKTOPSERVICES

View File

@ -1,177 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <qsettings.h>
#include <qdir.h>
#include <private/qsystemlibrary_p.h>
#include <qurl.h>
#include <qstringlist.h>
#include <qprocess.h>
#include <qtemporaryfile.h>
#include <qcoreapplication.h>
#include <qt_windows.h>
#include <shlobj.h>
#if !defined(Q_OS_WINCE)
# include <intshcut.h>
#else
# include <qguifunctions_wince.h>
# if !defined(STANDARDSHELL_UI_MODEL)
# include <winx.h>
# endif
#endif
#ifndef CSIDL_MYMUSIC
#define CSIDL_MYMUSIC 13
#define CSIDL_MYVIDEO 14
#endif
#ifndef QT_NO_DESKTOPSERVICES
QT_BEGIN_NAMESPACE
static bool openDocument(const QUrl &file)
{
if (!file.isValid())
return false;
QString filePath = file.toLocalFile();
if (filePath.isEmpty())
filePath = file.toString();
quintptr returnValue = (quintptr)ShellExecute(0, 0, (wchar_t*)filePath.utf16(), 0, 0, SW_SHOWNORMAL);
return (returnValue > 32); //ShellExecute returns a value greater than 32 if successful
}
static QString expandEnvStrings(const QString &command)
{
#if defined(Q_OS_WINCE)
return command;
#else
wchar_t buffer[MAX_PATH];
if (ExpandEnvironmentStrings((wchar_t*)command.utf16(), buffer, MAX_PATH))
return QString::fromWCharArray(buffer);
else
return command;
#endif
}
static bool launchWebBrowser(const QUrl &url)
{
if (url.scheme() == QLatin1String("mailto")) {
//Retrieve the commandline for the default mail client
//the default key used below is the command line for the mailto: shell command
DWORD bufferSize = sizeof(wchar_t) * MAX_PATH;
long returnValue = -1;
QString command;
HKEY handle;
LONG res;
wchar_t keyValue[MAX_PATH] = {0};
QString keyName(QLatin1String("mailto"));
//Check if user has set preference, otherwise use default.
res = RegOpenKeyEx(HKEY_CURRENT_USER,
L"Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\mailto\\UserChoice",
0, KEY_READ, &handle);
if (res == ERROR_SUCCESS) {
returnValue = RegQueryValueEx(handle, L"Progid", 0, 0, reinterpret_cast<unsigned char*>(keyValue), &bufferSize);
if (!returnValue)
keyName = QString::fromUtf16((const ushort*)keyValue);
RegCloseKey(handle);
}
keyName += QLatin1String("\\Shell\\Open\\Command");
res = RegOpenKeyExW(HKEY_CLASSES_ROOT, (const wchar_t*)keyName.utf16(), 0, KEY_READ, &handle);
if (res != ERROR_SUCCESS)
return false;
bufferSize = sizeof(wchar_t) * MAX_PATH;
returnValue = RegQueryValueEx(handle, L"", 0, 0, reinterpret_cast<unsigned char*>(keyValue), &bufferSize);
if (!returnValue)
command = QString::fromRawData((QChar*)keyValue, bufferSize);
RegCloseKey(handle);
if (returnValue)
return false;
command = expandEnvStrings(command);
command = command.trimmed();
//Make sure the path for the process is in quotes
int index = -1 ;
if (command[0]!= QLatin1Char('\"')) {
index = command.indexOf(QLatin1String(".exe "), 0, Qt::CaseInsensitive);
command.insert(index+4, QLatin1Char('\"'));
command.insert(0, QLatin1Char('\"'));
}
//pass the url as the parameter
index = command.lastIndexOf(QLatin1String("%1"));
if (index != -1){
command.replace(index, 2, url.toString());
}
//start the process
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
returnValue = CreateProcess(NULL, (wchar_t*)command.utf16(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
if (!returnValue)
return false;
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return true;
}
if (!url.isValid())
return false;
if (url.scheme().isEmpty())
return openDocument(url);
quintptr returnValue = (quintptr)ShellExecute(0, 0, (wchar_t *)QString::fromUtf8(url.toEncoded().constData()).utf16(),
0, 0, SW_SHOWNORMAL);
return (returnValue > 32);
}
QT_END_NAMESPACE
#endif // QT_NO_DESKTOPSERVICES

View File

@ -1,131 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qdesktopservices.h"
#ifndef QT_NO_DESKTOPSERVICES
#include <qprocess.h>
#include <qurl.h>
#include <qdir.h>
#include <qfile.h>
#include <qtextstream.h>
#include <private/qt_x11_p.h>
#include <qcoreapplication.h>
#include <stdlib.h>
QT_BEGIN_NAMESPACE
inline static bool launch(const QUrl &url, const QString &client)
{
#if !defined(QT_NO_PROCESS)
return (QProcess::startDetached(client + QLatin1Char(' ') + QString::fromLatin1(url.toEncoded().constData())));
#else
return (::system((client + QLatin1Char(' ') + QString::fromLatin1(url.toEncoded().constData())).toLocal8Bit().constData()) != -1);
#endif
}
static bool openDocument(const QUrl &url)
{
if (!url.isValid())
return false;
if (launch(url, QLatin1String("xdg-open")))
return true;
// Use the X11->desktopEnvironment value if X11 is non-NULL,
// otherwise just attempt to launch command regardless of the desktop environment
if ((!X11 || (X11 && X11->desktopEnvironment == DE_GNOME)) && launch(url, QLatin1String("gnome-open"))) {
return true;
} else {
if ((!X11 || (X11 && X11->desktopEnvironment == DE_KDE)) && launch(url, QLatin1String("kfmclient exec")))
return true;
}
if (launch(url, QLatin1String("firefox")))
return true;
if (launch(url, QLatin1String("mozilla")))
return true;
if (launch(url, QLatin1String("netscape")))
return true;
if (launch(url, QLatin1String("opera")))
return true;
return false;
}
static bool launchWebBrowser(const QUrl &url)
{
if (!url.isValid())
return false;
if (url.scheme() == QLatin1String("mailto"))
return openDocument(url);
if (launch(url, QLatin1String("xdg-open")))
return true;
if (launch(url, QString::fromLocal8Bit(getenv("DEFAULT_BROWSER"))))
return true;
if (launch(url, QString::fromLocal8Bit(getenv("BROWSER"))))
return true;
// Use the X11->desktopEnvironment value if X11 is non-NULL,
// otherwise just attempt to launch command regardless of the desktop environment
if ((!X11 || (X11 && X11->desktopEnvironment == DE_GNOME)) && launch(url, QLatin1String("gnome-open"))) {
return true;
} else {
if ((!X11 || (X11 && X11->desktopEnvironment == DE_KDE)) && launch(url, QLatin1String("kfmclient openURL")))
return true;
}
if (launch(url, QLatin1String("firefox")))
return true;
if (launch(url, QLatin1String("mozilla")))
return true;
if (launch(url, QLatin1String("netscape")))
return true;
if (launch(url, QLatin1String("opera")))
return true;
return false;
}
QT_END_NAMESPACE
#endif // QT_NO_DESKTOPSERVICES

View File

@ -34,3 +34,4 @@ include(glxconvenience/glxconvenience.pri)
#include(printersupport/printersupport.pri)
include(inputcontext/inputcontext.pri)
include(udev/udev.pri)
include(services/services.pri)

View File

@ -0,0 +1,2 @@
HEADERS += $$PWD/qgenericunixservices_p.h
SOURCES += $$PWD/qgenericunixservices.cpp

View File

@ -0,0 +1,151 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qgenericunixservices_p.h"
#include <QtCore/QStandardPaths>
#include <QtCore/QProcess>
#include <QtCore/QUrl>
#include <QtCore/QDebug>
#include <stdlib.h>
QT_BEGIN_NAMESPACE
enum { debug = 0 };
static inline QGenericUnixServices::DesktopEnvironment detectDesktopEnvironment()
{
if (!qgetenv("KDE_FULL_SESSION").isEmpty())
return QGenericUnixServices::DE_KDE;
// GNOME_DESKTOP_SESSION_ID is deprecated for some reason, but still check it
if (qgetenv("DESKTOP_SESSION") == "gnome" || !qgetenv("GNOME_DESKTOP_SESSION_ID").isEmpty())
return QGenericUnixServices::DE_GNOME;
return QGenericUnixServices::DE_UNKNOWN;
}
static inline bool checkExecutable(const QString &candidate, QString *result)
{
*result = QStandardPaths::findExecutable(candidate);
return !result->isEmpty();
}
static inline bool detectWebBrowser(QGenericUnixServices::DesktopEnvironment desktop,
bool checkBrowserVariable,
QString *browser)
{
const char *browsers[] = {"google-chrome", "firefox", "mozilla", "opera"};
browser->clear();
if (checkExecutable(QStringLiteral("xdg-open"), browser))
return true;
if (checkBrowserVariable) {
QByteArray browserVariable = qgetenv("DEFAULT_BROWSER");
if (browserVariable.isEmpty())
browserVariable = qgetenv("BROWSER");
if (!browserVariable.isEmpty() && checkExecutable(QString::fromLocal8Bit(browserVariable), browser))
return true;
}
switch (desktop) {
case QGenericUnixServices::DE_UNKNOWN:
break;
case QGenericUnixServices::DE_KDE:
// Konqueror launcher
if (checkExecutable(QStringLiteral("kfmclient"), browser)) {
browser->append(QStringLiteral(" exec"));
return true;
}
case QGenericUnixServices::DE_GNOME:
if (checkExecutable(QStringLiteral("gnome-open"), browser))
return true;
break;
}
for (size_t i = 0; i < sizeof(browsers)/sizeof(char *); ++i)
if (checkExecutable(QLatin1String(browsers[i]), browser))
return true;
return false;
}
static inline bool launch(const QString &launcher, const QUrl &url)
{
const QString command = launcher + QLatin1Char(' ') + QLatin1String(url.toEncoded());
if (debug)
qDebug("Launching %s", qPrintable(command));
#if defined(QT_NO_PROCESS)
const bool ok = ::system(qPrintable(command + QStringLiteral(" &")));
#else
const bool ok = QProcess::startDetached(command);
#endif
if (!ok)
qWarning("Launch failed (%s)", qPrintable(command));
return ok;
}
QGenericUnixServices::QGenericUnixServices() :
m_desktopEnvironment(detectDesktopEnvironment())
{
}
bool QGenericUnixServices::openUrl(const QUrl &url)
{
if (url.scheme() == QStringLiteral("mailto"))
return openDocument(url);
if (m_webBrowser.isEmpty() && !detectWebBrowser(m_desktopEnvironment, true, &m_webBrowser)) {
qWarning("%s: Unable to detect a web browser to launch '%s'", Q_FUNC_INFO, qPrintable(url.toString()));
return false;
}
return launch(m_webBrowser, url);
}
bool QGenericUnixServices::openDocument(const QUrl &url)
{
if (m_documentLauncher.isEmpty() && !detectWebBrowser(m_desktopEnvironment, false, &m_documentLauncher)) {
qWarning("%s: Unable to detect a launcher for '%s'", Q_FUNC_INFO, qPrintable(url.toString()));
return false;
}
return launch(m_documentLauncher, url);
}
QT_END_NAMESPACE

View File

@ -0,0 +1,76 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QGENERICUNIXDESKTOPSERVICES_H
#define QGENERICUNIXDESKTOPSERVICES_H
#include <QtGui/qplatformservices_qpa.h>
#include <QtCore/QString>
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
class QGenericUnixServices : public QPlatformServices
{
public:
enum DesktopEnvironment {
DE_UNKNOWN,
DE_KDE,
DE_GNOME
};
QGenericUnixServices();
virtual bool openUrl(const QUrl &url);
virtual bool openDocument(const QUrl &url);
private:
const DesktopEnvironment m_desktopEnvironment;
QString m_webBrowser;
QString m_documentLauncher;
};
QT_END_NAMESPACE
QT_END_HEADER
#endif // QGENERICUNIXDESKTOPSERVICES_H

View File

@ -0,0 +1,3 @@
unix:!mac {
include($$PWD/genericunix/genericunix.pri)
}

View File

@ -46,6 +46,7 @@
#include "qwindowsglcontext.h"
#include "qwindowsscreen.h"
#include "qwindowstheme.h"
#include "qwindowsservices.h"
#ifndef QT_NO_FREETYPE
#include "qwindowsfontdatabase_ft.h"
#endif
@ -162,6 +163,7 @@ struct QWindowsIntegrationPrivate
QWindowsInputContext m_inputContext;
QWindowsAccessibility m_accessibility;
QWindowsTheme m_theme;
QWindowsServices m_services;
};
QWindowsIntegrationPrivate::QWindowsIntegrationPrivate()
@ -339,4 +341,9 @@ QPlatformTheme *QWindowsIntegration::platformTheme() const
return &d->m_theme;
}
QPlatformServices *QWindowsIntegration::services() const
{
return &d->m_services;
}
QT_END_NAMESPACE

View File

@ -70,6 +70,7 @@ public:
virtual QPlatformNativeInterface *nativeInterface() const;
virtual QPlatformFontDatabase *fontDatabase() const;
virtual QPlatformTheme *platformTheme() const;
QPlatformServices *services() const;
virtual QVariant styleHint(StyleHint hint) const;
static QWindowsIntegration *instance();

View File

@ -0,0 +1,154 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwindowsservices.h"
#include "qtwindows_additional.h"
#include <QtCore/QUrl>
#include <QtCore/QDebug>
#include <shlobj.h>
#include <intshcut.h>
QT_BEGIN_NAMESPACE
enum { debug = 0 };
static inline bool shellExecute(const QString &file)
{
const int result = (int)ShellExecute(0, 0, (wchar_t*)file.utf16(), 0, 0, SW_SHOWNORMAL);
// ShellExecute returns a value greater than 32 if successful
if (result <= 32) {
qWarning("ShellExecute '%s' failed (error %0x).", qPrintable(file), result);
return false;
}
return true;
}
// Retrieve the commandline for the default mail client. It contains a
// placeholder %1 for the URL. The default key used below is the
// command line for the mailto: shell command.
static inline QString mailCommand()
{
enum { BufferSize = sizeof(wchar_t) * MAX_PATH };
const wchar_t mailUserKey[] = L"Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\mailto\\UserChoice";
wchar_t command[MAX_PATH] = {0};
// Check if user has set preference, otherwise use default.
HKEY handle;
QString keyName;
if (!RegOpenKeyEx(HKEY_CURRENT_USER, mailUserKey, 0, KEY_READ, &handle)) {
DWORD bufferSize = BufferSize;
if (!RegQueryValueEx(handle, L"Progid", 0, 0, reinterpret_cast<unsigned char*>(command), &bufferSize))
keyName = QString::fromWCharArray(command);
RegCloseKey(handle);
}
if (keyName.isEmpty())
keyName = QStringLiteral("mailto");
keyName += QStringLiteral("\\Shell\\Open\\Command");
if (debug)
qDebug() << __FUNCTION__ << "keyName=" << keyName;
command[0] = 0;
if (!RegOpenKeyExW(HKEY_CLASSES_ROOT, (const wchar_t*)keyName.utf16(), 0, KEY_READ, &handle)) {
DWORD bufferSize = BufferSize;
RegQueryValueEx(handle, L"", 0, 0, reinterpret_cast<unsigned char*>(command), &bufferSize);
RegCloseKey(handle);
}
if (!command[0])
return QString();
wchar_t expandedCommand[MAX_PATH] = {0};
return ExpandEnvironmentStrings(command, expandedCommand, MAX_PATH) ?
QString::fromWCharArray(expandedCommand) : QString::fromWCharArray(command);
}
static inline bool launchMail(const QUrl &url)
{
QString command = mailCommand();
if (command.isEmpty()) {
qWarning("Cannot launch '%s': There is no mail program installed.");
return false;
}
//Make sure the path for the process is in quotes
const QChar doubleQuote = QLatin1Char('"');
if (!command.startsWith(doubleQuote)) {
const int exeIndex = command.indexOf(QStringLiteral(".exe "), 0, Qt::CaseInsensitive);
if (exeIndex != -1) {
command.insert(exeIndex + 4, doubleQuote);
command.prepend(doubleQuote);
}
}
// Pass the url as the parameter. Should use QProcess::startDetached(),
// but that cannot handle a Windows command line [yet].
command.replace(QStringLiteral("%1"), url.toString());
if (debug)
qDebug() << __FUNCTION__ << "Launching" << command;
//start the process
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
if (!CreateProcess(NULL, (wchar_t*)command.utf16(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
qErrnoWarning("Unable to launch '%s'", qPrintable(command));
return false;
}
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return true;
}
bool QWindowsServices::openUrl(const QUrl &url)
{
const QString scheme = url.scheme();
if (scheme.isEmpty())
return openDocument(url);
if (scheme == QStringLiteral("mailto") && launchMail(url))
return true;
return shellExecute(QLatin1String(url.toEncoded()));
}
bool QWindowsServices::openDocument(const QUrl &url)
{
return shellExecute(url.isLocalFile() ? url.toLocalFile() : url.toString());
}
QT_END_NAMESPACE

View File

@ -0,0 +1,58 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWINDOWSDESKTOPSERVICES_H
#define QWINDOWSDESKTOPSERVICES_H
#include <QtGui/qplatformservices_qpa.h>
QT_BEGIN_NAMESPACE
class QWindowsServices : public QPlatformServices
{
public:
bool openUrl(const QUrl &url);
bool openDocument(const QUrl &url);
};
QT_END_NAMESPACE
#endif // QWINDOWSDESKTOPSERVICES_H

View File

@ -13,6 +13,7 @@ LIBS *= -lOpenGL32 -lGdi32 -lUser32 -lOle32 -lWinspool -lImm32 -lWinmm -lOleaut
win32-g++: LIBS *= -luuid
# For the dialog helpers:
LIBS *= -lshlwapi -lShell32
LIBS *= -lAdvapi32
DEFINES *= QT_NO_CAST_FROM_ASCII
@ -46,7 +47,8 @@ SOURCES += \
qwindowsinputcontext.cpp \
qwindowsaccessibility.cpp \
qwindowstheme.cpp \
qwindowsdialoghelpers.cpp
qwindowsdialoghelpers.cpp \
qwindowsservices.cpp
HEADERS += \
qwindowsnativeimage.h \
@ -73,7 +75,8 @@ HEADERS += \
qwindowsinputcontext.h \
qwindowsaccessibility.h \
qwindowstheme.h \
qwindowsdialoghelpers.h
qwindowsdialoghelpers.h \
qwindowsservices.h
# Enable access to HB_Face in harfbuzz includes included by qfontengine_p.h.
DEFINES *= QT_COMPILES_IN_HARFBUZZ

View File

@ -53,6 +53,8 @@
#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
#include <QtPlatformSupport/private/qgenericunixservices_p.h>
#include <stdio.h>
@ -84,7 +86,8 @@
QT_BEGIN_NAMESPACE
QXcbIntegration::QXcbIntegration(const QStringList &parameters)
: m_eventDispatcher(createUnixEventDispatcher())
: m_eventDispatcher(createUnixEventDispatcher()),
m_services(new QGenericUnixServices)
{
QGuiApplicationPrivate::instance()->setEventDispatcher(m_eventDispatcher);
@ -268,4 +271,9 @@ QPlatformSharedGraphicsCache *QXcbIntegration::createPlatformSharedGraphicsCache
}
#endif
QPlatformServices *QXcbIntegration::services() const
{
return m_services.data();
}
QT_END_NAMESPACE

View File

@ -81,6 +81,8 @@ public:
QPlatformSharedGraphicsCache *createPlatformSharedGraphicsCache(const char *cacheId) const;
#endif
QPlatformServices *services() const;
private:
QList<QXcbConnection *> m_connections;
@ -95,6 +97,8 @@ private:
#if defined(QT_USE_XCB_SHARED_GRAPHICS_CACHE)
QScopedPointer<QPlatformSharedGraphicsCache> m_sharedGraphicsCache;
#endif
QScopedPointer<QPlatformServices> m_services;
};
QT_END_NAMESPACE