summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Repository.mk2
-rwxr-xr-xoffapi/com/sun/star/system/windows/JumpListItem.idl18
-rwxr-xr-xoffapi/com/sun/star/system/windows/XJumpList.idl43
-rwxr-xr-xshell/source/win32/jumplist/JumpList.cxx100
4 files changed, 142 insertions, 21 deletions
diff --git a/Repository.mk b/Repository.mk
index 6a6b8bd12e06..e869694cde21 100644
--- a/Repository.mk
+++ b/Repository.mk
@@ -391,7 +391,7 @@ $(eval $(call gb_Helper_register_libraries_for_install,OOOLIBS,ooo, \
hyphen \
icg \
$(if $(ENABLE_JAVA),jdbc) \
- $(if $(filter $(OS),WNT),jumplist) \
+ $(if $(filter WNT,$(OS)),jumplist) \
$(if $(ENABLE_LDAP),ldapbe2) \
$(if $(filter WNT,$(OS)),WinUserInfoBe) \
localebe1 \
diff --git a/offapi/com/sun/star/system/windows/JumpListItem.idl b/offapi/com/sun/star/system/windows/JumpListItem.idl
index 310e5551911a..30a8bdd6f7e4 100755
--- a/offapi/com/sun/star/system/windows/JumpListItem.idl
+++ b/offapi/com/sun/star/system/windows/JumpListItem.idl
@@ -24,17 +24,27 @@ module com { module sun { module star { module system { module windows {
struct JumpListItem
{
- /** Item name. Appears in the JumpList. Has to be unique per category. */
+ /** Item name. Appears in the JumpList.
+ Has to be unique per category.
+ Must not include embedded NULs ('\\0'). */
string name;
- /** Item description, appears as tooltip */
+ /** Item description, appears as tooltip.
+ Must not include embedded NULs ('\\0').
+ */
string description;
/** Arguments to be passed to LibreOffice.
- This can be a file to be loaded, or any command line parameter supported by LibreOffice, and any combination of the two. */
+ This can be a file to be loaded, or any command line parameter supported by LibreOffice, and any combination of the two.
+ Add multiple arguments separated by space.
+ Must not include embedded NULs ('\\0').
+ */
string arguments;
- /** Icon to be displayed along the name. This should be a local path name like `C:\path\to\icon` */
+ /** Icon to be displayed along the name.
+ Must be a local path name like `C:\\path\\to\\icon.ico`.
+ Icon must be in ICO format.
+ */
string iconPath;
};
diff --git a/offapi/com/sun/star/system/windows/XJumpList.idl b/offapi/com/sun/star/system/windows/XJumpList.idl
index c483149e5dd8..80fef03b60aa 100755
--- a/offapi/com/sun/star/system/windows/XJumpList.idl
+++ b/offapi/com/sun/star/system/windows/XJumpList.idl
@@ -23,16 +23,26 @@ module com { module sun { module star { module system { module windows {
*/
interface XJumpList: com::sun::star::uno::XInterface
{
- /** Add a jump list category
+ /** Add (or update) a jump list category.
+
+ Note that it is only possible to have one jump list category per `application`.
+
+ When there is already a jump list for the given `application`,
+ that jump list will be cleared, and the new `category` and `jumpListItems` will be added.
@param category
Specifies the category name. It will appear as the title of the custom jump list.
+ Must not include embedded NULs ('\\0')
@param jumpListItems
Specifies a list of com::sun::star::system::JumpListItem.
+ Must contain at least one item.
These will be added as entries below the category name in the custom jump list.
+
Make sure you don't add items which the user has removed before
(check the result of `getRemovedItems` before updating a category).
+ If you try to add items which the user removed before,
+ they will be silently ignored and not added to the list.
@param application
Used to map the jump list to the correct application. Use one of the following values:
@@ -49,16 +59,43 @@ interface XJumpList: com::sun::star::uno::XInterface
"Startcenter" will map to the generic "LibreOffice" icon.
@throws com::sun::star::lang::IllegalArgumentException
- When an empty category name, or an invalid application name is given.
+ When one of the following applies:
+ <ul>
+ <li>`category` is empty</li>
+ <li>`jumpListItems` is empty or contains only items which were removed by the user</li>
+ <li>`application` is invalid</li>
+ </ul>
*/
void appendCategory( [in] string category,
[in] sequence<com::sun::star::system::windows::JumpListItem> jumpListItems,
[in] string application )
raises( ::com::sun::star::lang::IllegalArgumentException );
+ /** Delete a jump list category
+
+ @param application
+ Used to map the jump list to the correct application. Use one of the following values:
+ <ul>
+ <li>Writer</li>
+ <li>Calc</li>
+ <li>Impress</li>
+ <li>Draw</li>
+ <li>Math</li>
+ <li>Base</li>
+ <li>Startcenter</li>
+ </ul>
+
+ "Startcenter" will map to the generic "LibreOffice" icon.
+
+ @throws com::sun::star::lang::IllegalArgumentException
+ When `application` is invalid
+ */
+ void deleteCategory( [in] string application )
+ raises( ::com::sun::star::lang::IllegalArgumentException );
+
/** Returns items that were removed from the jump list by the user.
- `appendCategory` will fail if you try to reinsert an item which was removed by the user before.
+ `appendCategory` will ignore items which were removed by the user before.
Use this method to learn which items were removed by the user.
@param application
diff --git a/shell/source/win32/jumplist/JumpList.cxx b/shell/source/win32/jumplist/JumpList.cxx
index 74874c8bc53e..cbc72299b41a 100755
--- a/shell/source/win32/jumplist/JumpList.cxx
+++ b/shell/source/win32/jumplist/JumpList.cxx
@@ -12,10 +12,10 @@
#include <algorithm>
#include <cassert>
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/compbase.hxx>
#include <comphelper/sequence.hxx>
#include <cppuhelper/supportsservice.hxx>
-#include <cppuhelper/compbase.hxx>
-
#include <o3tl/char16_t2wchar_t.hxx>
#include <o3tl/runtimetooustring.hxx>
#include <o3tl/safeCoInitUninit.hxx>
@@ -23,6 +23,7 @@
#include <osl/mutex.hxx>
#include <osl/process.h>
#include <sal/log.hxx>
+#include <systools/win32/comtools.hxx>
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
@@ -34,7 +35,6 @@
#include <Shlobj.h>
#include <propkey.h>
#include <propvarutil.h>
-#include <systools/win32/comtools.hxx>
#include <postwin.h>
using namespace comphelper;
@@ -44,16 +44,14 @@ using namespace css::uno;
using namespace css::lang;
using namespace css::system::windows;
using namespace osl;
-
using sal::systools::COMReference;
using sal::systools::COM_QUERY_THROW;
using sal::systools::ComError;
using sal::systools::ThrowIfFailed;
-class JumpListImpl : public WeakComponentImplHelper<XJumpList, XServiceInfo>
+class JumpListImpl : public BaseMutex, public WeakComponentImplHelper<XJumpList, XServiceInfo>
{
Reference<XComponentContext> m_xContext;
- Mutex m_aMutex;
public:
explicit JumpListImpl(const Reference<XComponentContext>& xContext);
@@ -62,9 +60,9 @@ public:
// XJumpList
virtual void SAL_CALL appendCategory(const OUString& sCategory,
const Sequence<JumpListItem>& aJumpListItems,
- const OUString& sDocumentService) override;
- virtual Sequence<JumpListItem>
- SAL_CALL getRemovedItems(const OUString& sDocumentService) override;
+ const OUString& sApplication) override;
+ virtual void SAL_CALL deleteCategory(const OUString& sApplication) override;
+ virtual Sequence<JumpListItem> SAL_CALL getRemovedItems(const OUString& sApplication) override;
// XServiceInfo
virtual OUString SAL_CALL getImplementationName() override;
@@ -80,6 +78,39 @@ JumpListImpl::JumpListImpl(const Reference<XComponentContext>& xContext)
JumpListImpl::~JumpListImpl() {}
+namespace
+{
+// Determines if the provided IShellLinkItem is listed in the array of items that the user has removed
+bool lcl_isItemInArray(COMReference<IShellLinkW> pShellLinkItem,
+ COMReference<IObjectArray> poaRemoved)
+{
+ UINT nItems;
+ ThrowIfFailed(poaRemoved->GetCount(&nItems), "GetCount failed.");
+
+ COMReference<IShellLinkW> pShellLinkItemCompare;
+ for (UINT i = 0; i < nItems; i++)
+ {
+ if (!SUCCEEDED(poaRemoved->GetAt(i, IID_PPV_ARGS(&pShellLinkItemCompare))))
+ continue;
+
+ PROPVARIANT propvar;
+ COMReference<IPropertyStore> pps(pShellLinkItem, COM_QUERY_THROW);
+ ThrowIfFailed(pps->GetValue(PKEY_Title, &propvar), "GetValue failed.");
+ OUString title(o3tl::toU(PropVariantToStringWithDefault(propvar, L"")));
+
+ COMReference<IPropertyStore> ppsCompare(pShellLinkItemCompare, COM_QUERY_THROW);
+ ThrowIfFailed(ppsCompare->GetValue(PKEY_Title, &propvar), "GetValue failed.");
+ OUString titleCompare(o3tl::toU(PropVariantToStringWithDefault(propvar, L"")));
+ PropVariantClear(&propvar);
+
+ if (title == titleCompare)
+ return true;
+ }
+
+ return false;
+}
+}
+
void SAL_CALL JumpListImpl::appendCategory(const OUString& sCategory,
const Sequence<JumpListItem>& aJumpListItems,
const OUString& sApplication)
@@ -143,7 +174,7 @@ void SAL_CALL JumpListImpl::appendCategory(const OUString& sCategory,
COMReference<IPropertyStore> pps(pShellLinkItem, COM_QUERY_THROW);
PROPVARIANT propvar;
- sal::systools::ThrowIfFailed(
+ ThrowIfFailed(
InitPropVariantFromString(o3tl::toW(item.name.getStr()), &propvar),
"InitPropVariantFromString failed.");
@@ -168,6 +199,14 @@ void SAL_CALL JumpListImpl::appendCategory(const OUString& sCategory,
pShellLinkItem->SetIconLocation(o3tl::toW(item.iconPath.getStr()), 0),
OString("Setting icon path '" + item.iconPath.toUtf8() + "' failed."));
+ if (lcl_isItemInArray(pShellLinkItem, removed))
+ {
+ SAL_INFO("shell.jumplist", "Ignoring item '"
+ << item.name
+ << "' (was removed by user). See output of "
+ "XJumpList::getRemovedItems().");
+ continue;
+ }
aCollection->AddObject(pShellLinkItem.get());
}
catch (const ComError& e)
@@ -177,11 +216,20 @@ void SAL_CALL JumpListImpl::appendCategory(const OUString& sCategory,
}
}
- sal::systools::COMReference<IObjectArray> pObjectArray(aCollection, COM_QUERY_THROW);
+ COMReference<IObjectArray> pObjectArray(aCollection, COM_QUERY_THROW);
+ UINT nItems;
+ ThrowIfFailed(pObjectArray->GetCount(&nItems), "GetCount failed.");
+ if (nItems == 0)
+ {
+ throw IllegalArgumentException(
+ "No valid items given. `jumpListItems` is either empty, or contains only items "
+ "which were removed by the user. See `XJumpList::getRemovedItems()`.",
+ static_cast<OWeakObject*>(this), 1);
+ }
+
ThrowIfFailed(
aDestinationList->AppendCategory(o3tl::toW(sCategory.getStr()), pObjectArray.get()),
- "AppendCategory failed. You are not allowed to immediately re-insert entries which "
- "were removed by the user. Please see the output of `getRemovedItems`.");
+ "AppendCategory failed.");
ThrowIfFailed(aDestinationList->CommitList(), "CommitList failed.");
}
@@ -191,6 +239,32 @@ void SAL_CALL JumpListImpl::appendCategory(const OUString& sCategory,
}
}
+void SAL_CALL JumpListImpl::deleteCategory(const OUString& sApplication)
+{
+ if (sApplication != "Writer" && sApplication != "Calc" && sApplication != "Impress"
+ && sApplication != "Draw" && sApplication != "Math" && sApplication != "Base"
+ && sApplication != "Startcenter")
+ {
+ throw IllegalArgumentException(
+ "Parameter 'application' must be one of 'Writer', 'Calc', 'Impress', 'Draw', "
+ "'Math', 'Base', 'Startcenter'.",
+ static_cast<OWeakObject*>(this), 1);
+ }
+ OUString sApplicationID("TheDocumentFoundation.LibreOffice." + sApplication);
+
+ try
+ {
+ COMReference<ICustomDestinationList> aDestinationList;
+ CoCreateInstance(CLSID_DestinationList, nullptr, CLSCTX_INPROC_SERVER,
+ IID_PPV_ARGS(&aDestinationList));
+ aDestinationList->DeleteList(o3tl::toW(sApplicationID.getStr()));
+ }
+ catch (const ComError& e)
+ {
+ SAL_WARN("shell.jumplist", e.what());
+ }
+}
+
Sequence<JumpListItem> SAL_CALL JumpListImpl::getRemovedItems(const OUString& sApplication)
{
if (sApplication != "Writer" && sApplication != "Calc" && sApplication != "Impress"