Add QPlatformServices class.
authorFriedemann Kleint <Friedemann.Kleint@nokia.com>
Wed, 8 Feb 2012 07:40:48 +0000 (08:40 +0100)
committerQt by Nokia <qt-info@nokia.com>
Fri, 10 Feb 2012 21:53:13 +0000 (22:53 +0100)
- 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>
21 files changed:
src/gui/kernel/kernel.pri
src/gui/kernel/qplatformintegration_qpa.cpp
src/gui/kernel/qplatformintegration_qpa.h
src/gui/kernel/qplatformservices_qpa.cpp [new file with mode: 0644]
src/gui/kernel/qplatformservices_qpa.h [moved from src/gui/util/qdesktopservices_qpa.cpp with 83% similarity]
src/gui/util/qdesktopservices.cpp
src/gui/util/qdesktopservices_mac.cpp [deleted file]
src/gui/util/qdesktopservices_win.cpp [deleted file]
src/gui/util/qdesktopservices_x11.cpp [deleted file]
src/platformsupport/platformsupport.pro
src/platformsupport/services/genericunix/genericunix.pri [new file with mode: 0644]
src/platformsupport/services/genericunix/qgenericunixservices.cpp [new file with mode: 0644]
src/platformsupport/services/genericunix/qgenericunixservices_p.h [new file with mode: 0644]
src/platformsupport/services/services.pri [new file with mode: 0644]
src/plugins/platforms/windows/qwindowsintegration.cpp
src/plugins/platforms/windows/qwindowsintegration.h
src/plugins/platforms/windows/qwindowsservices.cpp [new file with mode: 0644]
src/plugins/platforms/windows/qwindowsservices.h [new file with mode: 0644]
src/plugins/platforms/windows/windows.pro
src/plugins/platforms/xcb/qxcbintegration.cpp
src/plugins/platforms/xcb/qxcbintegration.h

index 7b01ba1..9c5f3b1 100644 (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 += \
index e867e4e..1336a1a 100644 (file)
@@ -107,6 +107,11 @@ QPlatformNativeInterface * QPlatformIntegration::nativeInterface() const
     return 0;
 }
 
+QPlatformServices *QPlatformIntegration::services() const
+{
+    return 0;
+}
+
 /*!
     \class QPlatformIntegration
     \since 4.8
index efaf495..bd9ecd5 100644 (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,
diff --git a/src/gui/kernel/qplatformservices_qpa.cpp b/src/gui/kernel/qplatformservices_qpa.cpp
new file mode 100644 (file)
index 0000000..7993a82
--- /dev/null
@@ -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
similarity index 83%
rename from src/gui/util/qdesktopservices_qpa.cpp
rename to src/gui/kernel/qplatformservices_qpa.h
index b94267e..aff2e5d 100644 (file)
 **
 ****************************************************************************/
 
-#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
index 0f1312e..13e2585 100644 (file)
 
 #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);
 }
 
 /*!
diff --git a/src/gui/util/qdesktopservices_mac.cpp b/src/gui/util/qdesktopservices_mac.cpp
deleted file mode 100644 (file)
index 84c7156..0000000
+++ /dev/null
@@ -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
diff --git a/src/gui/util/qdesktopservices_win.cpp b/src/gui/util/qdesktopservices_win.cpp
deleted file mode 100644 (file)
index 88f245d..0000000
+++ /dev/null
@@ -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
diff --git a/src/gui/util/qdesktopservices_x11.cpp b/src/gui/util/qdesktopservices_x11.cpp
deleted file mode 100644 (file)
index 73cf47a..0000000
+++ /dev/null
@@ -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
index 64decd0..4c02a8f 100644 (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)
diff --git a/src/platformsupport/services/genericunix/genericunix.pri b/src/platformsupport/services/genericunix/genericunix.pri
new file mode 100644 (file)
index 0000000..6afafa3
--- /dev/null
@@ -0,0 +1,2 @@
+HEADERS += $$PWD/qgenericunixservices_p.h
+SOURCES += $$PWD/qgenericunixservices.cpp
diff --git a/src/platformsupport/services/genericunix/qgenericunixservices.cpp b/src/platformsupport/services/genericunix/qgenericunixservices.cpp
new file mode 100644 (file)
index 0000000..3c10fb6
--- /dev/null
@@ -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
diff --git a/src/platformsupport/services/genericunix/qgenericunixservices_p.h b/src/platformsupport/services/genericunix/qgenericunixservices_p.h
new file mode 100644 (file)
index 0000000..48b790a
--- /dev/null
@@ -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
diff --git a/src/platformsupport/services/services.pri b/src/platformsupport/services/services.pri
new file mode 100644 (file)
index 0000000..adee852
--- /dev/null
@@ -0,0 +1,3 @@
+unix:!mac {
+    include($$PWD/genericunix/genericunix.pri)
+}
index 2771ec7..3e98be4 100644 (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
index a96605f..ba5fafb 100644 (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();
diff --git a/src/plugins/platforms/windows/qwindowsservices.cpp b/src/plugins/platforms/windows/qwindowsservices.cpp
new file mode 100644 (file)
index 0000000..5cc4ce9
--- /dev/null
@@ -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
diff --git a/src/plugins/platforms/windows/qwindowsservices.h b/src/plugins/platforms/windows/qwindowsservices.h
new file mode 100644 (file)
index 0000000..d979ed1
--- /dev/null
@@ -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
index 01976a9..58a117b 100644 (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
index 4035916..0f7648a 100644 (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
index eefecd5..77d0e49 100644 (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