1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include <sfx2/templatelocalview.hxx>
12 #include <comphelper/string.hxx>
13 #include <sfx2/doctempl.hxx>
14 #include <sfx2/inputdlg.hxx>
15 #include <sfx2/sfxresid.hxx>
16 #include <templatecontaineritem.hxx>
17 #include <templateviewitem.hxx>
18 #include <sfx2/docfac.hxx>
19 #include <tools/urlobj.hxx>
20 #include <unotools/moduleoptions.hxx>
21 #include <vcl/help.hxx>
22 #include <vcl/svapp.hxx>
23 #include <vcl/weld.hxx>
24 #include <vcl/commandevent.hxx>
25 #include <vcl/event.hxx>
27 #include <sfx2/strings.hrc>
28 #include <bitmaps.hlst>
30 using namespace ::com::sun::star
;
32 bool ViewFilter_Application::isFilteredExtension(FILTER_APPLICATION filter
, const OUString
&rExt
)
34 bool bRet
= rExt
== "ott" || rExt
== "stw" || rExt
== "oth" || rExt
== "dot" || rExt
== "dotx" || rExt
== "otm"
35 || rExt
== "ots" || rExt
== "stc" || rExt
== "xlt" || rExt
== "xltm" || rExt
== "xltx"
36 || rExt
== "otp" || rExt
== "sti" || rExt
== "pot" || rExt
== "potm" || rExt
== "potx"
37 || rExt
== "otg" || rExt
== "std";
39 if (filter
== FILTER_APPLICATION::WRITER
)
41 bRet
= rExt
== "ott" || rExt
== "stw" || rExt
== "oth" || rExt
== "dot" || rExt
== "dotx" || rExt
== "otm";
43 else if (filter
== FILTER_APPLICATION::CALC
)
45 bRet
= rExt
== "ots" || rExt
== "stc" || rExt
== "xlt" || rExt
== "xltm" || rExt
== "xltx";
47 else if (filter
== FILTER_APPLICATION::IMPRESS
)
49 bRet
= rExt
== "otp" || rExt
== "sti" || rExt
== "pot" || rExt
== "potm" || rExt
== "potx";
51 else if (filter
== FILTER_APPLICATION::DRAW
)
53 bRet
= rExt
== "otg" || rExt
== "std";
59 bool ViewFilter_Application::isValid (const OUString
&rPath
) const
61 INetURLObject
aUrl(rPath
);
62 return isFilteredExtension(mApp
, aUrl
.getExtension());
65 bool ViewFilter_Application::operator () (const ThumbnailViewItem
*pItem
)
67 const TemplateViewItem
*pTempItem
= dynamic_cast<const TemplateViewItem
*>(pItem
);
69 return isValid(pTempItem
->getPath());
74 void TemplateLocalView::updateThumbnailDimensions(tools::Long itemMaxSize
)
76 mnThumbnailWidth
= itemMaxSize
;
77 mnThumbnailHeight
= itemMaxSize
;
80 TemplateLocalView::TemplateLocalView(std::unique_ptr
<weld::ScrolledWindow
> xWindow
,
81 std::unique_ptr
<weld::Menu
> xMenu
)
82 : ThumbnailView(std::move(xWindow
), std::move(xMenu
))
84 , maSelectedItem(nullptr)
85 , mnThumbnailWidth(TEMPLATE_THUMBNAIL_MAX_WIDTH
)
86 , mnThumbnailHeight(TEMPLATE_THUMBNAIL_MAX_HEIGHT
)
88 , mpDocTemplates(new SfxDocumentTemplates
)
92 TemplateLocalView::~TemplateLocalView()
96 void TemplateLocalView::Populate()
99 maAllTemplates
.clear();
101 sal_uInt16 nCount
= mpDocTemplates
->GetRegionCount();
102 for (sal_uInt16 i
= 0; i
< nCount
; ++i
)
104 OUString
aRegionName(mpDocTemplates
->GetFullRegionName(i
));
106 std::unique_ptr
<TemplateContainerItem
> pItem(new TemplateContainerItem( i
+1 ));
107 pItem
->mnRegionId
= i
;
108 pItem
->maTitle
= aRegionName
;
110 sal_uInt16 nEntries
= mpDocTemplates
->GetCount(i
);
112 for (sal_uInt16 j
= 0; j
< nEntries
; ++j
)
114 OUString aName
= mpDocTemplates
->GetName(i
,j
);
115 OUString aURL
= mpDocTemplates
->GetPath(i
,j
);
117 TemplateItemProperties aProperties
;
118 aProperties
.nId
= j
+1;
119 aProperties
.nDocId
= j
;
120 aProperties
.nRegionId
= i
;
121 aProperties
.aName
= aName
;
122 aProperties
.aPath
= aURL
;
123 aProperties
.aRegionName
= aRegionName
;
124 aProperties
.aThumbnail
= TemplateLocalView::fetchThumbnail(aURL
,
128 pItem
->maTemplates
.push_back(aProperties
);
129 maAllTemplates
.push_back(aProperties
);
132 maRegions
.push_back(std::move(pItem
));
136 void TemplateLocalView::reload()
138 mpDocTemplates
->Update();
142 // Check if we are currently browsing a region or root folder
145 sal_uInt16 nRegionId
= mnCurRegionId
- 1; //Is offset by 1
147 for (auto const & pRegion
: maRegions
)
149 if (pRegion
->mnRegionId
== nRegionId
)
151 showRegion(pRegion
.get());
159 //No items should be selected by default
163 void TemplateLocalView::showAllTemplates()
167 insertItems(maAllTemplates
, false, true);
169 maOpenRegionHdl
.Call(nullptr);
172 void TemplateLocalView::showRegion(TemplateContainerItem
const *pItem
)
174 mnCurRegionId
= pItem
->mnRegionId
+1;
176 insertItems(pItem
->maTemplates
);
178 maOpenRegionHdl
.Call(nullptr);
181 void TemplateLocalView::showRegion(const OUString
&rName
)
183 for (auto const & pRegion
: maRegions
)
185 if (pRegion
->maTitle
== rName
)
187 showRegion(pRegion
.get());
193 TemplateContainerItem
* TemplateLocalView::getRegion(OUString
const & rName
)
195 for (auto const & pRegion
: maRegions
)
196 if (pRegion
->maTitle
== rName
)
197 return pRegion
.get();
202 void TemplateLocalView::createContextMenu(const bool bIsDefault
)
204 mxContextMenu
->clear();
205 mxContextMenu
->append("open",SfxResId(STR_OPEN
));
206 mxContextMenu
->append("edit",SfxResId(STR_EDIT_TEMPLATE
));
209 mxContextMenu
->append("default",SfxResId(STR_DEFAULT_TEMPLATE
));
211 mxContextMenu
->append("default",SfxResId(STR_RESET_DEFAULT
));
213 mxContextMenu
->append_separator("separator");
214 mxContextMenu
->append("rename",SfxResId(STR_SFX_RENAME
));
215 mxContextMenu
->append("delete",SfxResId(STR_DELETE
));
217 maSelectedItem
->setSelection(true);
218 maItemStateHdl
.Call(maSelectedItem
);
219 ContextMenuSelectHdl(mxContextMenu
->popup_at_rect(GetDrawingArea(), tools::Rectangle(maPosition
, Size(1,1))));
223 void TemplateLocalView::ContextMenuSelectHdl(const OString
& rIdent
)
225 if (rIdent
== "open")
226 maOpenTemplateHdl
.Call(maSelectedItem
);
227 else if (rIdent
== "edit")
228 maEditTemplateHdl
.Call(maSelectedItem
);
229 else if (rIdent
== "rename")
231 InputDialog
aTitleEditDlg(GetDrawingArea(), SfxResId(STR_RENAME_TEMPLATE
));
232 OUString sOldTitle
= maSelectedItem
->getTitle();
233 aTitleEditDlg
.SetEntryText(sOldTitle
);
234 aTitleEditDlg
.HideHelpBtn();
236 if (!aTitleEditDlg
.run())
238 OUString sNewTitle
= comphelper::string::strip(aTitleEditDlg
.GetEntryText(), ' ');
240 if ( !sNewTitle
.isEmpty() && sNewTitle
!= sOldTitle
)
242 maSelectedItem
->setTitle(sNewTitle
);
245 else if (rIdent
== "delete")
247 std::unique_ptr
<weld::MessageDialog
> xQueryDlg(Application::CreateMessageDialog(GetDrawingArea(), VclMessageType::Question
, VclButtonsType::YesNo
,
248 SfxResId(STR_QMSG_SEL_TEMPLATE_DELETE
)));
249 if (xQueryDlg
->run() != RET_YES
)
252 maDeleteTemplateHdl
.Call(maSelectedItem
);
255 else if (rIdent
== "default")
256 maDefaultTemplateHdl
.Call(maSelectedItem
);
259 sal_uInt16
TemplateLocalView::getRegionId(size_t pos
) const
261 assert(pos
< maRegions
.size());
263 return maRegions
[pos
]->mnId
;
266 sal_uInt16
TemplateLocalView::getRegionId(OUString
const & sRegion
) const
268 for (auto const & pRegion
: maRegions
)
270 if (pRegion
->maTitle
== sRegion
)
271 return pRegion
->mnId
;
277 OUString
TemplateLocalView::getRegionName(const sal_uInt16 nRegionId
) const
279 return mpDocTemplates
->GetRegionName(nRegionId
);
282 OUString
TemplateLocalView::getRegionItemName(const sal_uInt16 nItemId
) const
284 for (auto const & pRegion
: maRegions
)
286 if (pRegion
->mnId
== nItemId
)
287 return pRegion
->maTitle
;
293 std::vector
<OUString
> TemplateLocalView::getFolderNames()
295 size_t n
= maRegions
.size();
296 std::vector
<OUString
> ret(n
);
298 for (size_t i
= 0; i
< n
; ++i
)
299 ret
[i
] = maRegions
[i
]->maTitle
;
304 std::vector
<TemplateItemProperties
>
305 TemplateLocalView::getFilteredItems(const std::function
<bool (const TemplateItemProperties
&)> &rFunc
) const
307 std::vector
<TemplateItemProperties
> aItems
;
311 TemplateContainerItem
*pFolderItem
= maRegions
[mnCurRegionId
-1].get();
313 for (const TemplateItemProperties
& rItemProps
: pFolderItem
->maTemplates
)
315 if (rFunc(rItemProps
))
316 aItems
.push_back(rItemProps
);
321 for (auto const & pFolderItem
: maRegions
)
323 for (const TemplateItemProperties
& rItemProps
: pFolderItem
->maTemplates
)
325 if (rFunc(rItemProps
))
326 aItems
.push_back(rItemProps
);
334 sal_uInt16
TemplateLocalView::createRegion(const OUString
&rName
)
336 sal_uInt16 nRegionId
= mpDocTemplates
->GetRegionCount(); // Next regionId
337 sal_uInt16 nItemId
= getNextItemId();
339 if (!mpDocTemplates
->InsertDir(rName
,nRegionId
))
342 // Insert to the region cache list and to the thumbnail item list
343 std::unique_ptr
<TemplateContainerItem
> pItem(new TemplateContainerItem( nItemId
));
344 pItem
->mnRegionId
= nRegionId
;
345 pItem
->maTitle
= rName
;
347 maRegions
.push_back(std::move(pItem
));
352 bool TemplateLocalView::renameRegion(const OUString
&rTitle
, const OUString
&rNewTitle
)
354 TemplateContainerItem
*pRegion
= getRegion(rTitle
);
358 sal_uInt16 nRegionId
= pRegion
->mnRegionId
;
359 return mpDocTemplates
->SetName( rNewTitle
, nRegionId
, USHRT_MAX
/*nDocId*/ );
364 bool TemplateLocalView::removeRegion(const sal_uInt16 nItemId
)
366 sal_uInt16 nRegionId
= USHRT_MAX
;
368 // Remove from the region cache list
369 for (auto pRegionIt
= maRegions
.begin(); pRegionIt
!= maRegions
.end();)
371 if ( (*pRegionIt
)->mnId
== nItemId
)
373 if (!mpDocTemplates
->Delete((*pRegionIt
)->mnRegionId
,USHRT_MAX
))
376 nRegionId
= (*pRegionIt
)->mnRegionId
;
378 pRegionIt
= maRegions
.erase(pRegionIt
);
382 // Synchronize regions cache ids with SfxDocumentTemplates
383 if (nRegionId
!= USHRT_MAX
&& (*pRegionIt
)->mnRegionId
> nRegionId
)
384 --(*pRegionIt
)->mnRegionId
;
390 if (nRegionId
== USHRT_MAX
)
393 // Synchronize view regions ids with SfxDocumentTemplates
394 for (auto const& region
: maRegions
)
396 if (region
->mnRegionId
> nRegionId
)
397 --region
->mnRegionId
;
403 bool TemplateLocalView::removeTemplate (const sal_uInt16 nItemId
, const sal_uInt16 nSrcItemId
)
405 for (auto const & pRegion
: maRegions
)
407 if (pRegion
->mnId
== nSrcItemId
)
409 TemplateContainerItem
*pItem
= pRegion
.get();
410 auto pIter
= std::find_if(pItem
->maTemplates
.begin(), pItem
->maTemplates
.end(),
411 [nItemId
](const TemplateItemProperties
& rTemplate
) { return rTemplate
.nId
== nItemId
; });
412 if (pIter
!= pItem
->maTemplates
.end())
414 if (!mpDocTemplates
->Delete(pItem
->mnRegionId
,pIter
->nDocId
))
417 pIter
= pItem
->maTemplates
.erase(pIter
);
419 if (pRegion
->mnRegionId
== mnCurRegionId
-1)
425 // Update Doc Idx for all templates that follow
426 for (; pIter
!= pItem
->maTemplates
.end(); ++pIter
)
427 pIter
->nDocId
= pIter
->nDocId
- 1;
430 CalculateItemPositions();
438 bool TemplateLocalView::moveTemplate (const ThumbnailViewItem
*pItem
, const sal_uInt16 nSrcItem
,
439 const sal_uInt16 nTargetItem
)
441 TemplateContainerItem
*pTarget
= nullptr;
442 TemplateContainerItem
*pSrc
= nullptr;
444 for (auto const & pRegion
: maRegions
)
446 if (pRegion
->mnId
== nTargetItem
)
447 pTarget
= pRegion
.get();
448 else if (pRegion
->mnId
== nSrcItem
)
449 pSrc
= pRegion
.get();
454 sal_uInt16 nSrcRegionId
= pSrc
->mnRegionId
;
455 sal_uInt16 nTargetRegion
= pTarget
->mnRegionId
;
456 sal_uInt16 nTargetIdx
= mpDocTemplates
->GetCount(nTargetRegion
); // Next Idx
458 const TemplateViewItem
*pViewItem
= static_cast<const TemplateViewItem
*>(pItem
);
460 bool bCopy
= !mpDocTemplates
->Move(nTargetRegion
,nTargetIdx
,nSrcRegionId
,pViewItem
->mnDocId
);
464 OUString sQuery
= SfxResId(STR_MSG_QUERY_COPY
).replaceFirst("$1", pViewItem
->maTitle
).replaceFirst("$2",
465 getRegionName(nTargetRegion
));
467 std::unique_ptr
<weld::MessageDialog
> xQueryDlg(Application::CreateMessageDialog(GetDrawingArea(), VclMessageType::Question
, VclButtonsType::YesNo
, sQuery
));
468 if (xQueryDlg
->run() != RET_YES
)
471 if (!mpDocTemplates
->Copy(nTargetRegion
,nTargetIdx
,nSrcRegionId
,pViewItem
->mnDocId
))
474 // move template to destination
476 TemplateItemProperties aTemplateItem
;
477 aTemplateItem
.nId
= nTargetIdx
+ 1;
478 aTemplateItem
.nDocId
= nTargetIdx
;
479 aTemplateItem
.nRegionId
= nTargetRegion
;
480 aTemplateItem
.aName
= pViewItem
->maTitle
;
481 aTemplateItem
.aPath
= mpDocTemplates
->GetPath(nTargetRegion
,nTargetIdx
);
482 aTemplateItem
.aRegionName
= pViewItem
->maHelpText
;
483 aTemplateItem
.aThumbnail
= pViewItem
->maPreview1
;
485 pTarget
->maTemplates
.push_back(aTemplateItem
);
489 // remove template from region cached data
491 std::vector
<TemplateItemProperties
>::iterator aIter
;
492 for (aIter
= pSrc
->maTemplates
.begin(); aIter
!= pSrc
->maTemplates
.end();)
494 if (aIter
->nDocId
== pViewItem
->mnDocId
)
496 aIter
= pSrc
->maTemplates
.erase(aIter
);
500 // Keep region document id synchronized with SfxDocumentTemplates
501 if (aIter
->nDocId
> pViewItem
->mnDocId
)
508 // Keep view document id synchronized with SfxDocumentTemplates
509 for (auto const& item
: mItemList
)
511 auto pTemplateViewItem
= static_cast<TemplateViewItem
*>(item
.get());
512 if (pTemplateViewItem
->mnDocId
> pViewItem
->mnDocId
)
513 --pTemplateViewItem
->mnDocId
;
517 CalculateItemPositions();
526 void TemplateLocalView::moveTemplates(const std::set
<const ThumbnailViewItem
*, selection_cmp_fn
> &rItems
,
527 const sal_uInt16 nTargetItem
)
529 TemplateContainerItem
*pTarget
= nullptr;
530 TemplateContainerItem
*pSrc
= nullptr;
532 for (auto const & pRegion
: maRegions
)
534 if (pRegion
->mnId
== nTargetItem
)
535 pTarget
= pRegion
.get();
541 bool refresh
= false;
543 sal_uInt16 nTargetRegion
= pTarget
->mnRegionId
;
544 sal_uInt16 nTargetIdx
= mpDocTemplates
->GetCount(nTargetRegion
); // Next Idx
545 std::vector
<sal_uInt16
> aItemIds
; // List of moved items ids (also prevents the invalidation of rItems iterators when we remove them as we go)
547 std::set
<const ThumbnailViewItem
*,selection_cmp_fn
>::const_iterator aSelIter
;
548 for ( aSelIter
= rItems
.begin(); aSelIter
!= rItems
.end(); ++aSelIter
, ++nTargetIdx
)
550 const TemplateViewItem
*pViewItem
= static_cast<const TemplateViewItem
*>(*aSelIter
);
551 sal_uInt16 nSrcRegionId
= pViewItem
->mnRegionId
;
553 for (auto const & pRegion
: maRegions
)
555 if (pRegion
->mnRegionId
== nSrcRegionId
)
556 pSrc
= pRegion
.get();
561 bool bCopy
= !mpDocTemplates
->Move(nTargetRegion
,nTargetIdx
,nSrcRegionId
,pViewItem
->mnDocId
);
565 OUString sQuery
= SfxResId(STR_MSG_QUERY_COPY
).replaceFirst("$1", pViewItem
->maTitle
).replaceFirst("$2",
566 getRegionName(nTargetRegion
));
567 std::unique_ptr
<weld::MessageDialog
> xQueryDlg(Application::CreateMessageDialog(GetDrawingArea(), VclMessageType::Question
, VclButtonsType::YesNo
, sQuery
));
568 if (xQueryDlg
->run() != RET_YES
)
570 OUString
sMsg(SfxResId(STR_MSG_ERROR_LOCAL_MOVE
));
571 sMsg
= sMsg
.replaceFirst("$1",getRegionName(nTargetRegion
));
572 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(GetDrawingArea(),
573 VclMessageType::Warning
, VclButtonsType::Ok
, sMsg
.replaceFirst( "$2",pViewItem
->maTitle
)));
576 return; //return if any single move operation fails
579 if (!mpDocTemplates
->Copy(nTargetRegion
,nTargetIdx
,nSrcRegionId
,pViewItem
->mnDocId
))
585 // move template to destination
587 TemplateItemProperties aTemplateItem
;
588 aTemplateItem
.nId
= nTargetIdx
+ 1;
589 aTemplateItem
.nDocId
= nTargetIdx
;
590 aTemplateItem
.nRegionId
= nTargetRegion
;
591 aTemplateItem
.aName
= pViewItem
->maTitle
;
592 aTemplateItem
.aPath
= mpDocTemplates
->GetPath(nTargetRegion
,nTargetIdx
);
593 aTemplateItem
.aRegionName
= pViewItem
->maHelpText
;
594 aTemplateItem
.aThumbnail
= pViewItem
->maPreview1
;
596 pTarget
->maTemplates
.push_back(aTemplateItem
);
600 // remove template from region cached data
602 std::vector
<TemplateItemProperties
>::iterator pPropIter
;
603 for (pPropIter
= pSrc
->maTemplates
.begin(); pPropIter
!= pSrc
->maTemplates
.end();)
605 if (pPropIter
->nDocId
== pViewItem
->mnDocId
)
607 pPropIter
= pSrc
->maTemplates
.erase(pPropIter
);
608 aItemIds
.push_back(pViewItem
->mnDocId
+ 1);//mnid
612 // Keep region document id synchronized with SfxDocumentTemplates
613 if (pPropIter
->nDocId
> pViewItem
->mnDocId
)
620 // Keep view document id synchronized with SfxDocumentTemplates
621 for (auto const& item
: mItemList
)
623 auto pTemplateViewItem
= static_cast<TemplateViewItem
*>(item
.get());
624 if (pTemplateViewItem
->mnDocId
> pViewItem
->mnDocId
)
625 --pTemplateViewItem
->mnDocId
;
633 // Remove items from the current view
634 for (auto const& itemId
: aItemIds
)
639 CalculateItemPositions();
644 bool TemplateLocalView::copyFrom (TemplateContainerItem
*pItem
, const OUString
&rPath
)
647 sal_uInt16 nDocId
= 0;
648 sal_uInt16 nRegionId
= pItem
->mnRegionId
;
649 OUString
aPath(rPath
);
651 if (!pItem
->maTemplates
.empty())
653 nId
= pItem
->maTemplates
.back().nId
+1;
654 nDocId
= pItem
->maTemplates
.back().nDocId
+1;
657 if (mpDocTemplates
->CopyFrom(nRegionId
,nDocId
,aPath
))
659 TemplateItemProperties aTemplate
;
661 aTemplate
.nDocId
= nDocId
;
662 aTemplate
.nRegionId
= nRegionId
;
663 aTemplate
.aName
= aPath
;
664 aTemplate
.aThumbnail
= TemplateLocalView::fetchThumbnail(rPath
,
665 TEMPLATE_THUMBNAIL_MAX_WIDTH
,
666 TEMPLATE_THUMBNAIL_MAX_HEIGHT
);
667 aTemplate
.aPath
= rPath
;
668 aTemplate
.aRegionName
= getRegionName(nRegionId
);
670 pItem
->maTemplates
.push_back(aTemplate
);
672 CalculateItemPositions();
680 bool TemplateLocalView::exportTo(const sal_uInt16 nItemId
, const sal_uInt16 nRegionItemId
, const OUString
&rName
)
682 for (auto const & pRegItem
: maRegions
)
684 if (pRegItem
->mnId
== nRegionItemId
)
686 for (auto const& elem
: pRegItem
->maTemplates
)
688 if (elem
.nId
== nItemId
)
690 return mpDocTemplates
->CopyTo(pRegItem
->mnRegionId
,elem
.nDocId
,rName
);
701 bool TemplateLocalView::renameItem(ThumbnailViewItem
* pItem
, const OUString
& sNewTitle
)
703 sal_uInt16 nRegionId
= 0;
704 sal_uInt16 nDocId
= USHRT_MAX
;
705 TemplateViewItem
* pDocItem
= dynamic_cast<TemplateViewItem
*>( pItem
);
709 nRegionId
= pDocItem
->mnRegionId
;
710 nDocId
= pDocItem
->mnDocId
;
713 return mpDocTemplates
->SetName( sNewTitle
, nRegionId
, nDocId
);
716 void TemplateLocalView::insertItems(const std::vector
<TemplateItemProperties
> &rTemplates
, bool isRegionSelected
, bool bShowCategoryInTooltip
)
718 std::vector
<std::unique_ptr
<ThumbnailViewItem
>> aItems(rTemplates
.size());
719 for (size_t i
= 0, n
= rTemplates
.size(); i
< n
; ++i
)
721 const TemplateItemProperties
*pCur
= &rTemplates
[i
];
723 std::unique_ptr
<TemplateViewItem
> pChild
;
725 pChild
.reset(new TemplateViewItem(*this, pCur
->nId
));
727 pChild
.reset(new TemplateViewItem(*this, i
+1));
729 pChild
->mnDocId
= pCur
->nDocId
;
730 pChild
->mnRegionId
= pCur
->nRegionId
;
731 pChild
->maTitle
= pCur
->aName
;
732 pChild
->setPath(pCur
->aPath
);
734 if(!bShowCategoryInTooltip
)
735 pChild
->setHelpText(pCur
->aName
);
738 OUString sHelpText
= SfxResId(STR_TEMPLATE_TOOLTIP
);
739 sHelpText
= (sHelpText
.replaceFirst("$1", pCur
->aName
)).replaceFirst("$2", pCur
->aRegionName
);
740 pChild
->setHelpText(sHelpText
);
743 pChild
->maPreview1
= pCur
->aThumbnail
;
745 if(IsDefaultTemplate(pCur
->aPath
))
746 pChild
->showDefaultIcon(true);
748 if ( pCur
->aThumbnail
.IsEmpty() )
750 // Use the default thumbnail if we have nothing else
751 pChild
->maPreview1
= TemplateLocalView::getDefaultThumbnail(pCur
->aPath
);
754 aItems
[i
] = std::move(pChild
);
757 updateItems(std::move(aItems
));
760 bool TemplateLocalView::MouseButtonDown( const MouseEvent
& rMEvt
)
763 return ThumbnailView::MouseButtonDown(rMEvt
);
766 bool TemplateLocalView::Command(const CommandEvent
& rCEvt
)
768 if (rCEvt
.GetCommand() != CommandEventId::ContextMenu
)
769 return CustomWidgetController::Command(rCEvt
);
771 if (rCEvt
.IsMouseEvent())
774 size_t nPos
= ImplGetItem(rCEvt
.GetMousePosPixel());
775 Point
aPosition(rCEvt
.GetMousePosPixel());
776 maPosition
= aPosition
;
777 ThumbnailViewItem
* pItem
= ImplGetItem(nPos
);
778 const TemplateViewItem
*pViewItem
= dynamic_cast<const TemplateViewItem
*>(pItem
);
782 maSelectedItem
= dynamic_cast<TemplateViewItem
*>(pItem
);
783 maCreateContextMenuHdl
.Call(pItem
);
788 for (ThumbnailViewItem
* pItem
: mFilteredItemList
)
790 //create context menu for the first selected item
791 if (pItem
->isSelected())
794 pItem
->setSelection(true);
795 maItemStateHdl
.Call(pItem
);
796 tools::Rectangle aRect
= pItem
->getDrawArea();
797 maPosition
= aRect
.Center();
798 maSelectedItem
= dynamic_cast<TemplateViewItem
*>(pItem
);
799 maCreateContextMenuHdl
.Call(pItem
);
807 bool TemplateLocalView::KeyInput( const KeyEvent
& rKEvt
)
809 vcl::KeyCode aKeyCode
= rKEvt
.GetKeyCode();
811 if(aKeyCode
== ( KEY_MOD1
| KEY_A
) )
813 for (ThumbnailViewItem
* pItem
: mFilteredItemList
)
815 if (!pItem
->isSelected())
817 pItem
->setSelection(true);
818 maItemStateHdl
.Call(pItem
);
822 if (IsReallyVisible() && IsUpdateMode())
826 else if( aKeyCode
== KEY_DELETE
&& !mFilteredItemList
.empty())
828 std::unique_ptr
<weld::MessageDialog
> xQueryDlg(Application::CreateMessageDialog(GetDrawingArea(), VclMessageType::Question
, VclButtonsType::YesNo
,
829 SfxResId(STR_QMSG_SEL_TEMPLATE_DELETE
)));
830 if (xQueryDlg
->run() != RET_YES
)
833 //copy to avoid changing filtered item list during deletion
834 ThumbnailValueItemList mFilteredItemListCopy
= mFilteredItemList
;
836 for (ThumbnailViewItem
* pItem
: mFilteredItemListCopy
)
838 if (pItem
->isSelected())
840 maDeleteTemplateHdl
.Call(pItem
);
846 return ThumbnailView::KeyInput(rKEvt
);
849 void TemplateLocalView::setOpenRegionHdl(const Link
<void*,void> &rLink
)
851 maOpenRegionHdl
= rLink
;
854 void TemplateLocalView::setCreateContextMenuHdl(const Link
<ThumbnailViewItem
*,void> &rLink
)
856 maCreateContextMenuHdl
= rLink
;
859 void TemplateLocalView::setOpenTemplateHdl(const Link
<ThumbnailViewItem
*,void> &rLink
)
861 maOpenTemplateHdl
= rLink
;
864 void TemplateLocalView::setEditTemplateHdl(const Link
<ThumbnailViewItem
*,void> &rLink
)
866 maEditTemplateHdl
= rLink
;
869 void TemplateLocalView::setDeleteTemplateHdl(const Link
<ThumbnailViewItem
*,void> &rLink
)
871 maDeleteTemplateHdl
= rLink
;
874 void TemplateLocalView::setDefaultTemplateHdl(const Link
<ThumbnailViewItem
*,void> &rLink
)
876 maDefaultTemplateHdl
= rLink
;
879 BitmapEx
TemplateLocalView::scaleImg (const BitmapEx
&rImg
, tools::Long width
, tools::Long height
)
881 BitmapEx aImg
= rImg
;
885 Size aSize
= rImg
.GetSizePixel();
887 if (aSize
.Width() == 0)
890 if (aSize
.Height() == 0)
891 aSize
.setHeight( 1 );
893 // make the picture fit the given width/height constraints
894 double nRatio
= std::min(double(width
)/double(aSize
.Width()), double(height
)/double(aSize
.Height()));
896 aImg
.Scale(Size(aSize
.Width() * nRatio
, aSize
.Height() * nRatio
));
902 bool TemplateLocalView::IsDefaultTemplate(const OUString
& rPath
)
904 SvtModuleOptions aModOpt
;
905 const css::uno::Sequence
<OUString
> &aServiceNames
= aModOpt
.GetAllServiceNames();
907 return std::any_of(aServiceNames
.begin(), aServiceNames
.end(), [&rPath
](const OUString
& rName
) {
908 return SfxObjectFactory::GetStandardTemplate(rName
).match(rPath
); });
911 void TemplateLocalView::RemoveDefaultTemplateIcon(std::u16string_view rPath
)
913 for (const std::unique_ptr
<ThumbnailViewItem
>& pItem
: mItemList
)
915 TemplateViewItem
* pViewItem
= dynamic_cast<TemplateViewItem
*>(pItem
.get());
916 if (pViewItem
&& pViewItem
->getPath().match(rPath
))
918 pViewItem
->showDefaultIcon(false);
925 BitmapEx
TemplateLocalView::getDefaultThumbnail( const OUString
& rPath
)
928 INetURLObject
aUrl(rPath
);
929 OUString aExt
= aUrl
.getExtension();
931 if ( ViewFilter_Application::isFilteredExtension( FILTER_APPLICATION::WRITER
, aExt
) )
932 aImg
= BitmapEx(SFX_THUMBNAIL_TEXT
);
933 else if ( ViewFilter_Application::isFilteredExtension( FILTER_APPLICATION::CALC
, aExt
) )
934 aImg
= BitmapEx(SFX_THUMBNAIL_SHEET
);
935 else if ( ViewFilter_Application::isFilteredExtension( FILTER_APPLICATION::IMPRESS
, aExt
) )
936 aImg
= BitmapEx(SFX_THUMBNAIL_PRESENTATION
);
937 else if ( ViewFilter_Application::isFilteredExtension( FILTER_APPLICATION::DRAW
, aExt
) )
938 aImg
= BitmapEx(SFX_THUMBNAIL_DRAWING
);
943 BitmapEx
TemplateLocalView::fetchThumbnail (const OUString
&msURL
, tools::Long width
, tools::Long height
)
945 return TemplateLocalView::scaleImg(ThumbnailView::readThumbnail(msURL
), width
, height
);
948 void TemplateLocalView::OnItemDblClicked (ThumbnailViewItem
*pItem
)
950 TemplateViewItem
* pViewItem
= dynamic_cast<TemplateViewItem
*>(pItem
);
953 maOpenTemplateHdl
.Call(pViewItem
);
957 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */