xref: /core/sfx2/source/doc/templatedlg.cxx (revision f7804fc2)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  */
9 
10 #include <sfx2/templatedlg.hxx>
11 
12 #include <sfx2/inputdlg.hxx>
13 #include <templatesearchview.hxx>
14 #include <templatesearchviewitem.hxx>
15 
16 #include <comphelper/processfactory.hxx>
17 #include <comphelper/propertysequence.hxx>
18 #include <comphelper/string.hxx>
19 #include <comphelper/storagehelper.hxx>
20 #include <sfx2/app.hxx>
21 #include <sfx2/docfac.hxx>
22 #include <sfx2/docfilt.hxx>
23 #include <sfx2/fcontnr.hxx>
24 #include <sfx2/filedlghelper.hxx>
25 #include <sfx2/objsh.hxx>
26 #include <sfx2/sfxresid.hxx>
27 #include <sfx2/templatelocalview.hxx>
28 #include <sfx2/templatecontaineritem.hxx>
29 #include <sfx2/templateviewitem.hxx>
30 #include <sfx2/thumbnailviewitem.hxx>
31 #include <sot/storage.hxx>
32 #include <svtools/imagemgr.hxx>
33 #include <svtools/langhelp.hxx>
34 #include <tools/urlobj.hxx>
35 #include <unotools/moduleoptions.hxx>
36 #include <unotools/pathoptions.hxx>
37 #include <unotools/viewoptions.hxx>
38 #include <vcl/event.hxx>
39 #include <vcl/svapp.hxx>
40 #include <vcl/weld.hxx>
41 
42 #include <com/sun/star/beans/NamedValue.hpp>
43 #include <com/sun/star/beans/PropertyValue.hpp>
44 #include <com/sun/star/configuration/theDefaultProvider.hpp>
45 #include <com/sun/star/document/MacroExecMode.hpp>
46 #include <com/sun/star/document/UpdateDocMode.hpp>
47 #include <com/sun/star/embed/XStorage.hpp>
48 #include <com/sun/star/embed/ElementModes.hpp>
49 #include <com/sun/star/frame/Desktop.hpp>
50 #include <com/sun/star/frame/XStorable.hpp>
51 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
52 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
53 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
54 #include <com/sun/star/ui/dialogs/FolderPicker.hpp>
55 #include <com/sun/star/system/SystemShellExecute.hpp>
56 #include <com/sun/star/system/SystemShellExecuteFlags.hpp>
57 #include <com/sun/star/task/InteractionHandler.hpp>
58 
59 #include <sfx2/strings.hrc>
60 #include <bitmaps.hlst>
61 
62 const char TM_SETTING_MANAGER[] = "TemplateManager";
63 const char TM_SETTING_LASTFOLDER[] = "LastFolder";
64 const char TM_SETTING_LASTAPPLICATION[] = "LastApplication";
65 
66 #define MNI_ACTION_NEW_FOLDER "new"
67 #define MNI_ACTION_RENAME_FOLDER "rename"
68 #define MNI_ACTION_DELETE_FOLDER "delete"
69 #define MNI_ACTION_REFRESH   "refresh"
70 #define MNI_ACTION_DEFAULT   "default"
71 #define MNI_WRITER           1
72 #define MNI_CALC             2
73 #define MNI_IMPRESS          3
74 #define MNI_DRAW             4
75 
76 using namespace ::com::sun::star;
77 using namespace ::com::sun::star::beans;
78 using namespace ::com::sun::star::embed;
79 using namespace ::com::sun::star::frame;
80 using namespace ::com::sun::star::lang;
81 using namespace ::com::sun::star::uno;
82 using namespace ::com::sun::star::ui::dialogs;
83 using namespace ::com::sun::star::document;
84 
85 static bool lcl_getServiceName (const OUString &rFileURL, OUString &rName );
86 
87 static std::vector<OUString> lcl_getAllFactoryURLs ();
88 
89 namespace {
90 
91 class SearchView_Keyword
92 {
93 public:
94 
95     SearchView_Keyword (const OUString &rKeyword, FILTER_APPLICATION App)
96         : maKeyword(rKeyword.toAsciiLowerCase()), meApp(App)
97     {}
98 
99     bool operator() (const TemplateItemProperties &rItem)
100     {
101         bool bRet = true;
102 
103         INetURLObject aUrl(rItem.aPath);
104         OUString aExt = aUrl.getExtension();
105 
106         if (meApp == FILTER_APPLICATION::WRITER)
107         {
108             bRet = aExt == "ott" || aExt == "stw" || aExt == "oth" || aExt == "dot" || aExt == "dotx";
109         }
110         else if (meApp == FILTER_APPLICATION::CALC)
111         {
112             bRet = aExt == "ots" || aExt == "stc" || aExt == "xlt" || aExt == "xltm" || aExt == "xltx";
113         }
114         else if (meApp == FILTER_APPLICATION::IMPRESS)
115         {
116             bRet = aExt == "otp" || aExt == "sti" || aExt == "pot" || aExt == "potm" || aExt == "potx";
117         }
118         else if (meApp == FILTER_APPLICATION::DRAW)
119         {
120             bRet = aExt == "otg" || aExt == "std";
121         }
122 
123         return bRet && MatchSubstring(rItem.aName);
124     }
125 
126     bool MatchSubstring( OUString const & sItemName )
127     {
128         if(maKeyword.isEmpty())
129             return false;
130         return sItemName.toAsciiLowerCase().indexOf(maKeyword) >= 0;
131     }
132 
133 private:
134 
135     OUString const maKeyword;
136     FILTER_APPLICATION const meApp;
137 };
138 
139 }
140 
141 /***
142  *
143  * Order items in ascending order (useful for the selection sets and move/copy operations since the associated ids
144  * change when processed by the SfxDocumentTemplates class so we want to process to ones with higher id first)
145  *
146  ***/
147 
148 static bool cmpSelectionItems (const ThumbnailViewItem *pItem1, const ThumbnailViewItem *pItem2)
149 {
150     return pItem1->mnId > pItem2->mnId;
151 }
152 
153 SfxTemplateManagerDlg::SfxTemplateManagerDlg(weld::Window *pParent)
154     : GenericDialogController(pParent, "sfx/ui/templatedlg.ui", "TemplateDialog")
155     , maSelTemplates(cmpSelectionItems)
156     , mxDesktop(Desktop::create(comphelper::getProcessComponentContext()))
157     , m_aUpdateDataTimer("UpdateDataTimer")
158     , mxSearchFilter(m_xBuilder->weld_entry("search_filter"))
159     , mxCBApp(m_xBuilder->weld_combo_box("filter_application"))
160     , mxCBFolder(m_xBuilder->weld_combo_box("filter_folder"))
161     , mxOKButton(m_xBuilder->weld_button("ok"))
162     , mxMoveButton(m_xBuilder->weld_button("move_btn"))
163     , mxExportButton(m_xBuilder->weld_button("export_btn"))
164     , mxImportButton(m_xBuilder->weld_button("import_btn"))
165     , mxLinkButton(m_xBuilder->weld_button("online_link"))
166     , mxCBXHideDlg(m_xBuilder->weld_check_button("hidedialogcb"))
167     , mxActionBar(m_xBuilder->weld_menu_button("action_menu"))
168     , mxSearchView(new TemplateSearchView(m_xBuilder->weld_scrolled_window("scrollsearch"),
169                                           m_xBuilder->weld_menu("contextmenu1")))
170     , mxLocalView(new SfxTemplateLocalView(m_xBuilder->weld_scrolled_window("scrolllocal"),
171                                            m_xBuilder->weld_menu("contextmenu2")))
172     , mxTemplateDefaultMenu(m_xBuilder->weld_menu("submenu"))
173     , mxSearchViewWeld(new weld::CustomWeld(*m_xBuilder, "search_view", *mxSearchView))
174     , mxLocalViewWeld(new weld::CustomWeld(*m_xBuilder, "template_view", *mxLocalView))
175 {
176     // Create popup menus
177     OUString sBmp(BMP_ACTION_REFRESH);
178     mxActionBar->insert_item(0, MNI_ACTION_NEW_FOLDER, SfxResId(STR_CATEGORY_NEW), &sBmp, nullptr, false);
179     mxActionBar->insert_item(1, MNI_ACTION_RENAME_FOLDER, SfxResId(STR_CATEGORY_RENAME), nullptr, nullptr, false);
180     mxActionBar->insert_item(2, MNI_ACTION_DELETE_FOLDER, SfxResId(STR_CATEGORY_DELETE), nullptr, nullptr, false);
181     mxActionBar->insert_separator(3, "separator");
182     mxActionBar->insert_item(4, MNI_ACTION_REFRESH, SfxResId(STR_ACTION_REFRESH), &sBmp, nullptr, false);
183     mxActionBar->connect_selected(LINK(this,SfxTemplateManagerDlg,MenuSelectHdl));
184 
185     mxLocalView->setItemMaxTextLength(TEMPLATE_ITEM_MAX_TEXT_LENGTH);
186     mxLocalView->setItemDimensions(TEMPLATE_ITEM_MAX_WIDTH,TEMPLATE_ITEM_THUMBNAIL_MAX_HEIGHT,
187                               TEMPLATE_ITEM_MAX_HEIGHT-TEMPLATE_ITEM_THUMBNAIL_MAX_HEIGHT,
188                               TEMPLATE_ITEM_PADDING);
189 
190     mxLocalView->setItemStateHdl(LINK(this,SfxTemplateManagerDlg,TVItemStateHdl));
191     mxLocalView->setCreateContextMenuHdl(LINK(this,SfxTemplateManagerDlg, CreateContextMenuHdl));
192     mxLocalView->setOpenRegionHdl(LINK(this,SfxTemplateManagerDlg, OpenRegionHdl));
193     mxLocalView->setOpenTemplateHdl(LINK(this,SfxTemplateManagerDlg, OpenTemplateHdl));
194     mxLocalView->setEditTemplateHdl(LINK(this,SfxTemplateManagerDlg, EditTemplateHdl));
195     mxLocalView->setDeleteTemplateHdl(LINK(this,SfxTemplateManagerDlg, DeleteTemplateHdl));
196     mxLocalView->setDefaultTemplateHdl(LINK(this,SfxTemplateManagerDlg, DefaultTemplateHdl));
197 
198     mxSearchView->setItemMaxTextLength(TEMPLATE_ITEM_MAX_TEXT_LENGTH);
199 
200     mxSearchView->setItemDimensions(TEMPLATE_ITEM_MAX_WIDTH,TEMPLATE_ITEM_THUMBNAIL_MAX_HEIGHT,
201                                     TEMPLATE_ITEM_MAX_HEIGHT_SUB-TEMPLATE_ITEM_THUMBNAIL_MAX_HEIGHT,
202                                     TEMPLATE_ITEM_PADDING);
203 
204     mxSearchView->setItemStateHdl(LINK(this,SfxTemplateManagerDlg,TVItemStateHdl));
205     mxSearchView->setCreateContextMenuHdl(LINK(this,SfxTemplateManagerDlg, CreateContextMenuHdl));
206     mxSearchView->setOpenTemplateHdl(LINK(this,SfxTemplateManagerDlg,OpenTemplateHdl));
207     mxSearchView->setEditTemplateHdl(LINK(this,SfxTemplateManagerDlg, EditTemplateHdl));
208     mxSearchView->setDeleteTemplateHdl(LINK(this,SfxTemplateManagerDlg, DeleteTemplateHdl));
209     mxSearchView->setDefaultTemplateHdl(LINK(this,SfxTemplateManagerDlg, DefaultTemplateHdl));
210 
211     mxLocalView->ShowTooltips(true);
212     mxSearchView->ShowTooltips(true);
213 
214     mxOKButton->connect_clicked(LINK(this, SfxTemplateManagerDlg, OkClickHdl));
215     mxMoveButton->connect_clicked(LINK(this, SfxTemplateManagerDlg, MoveClickHdl));
216     mxExportButton->connect_clicked(LINK(this, SfxTemplateManagerDlg, ExportClickHdl));
217     mxImportButton->connect_clicked(LINK(this, SfxTemplateManagerDlg, ImportClickHdl));
218     mxLinkButton->connect_clicked(LINK(this, SfxTemplateManagerDlg, LinkClickHdl));
219 
220     mxSearchFilter->connect_changed(LINK(this, SfxTemplateManagerDlg, SearchUpdateHdl));
221     mxSearchFilter->connect_focus_in(LINK( this, SfxTemplateManagerDlg, GetFocusHdl ));
222     mxSearchFilter->connect_focus_out(LINK( this, SfxTemplateManagerDlg, LoseFocusHdl ));
223     mxSearchFilter->connect_key_press(LINK( this, SfxTemplateManagerDlg, KeyInputHdl));
224 
225     mxActionBar->show();
226 
227     createDefaultTemplateMenu();
228 
229     mxLocalView->Populate();
230     mxLocalView->filterItems(ViewFilter_Application(FILTER_APPLICATION::NONE));
231 
232     mxCBApp->set_active(0);
233     fillFolderComboBox();
234 
235     mxExportButton->set_sensitive(false);
236     mxMoveButton->set_sensitive(false);
237     mxOKButton->set_label(SfxResId(STR_OPEN));
238 
239     mxCBApp->connect_changed(LINK(this, SfxTemplateManagerDlg, SelectApplicationHdl));
240     mxCBFolder->connect_changed(LINK(this, SfxTemplateManagerDlg, SelectRegionHdl));
241 
242     mxLocalView->Show();
243 
244     m_aUpdateDataTimer.SetInvokeHandler(LINK(this, SfxTemplateManagerDlg, ImplUpdateDataHdl));
245     m_aUpdateDataTimer.SetDebugName( "SfxTemplateManagerDlg UpdateDataTimer" );
246     m_aUpdateDataTimer.SetTimeout(EDIT_UPDATEDATA_TIMEOUT);
247 }
248 
249 SfxTemplateManagerDlg::~SfxTemplateManagerDlg()
250 {
251     writeSettings();
252 
253     // Ignore view events since we are cleaning the object
254     mxLocalView->setItemStateHdl(Link<const ThumbnailViewItem*,void>());
255     mxLocalView->setOpenRegionHdl(Link<void*,void>());
256     mxLocalView->setOpenTemplateHdl(Link<ThumbnailViewItem*, void>());
257     mxSearchView->setItemStateHdl(Link<const ThumbnailViewItem*,void>());
258     mxSearchView->setOpenTemplateHdl(Link<ThumbnailViewItem*, void>());
259 }
260 
261 short SfxTemplateManagerDlg::run()
262 {
263     //use application specific settings if there's no previous setting
264     getApplicationSpecificSettings();
265     readSettings();
266 
267     return weld::GenericDialogController::run();
268 }
269 
270 IMPL_LINK(SfxTemplateManagerDlg, KeyInputHdl, const KeyEvent&, rKeyEvent, bool)
271 {
272     if (mxSearchFilter != nullptr && !mxSearchFilter->get_text().isEmpty())
273     {
274         vcl::KeyCode    aKeyCode = rKeyEvent.GetKeyCode();
275         sal_uInt16      nKeyCode = aKeyCode.GetCode();
276 
277         if ( nKeyCode == KEY_ESCAPE )
278         {
279             mxSearchFilter->set_text("");
280             SearchUpdateHdl(*mxSearchFilter);
281             return true;
282         }
283     }
284     return false;
285 }
286 
287 void SfxTemplateManagerDlg::setDocumentModel(const uno::Reference<frame::XModel> &rModel)
288 {
289     m_xModel = rModel;
290 }
291 
292 FILTER_APPLICATION SfxTemplateManagerDlg::getCurrentApplicationFilter() const
293 {
294     const sal_Int16 nCurAppId = mxCBApp->get_active();
295 
296     if (nCurAppId == MNI_WRITER)
297         return FILTER_APPLICATION::WRITER;
298     else if (nCurAppId == MNI_IMPRESS)
299         return FILTER_APPLICATION::IMPRESS;
300     else if (nCurAppId == MNI_CALC)
301         return FILTER_APPLICATION::CALC;
302     else if (nCurAppId == MNI_DRAW)
303         return FILTER_APPLICATION::DRAW;
304 
305     return FILTER_APPLICATION::NONE;
306 }
307 
308 void SfxTemplateManagerDlg::fillFolderComboBox()
309 {
310     std::vector<OUString> aFolderNames = mxLocalView->getFolderNames();
311 
312     for (size_t i = 0, n = aFolderNames.size(); i < n; ++i)
313         mxCBFolder->append_text(aFolderNames[i]);
314     mxCBFolder->set_active(0);
315     mxActionBar->set_item_visible(MNI_ACTION_RENAME_FOLDER, false);
316 }
317 
318 void SfxTemplateManagerDlg::getApplicationSpecificSettings()
319 {
320     if ( ! m_xModel.is() )
321     {
322         mxCBApp->set_active(0);
323         mxCBFolder->set_active(0);
324         mxActionBar->set_item_visible(MNI_ACTION_RENAME_FOLDER, false);
325         mxLocalView->filterItems(ViewFilter_Application(getCurrentApplicationFilter()));
326         mxLocalView->showAllTemplates();
327         return;
328     }
329 
330     SvtModuleOptions::EFactory eFactory = SvtModuleOptions::ClassifyFactoryByModel(m_xModel);
331 
332     switch(eFactory)
333     {
334         case SvtModuleOptions::EFactory::WRITER:
335         case SvtModuleOptions::EFactory::WRITERWEB:
336         case SvtModuleOptions::EFactory::WRITERGLOBAL:
337                             mxCBApp->set_active(MNI_WRITER);
338                             break;
339         case SvtModuleOptions::EFactory::CALC:
340                             mxCBApp->set_active(MNI_CALC);
341                             break;
342         case SvtModuleOptions::EFactory::IMPRESS:
343                             mxCBApp->set_active(MNI_IMPRESS);
344                             break;
345         case SvtModuleOptions::EFactory::DRAW:
346                             mxCBApp->set_active(MNI_DRAW);
347                             break;
348         default:
349                 mxCBApp->set_active(0);
350                 break;
351     }
352 
353     mxLocalView->filterItems(ViewFilter_Application(getCurrentApplicationFilter()));
354     mxCBFolder->set_active(0);
355     mxActionBar->set_item_visible(MNI_ACTION_RENAME_FOLDER, false);
356     mxLocalView->showAllTemplates();
357 }
358 
359 void SfxTemplateManagerDlg::readSettings ()
360 {
361     OUString aLastFolder;
362     SvtViewOptions aViewSettings( EViewType::Dialog, TM_SETTING_MANAGER );
363 
364     if ( aViewSettings.Exists() )
365     {
366         sal_uInt16 nTmp = 0;
367         aViewSettings.GetUserItem(TM_SETTING_LASTFOLDER) >>= aLastFolder;
368         aViewSettings.GetUserItem(TM_SETTING_LASTAPPLICATION) >>= nTmp;
369 
370         //open last remembered application only when application model is not set
371         if(!m_xModel.is())
372         {
373             switch (nTmp)
374             {
375                 case MNI_WRITER:
376                     mxCBApp->set_active(MNI_WRITER);
377                     break;
378                 case MNI_CALC:
379                     mxCBApp->set_active(MNI_CALC);
380                     break;
381                 case MNI_IMPRESS:
382                     mxCBApp->set_active(MNI_IMPRESS);
383                     break;
384                 case MNI_DRAW:
385                     mxCBApp->set_active(MNI_DRAW);
386                     break;
387                 default:
388                     mxCBApp->set_active(0);
389                     break;
390             }
391         }
392     }
393 
394     mxLocalView->filterItems(ViewFilter_Application(getCurrentApplicationFilter()));
395 
396     if (aLastFolder.isEmpty())
397     {
398         //show all categories
399         mxCBFolder->set_active(0);
400         mxActionBar->set_item_visible(MNI_ACTION_RENAME_FOLDER, false);
401         mxLocalView->showAllTemplates();
402     }
403     else
404     {
405         mxCBFolder->set_active_text(aLastFolder);
406         mxLocalView->showRegion(aLastFolder);
407         mxActionBar->set_item_visible(MNI_ACTION_RENAME_FOLDER, true);
408     }
409 }
410 
411 void SfxTemplateManagerDlg::writeSettings ()
412 {
413     OUString aLastFolder;
414 
415     if (mxLocalView->getCurRegionId())
416         aLastFolder = mxLocalView->getRegionName(mxLocalView->getCurRegionId()-1);
417 
418     // last folder
419     Sequence< NamedValue > aSettings
420     {
421         { TM_SETTING_LASTFOLDER, css::uno::makeAny(aLastFolder) },
422         { TM_SETTING_LASTAPPLICATION,     css::uno::makeAny(sal_uInt16(mxCBApp->get_active())) }
423     };
424 
425     // write
426     SvtViewOptions aViewSettings(EViewType::Dialog, TM_SETTING_MANAGER);
427     aViewSettings.SetUserData(aSettings);
428 }
429 
430 IMPL_LINK_NOARG(SfxTemplateManagerDlg, SelectApplicationHdl, weld::ComboBox&, void)
431 {
432     if (mxLocalView->IsVisible())
433     {
434         mxLocalView->filterItems(ViewFilter_Application(getCurrentApplicationFilter()));
435         mxLocalView->showAllTemplates();
436         mxCBFolder->set_active(0);
437         mxActionBar->set_item_visible(MNI_ACTION_RENAME_FOLDER, false);
438     }
439     if (mxSearchView->IsVisible())
440         SearchUpdate();
441 }
442 
443 IMPL_LINK_NOARG(SfxTemplateManagerDlg, SelectRegionHdl, weld::ComboBox&, void)
444 {
445     const OUString sSelectedRegion = mxCBFolder->get_active_text();
446 
447     if(mxCBFolder->get_active() == 0)
448     {
449         mxLocalView->showAllTemplates();
450         mxActionBar->set_item_visible(MNI_ACTION_RENAME_FOLDER, false);
451     }
452     else
453     {
454         mxLocalView->showRegion(sSelectedRegion);
455         mxActionBar->set_item_visible(MNI_ACTION_RENAME_FOLDER, true);
456     }
457     if (mxSearchView->IsVisible())
458         SearchUpdate();
459 }
460 
461 IMPL_LINK(SfxTemplateManagerDlg, TVItemStateHdl, const ThumbnailViewItem*, pItem, void)
462 {
463     const TemplateViewItem *pViewItem = dynamic_cast<const TemplateViewItem*>(pItem);
464 
465     if (pViewItem)
466         OnTemplateState(pItem);
467 }
468 
469 IMPL_LINK(SfxTemplateManagerDlg, MenuSelectHdl, const OString&, rIdent, void)
470 {
471     if (rIdent == MNI_ACTION_NEW_FOLDER)
472         OnCategoryNew();
473     else if (rIdent == MNI_ACTION_RENAME_FOLDER)
474         OnCategoryRename();
475     else if (rIdent == MNI_ACTION_DELETE_FOLDER)
476         OnCategoryDelete();
477     else if (rIdent == MNI_ACTION_REFRESH)
478         mxLocalView->reload();
479     else if (rIdent != MNI_ACTION_DEFAULT)
480         DefaultTemplateMenuSelectHdl(rIdent);
481 }
482 
483 void SfxTemplateManagerDlg::DefaultTemplateMenuSelectHdl(const OString& rIdent)
484 {
485     fprintf(stderr, "DefaultTemplateMenuSelectHdl ident %s\n", rIdent.getStr());
486 
487     OUString aServiceName = SfxObjectShell::GetServiceNameFromFactory(OUString::fromUtf8(rIdent));
488 
489     OUString sPrevDefault = SfxObjectFactory::GetStandardTemplate( aServiceName );
490     if(!sPrevDefault.isEmpty())
491         mxLocalView->RemoveDefaultTemplateIcon(sPrevDefault);
492 
493     SfxObjectFactory::SetStandardTemplate( aServiceName, OUString() );
494 
495     createDefaultTemplateMenu();
496 }
497 
498 IMPL_LINK_NOARG(SfxTemplateManagerDlg, OkClickHdl, weld::Button&, void)
499 {
500    OnTemplateOpen();
501    m_xDialog->response(RET_OK);
502 }
503 
504 IMPL_LINK_NOARG(SfxTemplateManagerDlg, MoveClickHdl, weld::Button&, void)
505 {
506     // modal dialog to select templates category
507     SfxTemplateCategoryDialog aDlg(m_xDialog.get());
508     aDlg.SetCategoryLBEntries(mxLocalView->getFolderNames());
509 
510     size_t nItemId = 0;
511 
512     if (aDlg.run() == RET_OK)
513     {
514         const OUString& sCategory = aDlg.GetSelectedCategory();
515         bool bIsNewCategory = aDlg.IsNewCategoryCreated();
516         if(bIsNewCategory)
517         {
518             if (!sCategory.isEmpty())
519             {
520                 nItemId = mxLocalView->createRegion(sCategory);
521                 if(nItemId)
522                     mxCBFolder->append_text(sCategory);
523             }
524         }
525         else
526             nItemId = mxLocalView->getRegionId(sCategory);
527     }
528 
529     if(nItemId)
530     {
531         if (mxSearchView->IsVisible())
532             localSearchMoveTo(nItemId);
533         else
534             localMoveTo(nItemId);
535     }
536 
537     mxLocalView->reload();
538 }
539 
540 IMPL_LINK_NOARG(SfxTemplateManagerDlg, ExportClickHdl, weld::Button&, void)
541 {
542     OnTemplateExport();
543 }
544 
545 IMPL_LINK_NOARG(SfxTemplateManagerDlg, ImportClickHdl, weld::Button&, void)
546 {
547     //Modal Dialog to select Category
548     SfxTemplateCategoryDialog aDlg(m_xDialog.get());
549     aDlg.SetCategoryLBEntries(mxLocalView->getFolderNames());
550 
551     if (aDlg.run() == RET_OK)
552     {
553         const OUString& sCategory = aDlg.GetSelectedCategory();
554         bool bIsNewCategory = aDlg.IsNewCategoryCreated();
555         if(bIsNewCategory)
556         {
557             if(mxLocalView->createRegion(sCategory))
558             {
559                 mxCBFolder->append_text(sCategory);
560                 OnTemplateImportCategory(sCategory);
561             }
562             else
563             {
564                 OUString aMsg( SfxResId(STR_CREATE_ERROR) );
565                 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
566                                                           VclMessageType::Warning, VclButtonsType::Ok,
567                                                           aMsg.replaceFirst("$1", sCategory)));
568                 xBox->run();
569                 return;
570             }
571         }
572         else
573             OnTemplateImportCategory(sCategory);
574     }
575 
576     mxLocalView->reload();
577     mxLocalView->showAllTemplates();
578     mxCBApp->set_active(0);
579     mxCBFolder->set_active(0);
580     mxActionBar->set_item_visible(MNI_ACTION_RENAME_FOLDER, false);
581 }
582 
583 IMPL_STATIC_LINK_NOARG(SfxTemplateManagerDlg, LinkClickHdl, weld::Button&, void)
584 {
585     OnTemplateLink();
586 }
587 
588 IMPL_LINK_NOARG(SfxTemplateManagerDlg, OpenRegionHdl, void*, void)
589 {
590     maSelTemplates.clear();
591     mxOKButton->set_sensitive(false);
592     mxActionBar->show();
593 }
594 
595 IMPL_LINK(SfxTemplateManagerDlg, CreateContextMenuHdl, ThumbnailViewItem*, pItem, void)
596 {
597     const TemplateViewItem *pViewItem = dynamic_cast<TemplateViewItem*>(pItem);
598 
599     if (pViewItem)
600     {
601         if (mxSearchView->IsVisible())
602             mxSearchView->createContextMenu(pViewItem->IsDefaultTemplate());
603         else
604             mxLocalView->createContextMenu(pViewItem->IsDefaultTemplate());
605     }
606 }
607 
608 IMPL_LINK(SfxTemplateManagerDlg, OpenTemplateHdl, ThumbnailViewItem*, pItem, void)
609 {
610     uno::Sequence< PropertyValue > aArgs(5);
611     aArgs[0].Name = "AsTemplate";
612     aArgs[0].Value <<= true;
613     aArgs[1].Name = "MacroExecutionMode";
614     aArgs[1].Value <<= MacroExecMode::USE_CONFIG;
615     aArgs[2].Name = "UpdateDocMode";
616     aArgs[2].Value <<= UpdateDocMode::ACCORDING_TO_CONFIG;
617     aArgs[3].Name = "InteractionHandler";
618     aArgs[3].Value <<= task::InteractionHandler::createWithParent( ::comphelper::getProcessComponentContext(), nullptr );
619     aArgs[4].Name = "ReadOnly";
620     aArgs[4].Value <<= true;
621 
622     TemplateViewItem *pTemplateItem = static_cast<TemplateViewItem*>(pItem);
623 
624     try
625     {
626         mxDesktop->loadComponentFromURL(pTemplateItem->getPath(),"_default", 0, aArgs );
627     }
628     catch( const uno::Exception& )
629     {
630     }
631 
632     m_xDialog->response(RET_OK);
633 }
634 
635 IMPL_LINK(SfxTemplateManagerDlg, EditTemplateHdl, ThumbnailViewItem*, pItem, void)
636 {
637     uno::Sequence< PropertyValue > aArgs(3);
638     aArgs[0].Name = "AsTemplate";
639     aArgs[0].Value <<= false;
640     aArgs[1].Name = "MacroExecutionMode";
641     aArgs[1].Value <<= MacroExecMode::USE_CONFIG;
642     aArgs[2].Name = "UpdateDocMode";
643     aArgs[2].Value <<= UpdateDocMode::ACCORDING_TO_CONFIG;
644 
645     uno::Reference< XStorable > xStorable;
646     TemplateViewItem *pViewItem = static_cast<TemplateViewItem*>(pItem);
647 
648     try
649     {
650         xStorable.set( mxDesktop->loadComponentFromURL(pViewItem->getPath(),"_default", 0, aArgs ),
651                        uno::UNO_QUERY );
652     }
653     catch( const uno::Exception& )
654     {
655     }
656 
657     m_xDialog->response(RET_OK);
658 }
659 
660 IMPL_LINK(SfxTemplateManagerDlg, DeleteTemplateHdl, ThumbnailViewItem*, pItem, void)
661 {
662     OUString aDeletedTemplate;
663     if(mxSearchView->IsVisible())
664     {
665         TemplateSearchViewItem *pSrchItem = static_cast<TemplateSearchViewItem*>(pItem);
666 
667         if (!mxLocalView->removeTemplate(pSrchItem->mnAssocId, pSrchItem->mnRegionId))
668         {
669             aDeletedTemplate = pSrchItem->maTitle;
670         }
671     }
672     else
673     {
674         TemplateViewItem *pViewItem = static_cast<TemplateViewItem*>(pItem);
675         sal_uInt16 nRegionItemId = mxLocalView->getRegionId(pViewItem->mnRegionId);
676 
677         if (!mxLocalView->removeTemplate(pViewItem->mnDocId + 1, nRegionItemId))//mnId w.r.t. region is mnDocId + 1;
678         {
679             aDeletedTemplate = pItem->maTitle;
680         }
681     }
682 
683     if (!aDeletedTemplate.isEmpty())
684     {
685         OUString aMsg( SfxResId(STR_MSG_ERROR_DELETE_TEMPLATE) );
686         std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
687                                                   VclMessageType::Warning, VclButtonsType::Ok,
688                                                   aMsg.replaceFirst("$1",aDeletedTemplate)));
689         xBox->run();
690     }
691 }
692 
693 IMPL_LINK(SfxTemplateManagerDlg, DefaultTemplateHdl, ThumbnailViewItem*, pItem, void)
694 {
695     TemplateViewItem *pViewItem = static_cast<TemplateViewItem*>(pItem);
696     OUString aServiceName;
697 
698     if(!pViewItem->IsDefaultTemplate())
699     {
700         if (lcl_getServiceName(pViewItem->getPath(),aServiceName))
701         {
702             OUString sPrevDefault = SfxObjectFactory::GetStandardTemplate( aServiceName );
703             if(!sPrevDefault.isEmpty())
704                 mxLocalView->RemoveDefaultTemplateIcon(sPrevDefault);
705 
706             SfxObjectFactory::SetStandardTemplate(aServiceName,pViewItem->getPath());
707             pViewItem->showDefaultIcon(true);
708         }
709     }
710     else
711     {
712         if(lcl_getServiceName(pViewItem->getPath(),aServiceName))
713         {
714             SfxObjectFactory::SetStandardTemplate( aServiceName, OUString() );
715             pViewItem->showDefaultIcon(false);
716         }
717     }
718 
719     createDefaultTemplateMenu();
720 }
721 
722 IMPL_LINK_NOARG(SfxTemplateManagerDlg, SearchUpdateHdl, weld::Entry&, void)
723 {
724     m_aUpdateDataTimer.Start();
725 }
726 
727 IMPL_LINK_NOARG(SfxTemplateManagerDlg, ImplUpdateDataHdl, Timer*, void)
728 {
729     SearchUpdate();
730 }
731 
732 IMPL_LINK_NOARG(SfxTemplateManagerDlg, LoseFocusHdl, weld::Widget&, void)
733 {
734     if (m_aUpdateDataTimer.IsActive())
735     {
736         m_aUpdateDataTimer.Stop();
737         m_aUpdateDataTimer.Invoke();
738     }
739 }
740 
741 void SfxTemplateManagerDlg::SearchUpdate()
742 {
743     OUString aKeyword = mxSearchFilter->get_text();
744 
745     if (!aKeyword.isEmpty())
746     {
747         mxSearchView->Clear();
748 
749         // if the search view is hidden, hide the folder view and display search one
750         if (!mxSearchView->IsVisible())
751         {
752             mxLocalView->deselectItems();
753             mxSearchView->Show();
754             mxLocalView->Hide();
755         }
756 
757         std::vector<TemplateItemProperties> aItems =
758                 mxLocalView->getFilteredItems(SearchView_Keyword(aKeyword, getCurrentApplicationFilter()));
759 
760         for (const TemplateItemProperties& rItem : aItems)
761         {
762             OUString aFolderName = mxLocalView->getRegionName(rItem.nRegionId);
763 
764             mxSearchView->AppendItem(rItem.nId,mxLocalView->getRegionId(rItem.nRegionId),
765                                      rItem.nDocId,
766                                      rItem.aName,
767                                      aFolderName,
768                                      rItem.aPath,
769                                      rItem.aThumbnail);
770         }
771 
772         mxSearchView->Invalidate();
773     }
774     else
775     {
776         mxSearchView->deselectItems();
777         mxSearchView->Hide();
778         mxLocalView->Show();
779         mxLocalView->filterItems(ViewFilter_Application(getCurrentApplicationFilter()));
780         mxLocalView->reload();
781         OUString sLastFolder = mxCBFolder->get_active_text();
782         mxLocalView->showRegion(sLastFolder);
783         mxActionBar->set_item_visible(MNI_ACTION_RENAME_FOLDER, true);
784     }
785 }
786 
787 IMPL_LINK_NOARG(SfxTemplateManagerDlg, GetFocusHdl, weld::Widget&, void)
788 {
789     mxLocalView->deselectItems();
790     mxSearchView->deselectItems();
791 
792     maSelTemplates.clear();
793 }
794 
795 void SfxTemplateManagerDlg::OnTemplateState (const ThumbnailViewItem *pItem)
796 {
797     bool bInSelection = maSelTemplates.find(pItem) != maSelTemplates.end();
798 
799     if (pItem->isSelected())
800     {
801         if (maSelTemplates.empty())
802         {
803             mxOKButton->set_sensitive(true);
804         }
805         else if (maSelTemplates.size() != 1 || !bInSelection)
806         {
807             mxOKButton->set_sensitive(false);
808         }
809 
810         if (!bInSelection)
811             maSelTemplates.insert(pItem);
812     }
813     else
814     {
815         if (bInSelection)
816         {
817             maSelTemplates.erase(pItem);
818 
819             if (maSelTemplates.empty())
820             {
821                 mxOKButton->set_sensitive(false);
822             }
823             else if (maSelTemplates.size() == 1)
824             {
825                 mxOKButton->set_sensitive(true);
826             }
827         }
828     }
829 
830     if(maSelTemplates.empty())
831     {
832         mxMoveButton->set_sensitive(false);
833         mxExportButton->set_sensitive(false);
834     }
835     else
836     {
837         mxMoveButton->set_sensitive(true);
838         mxExportButton->set_sensitive(true);
839     }
840 }
841 
842 void SfxTemplateManagerDlg::OnTemplateImportCategory(const OUString& sCategory)
843 {
844     sfx2::FileDialogHelper aFileDlg(css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE,
845                                     FileDialogFlags::MultiSelection, m_xDialog.get());
846 
847     // add "All" filter
848     aFileDlg.AddFilter( SfxResId(STR_SFX_FILTERNAME_ALL),
849                         FILEDIALOG_FILTER_ALL );
850 
851     // add template filter
852     OUString sFilterExt;
853     OUString sFilterName( SfxResId( STR_TEMPLATE_FILTER ) );
854 
855     // add filters of modules which are installed
856     SvtModuleOptions aModuleOpt;
857     if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
858         sFilterExt += "*.ott;*.stw;*.oth;*.dotx;*.dot";
859 
860     if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::CALC ) )
861     {
862         if ( !sFilterExt.isEmpty() )
863             sFilterExt += ";";
864 
865         sFilterExt += "*.ots;*.stc;*.xltx;*.xlt";
866     }
867 
868     if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::IMPRESS ) )
869     {
870         if ( !sFilterExt.isEmpty() )
871             sFilterExt += ";";
872 
873         sFilterExt += "*.otp;*.sti;*.pot;*.potx";
874     }
875 
876     if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::DRAW ) )
877     {
878         if ( !sFilterExt.isEmpty() )
879             sFilterExt += ";";
880 
881         sFilterExt += "*.otg;*.std";
882     }
883 
884     if ( !sFilterExt.isEmpty() )
885         sFilterExt += ";";
886 
887     sFilterExt += "*.vor";
888 
889     sFilterName += " (" + sFilterExt + ")";
890 
891     aFileDlg.AddFilter( sFilterName, sFilterExt );
892     aFileDlg.SetCurrentFilter( sFilterName );
893 
894     ErrCode nCode = aFileDlg.Execute();
895 
896     if ( nCode != ERRCODE_NONE )
897         return;
898 
899     const css::uno::Sequence<OUString> aFiles = aFileDlg.GetSelectedFiles();
900 
901     if (!aFiles.hasElements())
902         return;
903 
904     //Import to the selected regions
905     TemplateContainerItem* pContItem = mxLocalView->getRegion(sCategory);
906     if(!pContItem)
907         return;
908 
909     OUString aTemplateList;
910 
911     for (const auto& rFile : aFiles)
912     {
913         if(!mxLocalView->copyFrom(pContItem, rFile))
914         {
915             if (aTemplateList.isEmpty())
916                 aTemplateList = rFile;
917             else
918                 aTemplateList += "\n" + rFile;
919         }
920     }
921 
922     if (!aTemplateList.isEmpty())
923     {
924         OUString aMsg(SfxResId(STR_MSG_ERROR_IMPORT));
925         aMsg = aMsg.replaceFirst("$1",pContItem->maTitle);
926         std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
927                                                   VclMessageType::Warning, VclButtonsType::Ok,
928                                                   aMsg.replaceFirst("$2",aTemplateList)));
929         xBox->run();
930     }
931 }
932 
933 void SfxTemplateManagerDlg::OnTemplateExport()
934 {
935     uno::Reference<XComponentContext> xContext(comphelper::getProcessComponentContext());
936     uno::Reference<XFolderPicker2> xFolderPicker = FolderPicker::create(xContext);
937 
938     xFolderPicker->setDisplayDirectory(SvtPathOptions().GetWorkPath());
939 
940     sal_Int16 nResult = xFolderPicker->execute();
941     sal_Int16 nCount = maSelTemplates.size();
942 
943     if( nResult != ExecutableDialogResults::OK )
944         return;
945 
946     OUString aTemplateList;
947     INetURLObject aPathObj(xFolderPicker->getDirectory());
948     aPathObj.setFinalSlash();
949 
950     if (mxSearchView->IsVisible())
951     {
952         sal_uInt16 i = 1;
953 
954         for (auto const& selTemplate : maSelTemplates)
955         {
956             const TemplateSearchViewItem *pItem = static_cast<const TemplateSearchViewItem*>(selTemplate);
957 
958             INetURLObject aItemPath(pItem->getPath());
959 
960             if ( 1 == i )
961                 aPathObj.Append(aItemPath.getName());
962             else
963                 aPathObj.setName(aItemPath.getName());
964 
965             OUString aPath = aPathObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
966 
967             if (!mxLocalView->exportTo(pItem->mnAssocId,pItem->mnRegionId,aPath))
968             {
969                 if (aTemplateList.isEmpty())
970                     aTemplateList = pItem->maTitle;
971                 else
972                     aTemplateList += "\n" + pItem->maTitle;
973             }
974             ++i;
975         }
976 
977         mxSearchView->deselectItems();
978     }
979     else
980     {
981         // export templates from the current view
982 
983         sal_uInt16 i = 1;
984 
985         for (auto const& selTemplate : maSelTemplates)
986         {
987             const TemplateViewItem *pItem = static_cast<const TemplateViewItem*>(selTemplate);
988 
989             INetURLObject aItemPath(pItem->getPath());
990 
991             if ( 1 == i )
992                 aPathObj.Append(aItemPath.getName());
993             else
994                 aPathObj.setName(aItemPath.getName());
995 
996             OUString aPath = aPathObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
997 
998             if (!mxLocalView->exportTo(pItem->mnDocId + 1,   //mnId w.r.t. region = mDocId + 1
999                 mxLocalView->getRegionId(pItem->mnRegionId), //pItem->mnRegionId does not store actual region Id
1000                 aPath))
1001             {
1002                 if (aTemplateList.isEmpty())
1003                     aTemplateList = pItem->maTitle;
1004                 else
1005                     aTemplateList += "\n" + pItem->maTitle;
1006             }
1007             ++i;
1008         }
1009 
1010         mxLocalView->deselectItems();
1011     }
1012 
1013     if (!aTemplateList.isEmpty())
1014     {
1015         OUString aText( SfxResId(STR_MSG_ERROR_EXPORT) );
1016         std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
1017                                                   VclMessageType::Warning, VclButtonsType::Ok,
1018                                                   aText.replaceFirst("$1",aTemplateList)));
1019         xBox->run();
1020     }
1021     else
1022     {
1023         OUString sText( SfxResId(STR_MSG_EXPORT_SUCCESS) );
1024         std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
1025                                                   VclMessageType::Info, VclButtonsType::Ok,
1026                                                   sText.replaceFirst("$1", OUString::number(nCount))));
1027         xBox->run();
1028     }
1029 }
1030 
1031 void SfxTemplateManagerDlg::OnTemplateLink ()
1032 {
1033     OUString sNodePath("/org.openoffice.Office.Common/Help/StartCenter");
1034     try
1035     {
1036         Reference<lang::XMultiServiceFactory> xConfig = configuration::theDefaultProvider::get( comphelper::getProcessComponentContext() );
1037         uno::Sequence<uno::Any> args(comphelper::InitAnyPropertySequence(
1038         {
1039             {"nodepath", uno::Any(sNodePath)}
1040         }));
1041         Reference<container::XNameAccess> xNameAccess(xConfig->createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", args), UNO_QUERY);
1042         if( xNameAccess.is() )
1043         {
1044             OUString sURL;
1045             //throws css::container::NoSuchElementException, css::lang::WrappedTargetException
1046             Any value( xNameAccess->getByName("TemplateRepositoryURL") );
1047             sURL = value.get<OUString> ();
1048             localizeWebserviceURI(sURL);
1049 
1050             Reference< css::system::XSystemShellExecute > xSystemShellExecute(
1051                 css::system::SystemShellExecute::create(comphelper::getProcessComponentContext()));
1052             xSystemShellExecute->execute( sURL, OUString(), css::system::SystemShellExecuteFlags::URIS_ONLY);
1053         }
1054     }
1055     catch (const Exception&)
1056     {
1057     }
1058 }
1059 
1060 void SfxTemplateManagerDlg::OnTemplateOpen ()
1061 {
1062     ThumbnailViewItem *pItem = const_cast<ThumbnailViewItem*>(*maSelTemplates.begin());
1063 
1064     OpenTemplateHdl(pItem);
1065 }
1066 
1067 void SfxTemplateManagerDlg::OnCategoryNew()
1068 {
1069     InputDialog dlg(m_xDialog.get(), SfxResId(STR_INPUT_NEW));
1070 
1071     int ret = dlg.run();
1072 
1073     if (!ret)
1074         return;
1075 
1076     OUString aName = dlg.GetEntryText();
1077 
1078     if(mxLocalView->createRegion(aName))
1079         mxCBFolder->append_text(aName);
1080     else
1081     {
1082         OUString aMsg( SfxResId(STR_CREATE_ERROR) );
1083         std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
1084                                                   VclMessageType::Warning, VclButtonsType::Ok,
1085                                                   aMsg.replaceFirst("$1", aName)));
1086         xBox->run();
1087     }
1088 }
1089 
1090 void SfxTemplateManagerDlg::OnCategoryRename()
1091 {
1092     OUString sCategory = mxCBFolder->get_active_text();
1093     InputDialog dlg(m_xDialog.get(), SfxResId(STR_INPUT_NEW));
1094 
1095     dlg.SetEntryText(sCategory);
1096     int ret = dlg.run();
1097 
1098     if (!ret)
1099         return;
1100 
1101     OUString aName = dlg.GetEntryText();
1102 
1103     if(mxLocalView->renameRegion(sCategory, aName))
1104     {
1105         sal_Int32 nPos = mxCBFolder->find_text(sCategory);
1106         mxCBFolder->remove(nPos);
1107         mxCBFolder->insert_text(nPos, aName);
1108         mxCBFolder->set_active(nPos);
1109 
1110         mxLocalView->reload();
1111         mxLocalView->showRegion(aName);
1112     }
1113     else
1114     {
1115         OUString aMsg( SfxResId(STR_CREATE_ERROR) );
1116         std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
1117                                                   VclMessageType::Warning, VclButtonsType::Ok,
1118                                                   aMsg.replaceFirst("$1", aName)));
1119         xBox->run();
1120     }
1121 }
1122 
1123 void SfxTemplateManagerDlg::OnCategoryDelete()
1124 {
1125     SfxTemplateCategoryDialog aDlg(m_xDialog.get());
1126     aDlg.SetCategoryLBEntries(mxLocalView->getFolderNames());
1127     aDlg.HideNewCategoryOption();
1128     aDlg.set_title(SfxResId(STR_CATEGORY_DELETE));
1129     aDlg.SetSelectLabelText(SfxResId(STR_CATEGORY_SELECT));
1130 
1131     if (aDlg.run() == RET_OK)
1132     {
1133         const OUString& sCategory = aDlg.GetSelectedCategory();
1134         std::unique_ptr<weld::MessageDialog> popupDlg(Application::CreateMessageDialog(m_xDialog.get(),
1135                                                       VclMessageType::Question, VclButtonsType::YesNo,
1136                                                       SfxResId(STR_QMSG_SEL_FOLDER_DELETE)));
1137         if (popupDlg->run() != RET_YES)
1138             return;
1139 
1140         sal_Int16 nItemId = mxLocalView->getRegionId(sCategory);
1141 
1142         if (!mxLocalView->removeRegion(nItemId))
1143         {
1144             OUString sMsg( SfxResId(STR_MSG_ERROR_DELETE_FOLDER) );
1145             std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
1146                                                       VclMessageType::Warning, VclButtonsType::Ok,
1147                                                       sMsg.replaceFirst("$1",sCategory)));
1148             xBox->run();
1149         }
1150         else
1151         {
1152             mxCBFolder->remove_text(sCategory);
1153         }
1154     }
1155 
1156     mxLocalView->reload();
1157     mxLocalView->showAllTemplates();
1158     mxCBApp->set_active(0);
1159     mxCBFolder->set_active(0);
1160     mxActionBar->set_item_visible(MNI_ACTION_RENAME_FOLDER, false);
1161 }
1162 
1163 void SfxTemplateManagerDlg::createDefaultTemplateMenu ()
1164 {
1165     std::vector<OUString> aList = lcl_getAllFactoryURLs();
1166 
1167     if (!aList.empty())
1168     {
1169         mxTemplateDefaultMenu->clear();
1170 
1171         for (auto const& elem : aList)
1172         {
1173             INetURLObject aObj(elem);
1174             OUString aTitle = SvFileInformationManager::GetDescription(aObj);
1175             mxTemplateDefaultMenu->append(elem, aTitle, SvFileInformationManager::GetImageId(aObj));
1176         }
1177 
1178         mxActionBar->set_item_visible(MNI_ACTION_DEFAULT, true);
1179     }
1180     else
1181         mxActionBar->set_item_visible(MNI_ACTION_DEFAULT, false);
1182 }
1183 
1184 void SfxTemplateManagerDlg::localMoveTo(sal_uInt16 nItemId)
1185 {
1186     if (nItemId)
1187     {
1188         // Move templates to desired folder if for some reason move fails
1189         // try copying them.
1190         mxLocalView->moveTemplates(maSelTemplates,nItemId);
1191     }
1192 }
1193 
1194 void SfxTemplateManagerDlg::localSearchMoveTo(sal_uInt16 nItemId)
1195 {
1196     if (nItemId)
1197     {
1198         // Move templates to desired folder if for some reason move fails
1199         // try copying them.
1200         std::set<const ThumbnailViewItem*,selection_cmp_fn> aSelTemplates = maSelTemplates; //Copy to avoid invalidating an iterator
1201 
1202         for (auto const& selTemplate : aSelTemplates)
1203         {
1204             const TemplateSearchViewItem *pItem =
1205                     static_cast<const TemplateSearchViewItem*>(selTemplate);
1206 
1207             if(!mxLocalView->moveTemplate(pItem,pItem->mnRegionId,nItemId))
1208             {
1209                 OUString sDst = mxLocalView->getRegionItemName(nItemId);
1210                 OUString sMsg(SfxResId(STR_MSG_ERROR_LOCAL_MOVE));
1211                 sMsg = sMsg.replaceFirst("$1",sDst);
1212                 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
1213                                                           VclMessageType::Warning, VclButtonsType::Ok,
1214                                                           sMsg.replaceFirst( "$2",pItem->maTitle)));
1215                 xBox->run();
1216             }
1217         }
1218     }
1219 
1220     // Deselect all items and update search results
1221     mxSearchView->deselectItems();
1222 
1223     SearchUpdateHdl(*mxSearchFilter);
1224 }
1225 
1226 static bool lcl_getServiceName ( const OUString &rFileURL, OUString &rName )
1227 {
1228     bool bRet = false;
1229 
1230     if ( !rFileURL.isEmpty() )
1231     {
1232         try
1233         {
1234             uno::Reference< embed::XStorage > xStorage =
1235                     comphelper::OStorageHelper::GetStorageFromURL( rFileURL, embed::ElementModes::READ );
1236 
1237             SotClipboardFormatId nFormat = SotStorage::GetFormatID( xStorage );
1238 
1239             std::shared_ptr<const SfxFilter> pFilter = SfxGetpApp()->GetFilterMatcher().GetFilter4ClipBoardId( nFormat );
1240 
1241             if ( pFilter )
1242             {
1243                 rName = pFilter->GetServiceName();
1244                 bRet = true;
1245             }
1246         }
1247         catch( uno::Exception& )
1248         {}
1249     }
1250 
1251     return bRet;
1252 }
1253 
1254 static std::vector<OUString> lcl_getAllFactoryURLs ()
1255 {
1256     SvtModuleOptions aModOpt;
1257     std::vector<OUString> aList;
1258     const css::uno::Sequence<OUString> &aServiceNames = aModOpt.GetAllServiceNames();
1259 
1260     for( const auto& rServiceName : aServiceNames )
1261     {
1262         if ( ! SfxObjectFactory::GetStandardTemplate( rServiceName ).isEmpty() )
1263         {
1264             SvtModuleOptions::EFactory eFac = SvtModuleOptions::EFactory::WRITER;
1265             SvtModuleOptions::ClassifyFactoryByName( rServiceName, eFac );
1266             aList.push_back(aModOpt.GetFactoryEmptyDocumentURL(eFac));
1267         }
1268     }
1269 
1270     return aList;
1271 }
1272 
1273 
1274 //   Class SfxTemplateCategoryDialog --------------------------------------------------
1275 
1276 SfxTemplateCategoryDialog::SfxTemplateCategoryDialog(weld::Window* pParent)
1277     : GenericDialogController(pParent, "sfx/ui/templatecategorydlg.ui", "TemplatesCategoryDialog")
1278     , msSelectedCategory(OUString())
1279     , mbIsNewCategory(false)
1280     , mxLBCategory(m_xBuilder->weld_tree_view("categorylb"))
1281     , mxSelectLabel(m_xBuilder->weld_label("select_label"))
1282     , mxNewCategoryEdit(m_xBuilder->weld_entry("category_entry"))
1283     , mxCreateLabel(m_xBuilder->weld_label("create_label"))
1284     , mxOKButton(m_xBuilder->weld_button("ok"))
1285 {
1286     mxLBCategory->append_text(SfxResId(STR_CATEGORY_NONE));
1287     mxNewCategoryEdit->connect_changed(LINK(this, SfxTemplateCategoryDialog, NewCategoryEditHdl));
1288     mxLBCategory->set_size_request(mxLBCategory->get_approximate_digit_width() * 32,
1289                                    mxLBCategory->get_height_rows(8));
1290     mxLBCategory->connect_changed(LINK(this, SfxTemplateCategoryDialog, SelectCategoryHdl));
1291     mxOKButton->set_sensitive(false);
1292 }
1293 
1294 SfxTemplateCategoryDialog::~SfxTemplateCategoryDialog()
1295 {
1296 }
1297 
1298 IMPL_LINK_NOARG(SfxTemplateCategoryDialog, NewCategoryEditHdl, weld::Entry&, void)
1299 {
1300     OUString sParam = comphelper::string::strip(mxNewCategoryEdit->get_text(), ' ');
1301     mxLBCategory->set_sensitive(sParam.isEmpty());
1302     if(!sParam.isEmpty())
1303     {
1304         msSelectedCategory = sParam;
1305         mbIsNewCategory = true;
1306         mxOKButton->set_sensitive(true);
1307     }
1308     else
1309     {
1310         SelectCategoryHdl(*mxLBCategory);
1311         mbIsNewCategory = false;
1312     }
1313 }
1314 
1315 IMPL_LINK_NOARG(SfxTemplateCategoryDialog, SelectCategoryHdl, weld::TreeView&, void)
1316 {
1317     if (mxLBCategory->get_selected_index() == 0)
1318     {
1319         msSelectedCategory = OUString();
1320         mxOKButton->set_sensitive(false);
1321         mxNewCategoryEdit->set_sensitive(true);
1322     }
1323     else
1324     {
1325         msSelectedCategory = mxLBCategory->get_selected_text();
1326         mxNewCategoryEdit->set_sensitive(false);
1327         mxOKButton->set_sensitive(true);
1328     }
1329 
1330     mbIsNewCategory = false;
1331 }
1332 
1333 void SfxTemplateCategoryDialog::SetCategoryLBEntries(std::vector<OUString> aFolderNames)
1334 {
1335     for (size_t i = 0, n = aFolderNames.size(); i < n; ++i)
1336         mxLBCategory->append_text(aFolderNames[i]);
1337     mxLBCategory->select(0);
1338 }
1339 
1340 void SfxTemplateCategoryDialog::HideNewCategoryOption()
1341 {
1342     mxCreateLabel->hide();
1343     mxNewCategoryEdit->hide();
1344 }
1345 
1346 // SfxTemplateSelectionDialog -----------------------------------------------------------------
1347 
1348 SfxTemplateSelectionDlg::SfxTemplateSelectionDlg(weld::Window* pParent)
1349     : SfxTemplateManagerDlg(pParent)
1350     , msTemplatePath(OUString())
1351 {
1352     mxCBApp->set_active(MNI_IMPRESS);
1353     mxCBFolder->set_active(0);
1354     m_xDialog->set_title(SfxResId(STR_TEMPLATE_SELECTION));
1355 
1356     if (mxLocalView->IsVisible())
1357     {
1358         mxLocalView->filterItems(ViewFilter_Application(getCurrentApplicationFilter()));
1359         mxLocalView->showAllTemplates();
1360     }
1361 
1362     mxCBApp->set_sensitive(false);
1363     mxActionBar->hide();
1364     mxLinkButton->hide();
1365     mxMoveButton->hide();
1366     mxExportButton->hide();
1367     mxCBXHideDlg->show();
1368     mxCBXHideDlg->set_active(true);
1369 
1370     mxLocalView->setOpenTemplateHdl(LINK(this,SfxTemplateSelectionDlg, OpenTemplateHdl));
1371     mxSearchView->setOpenTemplateHdl(LINK(this,SfxTemplateSelectionDlg, OpenTemplateHdl));
1372 
1373     mxSearchView->SetMultiSelectionEnabled(false);
1374 
1375     mxOKButton->connect_clicked(LINK(this, SfxTemplateSelectionDlg, OkClickHdl));
1376 }
1377 
1378 SfxTemplateSelectionDlg::~SfxTemplateSelectionDlg()
1379 {
1380     maIdle.Stop();
1381 }
1382 
1383 short SfxTemplateSelectionDlg::run()
1384 {
1385     // tdf#124597 at startup this dialog is launched before its parent window
1386     // has taken its final size. The parent size request is processed during
1387     // the dialogs event loop so configure this dialog to center to
1388     // the parents pending geometry request
1389     m_xDialog->set_centered_on_parent(true);
1390 
1391     // tdf#125079 toggle off the size tracking at some future idle point
1392     maIdle.SetPriority(TaskPriority::LOWEST);
1393     maIdle.SetInvokeHandler(LINK(this,SfxTemplateSelectionDlg,TimeOut));
1394     maIdle.Start();
1395 
1396     return weld::GenericDialogController::run();
1397 }
1398 
1399 IMPL_LINK_NOARG(SfxTemplateSelectionDlg, TimeOut, Timer*, void)
1400 {
1401     m_xDialog->set_centered_on_parent(false);
1402 }
1403 
1404 IMPL_LINK(SfxTemplateSelectionDlg, OpenTemplateHdl, ThumbnailViewItem*, pItem, void)
1405 {
1406     TemplateViewItem *pViewItem = static_cast<TemplateViewItem*>(pItem);
1407     msTemplatePath = pViewItem->getPath();
1408 
1409     m_xDialog->response(RET_OK);
1410 }
1411 
1412 IMPL_LINK_NOARG(SfxTemplateSelectionDlg, OkClickHdl, weld::Button&, void)
1413 {
1414    TemplateViewItem *pViewItem = static_cast<TemplateViewItem*>(const_cast<ThumbnailViewItem*>(*maSelTemplates.begin()));
1415    msTemplatePath = pViewItem->getPath();
1416 
1417    m_xDialog->response(RET_OK);
1418 }
1419 
1420 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1421