[Libreoffice-commits] core.git: extras/source include/sfx2 include/svx include/vcl sd/source sfx2/source sfx2/uiconfig solenv/bin svx/source sw/source vcl/source vcl/unx
Caolán McNamara (via logerrit)
logerrit at kemper.freedesktop.org
Thu Mar 28 21:07:35 UTC 2019
extras/source/glade/libreoffice-catalog.xml.in | 7
include/sfx2/emojiviewitem.hxx | 2
include/sfx2/inputdlg.hxx | 2
include/sfx2/recentdocsviewitem.hxx | 9
include/sfx2/templatedlg.hxx | 86 -
include/sfx2/templatelocalview.hxx | 121 ++
include/sfx2/templateviewitem.hxx | 2
include/sfx2/thumbnailview.hxx | 184 +++
include/sfx2/thumbnailviewitem.hxx | 6
include/svx/SvxPresetListBox.hxx | 2
include/svx/charmap.hxx | 4
include/vcl/customweld.hxx | 8
include/vcl/layout.hxx | 6
include/vcl/weld.hxx | 22
sd/source/ui/app/sdmod1.cxx | 11
sfx2/source/appl/appopen.cxx | 6
sfx2/source/appl/appserv.cxx | 4
sfx2/source/control/emojiviewitem.cxx | 2
sfx2/source/control/recentdocsviewitem.cxx | 7
sfx2/source/control/templatelocalview.cxx | 888 ++++++++++++++++++
sfx2/source/control/templatesearchview.cxx | 143 +--
sfx2/source/control/templateviewitem.cxx | 2
sfx2/source/control/thumbnailview.cxx | 1176 ++++++++++++++++++++++++-
sfx2/source/control/thumbnailviewacc.cxx | 560 +++++++++++
sfx2/source/control/thumbnailviewacc.hxx | 112 ++
sfx2/source/control/thumbnailviewitem.cxx | 2
sfx2/source/dialog/inputdlg.cxx | 2
sfx2/source/doc/templatedlg.cxx | 690 ++++++--------
sfx2/source/inc/templatesearchview.hxx | 13
sfx2/source/inc/templatesearchviewitem.hxx | 2
sfx2/uiconfig/ui/templatedlg.ui | 170 ++-
solenv/bin/native-code.py | 2
svx/source/dialog/charmap.cxx | 4
svx/source/tbxctrls/SvxPresetListBox.cxx | 5
sw/source/uibase/uiview/view2.cxx | 4
vcl/source/app/customweld.cxx | 2
vcl/source/app/salvtables.cxx | 76 +
vcl/unx/gtk3/gtk3gtkinst.cxx | 109 +-
38 files changed, 3785 insertions(+), 668 deletions(-)
New commits:
commit 3e078e17ee2144fb976a7e6b9227152113cea0d4
Author: Caolán McNamara <caolanm at redhat.com>
AuthorDate: Tue Mar 26 16:27:17 2019 +0000
Commit: Caolán McNamara <caolanm at redhat.com>
CommitDate: Thu Mar 28 22:07:06 2019 +0100
weld SfxTemplateManagerDlg
like expert configuration change the gear menu not to display a down indicator
and use CommandEvent to distinguish mouse/non-mouse context menus
Change-Id: I64bb660a9c7dacb5b90b240d9d76d29324c5fd9f
Reviewed-on: https://gerrit.libreoffice.org/69893
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
Tested-by: Caolán McNamara <caolanm at redhat.com>
diff --git a/extras/source/glade/libreoffice-catalog.xml.in b/extras/source/glade/libreoffice-catalog.xml.in
index abeb0910a2dc..57106338489d 100644
--- a/extras/source/glade/libreoffice-catalog.xml.in
+++ b/extras/source/glade/libreoffice-catalog.xml.in
@@ -134,10 +134,6 @@
generic-name="Gamma Grid Widget" parent="GtkDrawingArea"
icon-name="widget-gtk-drawingarea"/>
- <glade-widget-class title="Template Local View" name="sfxlo-TemplateLocalView"
- generic-name="Template Local View" parent="GtkDrawingArea"
- icon-name="widget-gtk-drawingarea"/>
-
<glade-widget-class title="Mark Preview" name="swuilo-SwMarkPreview"
generic-name="Mark Preview Window" parent="GtkDrawingArea"
icon-name="widget-gtk-drawingarea"/>
@@ -437,9 +433,6 @@
<glade-widget-class title="Template Thumbnail View" name="sfxlo-TemplateDefaultView"
generic-name="Template Icon View" parent="GtkIconView"
icon-name="widget-gtk-iconview"/>
- <glade-widget-class title="Template Search View" name="sfxlo-TemplateSearchView"
- generic-name="Template Icon View" parent="GtkIconView"
- icon-name="widget-gtk-iconview"/>
<glade-widget-class title="Driver List Control" name="cuilo-DriverListControl"
generic-name="DriverListControl" parent="GtkEntry"
diff --git a/include/sfx2/emojiviewitem.hxx b/include/sfx2/emojiviewitem.hxx
index 0ca32e78238f..e0aa57675f9a 100644
--- a/include/sfx2/emojiviewitem.hxx
+++ b/include/sfx2/emojiviewitem.hxx
@@ -15,7 +15,7 @@
class EmojiViewItem : public ThumbnailViewItem
{
public:
- EmojiViewItem (ThumbnailView &rView, sal_uInt16 nId);
+ EmojiViewItem (ThumbnailViewBase &rView, sal_uInt16 nId);
virtual ~EmojiViewItem () override;
diff --git a/include/sfx2/inputdlg.hxx b/include/sfx2/inputdlg.hxx
index 6f50e012e997..bd54b6a5de02 100644
--- a/include/sfx2/inputdlg.hxx
+++ b/include/sfx2/inputdlg.hxx
@@ -21,7 +21,7 @@ private:
std::unique_ptr<weld::Button> m_xHelp;
public:
- InputDialog(weld::Window* pParent, const OUString &rLabelText);
+ InputDialog(weld::Widget* pParent, const OUString &rLabelText);
OUString GetEntryText() const;
void SetEntryText(const OUString& rStr);
void HideHelpBtn();
diff --git a/include/sfx2/recentdocsviewitem.hxx b/include/sfx2/recentdocsviewitem.hxx
index 8320d4710d81..2ee90de19f03 100644
--- a/include/sfx2/recentdocsviewitem.hxx
+++ b/include/sfx2/recentdocsviewitem.hxx
@@ -12,10 +12,15 @@
#include <sfx2/thumbnailview.hxx>
+namespace sfx2
+{
+ class RecentDocsView;
+}
+
class RecentDocsViewItem final : public ThumbnailViewItem
{
public:
- RecentDocsViewItem(ThumbnailView &rView, const OUString &rURL,
+ RecentDocsViewItem(sfx2::RecentDocsView &rView, const OUString &rURL,
const OUString &rTitle, const BitmapEx& rThumbnail, sal_uInt16 nId, long nThumbnailSize);
/** Updates own highlight status based on the aPoint position.
@@ -38,6 +43,8 @@ public:
void OpenDocument();
private:
+ sfx2::RecentDocsView& mrParentView;
+
/// Return area where is the icon to remove document from the recent documents.
tools::Rectangle getRemoveIconArea() const;
diff --git a/include/sfx2/templatedlg.hxx b/include/sfx2/templatedlg.hxx
index 7f730c50161d..5e8a12853419 100644
--- a/include/sfx2/templatedlg.hxx
+++ b/include/sfx2/templatedlg.hxx
@@ -38,18 +38,16 @@ namespace com {
} } }
}
-class SFX2_DLLPUBLIC SfxTemplateManagerDlg : public ModalDialog
+class SFX2_DLLPUBLIC SfxTemplateManagerDlg : public weld::GenericDialogController
{
typedef bool (*selection_cmp_fn)(const ThumbnailViewItem*,const ThumbnailViewItem*);
public:
- SfxTemplateManagerDlg(vcl::Window *parent = nullptr);
+ SfxTemplateManagerDlg(weld::Window *parent);
virtual ~SfxTemplateManagerDlg() override;
- virtual void dispose() override;
- virtual short Execute() override;
- virtual bool EventNotify( NotifyEvent& rNEvt ) override;
+ virtual short run() override;
void setDocumentModel (const css::uno::Reference<css::frame::XModel> &rModel);
@@ -63,21 +61,19 @@ protected:
void fillFolderComboBox();
- DECL_LINK(TBXDropdownHdl, ToolBox*, void);
+ DECL_LINK(SelectApplicationHdl, weld::ComboBox&, void);
+ DECL_LINK(SelectRegionHdl, weld::ComboBox&, void);
- DECL_LINK(SelectApplicationHdl, ListBox&, void);
- DECL_LINK(SelectRegionHdl, ListBox&, void);
-
- DECL_LINK(OkClickHdl, Button*, void);
- DECL_LINK(MoveClickHdl, Button*, void);
- DECL_LINK(ExportClickHdl, Button*, void);
- DECL_LINK(ImportClickHdl, Button*, void);
- DECL_STATIC_LINK(SfxTemplateManagerDlg, LinkClickHdl, Button*, void);
+ DECL_LINK(OkClickHdl, weld::Button&, void);
+ DECL_LINK(MoveClickHdl, weld::Button&, void);
+ DECL_LINK(ExportClickHdl, weld::Button&, void);
+ DECL_LINK(ImportClickHdl, weld::Button&, void);
+ DECL_STATIC_LINK(SfxTemplateManagerDlg, LinkClickHdl, weld::Button&, void);
DECL_LINK(TVItemStateHdl, const ThumbnailViewItem*, void);
- DECL_LINK(MenuSelectHdl, Menu*, bool);
- DECL_LINK(DefaultTemplateMenuSelectHdl, Menu*, bool);
+ DECL_LINK(MenuSelectHdl, const OString&, void);
+ void DefaultTemplateMenuSelectHdl(const OString& rIdent);
DECL_LINK(OpenRegionHdl, void*, void);
DECL_LINK(CreateContextMenuHdl, ThumbnailViewItem*, void);
@@ -86,8 +82,13 @@ protected:
DECL_LINK(DeleteTemplateHdl, ThumbnailViewItem*, void);
DECL_LINK(DefaultTemplateHdl, ThumbnailViewItem*, void);
- DECL_LINK(SearchUpdateHdl, Edit&, void);
- DECL_LINK(GetFocusHdl, Control&, void);
+ void SearchUpdate();
+
+ DECL_LINK(SearchUpdateHdl, weld::Entry&, void);
+ DECL_LINK(GetFocusHdl, weld::Widget&, void);
+ DECL_LINK(LoseFocusHdl, weld::Widget&, void);
+ DECL_LINK(ImplUpdateDataHdl, Timer*, void);
+ DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
void OnTemplateImportCategory(const OUString& sCategory);
static void OnTemplateLink ();
@@ -122,27 +123,28 @@ protected:
FILTER_APPLICATION getCurrentApplicationFilter();
protected:
-
- VclPtr<Edit> mpSearchFilter;
- VclPtr<ListBox> mpCBApp;
- VclPtr<ListBox> mpCBFolder;
-
- VclPtr<PushButton> mpOKButton;
- VclPtr<PushButton> mpMoveButton;
- VclPtr<PushButton> mpExportButton;
- VclPtr<PushButton> mpImportButton;
- VclPtr<PushButton> mpLinkButton;
- VclPtr<CheckBox> mpCBXHideDlg;
- VclPtr<ToolBox> mpActionBar;
- VclPtr<TemplateSearchView> mpSearchView;
- VclPtr<TemplateLocalView> mpLocalView;
- VclPtr<PopupMenu> mpActionMenu;
- VclPtr<PopupMenu> mpTemplateDefaultMenu;
-
std::set<const ThumbnailViewItem*,selection_cmp_fn> maSelTemplates;
-
css::uno::Reference< css::frame::XModel > m_xModel;
css::uno::Reference< css::frame::XDesktop2 > mxDesktop;
+
+ Timer m_aUpdateDataTimer;
+
+ std::unique_ptr<weld::Entry> mxSearchFilter;
+ std::unique_ptr<weld::ComboBox> mxCBApp;
+ std::unique_ptr<weld::ComboBox> mxCBFolder;
+
+ std::unique_ptr<weld::Button> mxOKButton;
+ std::unique_ptr<weld::Button> mxMoveButton;
+ std::unique_ptr<weld::Button> mxExportButton;
+ std::unique_ptr<weld::Button> mxImportButton;
+ std::unique_ptr<weld::Button> mxLinkButton;
+ std::unique_ptr<weld::CheckButton> mxCBXHideDlg;
+ std::unique_ptr<weld::MenuButton> mxActionBar;
+ std::unique_ptr<TemplateSearchView> mxSearchView;
+ std::unique_ptr<SfxTemplateLocalView> mxLocalView;
+ std::unique_ptr<weld::Menu> mxTemplateDefaultMenu;
+ std::unique_ptr<weld::CustomWeld> mxSearchViewWeld;
+ std::unique_ptr<weld::CustomWeld> mxLocalViewWeld;
};
// class SfxTemplateCategoryDialog -------------------------------------------------------------------
@@ -192,23 +194,21 @@ public:
class SFX2_DLLPUBLIC SfxTemplateSelectionDlg : public SfxTemplateManagerDlg
{
public:
- SfxTemplateSelectionDlg(vcl::Window *parent);
+ SfxTemplateSelectionDlg(weld::Window *parent);
virtual ~SfxTemplateSelectionDlg() override;
- virtual void dispose() override;
- virtual short Execute() override;
+ virtual short run() override;
OUString const & getTemplatePath() const { return msTemplatePath; };
- bool IsStartWithTemplate() const { return mpCBXHideDlg->IsChecked(); };
+ bool IsStartWithTemplate() const { return mxCBXHideDlg->get_active(); };
private:
DECL_LINK(OpenTemplateHdl, ThumbnailViewItem*, void);
- DECL_LINK(OkClickHdl, Button*, void);
+ DECL_LINK(OkClickHdl, weld::Button&, void);
- OUString msTemplatePath;
+ OUString msTemplatePath;
};
-
#endif // INCLUDED_SFX2_INC_TEMPLATEDLG_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/sfx2/templatelocalview.hxx b/include/sfx2/templatelocalview.hxx
index b739549580a8..93282b9ae9d0 100644
--- a/include/sfx2/templatelocalview.hxx
+++ b/include/sfx2/templatelocalview.hxx
@@ -193,6 +193,127 @@ protected:
std::vector<TemplateItemProperties > maAllTemplates;
};
+class SFX2_DLLPUBLIC SfxTemplateLocalView : public SfxThumbnailView
+{
+ typedef bool (*selection_cmp_fn)(const ThumbnailViewItem*,const ThumbnailViewItem*);
+
+public:
+
+ SfxTemplateLocalView(std::unique_ptr<weld::ScrolledWindow> xWindow,
+ std::unique_ptr<weld::Menu> xMenu);
+
+ virtual ~SfxTemplateLocalView () override;
+
+ // Fill view with new item list
+ void insertItems (const std::vector<TemplateItemProperties> &rTemplates, bool isRegionSelected = true, bool bShowCategoryInTooltip = false);
+
+ // Fill view with template folders thumbnails
+ void Populate ();
+
+ virtual void reload ();
+
+ virtual void showAllTemplates ();
+
+ void showRegion (TemplateContainerItem const *pItem);
+
+ void showRegion (const OUString &rName);
+
+ void createContextMenu(const bool bIsDefault );
+
+ void ContextMenuSelectHdl(const OString& rIdent);
+
+ TemplateContainerItem* getRegion(OUString const & sStr);
+
+ sal_uInt16 getRegionId (size_t pos) const;
+
+ sal_uInt16 getRegionId (OUString const & sRegionName) const;
+
+ OUString getRegionName(const sal_uInt16 nRegionId) const;
+
+ OUString getRegionItemName(const sal_uInt16 nItemId) const;
+
+ std::vector<OUString> getFolderNames ();
+
+ std::vector<TemplateItemProperties>
+ getFilteredItems (const std::function<bool (const TemplateItemProperties&) > &rFunc) const;
+
+ sal_uInt16 createRegion (const OUString &rName);
+
+ bool renameRegion(const OUString &rTitle, const OUString &rNewTitle);
+
+ bool removeRegion (const sal_uInt16 nItemId);
+
+ bool removeTemplate (const sal_uInt16 nItemId, const sal_uInt16 nSrcItemId);
+
+ bool moveTemplate (const ThumbnailViewItem* pItem, const sal_uInt16 nSrcItem,
+ const sal_uInt16 nTargetItem);
+
+ void moveTemplates (const std::set<const ThumbnailViewItem*,selection_cmp_fn> &rItems, const sal_uInt16 nTargetItem);
+
+ bool copyFrom(TemplateContainerItem *pItem, const OUString &rPath);
+
+ bool exportTo (const sal_uInt16 nItemId, const sal_uInt16 nRegionItemId, const OUString &rName);
+
+ virtual bool renameItem(ThumbnailViewItem* pItem, const OUString& sNewTitle) override;
+
+ virtual bool MouseButtonDown( const MouseEvent& rMEvt ) override;
+
+ virtual bool ContextMenu(const CommandEvent& rPos) override;
+
+ virtual bool KeyInput( const KeyEvent& rKEvt ) override;
+
+ sal_uInt16 getCurRegionId () const { return mnCurRegionId;}
+
+ void setOpenRegionHdl(const Link<void*,void> &rLink);
+
+ void setCreateContextMenuHdl(const Link<ThumbnailViewItem*,void> &rLink);
+
+ void setOpenTemplateHdl(const Link<ThumbnailViewItem*,void> &rLink);
+
+ void setEditTemplateHdl(const Link<ThumbnailViewItem*,void> &rLink);
+
+ void setDeleteTemplateHdl(const Link<ThumbnailViewItem*,void> &rLink);
+
+ void setDefaultTemplateHdl(const Link<ThumbnailViewItem*,void> &rLink);
+
+ void updateThumbnailDimensions(long itemMaxSize);
+
+ void RemoveDefaultTemplateIcon( const OUString& rPath);
+
+ static BitmapEx scaleImg (const BitmapEx &rImg, long width, long height);
+
+ static BitmapEx getDefaultThumbnail( const OUString& rPath );
+
+ static BitmapEx fetchThumbnail (const OUString &msURL, long width, long height);
+
+ static bool IsDefaultTemplate(const OUString& rPath);
+
+protected:
+ virtual void OnItemDblClicked(ThumbnailViewItem *pItem) override;
+
+protected:
+ sal_uInt16 mnCurRegionId;
+
+ TemplateViewItem *maSelectedItem;
+
+ long mnThumbnailWidth;
+ long mnThumbnailHeight;
+
+ Point maPosition; //store the point of click event
+
+ Link<void*,void> maOpenRegionHdl;
+ Link<ThumbnailViewItem*,void> maCreateContextMenuHdl;
+ Link<ThumbnailViewItem*,void> maOpenTemplateHdl;
+ Link<ThumbnailViewItem*,void> maEditTemplateHdl;
+ Link<ThumbnailViewItem*,void> maDeleteTemplateHdl;
+ Link<ThumbnailViewItem*,void> maDefaultTemplateHdl;
+
+ std::unique_ptr<SfxDocumentTemplates> mpDocTemplates;
+ std::vector<std::unique_ptr<TemplateContainerItem> > maRegions;
+ std::vector<TemplateItemProperties > maAllTemplates;
+};
+
+
#endif // INCLUDED_SFX2_TEMPLATELOCALVIEW_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/sfx2/templateviewitem.hxx b/include/sfx2/templateviewitem.hxx
index e64b82ec23a2..21433157f796 100644
--- a/include/sfx2/templateviewitem.hxx
+++ b/include/sfx2/templateviewitem.hxx
@@ -16,7 +16,7 @@ class TemplateViewItem : public ThumbnailViewItem
{
public:
- TemplateViewItem (ThumbnailView &rView, sal_uInt16 nId);
+ TemplateViewItem (ThumbnailViewBase &rView, sal_uInt16 nId);
virtual ~TemplateViewItem () override;
diff --git a/include/sfx2/thumbnailview.hxx b/include/sfx2/thumbnailview.hxx
index 238004cdc67b..d1807f454583 100644
--- a/include/sfx2/thumbnailview.hxx
+++ b/include/sfx2/thumbnailview.hxx
@@ -18,6 +18,7 @@
#include <sfx2/thumbnailviewitem.hxx>
#include <vcl/ctrl.hxx>
+#include <vcl/customweld.hxx>
#include <vcl/timer.hxx>
#include <vcl/pngread.hxx>
@@ -174,7 +175,26 @@ public:
*
**/
-class SFX2_DLLPUBLIC ThumbnailView : public Control
+class SFX2_DLLPUBLIC ThumbnailViewBase
+{
+ friend class ThumbnailViewAcc;
+ friend class ThumbnailViewItemAcc;
+
+ SFX2_DLLPRIVATE virtual sal_uInt16 ImplGetVisibleItemCount() const = 0;
+ SFX2_DLLPRIVATE virtual ThumbnailViewItem* ImplGetVisibleItem(sal_uInt16 nVisiblePos) = 0;
+
+ virtual css::uno::Reference<css::accessibility::XAccessible> getAccessible() = 0;
+
+public:
+ /// Updates information in the view; used only in RecentDocsView ATM.
+ virtual void Reload() {}
+
+ virtual bool renameItem(ThumbnailViewItem* pItem, const OUString& sNewTitle);
+
+ virtual ~ThumbnailViewBase();
+};
+
+class SFX2_DLLPUBLIC ThumbnailView : public Control, public ThumbnailViewBase
{
public:
@@ -191,9 +211,6 @@ public:
virtual void Clear();
- /// Updates information in the view; used only in RecentDocsView ATM.
- virtual void Reload() {}
-
// Change current thumbnail item list with new one (invalidates all pointers to a thumbnail item)
void updateItems(std::vector<std::unique_ptr<ThumbnailViewItem>> items);
@@ -232,8 +249,6 @@ public:
virtual void Resize() override;
- virtual bool renameItem(ThumbnailViewItem* pItem, const OUString& sNewTitle);
-
static BitmapEx readThumbnail(const OUString &msURL);
protected:
@@ -256,6 +271,8 @@ protected:
virtual css::uno::Reference< css::accessibility::XAccessible > CreateAccessible() override;
+ virtual css::uno::Reference<css::accessibility::XAccessible> getAccessible() override;
+
protected:
// Drawing item related functions, override them to make your own custom ones.
@@ -280,8 +297,8 @@ protected:
SFX2_DLLPRIVATE void ImplDeleteItems();
SFX2_DLLPRIVATE size_t ImplGetItem( const Point& rPoint ) const;
SFX2_DLLPRIVATE ThumbnailViewItem* ImplGetItem( size_t nPos );
- SFX2_DLLPRIVATE sal_uInt16 ImplGetVisibleItemCount() const;
- SFX2_DLLPRIVATE ThumbnailViewItem* ImplGetVisibleItem( sal_uInt16 nVisiblePos );
+ SFX2_DLLPRIVATE virtual sal_uInt16 ImplGetVisibleItemCount() const override;
+ SFX2_DLLPRIVATE virtual ThumbnailViewItem* ImplGetVisibleItem(sal_uInt16 nVisiblePos) override;
SFX2_DLLPRIVATE void ImplFireAccessibleEvent( short nEventId, const css::uno::Any& rOldValue, const css::uno::Any& rNewValue );
SFX2_DLLPRIVATE bool ImplHasAccessibleListeners();
DECL_DLLPRIVATE_LINK( ImplScrollHdl, ScrollBar*, void );
@@ -320,6 +337,157 @@ protected:
std::function<bool (const ThumbnailViewItem*)> maFilterFunc;
};
+class SFX2_DLLPUBLIC SfxThumbnailView : public weld::CustomWidgetController, public ThumbnailViewBase
+{
+public:
+ SfxThumbnailView(std::unique_ptr<weld::ScrolledWindow> xWindow, std::unique_ptr<weld::Menu> xMenu);
+
+ virtual ~SfxThumbnailView() override;
+
+ virtual bool MouseMove(const MouseEvent& rMEvt) override;
+
+ void AppendItem(std::unique_ptr<ThumbnailViewItem> pItem);
+
+ void RemoveItem(sal_uInt16 nItemId);
+
+ virtual void Clear();
+
+ // Change current thumbnail item list with new one (invalidates all pointers to a thumbnail item)
+ void updateItems(std::vector<std::unique_ptr<ThumbnailViewItem>> items);
+
+ size_t GetItemPos( sal_uInt16 nItemId ) const;
+
+ sal_uInt16 GetItemId( size_t nPos ) const;
+
+ sal_uInt16 GetItemId( const Point& rPos ) const;
+
+ sal_uInt16 getNextItemId () const;
+
+ void setItemMaxTextLength (sal_uInt32 nLength);
+
+ void setItemDimensions (long ItemWidth, long ThumbnailHeight,
+ long DisplayHeight, int itemPadding);
+
+ void SelectItem( sal_uInt16 nItemId );
+
+ bool IsItemSelected( sal_uInt16 nItemId ) const;
+
+ /**
+ *
+ * @brief deselect all current selected items.
+ *
+ **/
+
+ void deselectItems ();
+
+ void ShowTooltips( bool bShowTooltips );
+
+ void SetMultiSelectionEnabled( bool bIsMultiSelectionEnabled );
+
+ void filterItems (const std::function<bool (const ThumbnailViewItem*) > &func);
+
+ void setItemStateHdl (const Link<const ThumbnailViewItem*,void> &aLink) { maItemStateHdl = aLink; }
+
+ virtual void Resize() override;
+
+ static BitmapEx readThumbnail(const OUString &msURL);
+
+ virtual void Show() override
+ {
+ mxScrolledWindow->show();
+ CustomWidgetController::Show();
+ }
+
+ virtual void Hide() override
+ {
+ mxScrolledWindow->hide();
+ CustomWidgetController::Hide();
+ }
+
+ virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override;
+
+protected:
+
+ virtual bool KeyInput( const KeyEvent& rKEvt ) override;
+
+ virtual bool MouseButtonDown( const MouseEvent& rMEvt ) override;
+
+ virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override;
+
+ virtual void GetFocus() override;
+
+ virtual void LoseFocus() override;
+
+ virtual OUString RequestHelp(tools::Rectangle& rRect) override;
+
+ virtual css::uno::Reference< css::accessibility::XAccessible > CreateAccessible() override;
+
+ virtual css::uno::Reference<css::accessibility::XAccessible> getAccessible() override;
+
+protected:
+
+ // Drawing item related functions, override them to make your own custom ones.
+
+ void DrawItem (ThumbnailViewItem const *pItem);
+
+ virtual void OnItemDblClicked (ThumbnailViewItem *pItem);
+
+protected:
+
+ friend class SfxThumbnailViewAcc;
+ friend class ThumbnailViewItemAcc;
+
+ void CalculateItemPositions (bool bScrollBarUsed = false);
+ void MakeItemVisible( sal_uInt16 nId );
+
+ SFX2_DLLPRIVATE void ImplInit();
+
+ SFX2_DLLPRIVATE void ImplDeleteItems();
+ SFX2_DLLPRIVATE size_t ImplGetItem( const Point& rPoint ) const;
+ SFX2_DLLPRIVATE ThumbnailViewItem* ImplGetItem( size_t nPos );
+ SFX2_DLLPRIVATE virtual sal_uInt16 ImplGetVisibleItemCount() const override;
+ SFX2_DLLPRIVATE virtual ThumbnailViewItem* ImplGetVisibleItem(sal_uInt16 nVisiblePos) override;
+ SFX2_DLLPRIVATE void ImplFireAccessibleEvent( short nEventId, const css::uno::Any& rOldValue, const css::uno::Any& rNewValue );
+ SFX2_DLLPRIVATE bool ImplHasAccessibleListeners();
+ DECL_DLLPRIVATE_LINK( ImplScrollHdl, weld::ScrolledWindow&, void );
+
+protected:
+
+ std::vector< std::unique_ptr<ThumbnailViewItem> > mItemList;
+ css::uno::Reference<css::accessibility::XAccessible> mxAccessible;
+ ThumbnailValueItemList mFilteredItemList; ///< Cache to store the filtered items
+ ThumbnailValueItemList::iterator mpStartSelRange;
+ long mnItemWidth;
+ long mnItemHeight;
+ long mnItemPadding;
+ long mnThumbnailHeight; // Maximum height of the thumbnail
+ long mnDisplayHeight; // Height of the data display box (name, etc)
+ long mnVisLines;
+ long mnLines;
+
+ sal_uInt16 mnCols;
+ sal_uInt16 mnFirstLine;
+ bool mbScroll : 1;
+ bool mbHasVisibleItems : 1;
+ bool mbShowTooltips : 1;
+ bool mbIsMultiSelectionEnabled: 1;
+ Color maFillColor; ///< Background color of the thumbnail view widget.
+ Color maTextColor; ///< Text color.
+ Color maHighlightColor; ///< Color of the highlight (background) of the hovered item.
+ Color maHighlightTextColor; ///< Color of the text for the highlighted item.
+ Color maSelectHighlightColor; ///< Color of the highlight (background) of the selected and hovered item.
+ Color maSelectHighlightTextColor; ///< Color of the text of the selected and hovered item.
+ double mfHighlightTransparence; ///< Transparence of the highlight.
+
+ Link<const ThumbnailViewItem*, void> maItemStateHdl;
+ std::unique_ptr<ThumbnailItemAttributes> mpItemAttrs;
+ std::unique_ptr<weld::ScrolledWindow> mxScrolledWindow;
+ std::unique_ptr<weld::Menu> mxContextMenu;
+
+ std::function<bool (const ThumbnailViewItem*)> maFilterFunc;
+};
+
+
#endif // INCLUDED_SFX2_THUMBNAILVIEW_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/sfx2/thumbnailviewitem.hxx b/include/sfx2/thumbnailviewitem.hxx
index 3568da70d31b..26cb96966967 100644
--- a/include/sfx2/thumbnailviewitem.hxx
+++ b/include/sfx2/thumbnailviewitem.hxx
@@ -32,7 +32,7 @@
const int THUMBNAILVIEW_ITEM_CORNER = 5;
-class ThumbnailView;
+class ThumbnailViewBase;
class MouseEvent;
namespace basegfx {
@@ -67,7 +67,7 @@ class SFX2_DLLPUBLIC ThumbnailViewItem
{
public:
- ThumbnailView &mrParent;
+ ThumbnailViewBase &mrParent;
sal_uInt16 const mnId;
bool mbVisible;
bool mbSelected;
@@ -77,7 +77,7 @@ public:
OUString maHelpText;
css::uno::Reference< css::accessibility::XAccessible > mxAcc;
- ThumbnailViewItem (ThumbnailView &rView, sal_uInt16 nId);
+ ThumbnailViewItem (ThumbnailViewBase &rView, sal_uInt16 nId);
virtual ~ThumbnailViewItem ();
diff --git a/include/svx/SvxPresetListBox.hxx b/include/svx/SvxPresetListBox.hxx
index e8809eca0f61..f580ebac04fb 100644
--- a/include/svx/SvxPresetListBox.hxx
+++ b/include/svx/SvxPresetListBox.hxx
@@ -44,7 +44,7 @@ public:
SvxPresetListBox(std::unique_ptr<weld::ScrolledWindow> pWindow);
virtual void Resize() override;
- virtual bool ContextMenu(const Point& rPos) override;
+ virtual bool ContextMenu(const CommandEvent& rEvent) override;
static sal_uInt32 getColumnCount() { return nColCount; }
Size const & GetIconSize() const { return aIconSize; }
diff --git a/include/svx/charmap.hxx b/include/svx/charmap.hxx
index 0551f2ad03c8..df6b29e1ef21 100644
--- a/include/svx/charmap.hxx
+++ b/include/svx/charmap.hxx
@@ -103,8 +103,8 @@ public:
virtual sal_Int32 getMaxCharCount() const;
- void Show() { mxScrollArea->show(); }
- void Hide() { mxScrollArea->hide(); }
+ virtual void Show() override { mxScrollArea->show(); }
+ virtual void Hide() override { mxScrollArea->hide(); }
uno::Reference<css::accessibility::XAccessible> getAccessibleParent() { return GetDrawingArea()->get_accessible_parent(); }
diff --git a/include/vcl/customweld.hxx b/include/vcl/customweld.hxx
index db60521a195d..e8bbb2129912 100644
--- a/include/vcl/customweld.hxx
+++ b/include/vcl/customweld.hxx
@@ -33,7 +33,7 @@ public:
virtual void GetFocus() {}
virtual void LoseFocus() {}
virtual void StyleUpdated() { Invalidate(); }
- virtual bool ContextMenu(const Point&) { return false; }
+ virtual bool ContextMenu(const CommandEvent&) { return false; }
virtual bool KeyInput(const KeyEvent&) { return false; }
virtual tools::Rectangle GetFocusRect() { return tools::Rectangle(); }
virtual FactoryFunction GetUITestFactory() const { return nullptr; }
@@ -49,8 +49,8 @@ public:
m_pDrawingArea->queue_draw_area(rRect.Left(), rRect.Top(), rRect.GetWidth(),
rRect.GetHeight());
}
- void Show() { m_pDrawingArea->show(); }
- void Hide() { m_pDrawingArea->hide(); }
+ virtual void Show() { m_pDrawingArea->show(); }
+ virtual void Hide() { m_pDrawingArea->hide(); }
void GrabFocus() { m_pDrawingArea->grab_focus(); }
bool HasFocus() const { return m_pDrawingArea->has_focus(); }
bool IsVisible() const { return m_pDrawingArea->get_visible(); }
@@ -101,7 +101,7 @@ private:
DECL_LINK(DoLoseFocus, weld::Widget&, void);
DECL_LINK(DoKeyPress, const KeyEvent&, bool);
DECL_LINK(DoFocusRect, weld::Widget&, tools::Rectangle);
- DECL_LINK(DoPopupMenu, const Point&, bool);
+ DECL_LINK(DoPopupMenu, const CommandEvent&, bool);
DECL_LINK(DoStyleUpdated, weld::Widget&, void);
DECL_LINK(DoRequestHelp, tools::Rectangle&, OUString);
diff --git a/include/vcl/layout.hxx b/include/vcl/layout.hxx
index 33a6db730a85..2ea881a31fd6 100644
--- a/include/vcl/layout.hxx
+++ b/include/vcl/layout.hxx
@@ -620,7 +620,7 @@ private:
Link<const KeyEvent&, bool> m_aKeyPressHdl;
Link<const KeyEvent&, bool> m_aKeyReleaseHdl;
Link<VclDrawingArea&, void> m_aStyleUpdatedHdl;
- Link<const Point&, bool> m_aPopupMenuHdl;
+ Link<const CommandEvent&, bool> m_aPopupMenuHdl;
Link<tools::Rectangle&, OUString> m_aQueryTooltipHdl;
virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override
@@ -677,7 +677,7 @@ private:
}
virtual void Command(const CommandEvent& rEvent) override
{
- if (rEvent.GetCommand() == CommandEventId::ContextMenu && m_aPopupMenuHdl.Call(rEvent.GetMousePosPixel()))
+ if (rEvent.GetCommand() == CommandEventId::ContextMenu && m_aPopupMenuHdl.Call(rEvent))
return;
Control::Command(rEvent);
}
@@ -755,7 +755,7 @@ public:
{
m_aStyleUpdatedHdl = rLink;
}
- void SetPopupMenuHdl(const Link<const Point&, bool>& rLink)
+ void SetPopupMenuHdl(const Link<const CommandEvent&, bool>& rLink)
{
m_aPopupMenuHdl = rLink;
}
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index 91fc19f65a87..f258b83c2cd5 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -254,6 +254,8 @@ public:
virtual int hadjustment_get_upper() const = 0;
virtual void hadjustment_set_upper(int upper) = 0;
virtual int hadjustment_get_page_size() const = 0;
+ virtual void hadjustment_set_page_size(int size) = 0;
+ virtual void hadjustment_set_page_increment(int size) = 0;
virtual void set_hpolicy(VclPolicyType eHPolicy) = 0;
virtual VclPolicyType get_hpolicy() const = 0;
void connect_hadjustment_changed(const Link<ScrolledWindow&, void>& rLink)
@@ -270,6 +272,8 @@ public:
virtual int vadjustment_get_upper() const = 0;
virtual void vadjustment_set_upper(int upper) = 0;
virtual int vadjustment_get_page_size() const = 0;
+ virtual void vadjustment_set_page_size(int size) = 0;
+ virtual void vadjustment_set_page_increment(int size) = 0;
virtual int vadjustment_get_lower() const = 0;
virtual void vadjustment_set_lower(int upper) = 0;
virtual void set_vpolicy(VclPolicyType eVPolicy) = 0;
@@ -852,11 +856,14 @@ public:
{
insert_item(-1, rId, rStr, nullptr, &rImage, false);
}
+ virtual void insert_separator(int pos, const OUString& rId) = 0;
+ void append_separator(const OUString& rId) { insert_separator(-1, rId); }
virtual void remove_item(const OString& rId) = 0;
virtual void set_item_sensitive(const OString& rIdent, bool bSensitive) = 0;
virtual void set_item_active(const OString& rIdent, bool bActive) = 0;
virtual void set_item_label(const OString& rIdent, const OUString& rLabel) = 0;
virtual void set_item_help_id(const OString& rIdent, const OString& rHelpId) = 0;
+ virtual void set_item_visible(const OString& rIdent, bool bVisible) = 0;
virtual OString get_item_help_id(const OString& rIdent) const = 0;
virtual void set_popover(weld::Widget* pPopover) = 0;
@@ -1474,7 +1481,7 @@ public:
protected:
Link<draw_args, void> m_aDrawHdl;
Link<Widget&, void> m_aStyleUpdatedHdl;
- Link<const Point&, bool> m_aPopupMenuHdl;
+ Link<const CommandEvent&, bool> m_aPopupMenuHdl;
Link<Widget&, tools::Rectangle> m_aGetFocusRectHdl;
Link<tools::Rectangle&, OUString> m_aQueryTooltipHdl;
@@ -1486,7 +1493,10 @@ protected:
public:
void connect_draw(const Link<draw_args, void>& rLink) { m_aDrawHdl = rLink; }
void connect_style_updated(const Link<Widget&, void>& rLink) { m_aStyleUpdatedHdl = rLink; }
- void connect_popup_menu(const Link<const Point&, bool>& rLink) { m_aPopupMenuHdl = rLink; }
+ void connect_popup_menu(const Link<const CommandEvent&, bool>& rLink)
+ {
+ m_aPopupMenuHdl = rLink;
+ }
void connect_focus_rect(const Link<Widget&, tools::Rectangle>& rLink)
{
m_aGetFocusRectHdl = rLink;
@@ -1512,11 +1522,17 @@ public:
virtual OString popup_at_rect(weld::Widget* pParent, const tools::Rectangle& rRect) = 0;
virtual void set_sensitive(const OString& rIdent, bool bSensitive) = 0;
virtual void set_active(const OString& rIdent, bool bActive) = 0;
- virtual void show(const OString& rIdent, bool bShow) = 0;
+ virtual void set_visible(const OString& rIdent, bool bVisible) = 0;
virtual void insert(int pos, const OUString& rId, const OUString& rStr,
const OUString* pIconName, VirtualDevice* pImageSufface, bool bCheck)
= 0;
+
+ virtual void clear() = 0;
+
+ virtual void insert_separator(int pos, const OUString& rId) = 0;
+ void append_separator(const OUString& rId) { insert_separator(-1, rId); }
+
void append(const OUString& rId, const OUString& rStr)
{
insert(-1, rId, rStr, nullptr, nullptr, false);
diff --git a/sd/source/ui/app/sdmod1.cxx b/sd/source/ui/app/sdmod1.cxx
index 42bde350851f..f60e2ee4d0b8 100644
--- a/sd/source/ui/app/sdmod1.cxx
+++ b/sd/source/ui/app/sdmod1.cxx
@@ -475,15 +475,16 @@ SfxFrame* SdModule::ExecuteNewDocument( SfxRequest const & rReq )
if(bStartWithTemplate)
{
//Launch TemplateSelectionDialog
- ScopedVclPtrInstance< SfxTemplateSelectionDlg > aTemplDlg( SfxGetpApp()->GetTopWindow());
- aTemplDlg->Execute();
+ vcl::Window* pTopLevel = SfxGetpApp()->GetTopWindow();
+ SfxTemplateSelectionDlg aTemplDlg(pTopLevel ? pTopLevel->GetFrameWeld() : nullptr);
+ aTemplDlg.run();
//check to disable the dialog
- pOpt->SetStartWithTemplate( aTemplDlg->IsStartWithTemplate() );
+ pOpt->SetStartWithTemplate( aTemplDlg.IsStartWithTemplate() );
//pFrame is loaded with the desired template
- if(!aTemplDlg->getTemplatePath().isEmpty())
- pFrame = CreateFromTemplate(aTemplDlg->getTemplatePath(), xTargetFrame);
+ if (!aTemplDlg.getTemplatePath().isEmpty())
+ pFrame = CreateFromTemplate(aTemplDlg.getTemplatePath(), xTargetFrame);
}
}
diff --git a/sfx2/source/appl/appopen.cxx b/sfx2/source/appl/appopen.cxx
index 4a655f940d4c..0c5288289098 100644
--- a/sfx2/source/appl/appopen.cxx
+++ b/sfx2/source/appl/appopen.cxx
@@ -448,12 +448,12 @@ void SfxApplication::NewDocExec_Impl( SfxRequest& rReq )
if(pCurrentShell)
xModel = pCurrentShell->GetModel();
- ScopedVclPtrInstance< SfxTemplateManagerDlg > aTemplDlg;
+ SfxTemplateManagerDlg aTemplDlg(rReq.GetFrameWeld());
if (xModel.is())
- aTemplDlg->setDocumentModel(xModel);
+ aTemplDlg.setDocumentModel(xModel);
- int nRet = aTemplDlg->Execute();
+ int nRet = aTemplDlg.run();
if ( nRet == RET_OK )
{
rReq.Done();
diff --git a/sfx2/source/appl/appserv.cxx b/sfx2/source/appl/appserv.cxx
index d2ac03b9c2ac..bfe3fb24abc3 100644
--- a/sfx2/source/appl/appserv.cxx
+++ b/sfx2/source/appl/appserv.cxx
@@ -660,8 +660,8 @@ void SfxApplication::MiscExec_Impl( SfxRequest& rReq )
case SID_TEMPLATE_MANAGER:
{
- ScopedVclPtrInstance< SfxTemplateManagerDlg > dlg;
- dlg->Execute();
+ SfxTemplateManagerDlg aDialog(rReq.GetFrameWeld());
+ aDialog.run();
bDone = true;
break;
}
diff --git a/sfx2/source/control/emojiviewitem.cxx b/sfx2/source/control/emojiviewitem.cxx
index e4f1e701363e..f393738d045f 100644
--- a/sfx2/source/control/emojiviewitem.cxx
+++ b/sfx2/source/control/emojiviewitem.cxx
@@ -27,7 +27,7 @@ using namespace basegfx::utils;
using namespace drawinglayer::attribute;
using namespace drawinglayer::primitive2d;
-EmojiViewItem::EmojiViewItem (ThumbnailView &rView, sal_uInt16 nId)
+EmojiViewItem::EmojiViewItem (ThumbnailViewBase &rView, sal_uInt16 nId)
: ThumbnailViewItem(rView, nId)
{
}
diff --git a/sfx2/source/control/recentdocsviewitem.cxx b/sfx2/source/control/recentdocsviewitem.cxx
index f1992285e782..cddbe57ae500 100644
--- a/sfx2/source/control/recentdocsviewitem.cxx
+++ b/sfx2/source/control/recentdocsviewitem.cxx
@@ -32,9 +32,10 @@ using namespace com::sun::star::uno;
using namespace drawinglayer::primitive2d;
using namespace drawinglayer::processor2d;
-RecentDocsViewItem::RecentDocsViewItem(ThumbnailView &rView, const OUString &rURL,
+RecentDocsViewItem::RecentDocsViewItem(sfx2::RecentDocsView &rView, const OUString &rURL,
const OUString &rTitle, const BitmapEx &rThumbnail, sal_uInt16 nId, long nThumbnailSize)
: ThumbnailViewItem(rView, nId),
+ mrParentView(rView),
maURL(rURL),
m_bRemoveIconHighlighted(false),
m_aRemoveRecentBitmap(BMP_RECENTDOC_REMOVE),
@@ -178,7 +179,7 @@ void RecentDocsViewItem::MouseButtonUp(const MouseEvent& rMEvt)
void RecentDocsViewItem::OpenDocument()
{
// show busy mouse pointer
- mrParent.SetPointer(PointerStyle::Wait);
+ mrParentView.SetPointer(PointerStyle::Wait);
Reference<frame::XDispatch> xDispatch;
Reference<frame::XDispatchProvider> xDispatchProvider;
@@ -216,7 +217,7 @@ void RecentDocsViewItem::OpenDocument()
pLoadRecentFile->xDispatch = xDispatch;
pLoadRecentFile->aTargetURL = aTargetURL;
pLoadRecentFile->aArgSeq = aArgsList;
- pLoadRecentFile->pView.set(&mrParent);
+ pLoadRecentFile->pView = &mrParentView;
Application::PostUserEvent(LINK(nullptr, sfx2::RecentDocsView, ExecuteHdl_Impl), pLoadRecentFile, true);
}
diff --git a/sfx2/source/control/templatelocalview.cxx b/sfx2/source/control/templatelocalview.cxx
index d15109f8943b..816448a3b298 100644
--- a/sfx2/source/control/templatelocalview.cxx
+++ b/sfx2/source/control/templatelocalview.cxx
@@ -96,8 +96,6 @@ TemplateLocalView::TemplateLocalView ( vcl::Window* pParent, WinBits nWinStyle)
{
}
-VCL_BUILDER_FACTORY(TemplateLocalView)
-
TemplateLocalView::~TemplateLocalView()
{
disposeOnce();
@@ -1017,4 +1015,890 @@ void TemplateLocalView::OnItemDblClicked (ThumbnailViewItem *pItem)
maOpenTemplateHdl.Call(pViewItem);
}
+SfxTemplateLocalView::SfxTemplateLocalView(std::unique_ptr<weld::ScrolledWindow> xWindow,
+ std::unique_ptr<weld::Menu> xMenu)
+ : SfxThumbnailView(std::move(xWindow), std::move(xMenu))
+ , mnCurRegionId(0)
+ , maSelectedItem(nullptr)
+ , mnThumbnailWidth(TEMPLATE_THUMBNAIL_MAX_WIDTH)
+ , mnThumbnailHeight(TEMPLATE_THUMBNAIL_MAX_HEIGHT)
+ , maPosition(0,0)
+ , mpDocTemplates(new SfxDocumentTemplates)
+{
+}
+
+SfxTemplateLocalView::~SfxTemplateLocalView()
+{
+}
+
+void SfxTemplateLocalView::Populate()
+{
+ maRegions.clear();
+ maAllTemplates.clear();
+
+ sal_uInt16 nCount = mpDocTemplates->GetRegionCount();
+ for (sal_uInt16 i = 0; i < nCount; ++i)
+ {
+ OUString aRegionName(mpDocTemplates->GetFullRegionName(i));
+
+ std::unique_ptr<TemplateContainerItem> pItem(new TemplateContainerItem( i+1 ));
+ pItem->mnRegionId = i;
+ pItem->maTitle = aRegionName;
+
+ sal_uInt16 nEntries = mpDocTemplates->GetCount(i);
+
+ for (sal_uInt16 j = 0; j < nEntries; ++j)
+ {
+ OUString aName = mpDocTemplates->GetName(i,j);
+ OUString aURL = mpDocTemplates->GetPath(i,j);
+
+ TemplateItemProperties aProperties;
+ aProperties.nId = j+1;
+ aProperties.nDocId = j;
+ aProperties.nRegionId = i;
+ aProperties.aName = aName;
+ aProperties.aPath = aURL;
+ aProperties.aRegionName = aRegionName;
+ aProperties.aThumbnail = TemplateLocalView::fetchThumbnail(aURL,
+ mnThumbnailWidth,
+ mnThumbnailHeight);
+
+ pItem->maTemplates.push_back(aProperties);
+ maAllTemplates.push_back(aProperties);
+ }
+
+ maRegions.push_back(std::move(pItem));
+ }
+}
+
+void SfxTemplateLocalView::reload()
+{
+ mpDocTemplates->Update();
+
+ Populate();
+
+ // Check if we are currently browsing a region or root folder
+ if (mnCurRegionId)
+ {
+ sal_uInt16 nRegionId = mnCurRegionId - 1; //Is offset by 1
+
+ for (auto const & pRegion : maRegions)
+ {
+ if (pRegion->mnRegionId == nRegionId)
+ {
+ showRegion(pRegion.get());
+ break;
+ }
+ }
+ }
+ else
+ showAllTemplates();
+
+ //No items should be selected by default
+ deselectItems();
+}
+
+void SfxTemplateLocalView::showAllTemplates()
+{
+ mnCurRegionId = 0;
+
+ insertItems(maAllTemplates, false, true);
+
+ maOpenRegionHdl.Call(nullptr);
+}
+
+void SfxTemplateLocalView::showRegion(TemplateContainerItem const *pItem)
+{
+ mnCurRegionId = pItem->mnRegionId+1;
+
+ insertItems(pItem->maTemplates);
+
+ maOpenRegionHdl.Call(nullptr);
+}
+
+void SfxTemplateLocalView::showRegion(const OUString &rName)
+{
+ for (auto const & pRegion : maRegions)
+ {
+ if (pRegion->maTitle == rName)
+ {
+ showRegion(pRegion.get());
+ break;
+ }
+ }
+}
+
+TemplateContainerItem* SfxTemplateLocalView::getRegion(OUString const & rName)
+{
+ for (auto const & pRegion : maRegions)
+ if (pRegion->maTitle == rName)
+ return pRegion.get();
+
+ return nullptr;
+}
+
+void SfxTemplateLocalView::createContextMenu(const bool bIsDefault)
+{
+ mxContextMenu->clear();
+ mxContextMenu->append("open",SfxResId(STR_OPEN));
+ mxContextMenu->append("edit",SfxResId(STR_EDIT_TEMPLATE));
+
+ if(!bIsDefault)
+ mxContextMenu->append("default",SfxResId(STR_DEFAULT_TEMPLATE));
+ else
+ mxContextMenu->append("default",SfxResId(STR_RESET_DEFAULT));
+
+ mxContextMenu->append_separator("separator");
+ mxContextMenu->append("rename",SfxResId(STR_RENAME));
+ mxContextMenu->append("delete",SfxResId(STR_DELETE));
+ deselectItems();
+ maSelectedItem->setSelection(true);
+ maItemStateHdl.Call(maSelectedItem);
+ ContextMenuSelectHdl(mxContextMenu->popup_at_rect(GetDrawingArea(), tools::Rectangle(maPosition, Size(1,1))));
+ Invalidate();
+}
+
+void SfxTemplateLocalView::ContextMenuSelectHdl(const OString& rIdent)
+{
+ if (rIdent == "open")
+ maOpenTemplateHdl.Call(maSelectedItem);
+ else if (rIdent == "edit")
+ maEditTemplateHdl.Call(maSelectedItem);
+ else if (rIdent == "rename")
+ {
+ InputDialog aTitleEditDlg(GetDrawingArea(), SfxResId(STR_RENAME_TEMPLATE));
+ OUString sOldTitle = maSelectedItem->getTitle();
+ aTitleEditDlg.SetEntryText(sOldTitle);
+ aTitleEditDlg.HideHelpBtn();
+
+ if (!aTitleEditDlg.run())
+ return;
+ OUString sNewTitle = comphelper::string::strip(aTitleEditDlg.GetEntryText(), ' ');
+
+ if ( !sNewTitle.isEmpty() && sNewTitle != sOldTitle )
+ {
+ maSelectedItem->setTitle(sNewTitle);
+ }
+ }
+ else if (rIdent == "delete")
+ {
+ std::unique_ptr<weld::MessageDialog> xQueryDlg(Application::CreateMessageDialog(GetDrawingArea(), VclMessageType::Question, VclButtonsType::YesNo,
+ SfxResId(STR_QMSG_SEL_TEMPLATE_DELETE)));
+ if (xQueryDlg->run() != RET_YES)
+ return;
+
+ maDeleteTemplateHdl.Call(maSelectedItem);
+ reload();
+ }
+ else if (rIdent == "default")
+ maDefaultTemplateHdl.Call(maSelectedItem);
+}
+
+sal_uInt16 SfxTemplateLocalView::getRegionId(size_t pos) const
+{
+ assert(pos < maRegions.size());
+
+ return maRegions[pos]->mnId;
+}
+
+sal_uInt16 SfxTemplateLocalView::getRegionId(OUString const & sRegion) const
+{
+ for (auto const & pRegion : maRegions)
+ {
+ if (pRegion->maTitle == sRegion)
+ return pRegion->mnId;
+ }
+
+ return 0;
+}
+
+OUString SfxTemplateLocalView::getRegionName(const sal_uInt16 nRegionId) const
+{
+ return mpDocTemplates->GetRegionName(nRegionId);
+}
+
+OUString SfxTemplateLocalView::getRegionItemName(const sal_uInt16 nItemId) const
+{
+ for (auto const & pRegion : maRegions)
+ {
+ if (pRegion->mnId == nItemId)
+ return pRegion->maTitle;
+ }
+
+ return OUString();
+}
+
+std::vector<OUString> SfxTemplateLocalView::getFolderNames()
+{
+ size_t n = maRegions.size();
+ std::vector<OUString> ret(n);
+
+ for (size_t i = 0; i < n; ++i)
+ ret[i] = maRegions[i]->maTitle;
+
+ return ret;
+}
+
+std::vector<TemplateItemProperties>
+SfxTemplateLocalView::getFilteredItems(const std::function<bool (const TemplateItemProperties&)> &rFunc) const
+{
+ std::vector<TemplateItemProperties> aItems;
+
+ if (mnCurRegionId)
+ {
+ TemplateContainerItem *pFolderItem = maRegions[mnCurRegionId-1].get();
+
+ for (TemplateItemProperties & rItemProps : pFolderItem->maTemplates)
+ {
+ if (rFunc(rItemProps))
+ aItems.push_back(rItemProps);
+ }
+ }
+ else
+ {
+ for (auto const & pFolderItem : maRegions)
+ {
+ for (const TemplateItemProperties & rItemProps : pFolderItem->maTemplates)
+ {
+ if (rFunc(rItemProps))
+ aItems.push_back(rItemProps);
+ }
+ }
+ }
+
+ return aItems;
+}
+
+sal_uInt16 SfxTemplateLocalView::createRegion(const OUString &rName)
+{
+ sal_uInt16 nRegionId = mpDocTemplates->GetRegionCount(); // Next regionId
+ sal_uInt16 nItemId = getNextItemId();
+
+ if (!mpDocTemplates->InsertDir(rName,nRegionId))
+ return 0;
+
+ // Insert to the region cache list and to the thumbnail item list
+ std::unique_ptr<TemplateContainerItem> pItem(new TemplateContainerItem( nItemId ));
+ pItem->mnRegionId = nRegionId;
+ pItem->maTitle = rName;
+
+ maRegions.push_back(std::move(pItem));
+
+ return nItemId;
+}
+
+bool SfxTemplateLocalView::renameRegion(const OUString &rTitle, const OUString &rNewTitle)
+{
+ TemplateContainerItem *pRegion = getRegion(rTitle);
+
+ if(pRegion)
+ {
+ sal_uInt16 nRegionId = pRegion->mnRegionId;
+ return mpDocTemplates->SetName( rNewTitle, nRegionId, USHRT_MAX/*nDocId*/ );
+ }
+ return false;
+}
+
+bool SfxTemplateLocalView::removeRegion(const sal_uInt16 nItemId)
+{
+ sal_uInt16 nRegionId = USHRT_MAX;
+
+ // Remove from the region cache list
+ for (auto pRegionIt = maRegions.begin(); pRegionIt != maRegions.end();)
+ {
+ if ( (*pRegionIt)->mnId == nItemId )
+ {
+ if (!mpDocTemplates->Delete((*pRegionIt)->mnRegionId,USHRT_MAX))
+ return false;
+
+ nRegionId = (*pRegionIt)->mnRegionId;
+
+ pRegionIt = maRegions.erase(pRegionIt);
+ }
+ else
+ {
+ // Synchronize regions cache ids with SfxDocumentTemplates
+ if (nRegionId != USHRT_MAX && (*pRegionIt)->mnRegionId > nRegionId)
+ --(*pRegionIt)->mnRegionId;
+
+ ++pRegionIt;
+ }
+ }
+
+ if (nRegionId == USHRT_MAX)
+ return false;
+
+ // Synchronize view regions ids with SfxDocumentTemplates
+ for (auto const& region : maRegions)
+ {
+ if (region->mnRegionId > nRegionId)
+ --region->mnRegionId;
+ }
+
+ return true;
+}
+
+bool SfxTemplateLocalView::removeTemplate (const sal_uInt16 nItemId, const sal_uInt16 nSrcItemId)
+{
+ for (auto const & pRegion : maRegions)
+ {
+ if (pRegion->mnId == nSrcItemId)
+ {
+ TemplateContainerItem *pItem = pRegion.get();
+ auto pIter = std::find_if(pItem->maTemplates.begin(), pItem->maTemplates.end(),
+ [nItemId](const TemplateItemProperties& rTemplate) { return rTemplate.nId == nItemId; });
+ if (pIter != pItem->maTemplates.end())
+ {
+ if (!mpDocTemplates->Delete(pItem->mnRegionId,pIter->nDocId))
+ return false;
+
+ pIter = pItem->maTemplates.erase(pIter);
+
+ if (pRegion->mnRegionId == mnCurRegionId-1)
+ {
+ RemoveItem(nItemId);
+ Invalidate();
+ }
+
+ // Update Doc Idx for all templates that follow
+ for (; pIter != pItem->maTemplates.end(); ++pIter)
+ pIter->nDocId = pIter->nDocId - 1;
+ }
+
+ CalculateItemPositions();
+ break;
+ }
+ }
+
+ return true;
+}
+
+bool SfxTemplateLocalView::moveTemplate (const ThumbnailViewItem *pItem, const sal_uInt16 nSrcItem,
+ const sal_uInt16 nTargetItem)
+{
+ TemplateContainerItem *pTarget = nullptr;
+ TemplateContainerItem *pSrc = nullptr;
+
+ for (auto const & pRegion : maRegions)
+ {
+ if (pRegion->mnId == nTargetItem)
+ pTarget = pRegion.get();
+ else if (pRegion->mnId == nSrcItem)
+ pSrc = pRegion.get();
+ }
+
+ if (pTarget && pSrc)
+ {
+ sal_uInt16 nSrcRegionId = pSrc->mnRegionId;
+ sal_uInt16 nTargetRegion = pTarget->mnRegionId;
+ sal_uInt16 nTargetIdx = mpDocTemplates->GetCount(nTargetRegion); // Next Idx
+
+ const TemplateViewItem *pViewItem = static_cast<const TemplateViewItem*>(pItem);
+
+ bool bCopy = !mpDocTemplates->Move(nTargetRegion,nTargetIdx,nSrcRegionId,pViewItem->mnDocId);
+
+ if (bCopy)
+ {
+ OUString sQuery = SfxResId(STR_MSG_QUERY_COPY).replaceFirst("$1", pViewItem->maTitle).replaceFirst("$2",
+ getRegionName(nTargetRegion));
+
+ std::unique_ptr<weld::MessageDialog> xQueryDlg(Application::CreateMessageDialog(GetDrawingArea(), VclMessageType::Question, VclButtonsType::YesNo, sQuery));
+ if (xQueryDlg->run() != RET_YES)
+ return false;
+
+ if (!mpDocTemplates->Copy(nTargetRegion,nTargetIdx,nSrcRegionId,pViewItem->mnDocId))
+ return false;
+ }
+ // move template to destination
+
+ TemplateItemProperties aTemplateItem;
+ aTemplateItem.nId = nTargetIdx + 1;
+ aTemplateItem.nDocId = nTargetIdx;
+ aTemplateItem.nRegionId = nTargetRegion;
+ aTemplateItem.aName = pViewItem->maTitle;
+ aTemplateItem.aPath = mpDocTemplates->GetPath(nTargetRegion,nTargetIdx);
+ aTemplateItem.aRegionName = pViewItem->maHelpText;
+ aTemplateItem.aThumbnail = pViewItem->maPreview1;
+
+ pTarget->maTemplates.push_back(aTemplateItem);
+
+ if (!bCopy)
+ {
+ // remove template from region cached data
+
+ std::vector<TemplateItemProperties>::iterator aIter;
+ for (aIter = pSrc->maTemplates.begin(); aIter != pSrc->maTemplates.end();)
+ {
+ if (aIter->nDocId == pViewItem->mnDocId)
+ {
+ aIter = pSrc->maTemplates.erase(aIter);
+ }
+ else
+ {
+ // Keep region document id synchronized with SfxDocumentTemplates
+ if (aIter->nDocId > pViewItem->mnDocId)
+ --aIter->nDocId;
+
+ ++aIter;
+ }
+ }
+
+ // Keep view document id synchronized with SfxDocumentTemplates
+ for (auto const& item : mItemList)
+ {
+ auto pTemplateViewItem = static_cast<TemplateViewItem*>(item.get());
+ if (pTemplateViewItem->mnDocId > pViewItem->mnDocId)
+ --pTemplateViewItem->mnDocId;
+ }
+ }
+
+ CalculateItemPositions();
+ Invalidate();
+
+ return true;
+ }
+
+ return false;
+}
+
+void SfxTemplateLocalView::moveTemplates(const std::set<const ThumbnailViewItem*, selection_cmp_fn> &rItems,
+ const sal_uInt16 nTargetItem)
+{
+ TemplateContainerItem *pTarget = nullptr;
+ TemplateContainerItem *pSrc = nullptr;
+
+ for (auto const & pRegion : maRegions)
+ {
+ if (pRegion->mnId == nTargetItem)
+ pTarget = pRegion.get();
+ }
+
+ if (!pTarget)
+ return;
+
+ bool refresh = false;
+
+ sal_uInt16 nTargetRegion = pTarget->mnRegionId;
+ sal_uInt16 nTargetIdx = mpDocTemplates->GetCount(nTargetRegion); // Next Idx
+ std::vector<sal_uInt16> aItemIds; // List of moved items ids (also prevents the invalidation of rItems iterators when we remove them as we go)
+
+ std::set<const ThumbnailViewItem*,selection_cmp_fn>::const_iterator aSelIter;
+ for ( aSelIter = rItems.begin(); aSelIter != rItems.end(); ++aSelIter, ++nTargetIdx )
+ {
+ const TemplateViewItem *pViewItem = static_cast<const TemplateViewItem*>(*aSelIter);
+ sal_uInt16 nSrcRegionId = pViewItem->mnRegionId;
+
+ for (auto const & pRegion : maRegions)
+ {
+ if (pRegion->mnRegionId == nSrcRegionId)
+ pSrc = pRegion.get();
+ }
+
+ if(pSrc)
+ {
+ bool bCopy = !mpDocTemplates->Move(nTargetRegion,nTargetIdx,nSrcRegionId,pViewItem->mnDocId);
+
+ if (bCopy)
+ {
+ OUString sQuery = SfxResId(STR_MSG_QUERY_COPY).replaceFirst("$1", pViewItem->maTitle).replaceFirst("$2",
+ getRegionName(nTargetRegion));
+ std::unique_ptr<weld::MessageDialog> xQueryDlg(Application::CreateMessageDialog(GetDrawingArea(), VclMessageType::Question, VclButtonsType::YesNo, sQuery));
+ if (xQueryDlg->run() != RET_YES)
+ {
+ OUString sMsg(SfxResId(STR_MSG_ERROR_LOCAL_MOVE));
+ sMsg = sMsg.replaceFirst("$1",getRegionName(nTargetRegion));
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetDrawingArea(),
+ VclMessageType::Warning, VclButtonsType::Ok, sMsg.replaceFirst( "$2",pViewItem->maTitle)));
+ xBox->run();
+
+ return; //return if any single move operation fails
+ }
+
+ if (!mpDocTemplates->Copy(nTargetRegion,nTargetIdx,nSrcRegionId,pViewItem->mnDocId))
+ {
+ continue;
+ }
+ }
+
+ // move template to destination
+
+ TemplateItemProperties aTemplateItem;
+ aTemplateItem.nId = nTargetIdx + 1;
+ aTemplateItem.nDocId = nTargetIdx;
+ aTemplateItem.nRegionId = nTargetRegion;
+ aTemplateItem.aName = pViewItem->maTitle;
+ aTemplateItem.aPath = mpDocTemplates->GetPath(nTargetRegion,nTargetIdx);
+ aTemplateItem.aRegionName = pViewItem->maHelpText;
+ aTemplateItem.aThumbnail = pViewItem->maPreview1;
+
+ pTarget->maTemplates.push_back(aTemplateItem);
+
+ if (!bCopy)
+ {
+ // remove template from region cached data
+
+ std::vector<TemplateItemProperties>::iterator pPropIter;
+ for (pPropIter = pSrc->maTemplates.begin(); pPropIter != pSrc->maTemplates.end();)
+ {
+ if (pPropIter->nDocId == pViewItem->mnDocId)
+ {
+ pPropIter = pSrc->maTemplates.erase(pPropIter);
+ aItemIds.push_back(pViewItem->mnDocId + 1);//mnid
+ }
+ else
+ {
+ // Keep region document id synchronized with SfxDocumentTemplates
+ if (pPropIter->nDocId > pViewItem->mnDocId)
+ --pPropIter->nDocId;
+
+ ++pPropIter;
+ }
+ }
+
+ // Keep view document id synchronized with SfxDocumentTemplates
+ for (auto const& item : mItemList)
+ {
+ auto pTemplateViewItem = static_cast<TemplateViewItem*>(item.get());
+ if (pTemplateViewItem->mnDocId > pViewItem->mnDocId)
+ --pTemplateViewItem->mnDocId;
+ }
+ }
+ }
+
+ refresh = true;
+ }
+
+ // Remove items from the current view
+ for (auto const& itemId : aItemIds)
+ RemoveItem(itemId);
+
+ if (refresh)
+ {
+ CalculateItemPositions();
+ Invalidate();
+ }
+}
+
+bool SfxTemplateLocalView::copyFrom (TemplateContainerItem *pItem, const OUString &rPath)
+{
+ sal_uInt16 nId = 1;
+ sal_uInt16 nDocId = 0;
+ sal_uInt16 nRegionId = pItem->mnRegionId;
+ OUString aPath(rPath);
+
+ if (!pItem->maTemplates.empty())
+ {
+ nId = pItem->maTemplates.back().nId+1;
+ nDocId = pItem->maTemplates.back().nDocId+1;
+ }
+
+ if (mpDocTemplates->CopyFrom(nRegionId,nDocId,aPath))
+ {
+ TemplateItemProperties aTemplate;
+ aTemplate.nId = nId;
+ aTemplate.nDocId = nDocId;
+ aTemplate.nRegionId = nRegionId;
+ aTemplate.aName = aPath;
+ aTemplate.aThumbnail = SfxTemplateLocalView::fetchThumbnail(rPath,
+ TEMPLATE_THUMBNAIL_MAX_WIDTH,
+ TEMPLATE_THUMBNAIL_MAX_HEIGHT);
+ aTemplate.aPath = rPath;
+ aTemplate.aRegionName = getRegionName(nRegionId);
+
+ pItem->maTemplates.push_back(aTemplate);
+
+ CalculateItemPositions();
+
+ return true;
+ }
+
+ return false;
+}
+
+bool SfxTemplateLocalView::exportTo(const sal_uInt16 nItemId, const sal_uInt16 nRegionItemId, const OUString &rName)
+{
+ for (auto const & pRegItem : maRegions)
+ {
+ if (pRegItem->mnId == nRegionItemId)
+ {
+ for (auto const& elem : pRegItem->maTemplates)
+ {
+ if (elem.nId == nItemId)
+ {
+ return mpDocTemplates->CopyTo(pRegItem->mnRegionId,elem.nDocId,rName);
+ }
+ }
+
+ break;
+ }
+ }
+
+ return false;
+}
+
+bool SfxTemplateLocalView::renameItem(ThumbnailViewItem* pItem, const OUString& sNewTitle)
+{
+ sal_uInt16 nRegionId = 0;
+ sal_uInt16 nDocId = USHRT_MAX;
+ TemplateViewItem* pDocItem = dynamic_cast<TemplateViewItem*>( pItem );
+
+ if ( pDocItem )
+ {
+ nRegionId = pDocItem->mnRegionId;
+ nDocId = pDocItem->mnDocId;
+ }
+
+ return mpDocTemplates->SetName( sNewTitle, nRegionId, nDocId );
+}
+
+void SfxTemplateLocalView::insertItems(const std::vector<TemplateItemProperties> &rTemplates, bool isRegionSelected, bool bShowCategoryInTooltip)
+{
+ std::vector<std::unique_ptr<ThumbnailViewItem>> aItems(rTemplates.size());
+ for (size_t i = 0, n = rTemplates.size(); i < n; ++i )
+ {
+ const TemplateItemProperties *pCur = &rTemplates[i];
+
+ std::unique_ptr<TemplateViewItem> pChild;
+ if(isRegionSelected)
+ pChild.reset(new TemplateViewItem(*this, pCur->nId));
+ else
+ pChild.reset(new TemplateViewItem(*this, i+1));
+
+ pChild->mnDocId = pCur->nDocId;
+ pChild->mnRegionId = pCur->nRegionId;
+ pChild->maTitle = pCur->aName;
+ pChild->setPath(pCur->aPath);
+
+ if(!bShowCategoryInTooltip)
+ pChild->setHelpText(pCur->aName);
+ else
+ {
+ OUString sHelpText = SfxResId(STR_TEMPLATE_TOOLTIP);
+ sHelpText = (sHelpText.replaceFirst("$1", pCur->aName)).replaceFirst("$2", pCur->aRegionName);
+ pChild->setHelpText(sHelpText);
+ }
+
+ pChild->maPreview1 = pCur->aThumbnail;
+
+ if(IsDefaultTemplate(pCur->aPath))
+ pChild->showDefaultIcon(true);
+
+ if ( pCur->aThumbnail.IsEmpty() )
+ {
+ // Use the default thumbnail if we have nothing else
+ pChild->maPreview1 = SfxTemplateLocalView::getDefaultThumbnail(pCur->aPath);
+ }
+
+ aItems[i] = std::move(pChild);
+ }
+
+ updateItems(std::move(aItems));
+}
+
+void SfxTemplateLocalView::updateThumbnailDimensions(long itemMaxSize)
+{
+ mnThumbnailWidth = itemMaxSize;
+ mnThumbnailHeight = itemMaxSize;
+}
+
+bool SfxTemplateLocalView::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ GrabFocus();
+ return SfxThumbnailView::MouseButtonDown(rMEvt);
+}
+
+bool SfxTemplateLocalView::ContextMenu(const CommandEvent& rCEvt)
+{
+ if (rCEvt.IsMouseEvent())
+ {
+ deselectItems();
+ size_t nPos = ImplGetItem(rCEvt.GetMousePosPixel());
+ Point aPosition(rCEvt.GetMousePosPixel());
+ maPosition = aPosition;
+ ThumbnailViewItem* pItem = ImplGetItem(nPos);
+ const TemplateViewItem *pViewItem = dynamic_cast<const TemplateViewItem*>(pItem);
+
+ if(pViewItem)
+ {
+ maSelectedItem = dynamic_cast<TemplateViewItem*>(pItem);
+ maCreateContextMenuHdl.Call(pItem);
+ }
+ }
+ else
+ {
+ for (ThumbnailViewItem* pItem : mFilteredItemList)
+ {
+ //create context menu for the first selected item
+ if (pItem->isSelected())
+ {
+ deselectItems();
+ pItem->setSelection(true);
+ maItemStateHdl.Call(pItem);
+ tools::Rectangle aRect = pItem->getDrawArea();
+ maPosition = aRect.Center();
+ maSelectedItem = dynamic_cast<TemplateViewItem*>(pItem);
+ maCreateContextMenuHdl.Call(pItem);
+ break;
+ }
+ }
+ }
+ return true;
+}
+
+bool SfxTemplateLocalView::KeyInput( const KeyEvent& rKEvt )
+{
+ vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
+
+ if(aKeyCode == ( KEY_MOD1 | KEY_A ) )
+ {
+ for (ThumbnailViewItem* pItem : mFilteredItemList)
+ {
+ if (!pItem->isSelected())
+ {
+ pItem->setSelection(true);
+ maItemStateHdl.Call(pItem);
+ }
+ }
+
+ if (IsReallyVisible() && IsUpdateMode())
+ Invalidate();
+ return true;
+ }
+ else if( aKeyCode == KEY_DELETE && !mFilteredItemList.empty())
+ {
+ std::unique_ptr<weld::MessageDialog> xQueryDlg(Application::CreateMessageDialog(GetDrawingArea(), VclMessageType::Question, VclButtonsType::YesNo,
+ SfxResId(STR_QMSG_SEL_TEMPLATE_DELETE)));
+ if (xQueryDlg->run() != RET_YES)
+ return true;
+
+ //copy to avoid changing filtered item list during deletion
+ ThumbnailValueItemList mFilteredItemListCopy = mFilteredItemList;
+
+ for (ThumbnailViewItem* pItem : mFilteredItemListCopy)
+ {
+ if (pItem->isSelected())
+ {
+ maDeleteTemplateHdl.Call(pItem);
+ }
+ }
+ reload();
+ }
+
+ return SfxThumbnailView::KeyInput(rKEvt);
+}
+
+void SfxTemplateLocalView::setOpenRegionHdl(const Link<void*,void> &rLink)
+{
+ maOpenRegionHdl = rLink;
+}
+
+void SfxTemplateLocalView::setCreateContextMenuHdl(const Link<ThumbnailViewItem*,void> &rLink)
+{
+ maCreateContextMenuHdl = rLink;
+}
+
+void SfxTemplateLocalView::setOpenTemplateHdl(const Link<ThumbnailViewItem*,void> &rLink)
+{
+ maOpenTemplateHdl = rLink;
+}
+
+void SfxTemplateLocalView::setEditTemplateHdl(const Link<ThumbnailViewItem*,void> &rLink)
+{
+ maEditTemplateHdl = rLink;
+}
+
+void SfxTemplateLocalView::setDeleteTemplateHdl(const Link<ThumbnailViewItem*,void> &rLink)
+{
+ maDeleteTemplateHdl = rLink;
+}
+
+void SfxTemplateLocalView::setDefaultTemplateHdl(const Link<ThumbnailViewItem*,void> &rLink)
+{
+ maDefaultTemplateHdl = rLink;
+}
+
+BitmapEx SfxTemplateLocalView::scaleImg (const BitmapEx &rImg, long width, long height)
+{
+ BitmapEx aImg = rImg;
+
+ if (!rImg.IsEmpty())
+ {
+ Size aSize = rImg.GetSizePixel();
+
+ if (aSize.Width() == 0)
+ aSize.setWidth( 1 );
+
+ if (aSize.Height() == 0)
+ aSize.setHeight( 1 );
+
+ // make the picture fit the given width/height constraints
+ double nRatio = std::min(double(width)/double(aSize.Width()), double(height)/double(aSize.Height()));
+
+ aImg.Scale(Size(aSize.Width() * nRatio, aSize.Height() * nRatio));
+ }
+
+ return aImg;
+}
+
+bool SfxTemplateLocalView::IsDefaultTemplate(const OUString& rPath)
+{
+ SvtModuleOptions aModOpt;
+ const css::uno::Sequence<OUString> &aServiceNames = aModOpt.GetAllServiceNames();
+
+ for( sal_Int32 i=0, nCount = aServiceNames.getLength(); i < nCount; ++i )
+ {
+ const OUString defaultPath = SfxObjectFactory::GetStandardTemplate( aServiceNames[i] );
+ if(defaultPath.match(rPath))
+ return true;
+ }
+
+ return false;
+}
+
+void SfxTemplateLocalView::RemoveDefaultTemplateIcon(const OUString& rPath)
+{
+ for (std::unique_ptr<ThumbnailViewItem>& pItem : mItemList)
+ {
+ TemplateViewItem* pViewItem = dynamic_cast<TemplateViewItem*>(pItem.get());
+ if (pViewItem && pViewItem->getPath().match(rPath))
+ {
+ pViewItem->showDefaultIcon(false);
+ Invalidate();
+ return;
+ }
+ }
+}
+
+BitmapEx SfxTemplateLocalView::getDefaultThumbnail( const OUString& rPath )
+{
+ BitmapEx aImg;
+ INetURLObject aUrl(rPath);
+ OUString aExt = aUrl.getExtension();
+
+ if ( ViewFilter_Application::isFilteredExtension( FILTER_APPLICATION::WRITER, aExt) )
+ aImg = BitmapEx(SFX_THUMBNAIL_TEXT);
+ else if ( ViewFilter_Application::isFilteredExtension( FILTER_APPLICATION::CALC, aExt) )
+ aImg = BitmapEx(SFX_THUMBNAIL_SHEET);
+ else if ( ViewFilter_Application::isFilteredExtension( FILTER_APPLICATION::IMPRESS, aExt) )
+ aImg = BitmapEx(SFX_THUMBNAIL_PRESENTATION);
+ else if ( ViewFilter_Application::isFilteredExtension( FILTER_APPLICATION::DRAW, aExt) )
+ aImg = BitmapEx(SFX_THUMBNAIL_DRAWING);
+
+ return aImg;
+}
+
+BitmapEx SfxTemplateLocalView::fetchThumbnail (const OUString &msURL, long width, long height)
+{
+ return SfxTemplateLocalView::scaleImg(ThumbnailView::readThumbnail(msURL), width, height);
+}
+
+void SfxTemplateLocalView::OnItemDblClicked (ThumbnailViewItem *pItem)
+{
+ TemplateViewItem* pViewItem = dynamic_cast<TemplateViewItem*>(pItem);
+
+ if( pViewItem )
+ maOpenTemplateHdl.Call(pViewItem);
+}
+
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sfx2/source/control/templatesearchview.cxx b/sfx2/source/control/templatesearchview.cxx
index 279b8bc596ad..97848d65e28a 100644
--- a/sfx2/source/control/templatesearchview.cxx
+++ b/sfx2/source/control/templatesearchview.cxx
@@ -22,27 +22,26 @@
#include <vcl/builderfactory.hxx>
-#define MNI_OPEN 1
-#define MNI_EDIT 2
-#define MNI_DEFAULT_TEMPLATE 3
-#define MNI_DELETE 4
-
-TemplateSearchView::TemplateSearchView (vcl::Window *pParent)
- : ThumbnailView(pParent,WB_TABSTOP | WB_VSCROLL | WB_BORDER),
- maSelectedItem(nullptr),
- maPosition(0,0)
+#define MNI_OPEN "open"
+#define MNI_EDIT "edit"
+#define MNI_DEFAULT_TEMPLATE "default"
+#define MNI_DELETE "delete"
+
+TemplateSearchView::TemplateSearchView(std::unique_ptr<weld::ScrolledWindow> xWindow,
+ std::unique_ptr<weld::Menu> xMenu)
+ : SfxThumbnailView(std::move(xWindow), std::move(xMenu))
+ , maSelectedItem(nullptr)
+ , maPosition(0,0)
{
}
-VCL_BUILDER_FACTORY(TemplateSearchView)
-
-void TemplateSearchView::MouseButtonDown( const MouseEvent& rMEvt )
+bool TemplateSearchView::MouseButtonDown( const MouseEvent& rMEvt )
{
GrabFocus();
- ThumbnailView::MouseButtonDown(rMEvt);
+ return SfxThumbnailView::MouseButtonDown(rMEvt);
}
-void TemplateSearchView::KeyInput( const KeyEvent& rKEvt )
+bool TemplateSearchView::KeyInput( const KeyEvent& rKEvt )
{
vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
@@ -59,14 +58,14 @@ void TemplateSearchView::KeyInput( const KeyEvent& rKEvt )
if (IsReallyVisible() && IsUpdateMode())
Invalidate();
- return;
+ return true;
}
else if( aKeyCode == KEY_DELETE && !mFilteredItemList.empty())
{
- std::unique_ptr<weld::MessageDialog> xQueryDlg(Application::CreateMessageDialog(GetFrameWeld(), VclMessageType::Question, VclButtonsType::YesNo,
+ std::unique_ptr<weld::MessageDialog> xQueryDlg(Application::CreateMessageDialog(GetDrawingArea(), VclMessageType::Question, VclButtonsType::YesNo,
SfxResId(STR_QMSG_SEL_TEMPLATE_DELETE)));
if (xQueryDlg->run() != RET_YES)
- return;
+ return true;
//copy to avoid changing filtered item list during deletion
ThumbnailValueItemList mFilteredItemListCopy = mFilteredItemList;
@@ -83,104 +82,86 @@ void TemplateSearchView::KeyInput( const KeyEvent& rKEvt )
}
}
- ThumbnailView::KeyInput(rKEvt);
+ return SfxThumbnailView::KeyInput(rKEvt);
}
-void TemplateSearchView::Command( const CommandEvent& rCEvt )
+bool TemplateSearchView::ContextMenu(const CommandEvent& rCEvt)
{
- if ( rCEvt.GetCommand() == CommandEventId::ContextMenu )
+ if (rCEvt.IsMouseEvent())
{
- if(rCEvt.IsMouseEvent())
+ deselectItems();
+ size_t nPos = ImplGetItem(rCEvt.GetMousePosPixel());
+ Point aPosition(rCEvt.GetMousePosPixel());
+ maPosition = aPosition;
+ ThumbnailViewItem* pItem = ImplGetItem(nPos);
+ const TemplateViewItem *pViewItem = dynamic_cast<const TemplateViewItem*>(pItem);
+
+ if(pViewItem)
{
- deselectItems();
- size_t nPos = ImplGetItem(rCEvt.GetMousePosPixel());
- Point aPosition (rCEvt.GetMousePosPixel());
- maPosition = aPosition;
- ThumbnailViewItem* pItem = ImplGetItem(nPos);
- const TemplateViewItem *pViewItem = dynamic_cast<const TemplateViewItem*>(pItem);
-
- if(pViewItem)
- {
- maSelectedItem = dynamic_cast<TemplateViewItem*>(pItem);
- maCreateContextMenuHdl.Call(pItem);
- }
+ maSelectedItem = dynamic_cast<TemplateViewItem*>(pItem);
+ maCreateContextMenuHdl.Call(pItem);
}
- else
+ }
+ else
+ {
+ for (ThumbnailViewItem* pItem : mFilteredItemList)
{
- for (ThumbnailViewItem* pItem : mFilteredItemList)
+ //create context menu for the first selected item
+ if (pItem->isSelected())
{
- //create context menu for the first selected item
- if (pItem->isSelected())
- {
- deselectItems();
- pItem->setSelection(true);
- maItemStateHdl.Call(pItem);
- tools::Rectangle aRect = pItem->getDrawArea();
- maPosition = aRect.Center();
- maSelectedItem = dynamic_cast<TemplateViewItem*>(pItem);
- maCreateContextMenuHdl.Call(pItem);
- break;
- }
+ deselectItems();
+ pItem->setSelection(true);
+ maItemStateHdl.Call(pItem);
+ tools::Rectangle aRect = pItem->getDrawArea();
+ maPosition = aRect.Center();
+ maSelectedItem = dynamic_cast<TemplateViewItem*>(pItem);
+ maCreateContextMenuHdl.Call(pItem);
+ break;
}
}
}
-
- ThumbnailView::Command(rCEvt);
+ return true;
}
-void TemplateSearchView::createContextMenu( const bool bIsDefault)
+void TemplateSearchView::createContextMenu(const bool bIsDefault)
{
- ScopedVclPtrInstance<PopupMenu> pItemMenu;
- pItemMenu->InsertItem(MNI_OPEN,SfxResId(STR_OPEN));
- pItemMenu->InsertItem(MNI_EDIT,SfxResId(STR_EDIT_TEMPLATE));
+ mxContextMenu->clear();
+ mxContextMenu->append(MNI_OPEN,SfxResId(STR_OPEN));
+ mxContextMenu->append(MNI_EDIT,SfxResId(STR_EDIT_TEMPLATE));
- if(!bIsDefault)
- pItemMenu->InsertItem(MNI_DEFAULT_TEMPLATE,SfxResId(STR_DEFAULT_TEMPLATE));
+ if (!bIsDefault)
+ mxContextMenu->append(MNI_DEFAULT_TEMPLATE,SfxResId(STR_DEFAULT_TEMPLATE));
else
- pItemMenu->InsertItem(MNI_DEFAULT_TEMPLATE,SfxResId(STR_RESET_DEFAULT));
+ mxContextMenu->append(MNI_DEFAULT_TEMPLATE,SfxResId(STR_RESET_DEFAULT));
- pItemMenu->InsertSeparator();
- pItemMenu->InsertItem(MNI_DELETE,SfxResId(STR_DELETE));
+ mxContextMenu->append_separator("separator");
+ mxContextMenu->append(MNI_DELETE,SfxResId(STR_DELETE));
maSelectedItem->setSelection(true);
maItemStateHdl.Call(maSelectedItem);
- pItemMenu->SetSelectHdl(LINK(this, TemplateSearchView, ContextMenuSelectHdl));
- pItemMenu->Execute(this, tools::Rectangle(maPosition,Size(1,1)), PopupMenuFlags::ExecuteDown);
+ ContextMenuSelectHdl(mxContextMenu->popup_at_rect(GetDrawingArea(), tools::Rectangle(maPosition, Size(1,1))));
Invalidate();
}
-IMPL_LINK(TemplateSearchView, ContextMenuSelectHdl, Menu*, pMenu, bool)
+void TemplateSearchView::ContextMenuSelectHdl(const OString& rIdent)
{
- sal_uInt16 nMenuId = pMenu->GetCurItemId();
-
- switch(nMenuId)
- {
- case MNI_OPEN:
+ if (rIdent == MNI_OPEN)
maOpenTemplateHdl.Call(maSelectedItem);
- break;
- case MNI_EDIT:
+ else if (rIdent == MNI_EDIT)
maEditTemplateHdl.Call(maSelectedItem);
- break;
- case MNI_DELETE:
+ else if (rIdent == MNI_DELETE)
{
- std::unique_ptr<weld::MessageDialog> xQueryDlg(Application::CreateMessageDialog(GetFrameWeld(), VclMessageType::Question, VclButtonsType::YesNo,
+ std::unique_ptr<weld::MessageDialog> xQueryDlg(Application::CreateMessageDialog(GetDrawingArea(), VclMessageType::Question, VclButtonsType::YesNo,
SfxResId(STR_QMSG_SEL_TEMPLATE_DELETE)));
if (xQueryDlg->run() != RET_YES)
- break;
+ return;
maDeleteTemplateHdl.Call(maSelectedItem);
RemoveItem(maSelectedItem->mnId);
CalculateItemPositions();
}
- break;
- case MNI_DEFAULT_TEMPLATE:
+ else if (rIdent == MNI_DEFAULT_TEMPLATE)
maDefaultTemplateHdl.Call(maSelectedItem);
- break;
- default:
- break;
- }
-
- return false;
}
void TemplateSearchView::setCreateContextMenuHdl(const Link<ThumbnailViewItem*,void> &rLink)
@@ -235,7 +216,7 @@ void TemplateSearchView::AppendItem(sal_uInt16 nAssocItemId, sal_uInt16 nRegionI
if(TemplateLocalView::IsDefaultTemplate(rPath))
pItem->showDefaultIcon(true);
- ThumbnailView::AppendItem(std::move(pItem));
+ SfxThumbnailView::AppendItem(std::move(pItem));
CalculateItemPositions();
}
diff --git a/sfx2/source/control/templateviewitem.cxx b/sfx2/source/control/templateviewitem.cxx
index 6d6207554382..b6918de9445b 100644
--- a/sfx2/source/control/templateviewitem.cxx
+++ b/sfx2/source/control/templateviewitem.cxx
@@ -29,7 +29,7 @@ using namespace basegfx::utils;
using namespace drawinglayer::attribute;
using namespace drawinglayer::primitive2d;
-TemplateViewItem::TemplateViewItem (ThumbnailView &rView, sal_uInt16 nId)
+TemplateViewItem::TemplateViewItem (ThumbnailViewBase &rView, sal_uInt16 nId)
: ThumbnailViewItem(rView, nId),
mnRegionId(USHRT_MAX),
mnDocId(USHRT_MAX),
diff --git a/sfx2/source/control/thumbnailview.cxx b/sfx2/source/control/thumbnailview.cxx
index 04c47f81ffc0..9c4986a16220 100644
--- a/sfx2/source/control/thumbnailview.cxx
+++ b/sfx2/source/control/thumbnailview.cxx
@@ -229,6 +229,11 @@ css::uno::Reference< css::accessibility::XAccessible > ThumbnailView::CreateAcce
return new ThumbnailViewAcc( this );
}
+css::uno::Reference< css::accessibility::XAccessible > ThumbnailView::getAccessible()
+{
+ return GetAccessible();
+}
+
void ThumbnailView::CalculateItemPositions (bool bScrollBarUsed)
{
if (!mnItemHeight || !mnItemWidth)
@@ -1206,12 +1211,16 @@ void ThumbnailView::filterItems(const std::function<bool (const ThumbnailViewIte
Invalidate();
}
-bool ThumbnailView::renameItem(ThumbnailViewItem*, const OUString&)
+bool ThumbnailViewBase::renameItem(ThumbnailViewItem*, const OUString&)
{
// Do nothing by default
return false;
}
+ThumbnailViewBase::~ThumbnailViewBase()
+{
+}
+
BitmapEx ThumbnailView::readThumbnail(const OUString &msURL)
{
using namespace ::com::sun::star;
@@ -1306,4 +1315,1169 @@ BitmapEx ThumbnailView::readThumbnail(const OUString &msURL)
return aThumbnail;
}
+SfxThumbnailView::SfxThumbnailView(std::unique_ptr<weld::ScrolledWindow> xWindow, std::unique_ptr<weld::Menu> xMenu)
+ : mpItemAttrs(new ThumbnailItemAttributes)
+ , mxScrolledWindow(std::move(xWindow))
+ , mxContextMenu(std::move(xMenu))
+{
+ mxScrolledWindow->set_user_managed_scrolling();
+ ImplInit();
+ mxScrolledWindow->connect_vadjustment_changed(LINK(this, SfxThumbnailView, ImplScrollHdl));
+}
+
+SfxThumbnailView::~SfxThumbnailView()
+{
+ css::uno::Reference< css::lang::XComponent> xComponent(mxAccessible, css::uno::UNO_QUERY);
+
+ if (xComponent.is())
+ xComponent->dispose();
+
+ mpItemAttrs.reset();
+
+ ImplDeleteItems();
+}
+
+bool SfxThumbnailView::MouseMove(const MouseEvent& rMEvt)
+{
+ size_t nItemCount = mFilteredItemList.size();
+ Point aPoint = rMEvt.GetPosPixel();
+
+ for (size_t i = 0; i < nItemCount; i++)
+ {
+ ThumbnailViewItem *pItem = mFilteredItemList[i];
+ ::tools::Rectangle aToInvalidate(pItem->updateHighlight(pItem->mbVisible && !rMEvt.IsLeaveWindow(), aPoint));
+ if (!aToInvalidate.IsEmpty() && IsReallyVisible() && IsUpdateMode())
+ Invalidate(aToInvalidate);
+ }
+
+ return true;
+}
+
+OUString SfxThumbnailView::RequestHelp(tools::Rectangle& rHelpRect)
+{
+ if (!mbShowTooltips)
+ return OUString();
+
+ Point aPos = rHelpRect.TopLeft();
+ size_t nItemCount = mFilteredItemList.size();
+ for (size_t i = 0; i < nItemCount; i++)
+ {
+ ThumbnailViewItem *pItem = mFilteredItemList[i];
+ if (!pItem->mbVisible)
+ continue;
+ const tools::Rectangle& rDrawArea = pItem->getDrawArea();
+ if (pItem->mbVisible && rDrawArea.IsInside(aPos))
+ {
+ rHelpRect = rDrawArea;
+ return pItem->getHelpText();
+ }
+ }
+
+ return OUString();
+}
+
+void SfxThumbnailView::AppendItem(std::unique_ptr<ThumbnailViewItem> pItem)
+{
+ if (maFilterFunc(pItem.get()))
+ {
+ // Save current start,end range, iterator might get invalidated
+ size_t nSelStartPos = 0;
+ ThumbnailViewItem *pSelStartItem = nullptr;
+
+ if (mpStartSelRange != mFilteredItemList.end())
+ {
+ pSelStartItem = *mpStartSelRange;
+ nSelStartPos = mpStartSelRange - mFilteredItemList.begin();
+ }
+
+ mFilteredItemList.push_back(pItem.get());
+ mpStartSelRange = pSelStartItem != nullptr ? mFilteredItemList.begin() + nSelStartPos : mFilteredItemList.end();
+ }
+
+ mItemList.push_back(std::move(pItem));
+}
+
+void SfxThumbnailView::ImplInit()
+{
+ mnItemWidth = 0;
+ mnItemHeight = 0;
+ mnItemPadding = 0;
+ mnVisLines = 0;
+ mnLines = 0;
+ mnFirstLine = 0;
+ mnCols = 0;
+ mbScroll = false;
+ mbHasVisibleItems = false;
+ mbShowTooltips = false;
+ mbIsMultiSelectionEnabled = true;
+ maFilterFunc = ViewFilterAll();
+
+ const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
+ maFillColor = rSettings.GetFieldColor();
+ maTextColor = rSettings.GetWindowTextColor();
+ maHighlightColor = rSettings.GetHighlightColor();
+ maHighlightTextColor = rSettings.GetWindowTextColor();
+ maSelectHighlightColor = rSettings.GetActiveColor();
+ maSelectHighlightTextColor = rSettings.GetActiveTextColor();
+
+ const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
+ mfHighlightTransparence = aSvtOptionsDrawinglayer.GetTransparentSelectionPercent() * 0.01;
+
+ mpStartSelRange = mFilteredItemList.end();
+
+ mpItemAttrs->aFillColor = maFillColor.getBColor();
+ mpItemAttrs->aTextColor = maTextColor.getBColor();
+ mpItemAttrs->aHighlightColor = maHighlightColor.getBColor();
+ mpItemAttrs->aHighlightTextColor = maHighlightTextColor.getBColor();
+ mpItemAttrs->aSelectHighlightColor = maSelectHighlightColor.getBColor();
+ mpItemAttrs->aSelectHighlightTextColor = maSelectHighlightTextColor.getBColor();
+ mpItemAttrs->fHighlightTransparence = mfHighlightTransparence;
+
+ mpItemAttrs->nMaxTextLength = 0;
+}
+
+void SfxThumbnailView::ImplDeleteItems()
+{
+ const size_t n = mItemList.size();
+
+ for ( size_t i = 0; i < n; ++i )
+ {
+ ThumbnailViewItem *const pItem = mItemList[i].get();
+
+ // deselect all current selected items and fire events
+ if (pItem->isSelected())
+ {
+ pItem->setSelection(false);
+ maItemStateHdl.Call(pItem);
+
+ // fire accessible event???
+ }
+
+ if ( pItem->isVisible() && ImplHasAccessibleListeners() )
+ {
+ css::uno::Any aOldAny, aNewAny;
+
+ aOldAny <<= pItem->GetAccessible( false );
+ ImplFireAccessibleEvent( css::accessibility::AccessibleEventId::CHILD, aOldAny, aNewAny );
+ }
+
+ mItemList[i].reset();
+ }
+
+ mItemList.clear();
+ mFilteredItemList.clear();
+
+ mpStartSelRange = mFilteredItemList.end();
+}
+
+void SfxThumbnailView::DrawItem(ThumbnailViewItem const *pItem)
+{
+ if (pItem->isVisible())
+ {
+ ::tools::Rectangle aRect = pItem->getDrawArea();
+
+ if ((aRect.GetHeight() > 0) && (aRect.GetWidth() > 0))
+ Invalidate(aRect);
+ }
+}
+
+void SfxThumbnailView::OnItemDblClicked (ThumbnailViewItem*)
+{
+}
+
+css::uno::Reference< css::accessibility::XAccessible > SfxThumbnailView::CreateAccessible()
+{
+ mxAccessible.set(new SfxThumbnailViewAcc(this));
+ return mxAccessible;
+}
+
+css::uno::Reference< css::accessibility::XAccessible > SfxThumbnailView::getAccessible()
+{
+ return mxAccessible;
+}
+
+void SfxThumbnailView::CalculateItemPositions(bool bScrollBarUsed)
+{
+ if (!mnItemHeight || !mnItemWidth)
+ return;
+
+ Size aWinSize = GetOutputSizePixel();
+ size_t nItemCount = mFilteredItemList.size();
+
+ // calculate window scroll ratio
+ float nScrollRatio;
+ if (bScrollBarUsed)
+ nScrollRatio = static_cast<float>(mxScrolledWindow->vadjustment_get_value()) /
+ static_cast<float>(mxScrolledWindow->vadjustment_get_upper()-2);
+ else
+ nScrollRatio = 0;
+
+ // calculate ScrollBar width
+ long nScrBarWidth = mxScrolledWindow->get_vscroll_width();
+
+ // calculate maximum number of visible columns
+ mnCols = static_cast<sal_uInt16>((aWinSize.Width()-nScrBarWidth) / mnItemWidth);
+
+ if (!mnCols)
+ mnCols = 1;
+
+ // calculate maximum number of visible rows
+ mnVisLines = static_cast<sal_uInt16>(aWinSize.Height() / mnItemHeight);
+
+ // calculate empty space
+ long nHSpace = aWinSize.Width()-nScrBarWidth - mnCols*mnItemWidth;
+ long nVSpace = aWinSize.Height() - mnVisLines*mnItemHeight;
+ long nHItemSpace = nHSpace / (mnCols+1);
+ long nVItemSpace = nVSpace / (mnVisLines+1);
+
+ // calculate maximum number of rows
+ // Floor( (M+N-1)/N )==Ceiling( M/N )
+ mnLines = (static_cast<long>(nItemCount)+mnCols-1) / mnCols;
+
+ if ( !mnLines )
+ mnLines = 1;
+
+ if ( mnLines <= mnVisLines )
+ mnFirstLine = 0;
+ else if ( mnFirstLine > static_cast<sal_uInt16>(mnLines-mnVisLines) )
+ mnFirstLine = static_cast<sal_uInt16>(mnLines-mnVisLines);
+
+ mbHasVisibleItems = true;
+
+ long nItemHeightOffset = mnItemHeight + nVItemSpace;
+ long nHiddenLines = (static_cast<long>(
+ ( mnLines - 1 ) * nItemHeightOffset * nScrollRatio ) -
+ nVItemSpace ) /
+ nItemHeightOffset;
+
+ // calculate offsets
+ long nStartX = nHItemSpace;
+ long nStartY = nVItemSpace;
+
+ // calculate and draw items
+ long x = nStartX;
+ long y = nStartY - ( mnLines - 1 ) * nItemHeightOffset * nScrollRatio +
+ nHiddenLines * nItemHeightOffset;
+
+ // draw items
+ // Unless we are scrolling (via scrollbar) we just use the precalculated
+ // mnFirstLine -- our nHiddenLines calculation takes into account only
+ // what the user has done with the scrollbar but not any changes of selection
+ // using the keyboard, meaning we could accidentally hide the selected item
+ // if we believe the scrollbar (fdo#72287).
+ size_t nFirstItem = (bScrollBarUsed ? nHiddenLines : mnFirstLine) * mnCols;
+ size_t nLastItem = nFirstItem + (mnVisLines + 1) * mnCols;
+
+ // If want also draw parts of items in the last line,
+ // then we add one more line if parts of these line are
+ // visible
+
+ size_t nCurCount = 0;
+ for ( size_t i = 0; i < nItemCount; i++ )
+ {
+ ThumbnailViewItem *const pItem = mFilteredItemList[i];
+
+ if ((nCurCount >= nFirstItem) && (nCurCount < nLastItem))
+ {
+ if( !pItem->isVisible())
+ {
+ if ( ImplHasAccessibleListeners() )
+ {
+ css::uno::Any aOldAny, aNewAny;
+
+ aNewAny <<= pItem->GetAccessible( false );
+ ImplFireAccessibleEvent( css::accessibility::AccessibleEventId::CHILD, aOldAny, aNewAny );
+ }
+
+ pItem->show(true);
+
+ maItemStateHdl.Call(pItem);
+ }
+
+ pItem->setDrawArea(::tools::Rectangle( Point(x,y), Size(mnItemWidth, mnItemHeight) ));
+ pItem->calculateItemsPosition(mnThumbnailHeight,mnDisplayHeight,mnItemPadding,mpItemAttrs->nMaxTextLength,mpItemAttrs.get());
+
+ if ( !((nCurCount+1) % mnCols) )
+ {
+ x = nStartX;
+ y += mnItemHeight+nVItemSpace;
+ }
+ else
+ x += mnItemWidth+nHItemSpace;
+ }
+ else
+ {
+ if( pItem->isVisible())
+ {
+ if ( ImplHasAccessibleListeners() )
+ {
+ css::uno::Any aOldAny, aNewAny;
+
+ aOldAny <<= pItem->GetAccessible( false );
+ ImplFireAccessibleEvent( css::accessibility::AccessibleEventId::CHILD, aOldAny, aNewAny );
+ }
+
+ pItem->show(false);
+
+ maItemStateHdl.Call(pItem);
+ }
+
+ }
+
+ ++nCurCount;
+ }
+
+ // arrange ScrollBar, set values and show it
+ mnLines = (nCurCount+mnCols-1)/mnCols;
+
+ // check if scroll is needed
+ mbScroll = mnLines > mnVisLines;
+
+ mxScrolledWindow->vadjustment_set_upper((nCurCount+mnCols-1)*gnFineness/mnCols);
+ mxScrolledWindow->vadjustment_set_page_size(mnVisLines);
+ if (!bScrollBarUsed)
+ mxScrolledWindow->vadjustment_set_value(static_cast<long>(mnFirstLine)*gnFineness);
+ long nPageSize = mnVisLines;
+ if ( nPageSize < 1 )
+ nPageSize = 1;
+ mxScrolledWindow->vadjustment_set_page_increment(nPageSize);
+ mxScrolledWindow->set_vpolicy(mbScroll ? VclPolicyType::ALWAYS : VclPolicyType::NEVER);
+}
+
+size_t SfxThumbnailView::ImplGetItem( const Point& rPos ) const
+{
+ if ( !mbHasVisibleItems )
+ {
+ return THUMBNAILVIEW_ITEM_NOTFOUND;
+ }
+
+ for (size_t i = 0; i < mFilteredItemList.size(); ++i)
+ {
+ if (mFilteredItemList[i]->isVisible() && mFilteredItemList[i]->getDrawArea().IsInside(rPos))
+ return i;
+ }
+
+ return THUMBNAILVIEW_ITEM_NOTFOUND;
+}
+
+ThumbnailViewItem* SfxThumbnailView::ImplGetItem( size_t nPos )
+{
+ return ( nPos < mFilteredItemList.size() ) ? mFilteredItemList[nPos] : nullptr;
+}
+
+sal_uInt16 SfxThumbnailView::ImplGetVisibleItemCount() const
+{
+ sal_uInt16 nRet = 0;
+ const size_t nItemCount = mItemList.size();
+
+ for ( size_t n = 0; n < nItemCount; ++n )
+ {
+ if ( mItemList[n]->isVisible() )
+ ++nRet;
+ }
+
+ return nRet;
+}
+
+ThumbnailViewItem* SfxThumbnailView::ImplGetVisibleItem( sal_uInt16 nVisiblePos )
+{
+ const size_t nItemCount = mItemList.size();
+
+ for ( size_t n = 0; n < nItemCount; ++n )
+ {
+ ThumbnailViewItem *const pItem = mItemList[n].get();
+
+ if ( pItem->isVisible() && !nVisiblePos-- )
+ return pItem;
+ }
+
+ return nullptr;
+}
+
+void SfxThumbnailView::ImplFireAccessibleEvent( short nEventId, const css::uno::Any& rOldValue, const css::uno::Any& rNewValue )
+{
+ ThumbnailViewAcc* pAcc = ThumbnailViewAcc::getImplementation(mxAccessible);
+
+ if( pAcc )
+ pAcc->FireAccessibleEvent( nEventId, rOldValue, rNewValue );
+}
+
+bool SfxThumbnailView::ImplHasAccessibleListeners()
+{
+ ThumbnailViewAcc* pAcc = ThumbnailViewAcc::getImplementation(mxAccessible);
+ return( pAcc && pAcc->HasAccessibleListeners() );
+}
+
+IMPL_LINK_NOARG(SfxThumbnailView, ImplScrollHdl, weld::ScrolledWindow&, void)
+{
+ CalculateItemPositions(true);
+ if (IsReallyVisible() && IsUpdateMode())
+ Invalidate();
+}
+
+bool SfxThumbnailView::KeyInput( const KeyEvent& rKEvt )
+{
+ bool bHandled = true;
+
+ // Get the last selected item in the list
+ size_t nLastPos = 0;
+ bool bFoundLast = false;
+ for ( long i = mFilteredItemList.size() - 1; !bFoundLast && i >= 0; --i )
+ {
+ ThumbnailViewItem* pItem = mFilteredItemList[i];
+ if ( pItem->isSelected() )
+ {
+ nLastPos = i;
+ bFoundLast = true;
+ }
+ }
+
+ bool bValidRange = false;
+ bool bHasSelRange = mpStartSelRange != mFilteredItemList.end();
+ size_t nNextPos = nLastPos;
+ vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
+ ThumbnailViewItem* pNext = nullptr;
+
+ if (aKeyCode.IsShift() && bHasSelRange)
+ {
+ //If the last element selected is the start range position
+ //search for the first selected item
+ size_t nSelPos = mpStartSelRange - mFilteredItemList.begin();
+
+ if (nLastPos == nSelPos)
+ {
+ while (nLastPos && mFilteredItemList[nLastPos-1]->isSelected())
+ --nLastPos;
+ }
+ }
+
+ switch ( aKeyCode.GetCode() )
+ {
+ case KEY_RIGHT:
+ if (!mFilteredItemList.empty())
+ {
+ if ( bFoundLast && nLastPos + 1 < mFilteredItemList.size() )
+ {
+ bValidRange = true;
+ nNextPos = nLastPos + 1;
+ }
+
+ pNext = mFilteredItemList[nNextPos];
+ }
+ break;
+ case KEY_LEFT:
+ if (!mFilteredItemList.empty())
+ {
+ if ( nLastPos > 0 )
+ {
+ bValidRange = true;
+ nNextPos = nLastPos - 1;
+ }
+
+ pNext = mFilteredItemList[nNextPos];
+ }
+ break;
+ case KEY_DOWN:
+ if (!mFilteredItemList.empty())
+ {
+ if ( bFoundLast )
+ {
+ //If we are in the second last row just go the one in
+ //the row below, if there's not row below just go to the
+ //last item but for the last row don't do anything.
+ if ( nLastPos + mnCols < mFilteredItemList.size( ) )
+ {
+ bValidRange = true;
+ nNextPos = nLastPos + mnCols;
+ }
+ else
+ {
+ int curRow = nLastPos/mnCols;
+
+ if (curRow < mnLines-1)
+ nNextPos = mFilteredItemList.size()-1;
+ }
+ }
+
+ pNext = mFilteredItemList[nNextPos];
+ }
+ break;
+ case KEY_UP:
+ if (!mFilteredItemList.empty())
+ {
+ if ( nLastPos >= mnCols )
+ {
+ bValidRange = true;
+ nNextPos = nLastPos - mnCols;
+ }
+
+ pNext = mFilteredItemList[nNextPos];
+ }
+ break;
+ case KEY_RETURN:
+ {
+ if ( bFoundLast )
+ OnItemDblClicked( mFilteredItemList[nLastPos] );
+ }
+ [[fallthrough]];
+ default:
+ bHandled = CustomWidgetController::KeyInput(rKEvt);
+ }
+
+ if ( pNext && mbIsMultiSelectionEnabled)
+ {
+ if (aKeyCode.IsShift() && bValidRange)
+ {
+ std::pair<size_t,size_t> aRange;
+ size_t nSelPos = mpStartSelRange - mFilteredItemList.begin();
+
+ if (nLastPos < nSelPos)
+ {
+ if (nNextPos > nLastPos)
+ {
+ if ( nNextPos > nSelPos)
+ aRange = std::make_pair(nLastPos,nNextPos);
+ else
+ aRange = std::make_pair(nLastPos,nNextPos-1);
+ }
+ else
+ aRange = std::make_pair(nNextPos,nLastPos-1);
+ }
+ else if (nLastPos == nSelPos)
+ {
+ if (nNextPos > nLastPos)
+ aRange = std::make_pair(nLastPos+1,nNextPos);
+ else
+ aRange = std::make_pair(nNextPos,nLastPos-1);
+ }
+ else
+ {
+ if (nNextPos > nLastPos)
+ aRange = std::make_pair(nLastPos+1,nNextPos);
+ else
+ {
+ if ( nNextPos < nSelPos)
+ aRange = std::make_pair(nNextPos,nLastPos);
+ else
+ aRange = std::make_pair(nNextPos+1,nLastPos);
+ }
+ }
+
+ for (size_t i = aRange.first; i <= aRange.second; ++i)
+ {
+ if (i != nSelPos)
+ {
+ ThumbnailViewItem *pCurItem = mFilteredItemList[i];
+
+ pCurItem->setSelection(!pCurItem->isSelected());
+
+ if (pCurItem->isVisible())
+ DrawItem(pCurItem);
+
+ maItemStateHdl.Call(pCurItem);
+ }
+ }
+ }
+ else if (!aKeyCode.IsShift())
+ {
+ deselectItems();
+ SelectItem(pNext->mnId);
+
+ //Mark it as the selection range start position
+ mpStartSelRange = mFilteredItemList.begin() + nNextPos;
+ }
+
+ MakeItemVisible(pNext->mnId);
+ }
+ else if(pNext && !mbIsMultiSelectionEnabled)
+ {
+ deselectItems();
+ SelectItem(pNext->mnId);
+ MakeItemVisible(pNext->mnId);
+ }
+ return bHandled;
+}
+
+void SfxThumbnailView::MakeItemVisible( sal_uInt16 nItemId )
+{
+ // Get the item row
+ size_t nPos = 0;
+ bool bFound = false;
+ for ( size_t i = 0; !bFound && i < mFilteredItemList.size(); ++i )
+ {
+ ThumbnailViewItem* pItem = mFilteredItemList[i];
+ if ( pItem->mnId == nItemId )
+ {
+ nPos = i;
+ bFound = true;
+ }
+ }
+ sal_uInt16 nRow = mnCols ? nPos / mnCols : 0;
+
+ // Move the visible rows as little as possible to include that one
+ if ( nRow < mnFirstLine )
+ mnFirstLine = nRow;
+ else if ( nRow > mnFirstLine + mnVisLines )
+ mnFirstLine = nRow - mnVisLines;
+
+ CalculateItemPositions();
+ Invalidate();
+}
+
+bool SfxThumbnailView::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if (!rMEvt.IsLeft())
+ {
+ return CustomWidgetController::MouseButtonDown( rMEvt );
+ }
+
+ size_t nPos = ImplGetItem(rMEvt.GetPosPixel());
+ ThumbnailViewItem* pItem = ImplGetItem(nPos);
+
+ if ( !pItem )
+ {
+ deselectItems();
+ return CustomWidgetController::MouseButtonDown( rMEvt );
+ }
+
+ if ( rMEvt.GetClicks() == 2 )
+ {
+ OnItemDblClicked(pItem);
+ return true;
+ }
+
+ if ( rMEvt.GetClicks() == 1 && !mbIsMultiSelectionEnabled )
+ {
+ deselectItems();
+ pItem->setSelection(!pItem->isSelected());
+
+ if (!pItem->isHighlighted())
+ DrawItem(pItem);
+
+ maItemStateHdl.Call(pItem);
+ }
+ else if(rMEvt.GetClicks() == 1)
+ {
+ if (rMEvt.IsMod1())
+ {
+ //Keep selected item group state and just invert current desired one state
+ pItem->setSelection(!pItem->isSelected());
+
+ //This one becomes the selection range start position if it changes its state to selected otherwise resets it
+ mpStartSelRange = pItem->isSelected() ? mFilteredItemList.begin() + nPos : mFilteredItemList.end();
+ }
+ else if (rMEvt.IsShift() && mpStartSelRange != mFilteredItemList.end())
+ {
+ std::pair<size_t,size_t> aNewRange;
+ aNewRange.first = mpStartSelRange - mFilteredItemList.begin();
+ aNewRange.second = nPos;
+
+ if (aNewRange.first > aNewRange.second)
+ std::swap(aNewRange.first,aNewRange.second);
+
+ //Deselect the ones outside of it
+ for (size_t i = 0, n = mFilteredItemList.size(); i < n; ++i)
+ {
+ ThumbnailViewItem *pCurItem = mFilteredItemList[i];
+
+ if (pCurItem->isSelected() && (i < aNewRange.first || i > aNewRange.second))
+ {
+ pCurItem->setSelection(false);
+
+ if (pCurItem->isVisible())
+ DrawItem(pCurItem);
+
+ maItemStateHdl.Call(pCurItem);
+ }
+ }
+
+ size_t nSelPos = mpStartSelRange - mFilteredItemList.begin();
+
+ //Select the items between start range and the selected item
+ if (nSelPos != nPos)
+ {
+ int dir = nSelPos < nPos ? 1 : -1;
+ size_t nCurPos = nSelPos + dir;
+
+ while (nCurPos != nPos)
+ {
+ ThumbnailViewItem *pCurItem = mFilteredItemList[nCurPos];
+
+ if (!pCurItem->isSelected())
+ {
+ pCurItem->setSelection(true);
+
+ if (pCurItem->isVisible())
+ DrawItem(pCurItem);
+
+ maItemStateHdl.Call(pCurItem);
+ }
+
+ nCurPos += dir;
+ }
+ }
+
+ pItem->setSelection(true);
+ }
+ else
+ {
+ //If we got a group of selected items deselect the rest and only keep the desired one
+ //mark items as not selected to not fire unnecessary change state events.
+ pItem->setSelection(false);
+ deselectItems();
+ pItem->setSelection(true);
+
+ //Mark as initial selection range position and reset end one
+ mpStartSelRange = mFilteredItemList.begin() + nPos;
+ }
+
+ if (!pItem->isHighlighted())
+ DrawItem(pItem);
+
+ maItemStateHdl.Call(pItem);
+
+ //fire accessible event??
+ }
+ return true;
+}
+
+void SfxThumbnailView::SetDrawingArea(weld::DrawingArea* pDrawingArea)
+{
+ CustomWidgetController::SetDrawingArea(pDrawingArea);
+
+ if (vcl::Window* pDefaultDevice = dynamic_cast<vcl::Window*>(Application::GetDefaultDevice()))
+ {
+ OutputDevice& rDevice = pDrawingArea->get_ref_device();
+ pDefaultDevice->SetPointFont(rDevice, pDrawingArea->get_font());
+ mpItemAttrs->aFontAttr = getFontAttributeFromVclFont(mpItemAttrs->aFontSize, rDevice.GetFont(), false, true);
+ }
+
+ SetOutputSizePixel(pDrawingArea->get_preferred_size());
+}
+
+void SfxThumbnailView::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& /*rRect*/)
+{
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list