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