src/gui/util/qdesktopservices_win.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gui/util/qdesktopservices_win.cpp	Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,267 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qsettings.h>
+#include <qdir.h>
+#include <qlibrary.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
+
+#if defined(Q_CC_MINGW) && !defined(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 = 2 * MAX_PATH;
+        long  returnValue =  -1;
+        QString command;
+
+        HKEY handle;
+        LONG res;
+        wchar_t keyValue[2 * MAX_PATH] = {0};
+        QString keyName(QLatin1String("mailto"));
+
+        //Check if user has set preference, otherwise use default.
+        res = RegOpenKeyExW(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 = 2 * MAX_PATH;
+        returnValue = RegQueryValueExW(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);
+}
+
+QString QDesktopServices::storageLocation(StandardLocation type)
+{
+    QString result;
+
+#ifndef Q_OS_WINCE
+        QLibrary library(QLatin1String("shell32"));
+#else
+        QLibrary library(QLatin1String("coredll"));
+#endif // Q_OS_WINCE
+    typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, LPWSTR, int, BOOL);
+    static GetSpecialFolderPath SHGetSpecialFolderPath =
+            (GetSpecialFolderPath)library.resolve("SHGetSpecialFolderPathW");
+    if (!SHGetSpecialFolderPath)
+        return QString();
+
+    wchar_t path[MAX_PATH];
+
+    switch (type) {
+    case DataLocation:
+#if defined Q_WS_WINCE
+        if (SHGetSpecialFolderPath(0, path, CSIDL_APPDATA, FALSE))
+#else
+        if (SHGetSpecialFolderPath(0, path, CSIDL_LOCAL_APPDATA, FALSE))
+#endif
+            result = QString::fromWCharArray(path);
+        if (!QCoreApplication::organizationName().isEmpty())
+            result = result + QLatin1String("\\") + QCoreApplication::organizationName();
+        if (!QCoreApplication::applicationName().isEmpty())
+            result = result + QLatin1String("\\") + QCoreApplication::applicationName();
+        break;
+
+    case DesktopLocation:
+        if (SHGetSpecialFolderPath(0, path, CSIDL_DESKTOPDIRECTORY, FALSE))
+            result = QString::fromWCharArray(path);
+        break;
+
+    case DocumentsLocation:
+        if (SHGetSpecialFolderPath(0, path, CSIDL_PERSONAL, FALSE))
+            result = QString::fromWCharArray(path);
+        break;
+
+    case FontsLocation:
+        if (SHGetSpecialFolderPath(0, path, CSIDL_FONTS, FALSE))
+            result = QString::fromWCharArray(path);
+        break;
+
+    case ApplicationsLocation:
+        if (SHGetSpecialFolderPath(0, path, CSIDL_PROGRAMS, FALSE))
+            result = QString::fromWCharArray(path);
+        break;
+
+    case MusicLocation:
+        if (SHGetSpecialFolderPath(0, path, CSIDL_MYMUSIC, FALSE))
+            result = QString::fromWCharArray(path);
+        break;
+
+    case MoviesLocation:
+        if (SHGetSpecialFolderPath(0, path, CSIDL_MYVIDEO, FALSE))
+            result = QString::fromWCharArray(path);
+        break;
+
+    case PicturesLocation:
+        if (SHGetSpecialFolderPath(0, path, CSIDL_MYPICTURES, FALSE))
+            result = QString::fromWCharArray(path);
+        break;
+
+    case CacheLocation:
+        // Although Microsoft has a Cache key it is a pointer to IE's cache, not a cache
+        // location for everyone.  Most applications seem to be using a
+        // cache directory located in their AppData directory
+        return storageLocation(DataLocation) + QLatin1String("\\cache");
+
+    case QDesktopServices::HomeLocation:
+        return QDir::homePath(); break;
+
+    case QDesktopServices::TempLocation:
+        return QDir::tempPath(); break;
+
+    default:
+        break;
+    }
+    return result;
+}
+
+QString QDesktopServices::displayName(StandardLocation type)
+{
+    Q_UNUSED(type);
+    return QString();
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_DESKTOPSERVICES