diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index e9c0ccc..ae27b31 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -68,6 +68,7 @@ #define STRICT_TYPED_ITEMIDS #include +#include #include // #define USE_NATIVE_COLOR_DIALOG /* Testing purposes only */ @@ -355,6 +356,70 @@ static inline QString guidToString(const GUID &g) inline QDebug operator<<(QDebug d, const GUID &g) { d.nospace() << guidToString(g); return d; } +/* +SIGDN_NORMALDISPLAY = 0x00000000, +SIGDN_PARENTRELATIVEPARSING = (int)0x80018001, +SIGDN_DESKTOPABSOLUTEPARSING = (int)0x80028000, +SIGDN_PARENTRELATIVEEDITING = (int)0x80031001, +SIGDN_DESKTOPABSOLUTEEDITING = (int)0x8004c000, +SIGDN_FILESYSPATH = (int)0x80058000, +SIGDN_URL = (int)0x80068000, +SIGDN_PARENTRELATIVEFORADDRESSBAR = (int)0x8007c001, +SIGDN_PARENTRELATIVE = (int)0x80080001, +SIGDN_PARENTRELATIVEFORUI +*/ + +static inline QString getItemString(IShellItem *item, SIGDN sigdn) +{ + LPWSTR name = 0; + if (SUCCEEDED(item->GetDisplayName(sigdn, &name))) { + const QString result = QString::fromWCharArray(name); + CoTaskMemFree(name); + return result; + } + return QString(); +} + +#define DEBUG_SHELL_ITEM(item, sigdn) str << ' ' << #sigdn << ": \"" << getItemString(item, sigdn) << '"'; + +static void formatItem(IShellItem *item, QTextStream &str, int depth = 0) +{ + SFGAOF attributes = 0; + item->GetAttributes(SFGAO_STORAGECAPMASK | SFGAO_CONTENTSMASK, &attributes); + str << QString(2 * depth, QLatin1Char(' ')) + << hex << " Attributes: 0x" << attributes << dec; + if (attributes & SFGAO_LINK) + str << " [link]"; + DEBUG_SHELL_ITEM(item, SIGDN_NORMALDISPLAY) + DEBUG_SHELL_ITEM(item, SIGDN_PARENTRELATIVEPARSING) + DEBUG_SHELL_ITEM(item, SIGDN_DESKTOPABSOLUTEPARSING) + DEBUG_SHELL_ITEM(item, SIGDN_PARENTRELATIVEEDITING) + DEBUG_SHELL_ITEM(item, SIGDN_DESKTOPABSOLUTEEDITING) + DEBUG_SHELL_ITEM(item, SIGDN_FILESYSPATH) + DEBUG_SHELL_ITEM(item, SIGDN_URL) + DEBUG_SHELL_ITEM(item, SIGDN_PARENTRELATIVEFORADDRESSBAR) + DEBUG_SHELL_ITEM(item, SIGDN_PARENTRELATIVE) + if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS8) + DEBUG_SHELL_ITEM(item, SIGDN_PARENTRELATIVEFORUI) + str << '\n'; + IShellItem *parent = 0; + if (SUCCEEDED(item->GetParent(&parent)) && parent) + formatItem(parent, str, depth + 1); +} + +inline QDebug operator<<(QDebug debug, IShellItem *item) +{ + if (item) { + QString result; + QTextStream str(&result); + formatItem(item, str); + debug.nospace() << result; + } else { + debug << "null"; + } + return debug; +} + namespace QWindowsDialogs { /*! @@ -974,13 +1039,44 @@ void QWindowsNativeFileDialogBase::setMode(QFileDialogOptions::FileMode mode, QF QString QWindowsNativeFileDialogBase::itemPath(IShellItem *item) { - QString result; - LPWSTR name = 0; - if (SUCCEEDED(item->GetDisplayName(SIGDN_FILESYSPATH, &name))) { - result = QDir::cleanPath(QString::fromWCharArray(name)); - CoTaskMemFree(name); + SFGAOF attributes = 0; + qDebug() << item; + if (FAILED(item->GetAttributes(SFGAO_FILESYSTEM, &attributes))) + return QString(); + // Does it have a file system representation? + if (SFGAO_FILESYSTEM & attributes) + return QDir::cleanPath(getItemString(item, SIGDN_FILESYSPATH)); + // Try to construct from parent path. + QString name = getItemString(item, SIGDN_NORMALDISPLAY); + name = getItemString(item, SIGDN_DESKTOPABSOLUTEPARSING); + IShellItem2 *item2 = 0; + const HRESULT hr = + QWindowsContext::shell32dll.sHCreateItemFromParsingName(reinterpret_cast(name.utf16()), + NULL, IID_IShellItem2, + reinterpret_cast(&item2)); + + + wchar_t *n; + if (SUCCEEDED(item2->GetString(PKEY_FileName, &n))) + qDebug() <<"FN" << QString::fromWCharArray(n); + WIN32_FIND_DATAW findData; + PROPVARIANT property; + + + ZeroMemory(&property, sizeof(PROPVARIANT)); + if (SUCCEEDED(item2->GetProperty(PKEY_FindData, &property))) { + qDebug() <<"FD " << QByteArray((char *)&property, int(sizeof(property))).toHex() + << hex << property.vt << dec << property.ppunkVal; + char *p = (char*)&property + sizeof(property) - sizeof(void *); + qDebug("FD %p", p); + WIN32_FIND_DATAW *fw = *(WIN32_FIND_DATAW **)(p); + qDebug("FW %p", fw); + qDebug() << "FW " << QString::fromWCharArray(fw->cFileName) + << QString::fromWCharArray(fw->cAlternateFileName); + + } - return result; + return QString(); } int QWindowsNativeFileDialogBase::itemPaths(IShellItemArray *items, @@ -991,6 +1087,7 @@ int QWindowsNativeFileDialogBase::itemPaths(IShellItemArray *items, result->clear(); if (FAILED(items->GetCount(&itemCount))) return 0; + qDebug() << __FUNCTION__ << itemCount; if (result && itemCount) { result->reserve(itemCount); for (DWORD i = 0; i < itemCount; ++i) { diff --git a/tests/manual/dialogs/dialogs.pro b/tests/manual/dialogs/dialogs.pro index fe40994..0d85c0c 100644 --- a/tests/manual/dialogs/dialogs.pro +++ b/tests/manual/dialogs/dialogs.pro @@ -3,6 +3,6 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = dialogs TEMPLATE = app - +CONFIG+=console SOURCES += main.cpp filedialogpanel.cpp colordialogpanel.cpp fontdialogpanel.cpp HEADERS += filedialogpanel.h colordialogpanel.h fontdialogpanel.h