aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/winextras/qwinjumplist.cpp72
-rw-r--r--src/winextras/qwinjumplist.h4
-rw-r--r--src/winextras/qwinjumplist_p.h1
-rw-r--r--src/winextras/qwinjumplistcategory.cpp49
-rw-r--r--src/winextras/qwinjumplistcategory_p.h2
-rw-r--r--src/winextras/winshobjidl_p.h12
6 files changed, 119 insertions, 21 deletions
diff --git a/src/winextras/qwinjumplist.cpp b/src/winextras/qwinjumplist.cpp
index b0c4277..cc05c0e 100644
--- a/src/winextras/qwinjumplist.cpp
+++ b/src/winextras/qwinjumplist.cpp
@@ -69,6 +69,11 @@ QT_BEGIN_NAMESPACE
files or to display shortcuts to tasks or commands.
*/
+/*!
+ \title Application User Model IDs
+ \externalpage http://msdn.microsoft.com/en-us/library/windows/desktop/dd378459%28v=vs.85%29.aspx
+ */
+
// partial copy of qprocess_win.cpp:qt_create_commandline()
static QString createArguments(const QStringList &arguments)
{
@@ -92,6 +97,17 @@ static QString createArguments(const QStringList &arguments)
return args;
}
+static QString defaultIdentifier()
+{
+ // CompanyName.ProductName(.SubProduct).VersionInformation
+ QStringList identifier(QCoreApplication::applicationName());
+ if (!QCoreApplication::organizationName().isEmpty())
+ identifier.prepend(QCoreApplication::organizationName());
+ if (!QCoreApplication::applicationVersion().isEmpty())
+ identifier.append(QCoreApplication::applicationVersion());
+ return identifier.join(QLatin1Char('.'));
+}
+
QWinJumpListPrivate::QWinJumpListPrivate() :
pDestList(0), recent(0), frequent(0), tasks(0), dirty(false)
{
@@ -155,13 +171,21 @@ void QWinJumpListPrivate::destroy()
bool QWinJumpListPrivate::beginList()
{
- UINT maxSlots;
- IUnknown *array = 0;
- HRESULT hresult = pDestList->BeginList(&maxSlots, IID_IUnknown, reinterpret_cast<void **>(&array));
+ HRESULT hresult = S_OK;
+ if (!identifier.isEmpty()) {
+ wchar_t *id = qt_qstringToNullTerminated(identifier);
+ hresult = pDestList->SetAppID(id);
+ delete[] id;
+ }
+ if (SUCCEEDED(hresult)) {
+ UINT maxSlots = 0;
+ IUnknown *array = 0;
+ hresult = pDestList->BeginList(&maxSlots, IID_IUnknown, reinterpret_cast<void **>(&array));
+ if (array)
+ array->Release();
+ }
if (FAILED(hresult))
QWinJumpListPrivate::warning("BeginList", hresult);
- if (array)
- array->Release();
return SUCCEEDED(hresult);
}
@@ -409,6 +433,7 @@ QWinJumpList::QWinJumpList(QObject *parent) :
HRESULT hresult = CoCreateInstance(CLSID_DestinationList, 0, CLSCTX_INPROC_SERVER, IID_ICustomDestinationList, reinterpret_cast<void **>(&d_ptr->pDestList));
if (FAILED(hresult))
QWinJumpListPrivate::warning("CoCreateInstance", hresult);
+ setIdentifier(defaultIdentifier());
d->invalidate();
}
@@ -428,6 +453,43 @@ QWinJumpList::~QWinJumpList()
}
/*!
+ \property QWinJumpList::identifier
+ \brief the jump list identifier
+
+ Specifies a unique identifier for the application jump list.
+ See \l {Application User Model IDs} on MSDN for further details.
+
+ The default value is based on:
+ \list
+ \li QCoreApplication::organizationName
+ \li QCoreApplication::applicationName
+ \li QCoreApplication::applicationVersion
+ \endlist
+
+ \note The identifier cannot have more than \c 128 characters and
+ cannot contain spaces. A too long identifier is automatically truncated
+ to \c 128 characters, and spaces are replaced by underscores.
+ */
+QString QWinJumpList::identifier() const
+{
+ Q_D(const QWinJumpList);
+ return d->identifier;
+}
+
+void QWinJumpList::setIdentifier(const QString &identifier)
+{
+ Q_D(QWinJumpList);
+ QString id = identifier;
+ id.replace(QLatin1Char(' '), QLatin1Char('_'));
+ if (id.size() > 128)
+ id.truncate(128);
+ if (d->identifier != id) {
+ d->identifier = id;
+ d->invalidate();
+ }
+}
+
+/*!
Returns the recent items category in the jump list.
*/
QWinJumpListCategory *QWinJumpList::recent() const
diff --git a/src/winextras/qwinjumplist.h b/src/winextras/qwinjumplist.h
index bc4f431..08dfa3e 100644
--- a/src/winextras/qwinjumplist.h
+++ b/src/winextras/qwinjumplist.h
@@ -57,11 +57,15 @@ class QWinJumpListCategory;
class Q_WINEXTRAS_EXPORT QWinJumpList : public QObject
{
Q_OBJECT
+ Q_PROPERTY(QString identifier READ identifier WRITE setIdentifier)
public:
explicit QWinJumpList(QObject *parent = 0);
~QWinJumpList();
+ QString identifier() const;
+ void setIdentifier(const QString &identifier);
+
QWinJumpListCategory *recent() const;
QWinJumpListCategory *frequent() const;
QWinJumpListCategory *tasks() const;
diff --git a/src/winextras/qwinjumplist_p.h b/src/winextras/qwinjumplist_p.h
index ca21e33..aa3a754 100644
--- a/src/winextras/qwinjumplist_p.h
+++ b/src/winextras/qwinjumplist_p.h
@@ -89,6 +89,7 @@ public:
QWinJumpListCategory *frequent;
QWinJumpListCategory *tasks;
QList<QWinJumpListCategory *> categories;
+ QString identifier;
bool dirty;
};
diff --git a/src/winextras/qwinjumplistcategory.cpp b/src/winextras/qwinjumplistcategory.cpp
index c338bf6..25b10a2 100644
--- a/src/winextras/qwinjumplistcategory.cpp
+++ b/src/winextras/qwinjumplistcategory.cpp
@@ -45,6 +45,7 @@
#include "qwinjumplistitem_p.h"
#include "qwinfunctions_p.h"
#include "qwinjumplist_p.h"
+#include "winshobjidl_p.h"
#include <shlobj.h>
@@ -73,7 +74,7 @@ QT_BEGIN_NAMESPACE
*/
QWinJumpListCategoryPrivate::QWinJumpListCategoryPrivate() :
- visible(false), jumpList(0), type(QWinJumpListCategory::Custom), pDocList(0)
+ visible(false), jumpList(0), type(QWinJumpListCategory::Custom)
{
}
@@ -95,15 +96,25 @@ void QWinJumpListCategoryPrivate::invalidate()
void QWinJumpListCategoryPrivate::loadRecents()
{
+ Q_ASSERT(jumpList);
+ IApplicationDocumentLists *pDocList = 0;
HRESULT hresult = CoCreateInstance(CLSID_ApplicationDocumentLists, 0, CLSCTX_INPROC_SERVER, IID_IApplicationDocumentLists, reinterpret_cast<void **>(&pDocList));
if (SUCCEEDED(hresult)) {
- IObjectArray *array = 0;
- hresult = pDocList->GetList(type == QWinJumpListCategory::Recent ? ADLT_RECENT : ADLT_FREQUENT,
- 0, IID_IObjectArray, reinterpret_cast<void **>(&array));
+ if (!jumpList->identifier().isEmpty()) {
+ wchar_t *id = qt_qstringToNullTerminated(jumpList->identifier());
+ hresult = pDocList->SetAppID(id);
+ delete[] id;
+ }
if (SUCCEEDED(hresult)) {
- items = QWinJumpListPrivate::fromComCollection(array);
- array->Release();
+ IObjectArray *array = 0;
+ hresult = pDocList->GetList(type == QWinJumpListCategory::Recent ? ADLT_RECENT : ADLT_FREQUENT,
+ 0, IID_IObjectArray, reinterpret_cast<void **>(&array));
+ if (SUCCEEDED(hresult)) {
+ items = QWinJumpListPrivate::fromComCollection(array);
+ array->Release();
+ }
}
+ pDocList->Release();
}
if (FAILED(hresult))
QWinJumpListPrivate::warning("loadRecents", hresult);
@@ -111,10 +122,18 @@ void QWinJumpListCategoryPrivate::loadRecents()
void QWinJumpListCategoryPrivate::addRecent(QWinJumpListItem *item)
{
- if (item->type() == QWinJumpListItem::Link)
- SHAddToRecentDocs(SHARD_LINK, QWinJumpListPrivate::toIShellLink(item));
- else if (item->type() == QWinJumpListItem::Destination)
- SHAddToRecentDocs(SHARD_SHELLITEM, QWinJumpListPrivate::toIShellItem(item));
+ Q_ASSERT(item->type() == QWinJumpListItem::Link);
+ const QString identifier = jumpList ? jumpList->identifier() : QString();
+ wchar_t *id = qt_qstringToNullTerminated(identifier);
+
+ SHARDAPPIDINFOLINK info;
+ info.pszAppID = id;
+ info.psl = QWinJumpListPrivate::toIShellLink(item);
+ if (info.psl) {
+ SHAddToRecentDocs(SHARD_APPIDINFOLINK, &info);
+ info.psl->Release();
+ }
+ delete[] id;
}
void QWinJumpListCategoryPrivate::clearRecents()
@@ -122,6 +141,12 @@ void QWinJumpListCategoryPrivate::clearRecents()
IApplicationDestinations *pDest = 0;
HRESULT hresult = CoCreateInstance(CLSID_ApplicationDestinations, 0, CLSCTX_INPROC_SERVER, IID_IApplicationDestinations, reinterpret_cast<void **>(&pDest));
if (SUCCEEDED(hresult)) {
+ const QString identifier = jumpList ? jumpList->identifier() : QString();
+ if (!identifier.isEmpty()) {
+ wchar_t *id = qt_qstringToNullTerminated(identifier);
+ hresult = pDest->SetAppID(id);
+ delete[] id;
+ }
hresult = pDest->RemoveAllDestinations();
pDest->Release();
}
@@ -144,10 +169,6 @@ QWinJumpListCategory::QWinJumpListCategory(const QString &title) :
QWinJumpListCategory::~QWinJumpListCategory()
{
Q_D(QWinJumpListCategory);
- if (d->pDocList) {
- d->pDocList->Release();
- d->pDocList = 0;
- }
qDeleteAll(d->items);
d->items.clear();
}
diff --git a/src/winextras/qwinjumplistcategory_p.h b/src/winextras/qwinjumplistcategory_p.h
index d49c6f6..7dcef1c 100644
--- a/src/winextras/qwinjumplistcategory_p.h
+++ b/src/winextras/qwinjumplistcategory_p.h
@@ -44,7 +44,6 @@
#define QWINJUMPLISTCATEGORY_P_H
#include "qwinjumplistcategory.h"
-#include "winshobjidl_p.h"
QT_BEGIN_NAMESPACE
@@ -72,7 +71,6 @@ public:
QWinJumpList *jumpList;
QWinJumpListCategory::Type type;
QList<QWinJumpListItem *> items;
- IApplicationDocumentLists *pDocList;
};
QT_END_NAMESPACE
diff --git a/src/winextras/winshobjidl_p.h b/src/winextras/winshobjidl_p.h
index f0f8857..29d27aa 100644
--- a/src/winextras/winshobjidl_p.h
+++ b/src/winextras/winshobjidl_p.h
@@ -242,4 +242,16 @@ public:
#endif
+#if (defined _MSC_VER && _MSC_VER < 1600) || defined(Q_CC_MINGW)
+
+typedef struct SHARDAPPIDINFOLINK
+{
+ IShellLink *psl; // An IShellLink instance that when launched opens a recently used item in the specified
+ // application. This link is not added to the recent docs folder, but will be added to the
+ // specified application's destination list.
+ PCWSTR pszAppID; // The id of the application that should be associated with this recent doc.
+} SHARDAPPIDINFOLINK;
+
+#endif
+
#endif // ITASKBARLIST_H