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/svapp.hxx>
22 #include <vcl/weld.hxx>
23 #include <vcl/commandevent.hxx>
24 #include <vcl/event.hxx>
26 #include <sfx2/strings.hrc>
27 #include <bitmaps.hlst>
29 #include <comphelper/processfactory.hxx>
30 #include <com/sun/star/util/thePathSettings.hpp>
31 #include <unotools/ucbhelper.hxx>
32 #include <sfxurlrelocator.hxx>
33 #include <../doc/doctemplateslocal.hxx>
35 using namespace ::com::sun::star
;
37 bool ViewFilter_Application::isFilteredExtension(FILTER_APPLICATION filter
, std::u16string_view rExt
)
39 bool bRet
= rExt
== u
"ott" || rExt
== u
"stw" || rExt
== u
"oth" || rExt
== u
"dot" || rExt
== u
"dotx" || rExt
== u
"otm"
40 || rExt
== u
"ots" || rExt
== u
"stc" || rExt
== u
"xlt" || rExt
== u
"xltm" || rExt
== u
"xltx"
41 || rExt
== u
"otp" || rExt
== u
"sti" || rExt
== u
"pot" || rExt
== u
"potm" || rExt
== u
"potx"
42 || rExt
== u
"otg" || rExt
== u
"std";
44 if (filter
== FILTER_APPLICATION::WRITER
)
46 bRet
= rExt
== u
"ott" || rExt
== u
"stw" || rExt
== u
"oth" || rExt
== u
"dot" || rExt
== u
"dotx" || rExt
== u
"otm";
48 else if (filter
== FILTER_APPLICATION::CALC
)
50 bRet
= rExt
== u
"ots" || rExt
== u
"stc" || rExt
== u
"xlt" || rExt
== u
"xltm" || rExt
== u
"xltx";
52 else if (filter
== FILTER_APPLICATION::IMPRESS
)
54 bRet
= rExt
== u
"otp" || rExt
== u
"sti" || rExt
== u
"pot" || rExt
== u
"potm" || rExt
== u
"potx";
56 else if (filter
== FILTER_APPLICATION::DRAW
)
58 bRet
= rExt
== u
"otg" || rExt
== u
"std";
64 bool ViewFilter_Application::isValid (std::u16string_view rPath
) const
66 INetURLObject
aUrl(rPath
);
67 return isFilteredExtension(mApp
, aUrl
.getExtension());
70 bool ViewFilter_Application::operator () (const ThumbnailViewItem
*pItem
)
72 const TemplateViewItem
*pTempItem
= dynamic_cast<const TemplateViewItem
*>(pItem
);
74 return isValid(pTempItem
->getPath());
79 void TemplateLocalView::updateThumbnailDimensions(tools::Long itemMaxSize
)
81 mnThumbnailWidth
= itemMaxSize
;
82 mnThumbnailHeight
= itemMaxSize
;
85 TemplateLocalView::TemplateLocalView(std::unique_ptr
<weld::ScrolledWindow
> xWindow
,
86 std::unique_ptr
<weld::Menu
> xMenu
)
87 : ThumbnailView(std::move(xWindow
), std::move(xMenu
))
89 , maSelectedItem(nullptr)
90 , mnThumbnailWidth(TEMPLATE_THUMBNAIL_MAX_WIDTH
)
91 , mnThumbnailHeight(TEMPLATE_THUMBNAIL_MAX_HEIGHT
)
93 , mpDocTemplates(new SfxDocumentTemplates
)
97 TemplateLocalView::~TemplateLocalView()
101 void TemplateLocalView::Populate()
104 maAllTemplates
.clear();
106 sal_uInt16 nCount
= mpDocTemplates
->GetRegionCount();
107 for (sal_uInt16 i
= 0; i
< nCount
; ++i
)
109 OUString
aRegionName(mpDocTemplates
->GetFullRegionName(i
));
111 std::unique_ptr
<TemplateContainerItem
> pItem(new TemplateContainerItem( i
+1 ));
112 pItem
->mnRegionId
= i
;
113 pItem
->maTitle
= aRegionName
;
115 sal_uInt16 nEntries
= mpDocTemplates
->GetCount(i
);
117 for (sal_uInt16 j
= 0; j
< nEntries
; ++j
)
119 OUString aName
= mpDocTemplates
->GetName(i
,j
);
120 OUString aURL
= mpDocTemplates
->GetPath(i
,j
);
122 TemplateItemProperties aProperties
;
123 aProperties
.nId
= j
+1;
124 aProperties
.nDocId
= j
;
125 aProperties
.nRegionId
= i
;
126 aProperties
.aName
= aName
;
127 aProperties
.aPath
= aURL
;
128 aProperties
.aRegionName
= aRegionName
;
129 aProperties
.aThumbnail
= TemplateLocalView::fetchThumbnail(aURL
,
133 pItem
->maTemplates
.push_back(aProperties
);
134 maAllTemplates
.push_back(aProperties
);
137 maRegions
.push_back(std::move(pItem
));
141 void TemplateLocalView::reload()
143 mpDocTemplates
->Update();
144 OUString sCurRegionName
= getRegionItemName(mnCurRegionId
);
146 mnCurRegionId
= getRegionId(sCurRegionName
);
148 // Check if we are currently browsing a region or root folder
151 sal_uInt16 nRegionId
= mnCurRegionId
- 1; //Is offset by 1
153 for (auto const & pRegion
: maRegions
)
155 if (pRegion
->mnRegionId
== nRegionId
)
157 showRegion(pRegion
.get());
165 //No items should be selected by default
169 void TemplateLocalView::showAllTemplates()
173 insertItems(maAllTemplates
, false, true);
175 maOpenRegionHdl
.Call(nullptr);
178 void TemplateLocalView::showRegion(TemplateContainerItem
const *pItem
)
180 mnCurRegionId
= pItem
->mnRegionId
+1;
182 insertItems(pItem
->maTemplates
);
184 maOpenRegionHdl
.Call(nullptr);
187 TemplateContainerItem
* TemplateLocalView::getRegion(std::u16string_view rName
)
189 for (auto const & pRegion
: maRegions
)
190 if (pRegion
->maTitle
== rName
)
191 return pRegion
.get();
196 void TemplateLocalView::ContextMenuSelectHdl(std::u16string_view rIdent
)
198 if (rIdent
== u
"open")
199 maOpenTemplateHdl
.Call(maSelectedItem
);
200 else if (rIdent
== u
"edit")
201 maEditTemplateHdl
.Call(maSelectedItem
);
202 else if (rIdent
== u
"rename")
204 InputDialog
aTitleEditDlg(GetDrawingArea(), SfxResId(STR_RENAME_TEMPLATE
));
205 OUString sOldTitle
= maSelectedItem
->getTitle();
206 aTitleEditDlg
.SetEntryText(sOldTitle
);
207 aTitleEditDlg
.HideHelpBtn();
209 auto aCurRegionItems
= getFilteredItems([&](const TemplateItemProperties
& rItem
) {
210 return rItem
.aRegionName
== getRegionName(maSelectedItem
->mnRegionId
);
212 OUString
sTooltip(SfxResId(STR_TOOLTIP_ERROR_RENAME_TEMPLATE
));
213 sTooltip
= sTooltip
.replaceFirst("$2", getRegionName(maSelectedItem
->mnRegionId
));
214 aTitleEditDlg
.setCheckEntry([&](OUString sNewTitle
) {
215 if (sNewTitle
.isEmpty() || sNewTitle
== sOldTitle
)
217 for (const auto& rItem
: aCurRegionItems
)
219 if (rItem
.aName
== sNewTitle
)
221 aTitleEditDlg
.SetTooltip(sTooltip
.replaceFirst("$1", sNewTitle
));
227 if (!aTitleEditDlg
.run())
229 OUString sNewTitle
= comphelper::string::strip(aTitleEditDlg
.GetEntryText(), ' ');
231 if ( !sNewTitle
.isEmpty() && sNewTitle
!= sOldTitle
)
233 maSelectedItem
->setTitle(sNewTitle
);
236 else if (rIdent
== u
"delete")
238 std::unique_ptr
<weld::MessageDialog
> xQueryDlg(Application::CreateMessageDialog(GetDrawingArea(), VclMessageType::Question
, VclButtonsType::YesNo
,
239 SfxResId(STR_QMSG_SEL_TEMPLATE_DELETE
)));
240 if (xQueryDlg
->run() != RET_YES
)
243 maDeleteTemplateHdl
.Call(maSelectedItem
);
246 else if (rIdent
== u
"default")
247 maDefaultTemplateHdl
.Call(maSelectedItem
);
250 sal_uInt16
TemplateLocalView::getRegionId(size_t pos
) const
252 assert(pos
< maRegions
.size());
254 return maRegions
[pos
]->mnId
;
257 sal_uInt16
TemplateLocalView::getRegionId(std::u16string_view sRegion
) const
259 for (auto const & pRegion
: maRegions
)
261 if (pRegion
->maTitle
== sRegion
)
262 return pRegion
->mnId
;
268 OUString
TemplateLocalView::getRegionName(const sal_uInt16 nRegionId
) const
270 return mpDocTemplates
->GetRegionName(nRegionId
);
273 OUString
TemplateLocalView::getRegionItemName(const sal_uInt16 nItemId
) const
275 for (auto const & pRegion
: maRegions
)
277 if (pRegion
->mnId
== nItemId
)
278 return pRegion
->maTitle
;
284 std::vector
<OUString
> TemplateLocalView::getFolderNames()
286 size_t n
= maRegions
.size();
287 std::vector
<OUString
> ret(n
);
289 for (size_t i
= 0; i
< n
; ++i
)
290 ret
[i
] = maRegions
[i
]->maTitle
;
295 std::vector
<TemplateItemProperties
>
296 TemplateLocalView::getFilteredItems(const std::function
<bool (const TemplateItemProperties
&)> &rFunc
) const
298 std::vector
<TemplateItemProperties
> aItems
;
302 TemplateContainerItem
*pFolderItem
= maRegions
[mnCurRegionId
-1].get();
304 for (const TemplateItemProperties
& rItemProps
: pFolderItem
->maTemplates
)
306 if (rFunc(rItemProps
))
307 aItems
.push_back(rItemProps
);
312 for (auto const & pFolderItem
: maRegions
)
314 for (const TemplateItemProperties
& rItemProps
: pFolderItem
->maTemplates
)
316 if (rFunc(rItemProps
))
317 aItems
.push_back(rItemProps
);
325 sal_uInt16
TemplateLocalView::createRegion(const OUString
&rName
)
327 sal_uInt16 nRegionId
= mpDocTemplates
->GetRegionCount(); // Next regionId
328 sal_uInt16 nItemId
= maRegions
.size() + 1;
330 if (!mpDocTemplates
->InsertDir(rName
,nRegionId
))
333 // Insert to the region cache list and to the thumbnail item list
334 std::unique_ptr
<TemplateContainerItem
> pItem(new TemplateContainerItem( nItemId
));
335 pItem
->mnRegionId
= nRegionId
;
336 pItem
->maTitle
= rName
;
338 maRegions
.push_back(std::move(pItem
));
343 bool TemplateLocalView::renameRegion(std::u16string_view rTitle
, const OUString
&rNewTitle
)
345 TemplateContainerItem
*pRegion
= getRegion(rTitle
);
349 sal_uInt16 nRegionId
= pRegion
->mnRegionId
;
350 return mpDocTemplates
->SetName( rNewTitle
, nRegionId
, USHRT_MAX
/*nDocId*/ );
355 bool TemplateLocalView::removeRegion(const sal_uInt16 nItemId
)
357 sal_uInt16 nRegionId
= USHRT_MAX
;
359 // Remove from the region cache list
360 for (auto pRegionIt
= maRegions
.begin(); pRegionIt
!= maRegions
.end();)
362 if ( (*pRegionIt
)->mnId
== nItemId
)
364 if (!mpDocTemplates
->Delete((*pRegionIt
)->mnRegionId
,USHRT_MAX
))
367 nRegionId
= (*pRegionIt
)->mnRegionId
;
369 pRegionIt
= maRegions
.erase(pRegionIt
);
373 // Synchronize regions cache ids with SfxDocumentTemplates
374 if (nRegionId
!= USHRT_MAX
&& (*pRegionIt
)->mnRegionId
> nRegionId
)
375 --(*pRegionIt
)->mnRegionId
;
381 if (nRegionId
== USHRT_MAX
)
384 // Synchronize view regions ids with SfxDocumentTemplates
385 for (auto const& region
: maRegions
)
387 if (region
->mnRegionId
> nRegionId
)
388 --region
->mnRegionId
;
394 bool TemplateLocalView::removeTemplate (const sal_uInt16 nItemId
, const sal_uInt16 nSrcItemId
)
396 for (auto const & pRegion
: maRegions
)
398 if (pRegion
->mnId
== nSrcItemId
)
400 TemplateContainerItem
*pItem
= pRegion
.get();
401 auto pIter
= std::find_if(pItem
->maTemplates
.begin(), pItem
->maTemplates
.end(),
402 [nItemId
](const TemplateItemProperties
& rTemplate
) { return rTemplate
.nId
== nItemId
; });
403 if (pIter
!= pItem
->maTemplates
.end())
405 if (!mpDocTemplates
->Delete(pItem
->mnRegionId
,pIter
->nDocId
))
408 pIter
= pItem
->maTemplates
.erase(pIter
);
410 if (pRegion
->mnRegionId
== mnCurRegionId
-1)
416 // Update Doc Idx for all templates that follow
417 for (; pIter
!= pItem
->maTemplates
.end(); ++pIter
)
418 pIter
->nDocId
= pIter
->nDocId
- 1;
421 CalculateItemPositions();
429 void TemplateLocalView::moveTemplates(const std::set
<const ThumbnailViewItem
*, selection_cmp_fn
> &rItems
,
430 const sal_uInt16 nTargetItem
)
432 TemplateContainerItem
*pTarget
= nullptr;
433 TemplateContainerItem
*pSrc
= nullptr;
435 for (auto const & pRegion
: maRegions
)
437 if (pRegion
->mnId
== nTargetItem
)
438 pTarget
= pRegion
.get();
444 bool refresh
= false;
446 sal_uInt16 nTargetRegion
= pTarget
->mnRegionId
;
447 sal_uInt16 nTargetIdx
= mpDocTemplates
->GetCount(nTargetRegion
); // Next Idx
448 std::vector
<sal_uInt16
> aItemIds
; // List of moved items ids (also prevents the invalidation of rItems iterators when we remove them as we go)
450 std::set
<const ThumbnailViewItem
*,selection_cmp_fn
>::const_iterator aSelIter
;
451 for ( aSelIter
= rItems
.begin(); aSelIter
!= rItems
.end(); ++aSelIter
, ++nTargetIdx
)
453 const TemplateViewItem
*pViewItem
= static_cast<const TemplateViewItem
*>(*aSelIter
);
454 sal_uInt16 nSrcRegionId
= pViewItem
->mnRegionId
;
456 for (auto const & pRegion
: maRegions
)
458 if (pRegion
->mnRegionId
== nSrcRegionId
)
459 pSrc
= pRegion
.get();
464 bool bCopy
= !mpDocTemplates
->Move(nTargetRegion
,nTargetIdx
,nSrcRegionId
,pViewItem
->mnDocId
);
468 OUString sQuery
= SfxResId(STR_MSG_QUERY_COPY
).replaceFirst("$1", pViewItem
->maTitle
).replaceFirst("$2",
469 getRegionName(nTargetRegion
));
470 std::unique_ptr
<weld::MessageDialog
> xQueryDlg(Application::CreateMessageDialog(GetDrawingArea(), VclMessageType::Question
, VclButtonsType::YesNo
, sQuery
));
471 if (xQueryDlg
->run() != RET_YES
)
473 OUString
sMsg(SfxResId(STR_MSG_ERROR_LOCAL_MOVE
));
474 sMsg
= sMsg
.replaceFirst("$1",getRegionName(nTargetRegion
));
475 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(GetDrawingArea(),
476 VclMessageType::Warning
, VclButtonsType::Ok
, sMsg
.replaceFirst( "$2",pViewItem
->maTitle
)));
479 return; //return if any single move operation fails
482 if (!mpDocTemplates
->Copy(nTargetRegion
,nTargetIdx
,nSrcRegionId
,pViewItem
->mnDocId
))
488 // move template to destination
490 TemplateItemProperties aTemplateItem
;
491 aTemplateItem
.nId
= nTargetIdx
+ 1;
492 aTemplateItem
.nDocId
= nTargetIdx
;
493 aTemplateItem
.nRegionId
= nTargetRegion
;
494 aTemplateItem
.aName
= pViewItem
->maTitle
;
495 aTemplateItem
.aPath
= mpDocTemplates
->GetPath(nTargetRegion
,nTargetIdx
);
496 aTemplateItem
.aRegionName
= pViewItem
->maHelpText
;
497 aTemplateItem
.aThumbnail
= pViewItem
->maPreview1
;
499 pTarget
->maTemplates
.push_back(aTemplateItem
);
503 // remove template from region cached data
505 std::vector
<TemplateItemProperties
>::iterator pPropIter
;
506 for (pPropIter
= pSrc
->maTemplates
.begin(); pPropIter
!= pSrc
->maTemplates
.end();)
508 if (pPropIter
->nDocId
== pViewItem
->mnDocId
)
510 pPropIter
= pSrc
->maTemplates
.erase(pPropIter
);
511 aItemIds
.push_back(pViewItem
->mnDocId
+ 1);//mnid
515 // Keep region document id synchronized with SfxDocumentTemplates
516 if (pPropIter
->nDocId
> pViewItem
->mnDocId
)
523 // Keep view document id synchronized with SfxDocumentTemplates
524 for (auto const& item
: mItemList
)
526 auto pTemplateViewItem
= static_cast<TemplateViewItem
*>(item
.get());
527 if (pTemplateViewItem
->mnDocId
> pViewItem
->mnDocId
)
528 --pTemplateViewItem
->mnDocId
;
536 // Remove items from the current view
537 for (auto const& itemId
: aItemIds
)
542 CalculateItemPositions();
547 bool TemplateLocalView::copyFrom (TemplateContainerItem
*pItem
, const OUString
&rPath
)
550 sal_uInt16 nDocId
= 0;
551 sal_uInt16 nRegionId
= pItem
->mnRegionId
;
552 OUString
aPath(rPath
);
554 if (!pItem
->maTemplates
.empty())
556 nId
= pItem
->maTemplates
.back().nId
+1;
557 nDocId
= pItem
->maTemplates
.back().nDocId
+1;
560 if (mpDocTemplates
->CopyFrom(nRegionId
,nDocId
,aPath
))
562 TemplateItemProperties aTemplate
;
564 aTemplate
.nDocId
= nDocId
;
565 aTemplate
.nRegionId
= nRegionId
;
566 aTemplate
.aName
= aPath
;
567 aTemplate
.aThumbnail
= TemplateLocalView::fetchThumbnail(rPath
,
568 TEMPLATE_THUMBNAIL_MAX_WIDTH
,
569 TEMPLATE_THUMBNAIL_MAX_HEIGHT
);
570 aTemplate
.aPath
= rPath
;
571 aTemplate
.aRegionName
= getRegionName(nRegionId
);
573 pItem
->maTemplates
.push_back(aTemplate
);
575 CalculateItemPositions();
583 bool TemplateLocalView::exportTo(const sal_uInt16 nItemId
, const sal_uInt16 nRegionItemId
, std::u16string_view rName
)
585 for (auto const & pRegItem
: maRegions
)
587 if (pRegItem
->mnId
== nRegionItemId
)
589 for (auto const& elem
: pRegItem
->maTemplates
)
591 if (elem
.nId
== nItemId
)
593 return mpDocTemplates
->CopyTo(pRegItem
->mnRegionId
,elem
.nDocId
,rName
);
604 bool TemplateLocalView::renameItem(ThumbnailViewItem
* pItem
, const OUString
& sNewTitle
)
606 sal_uInt16 nRegionId
= 0;
607 sal_uInt16 nDocId
= USHRT_MAX
;
608 TemplateViewItem
* pDocItem
= dynamic_cast<TemplateViewItem
*>( pItem
);
612 nRegionId
= pDocItem
->mnRegionId
;
613 nDocId
= pDocItem
->mnDocId
;
616 bool bRes
= mpDocTemplates
->SetName( sNewTitle
, nRegionId
, nDocId
);
619 for (auto & pRegion
: maRegions
)
621 if (pRegion
->mnId
== nRegionId
+ 1 )
623 for(auto & aTemplate
: pRegion
->maTemplates
)
625 if(aTemplate
.nId
== nDocId
+ 1)
627 aTemplate
.aName
= sNewTitle
;
634 OUString sRegionName
;
635 for (auto & aTemplate
: maAllTemplates
)
637 if (aTemplate
.nRegionId
== nRegionId
&& aTemplate
.nDocId
== nDocId
)
639 aTemplate
.aName
= sNewTitle
;
640 sRegionName
= aTemplate
.aRegionName
;
645 OUString sHelpText
= SfxResId(STR_TEMPLATE_TOOLTIP
);
646 sHelpText
= (sHelpText
.replaceFirst("$1", sNewTitle
)).replaceFirst("$2", sRegionName
);
647 pItem
->setHelpText(sHelpText
);
648 pItem
->maTitle
= sNewTitle
;
653 void TemplateLocalView::insertItems(const std::vector
<TemplateItemProperties
> &rTemplates
, bool isRegionSelected
, bool bShowCategoryInTooltip
)
655 std::vector
<std::unique_ptr
<ThumbnailViewItem
>> aItems(rTemplates
.size());
656 for (size_t i
= 0, n
= rTemplates
.size(); i
< n
; ++i
)
658 const TemplateItemProperties
*pCur
= &rTemplates
[i
];
660 std::unique_ptr
<TemplateViewItem
> pChild
;
662 pChild
.reset(new TemplateViewItem(*this, pCur
->nId
));
664 pChild
.reset(new TemplateViewItem(*this, i
+1));
666 pChild
->mnDocId
= pCur
->nDocId
;
667 pChild
->mnRegionId
= pCur
->nRegionId
;
668 pChild
->maTitle
= pCur
->aName
;
669 pChild
->setPath(pCur
->aPath
);
671 if(!bShowCategoryInTooltip
)
672 pChild
->setHelpText(pCur
->aName
);
675 OUString sHelpText
= SfxResId(STR_TEMPLATE_TOOLTIP
);
676 sHelpText
= (sHelpText
.replaceFirst("$1", pCur
->aName
)).replaceFirst("$2", pCur
->aRegionName
);
677 pChild
->setHelpText(sHelpText
);
680 pChild
->maPreview1
= pCur
->aThumbnail
;
682 if(IsDefaultTemplate(pCur
->aPath
))
683 pChild
->showDefaultIcon(true);
685 if ( pCur
->aThumbnail
.IsEmpty() )
687 // Use the default thumbnail if we have nothing else
688 pChild
->maPreview1
= TemplateLocalView::getDefaultThumbnail(pCur
->aPath
);
691 aItems
[i
] = std::move(pChild
);
694 updateItems(std::move(aItems
));
697 bool TemplateLocalView::MouseButtonDown( const MouseEvent
& rMEvt
)
700 return ThumbnailView::MouseButtonDown(rMEvt
);
703 bool TemplateLocalView::Command(const CommandEvent
& rCEvt
)
705 if (rCEvt
.GetCommand() != CommandEventId::ContextMenu
)
706 return CustomWidgetController::Command(rCEvt
);
708 if (rCEvt
.IsMouseEvent())
710 size_t nPos
= ImplGetItem(rCEvt
.GetMousePosPixel());
711 Point
aPosition(rCEvt
.GetMousePosPixel());
712 maPosition
= aPosition
;
713 ThumbnailViewItem
* pItem
= ImplGetItem(nPos
);
714 const TemplateViewItem
*pViewItem
= dynamic_cast<const TemplateViewItem
*>(pItem
);
718 if(!pItem
->isSelected())
721 pItem
->setSelection(true);
722 maItemStateHdl
.Call(pItem
);
724 maSelectedItem
= dynamic_cast<TemplateViewItem
*>(pItem
);
725 maCreateContextMenuHdl
.Call(pItem
);
730 for (ThumbnailViewItem
* pItem
: mFilteredItemList
)
732 if (pItem
->isSelected())
734 tools::Rectangle aRect
= pItem
->getDrawArea();
735 maPosition
= aRect
.Center();
736 maSelectedItem
= dynamic_cast<TemplateViewItem
*>(pItem
);
737 maCreateContextMenuHdl
.Call(pItem
);
745 bool TemplateLocalView::KeyInput( const KeyEvent
& rKEvt
)
747 vcl::KeyCode aKeyCode
= rKEvt
.GetKeyCode();
749 if(aKeyCode
== ( KEY_MOD1
| KEY_A
) )
751 for (ThumbnailViewItem
* pItem
: mFilteredItemList
)
753 if (!pItem
->isSelected())
755 pItem
->setSelection(true);
756 maItemStateHdl
.Call(pItem
);
760 if (IsReallyVisible() && IsUpdateMode())
764 else if( aKeyCode
== KEY_DELETE
&& !mFilteredItemList
.empty())
766 std::unique_ptr
<weld::MessageDialog
> xQueryDlg(Application::CreateMessageDialog(GetDrawingArea(), VclMessageType::Question
, VclButtonsType::YesNo
,
767 SfxResId(STR_QMSG_SEL_TEMPLATE_DELETE
)));
768 if (xQueryDlg
->run() != RET_YES
)
771 //copy to avoid changing filtered item list during deletion
772 ThumbnailValueItemList mFilteredItemListCopy
= mFilteredItemList
;
774 for (ThumbnailViewItem
* pItem
: mFilteredItemListCopy
)
776 if (pItem
->isSelected())
778 maDeleteTemplateHdl
.Call(pItem
);
784 return ThumbnailView::KeyInput(rKEvt
);
787 void TemplateLocalView::setOpenRegionHdl(const Link
<void*,void> &rLink
)
789 maOpenRegionHdl
= rLink
;
792 void TemplateLocalView::setCreateContextMenuHdl(const Link
<ThumbnailViewItem
*,void> &rLink
)
794 maCreateContextMenuHdl
= rLink
;
797 void TemplateLocalView::setOpenTemplateHdl(const Link
<ThumbnailViewItem
*,void> &rLink
)
799 maOpenTemplateHdl
= rLink
;
802 void TemplateLocalView::setEditTemplateHdl(const Link
<ThumbnailViewItem
*,void> &rLink
)
804 maEditTemplateHdl
= rLink
;
807 void TemplateLocalView::setDeleteTemplateHdl(const Link
<void*,void> &rLink
)
809 maDeleteTemplateHdl
= rLink
;
812 void TemplateLocalView::setDefaultTemplateHdl(const Link
<ThumbnailViewItem
*,void> &rLink
)
814 maDefaultTemplateHdl
= rLink
;
817 void TemplateLocalView::setMoveTemplateHdl(const Link
<void*,void> &rLink
)
819 maMoveTemplateHdl
= rLink
;
822 void TemplateLocalView::setExportTemplateHdl(const Link
<void*,void> &rLink
)
824 maExportTemplateHdl
= rLink
;
827 BitmapEx
TemplateLocalView::scaleImg (const BitmapEx
&rImg
, tools::Long width
, tools::Long height
)
829 BitmapEx aImg
= rImg
;
833 Size aSize
= rImg
.GetSizePixel();
835 if (aSize
.Width() == 0)
838 if (aSize
.Height() == 0)
839 aSize
.setHeight( 1 );
841 // make the picture fit the given width/height constraints
842 double nRatio
= std::min(double(width
)/double(aSize
.Width()), double(height
)/double(aSize
.Height()));
844 aImg
.Scale(nRatio
, nRatio
);
850 bool TemplateLocalView::IsDefaultTemplate(const OUString
& rPath
)
852 SvtModuleOptions aModOpt
;
853 const css::uno::Sequence
<OUString
> &aServiceNames
= aModOpt
.GetAllServiceNames();
855 return std::any_of(aServiceNames
.begin(), aServiceNames
.end(), [&rPath
](const OUString
& rName
) {
856 return SfxObjectFactory::GetStandardTemplate(rName
).match(rPath
); });
859 void TemplateLocalView::RemoveDefaultTemplateIcon(std::u16string_view rPath
)
861 for (const std::unique_ptr
<ThumbnailViewItem
>& pItem
: mItemList
)
863 TemplateViewItem
* pViewItem
= dynamic_cast<TemplateViewItem
*>(pItem
.get());
864 if (pViewItem
&& pViewItem
->getPath().match(rPath
))
866 pViewItem
->showDefaultIcon(false);
873 BitmapEx
TemplateLocalView::getDefaultThumbnail( std::u16string_view rPath
)
876 INetURLObject
aUrl(rPath
);
877 OUString aExt
= aUrl
.getExtension();
879 if ( ViewFilter_Application::isFilteredExtension( FILTER_APPLICATION::WRITER
, aExt
) )
880 aImg
= BitmapEx(SFX_THUMBNAIL_TEXT
);
881 else if ( ViewFilter_Application::isFilteredExtension( FILTER_APPLICATION::CALC
, aExt
) )
882 aImg
= BitmapEx(SFX_THUMBNAIL_SHEET
);
883 else if ( ViewFilter_Application::isFilteredExtension( FILTER_APPLICATION::IMPRESS
, aExt
) )
884 aImg
= BitmapEx(SFX_THUMBNAIL_PRESENTATION
);
885 else if ( ViewFilter_Application::isFilteredExtension( FILTER_APPLICATION::DRAW
, aExt
) )
886 aImg
= BitmapEx(SFX_THUMBNAIL_DRAWING
);
891 BitmapEx
TemplateLocalView::fetchThumbnail (const OUString
&msURL
, tools::Long width
, tools::Long height
)
893 return TemplateLocalView::scaleImg(ThumbnailView::readThumbnail(msURL
), width
, height
);
896 void TemplateLocalView::OnItemDblClicked (ThumbnailViewItem
*pItem
)
898 TemplateViewItem
* pViewItem
= dynamic_cast<TemplateViewItem
*>(pItem
);
901 maOpenTemplateHdl
.Call(pViewItem
);
904 bool TemplateLocalView::IsInternalTemplate(const OUString
& rPath
)
906 uno::Reference
< uno::XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
907 css::uno::Reference
< css::util::XPathSettings
> xPathSettings
= css::util::thePathSettings::get(xContext
);
908 uno::Sequence
<OUString
> aInternalTemplateDirs
;
909 uno::Any aAny
= xPathSettings
->getPropertyValue("Template_internal");
910 aAny
>>= aInternalTemplateDirs
;
911 SfxURLRelocator_Impl
aRelocator(xContext
);
912 for (OUString
& rInternalTemplateDir
: asNonConstRange(aInternalTemplateDirs
))
914 aRelocator
.makeRelocatableURL(rInternalTemplateDir
);
915 aRelocator
.makeAbsoluteURL(rInternalTemplateDir
);
916 if(::utl::UCBContentHelper::IsSubPath(rInternalTemplateDir
, rPath
))
922 bool TemplateLocalView::IsBuiltInRegion(const OUString
& rRegionName
)
924 bool isBuiltInCategory
= false;
925 auto aGroupNames
= DocTemplLocaleHelper::GetBuiltInGroupNames();
926 isBuiltInCategory
= std::find(aGroupNames
.begin(), aGroupNames
.end(),
927 rRegionName
) != aGroupNames
.end();
928 if(isBuiltInCategory
)
930 //check if it contains any internal template
931 for(const auto& rItem
: maRegions
)
933 if(rItem
->maTitle
== rRegionName
)
935 for(const auto& rTemplateItem
: rItem
->maTemplates
)
937 if(IsInternalTemplate(rTemplateItem
.aPath
))
945 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */