Bump version to 4.2-24
[LibreOffice.git] / sfx2 / source / doc / templatedlg.cxx
blob759d2d4c0c0fab8c8d379c24dac5a20e54e4be24
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include "templatedlg.hxx"
12 #include "inputdlg.hxx"
13 #include "templatesearchview.hxx"
14 #include "templatesearchviewitem.hxx"
16 #include <comphelper/processfactory.hxx>
17 #include <comphelper/storagehelper.hxx>
18 #include <officecfg/Office/Common.hxx>
19 #include <sfx2/app.hxx>
20 #include <sfx2/docfac.hxx>
21 #include <sfx2/fcontnr.hxx>
22 #include <sfx2/filedlghelper.hxx>
23 #include <sfx2/sfxresid.hxx>
24 #include <sfx2/templateinfodlg.hxx>
25 #include <sfx2/templatelocalview.hxx>
26 #include <sfx2/templatecontaineritem.hxx>
27 #include <sfx2/templateremoteview.hxx>
28 #include <sfx2/templaterepository.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 <svtools/miscopt.hxx>
35 #include <svtools/PlaceEditDialog.hxx>
36 #include <tools/urlobj.hxx>
37 #include <unotools/moduleoptions.hxx>
38 #include <unotools/pathoptions.hxx>
39 #include <unotools/viewoptions.hxx>
40 #include <vcl/edit.hxx>
41 #include <vcl/msgbox.hxx>
42 #include <vcl/toolbox.hxx>
44 #include <com/sun/star/beans/PropertyValue.hpp>
45 #include <com/sun/star/configuration/theDefaultProvider.hpp>
46 #include <com/sun/star/document/MacroExecMode.hpp>
47 #include <com/sun/star/document/UpdateDocMode.hpp>
48 #include <com/sun/star/embed/XStorage.hpp>
49 #include <com/sun/star/embed/ElementModes.hpp>
50 #include <com/sun/star/frame/Desktop.hpp>
51 #include <com/sun/star/frame/XComponentLoader.hpp>
52 #include <com/sun/star/frame/XStorable.hpp>
53 #include <com/sun/star/lang/XComponent.hpp>
54 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
55 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
56 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
57 #include <com/sun/star/ui/dialogs/FolderPicker.hpp>
58 #include <com/sun/star/system/SystemShellExecute.hpp>
59 #include <com/sun/star/system/SystemShellExecuteFlags.hpp>
60 #include <com/sun/star/task/InteractionHandler.hpp>
62 #include "doc.hrc"
63 #include "templatedlg.hrc"
65 #define PADDING_DLG_BORDER 10
67 #define TM_SETTING_MANAGER "TemplateManager"
68 #define TM_SETTING_LASTFOLDER "LastFolder"
69 #define TM_SETTING_FILTER "SelectedFilter"
71 const char SERVICENAME_CFGREADACCESS[] = "com.sun.star.configuration.ConfigurationAccess";
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;
82 static bool lcl_getServiceName (const OUString &rFileURL, OUString &rName );
84 static std::vector<OUString> lcl_getAllFactoryURLs ();
86 // Sort by name in ascending order
87 class SortView_Name
89 public:
91 bool operator() (const ThumbnailViewItem *pItem1, const ThumbnailViewItem *pItem2)
93 return (pItem1->maTitle.compareTo(pItem2->maTitle) < 0);
97 class SearchView_Keyword
99 public:
101 SearchView_Keyword (const OUString &rKeyword, FILTER_APPLICATION App)
102 : maKeyword(rKeyword), meApp(App)
105 bool operator() (const TemplateItemProperties &rItem)
107 bool bRet = true;
109 INetURLObject aUrl(rItem.aPath);
110 OUString aExt = aUrl.getExtension();
112 if (meApp == FILTER_APP_WRITER)
114 bRet = aExt == "ott" || aExt == "stw" || aExt == "oth" || aExt == "dot" || aExt == "dotx";
116 else if (meApp == FILTER_APP_CALC)
118 bRet = aExt == "ots" || aExt == "stc" || aExt == "xlt" || aExt == "xltm" || aExt == "xltx";
120 else if (meApp == FILTER_APP_IMPRESS)
122 bRet = aExt == "otp" || aExt == "sti" || aExt == "pot" || aExt == "potm" || aExt == "potx";
124 else if (meApp == FILTER_APP_DRAW)
126 bRet = aExt == "otg" || aExt == "std";
129 return bRet && rItem.aName.matchIgnoreAsciiCase(maKeyword);
132 private:
134 OUString maKeyword;
135 FILTER_APPLICATION meApp;
138 /***
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)
143 ***/
145 static bool cmpSelectionItems (const ThumbnailViewItem *pItem1, const ThumbnailViewItem *pItem2)
147 return pItem1->mnId > pItem2->mnId;
150 SfxTemplateManagerDlg::SfxTemplateManagerDlg (Window *parent)
151 : ModelessDialog(parent, SfxResId(DLG_TEMPLATE_MANAGER)),
152 maTabControl(this,SfxResId(TAB_CONTROL)),
153 maTabPage(&maTabControl, SfxResId(TAB_TEMPLATE_MANAGER)),
154 mpSearchEdit(new Edit(&maTabPage,WB_HIDE | WB_BORDER)),
155 mpViewBar( new ToolBox(&maTabPage, SfxResId(TBX_ACTION_VIEW))),
156 mpTemplateBar( new ToolBox(&maTabPage, SfxResId(TBX_ACTION_TEMPLATES))),
157 mpActionBar( new ToolBox(&maTabPage, SfxResId(TBX_ACTION_ACTION))),
158 mpSearchView(new TemplateSearchView(&maTabPage)),
159 mpLocalView(new TemplateLocalView(&maTabPage,SfxResId(TEMPLATE_VIEW))),
160 mpRemoteView(new TemplateRemoteView(&maTabPage, WB_VSCROLL,false)),
161 maSelTemplates(cmpSelectionItems),
162 maSelFolders(cmpSelectionItems),
163 mbIsSaveMode(false),
164 mxDesktop( Desktop::create(comphelper::getProcessComponentContext()) ),
165 mbIsSynced(false),
166 maRepositories()
168 maTabPage.Hide();
169 maTabControl.SetTabPage( FILTER_DOCS, &maTabPage );
170 maTabPage.Hide();
171 maTabControl.SetTabPage( FILTER_SHEETS, &maTabPage );
172 maTabPage.Hide();
173 maTabControl.SetTabPage( FILTER_PRESENTATIONS, &maTabPage );
174 maTabPage.Hide();
175 maTabControl.SetTabPage( FILTER_DRAWS, &maTabPage );
176 maTabPage.Show();
178 // Create popup menus
179 mpActionMenu = new PopupMenu;
180 mpActionMenu->InsertItem(MNI_ACTION_SORT_NAME,
181 SfxResId(STR_ACTION_SORT_NAME).toString(),
182 Image(SfxResId(IMG_ACTION_SORT)));
183 mpActionMenu->InsertItem(MNI_ACTION_REFRESH,
184 SfxResId(STR_ACTION_REFRESH).toString(),
185 Image(SfxResId(IMG_ACTION_REFRESH)));
186 mpActionMenu->InsertItem(MNI_ACTION_DEFAULT,SfxResId(STR_ACTION_DEFAULT).toString());
187 mpActionMenu->SetSelectHdl(LINK(this,SfxTemplateManagerDlg,MenuSelectHdl));
189 mpRepositoryMenu = new PopupMenu;
190 mpRepositoryMenu->SetSelectHdl(LINK(this,SfxTemplateManagerDlg,RepositoryMenuSelectHdl));
192 mpTemplateDefaultMenu = new PopupMenu;
193 mpTemplateDefaultMenu->SetSelectHdl(LINK(this,SfxTemplateManagerDlg,DefaultTemplateMenuSelectHdl));
194 mpActionMenu->SetPopupMenu(MNI_ACTION_DEFAULT,mpTemplateDefaultMenu);
196 // Set toolbox styles
197 mpViewBar->SetButtonType(BUTTON_SYMBOLTEXT);
198 mpTemplateBar->SetButtonType(BUTTON_SYMBOLTEXT);
200 // Set toolbox button bits
201 mpViewBar->SetItemBits(TBI_TEMPLATE_REPOSITORY, TIB_DROPDOWNONLY);
202 mpActionBar->SetItemBits(TBI_TEMPLATE_ACTION, TIB_DROPDOWNONLY);
203 mpTemplateBar->SetItemBits(TBI_TEMPLATE_MOVE,TIB_DROPDOWNONLY);
205 // Set toolbox handlers
206 mpViewBar->SetClickHdl(LINK(this,SfxTemplateManagerDlg,TBXViewHdl));
207 mpViewBar->SetDropdownClickHdl(LINK(this,SfxTemplateManagerDlg,TBXDropdownHdl));
208 mpActionBar->SetClickHdl(LINK(this,SfxTemplateManagerDlg,TBXActionHdl));
209 mpActionBar->SetDropdownClickHdl(LINK(this,SfxTemplateManagerDlg,TBXDropdownHdl));
210 mpTemplateBar->SetClickHdl(LINK(this,SfxTemplateManagerDlg,TBXTemplateHdl));
211 mpTemplateBar->SetDropdownClickHdl(LINK(this,SfxTemplateManagerDlg,TBXDropdownHdl));
212 mpSearchEdit->SetUpdateDataHdl(LINK(this,SfxTemplateManagerDlg,SearchUpdateHdl));
213 mpSearchEdit->EnableUpdateData();
215 mpLocalView->SetStyle(mpLocalView->GetStyle() | WB_VSCROLL);
216 mpLocalView->setItemMaxTextLength(TEMPLATE_ITEM_MAX_TEXT_LENGTH);
218 mpLocalView->setItemDimensions(TEMPLATE_ITEM_MAX_WIDTH,TEMPLATE_ITEM_THUMBNAIL_MAX_HEIGHT,
219 TEMPLATE_ITEM_MAX_HEIGHT-TEMPLATE_ITEM_THUMBNAIL_MAX_HEIGHT,
220 TEMPLATE_ITEM_PADDING);
222 mpLocalView->setItemStateHdl(LINK(this,SfxTemplateManagerDlg,TVItemStateHdl));
223 mpLocalView->setOpenRegionHdl(LINK(this,SfxTemplateManagerDlg,OpenRegionHdl));
224 mpLocalView->setOpenTemplateHdl(LINK(this,SfxTemplateManagerDlg,OpenTemplateHdl));
226 // Set online view position and dimensions
227 mpRemoteView->setItemMaxTextLength(TEMPLATE_ITEM_MAX_TEXT_LENGTH);
229 mpRemoteView->setItemDimensions(TEMPLATE_ITEM_MAX_WIDTH,TEMPLATE_ITEM_THUMBNAIL_MAX_HEIGHT,
230 TEMPLATE_ITEM_MAX_HEIGHT-TEMPLATE_ITEM_THUMBNAIL_MAX_HEIGHT,
231 TEMPLATE_ITEM_PADDING);
233 mpRemoteView->setItemStateHdl(LINK(this,SfxTemplateManagerDlg,TVItemStateHdl));
234 mpRemoteView->setOpenRegionHdl(LINK(this,SfxTemplateManagerDlg,OpenRegionHdl));
235 mpRemoteView->setOpenTemplateHdl(LINK(this,SfxTemplateManagerDlg,OpenTemplateHdl));
237 mpSearchView->setItemMaxTextLength(TEMPLATE_ITEM_MAX_TEXT_LENGTH);
239 mpSearchView->setItemDimensions(TEMPLATE_ITEM_MAX_WIDTH,TEMPLATE_ITEM_THUMBNAIL_MAX_HEIGHT,
240 TEMPLATE_ITEM_MAX_HEIGHT_SUB-TEMPLATE_ITEM_THUMBNAIL_MAX_HEIGHT,
241 TEMPLATE_ITEM_PADDING);
243 mpSearchView->setItemStateHdl(LINK(this,SfxTemplateManagerDlg,TVItemStateHdl));
244 mpSearchView->setOpenTemplateHdl(LINK(this,SfxTemplateManagerDlg,OpenTemplateHdl));
246 maTabControl.SetActivatePageHdl(LINK(this,SfxTemplateManagerDlg,ActivatePageHdl));
248 SvtMiscOptions aMiscOptions;
249 if ( !aMiscOptions.IsExperimentalMode() )
251 sal_uInt16 nPos = mpViewBar->GetItemId(TBI_TEMPLATE_REPOSITORY);
252 mpViewBar->RemoveItem(nPos);
255 SetMinOutputSizePixel(GetOutputSizePixel());
257 mpViewBar->Show();
258 mpActionBar->Show();
260 switchMainView(true);
262 loadRepositories();
264 createRepositoryMenu();
265 createDefaultTemplateMenu();
267 mpLocalView->Populate();
268 mpCurView->filterItems(ViewFilter_Application(FILTER_APP_WRITER));
270 readSettings();
272 mpLocalView->Show();
274 FreeResource();
277 SfxTemplateManagerDlg::~SfxTemplateManagerDlg ()
279 writeSettings();
281 // Synchronize the config before deleting it
282 syncRepositories();
283 for (size_t i = 0, n = maRepositories.size(); i < n; ++i)
284 delete maRepositories[i];
286 // Ignore view events since we are cleaning the object
287 mpLocalView->setItemStateHdl(Link());
288 mpLocalView->setOpenRegionHdl(Link());
289 mpLocalView->setOpenTemplateHdl(Link());
291 mpRemoteView->setItemStateHdl(Link());
292 mpRemoteView->setOpenRegionHdl(Link());
293 mpRemoteView->setOpenTemplateHdl(Link());
295 mpSearchView->setItemStateHdl(Link());
296 mpSearchView->setOpenTemplateHdl(Link());
298 delete mpSearchEdit;
299 delete mpViewBar;
300 delete mpActionBar;
301 delete mpTemplateBar;
302 delete mpSearchView;
303 delete mpLocalView;
304 delete mpRemoteView;
305 delete mpTemplateDefaultMenu;
306 delete mpActionMenu;
307 delete mpRepositoryMenu;
310 void SfxTemplateManagerDlg::setSaveMode(bool bMode)
312 mbIsSaveMode = bMode;
313 maTabControl.Clear();
314 mpCurView->filterItems(ViewFilter_Application(FILTER_APP_NONE));
316 if (bMode)
318 mpViewBar->ShowItem(TBI_TEMPLATE_SAVE);
319 mpViewBar->HideItem(TBI_TEMPLATE_IMPORT);
320 mpViewBar->HideItem(TBI_TEMPLATE_REPOSITORY);
322 mpTemplateBar->ShowItem(TBI_TEMPLATE_SAVE);
323 mpTemplateBar->ShowItem(TBI_TEMPLATE_PROPERTIES);
324 mpTemplateBar->ShowItem(TBI_TEMPLATE_DEFAULT);
325 mpTemplateBar->HideItem(TBI_TEMPLATE_OPEN);
326 mpTemplateBar->HideItem(TBI_TEMPLATE_EDIT);
327 mpTemplateBar->HideItem(TBI_TEMPLATE_MOVE);
328 mpTemplateBar->HideItem(TBI_TEMPLATE_EXPORT);
329 mpTemplateBar->HideItem(TBI_TEMPLATE_DELETE);
331 else
333 mpViewBar->HideItem(TBI_TEMPLATE_SAVE);
334 mpViewBar->ShowItem(TBI_TEMPLATE_IMPORT);
335 mpViewBar->ShowItem(TBI_TEMPLATE_REPOSITORY);
339 void SfxTemplateManagerDlg::setDocumentModel(const uno::Reference<frame::XModel> &rModel)
341 m_xModel = rModel;
344 IMPL_LINK_NOARG(SfxTemplateManagerDlg,ActivatePageHdl)
346 FILTER_APPLICATION eFilter = FILTER_APP_NONE;
347 switch (maTabControl.GetCurPageId())
349 case FILTER_DOCS:
350 eFilter = FILTER_APP_WRITER;
351 break;
352 case FILTER_PRESENTATIONS:
353 eFilter = FILTER_APP_IMPRESS;
354 break;
355 case FILTER_SHEETS:
356 eFilter = FILTER_APP_CALC;
357 break;
358 case FILTER_DRAWS:
359 eFilter = FILTER_APP_DRAW;
360 break;
362 mpCurView->filterItems(ViewFilter_Application(eFilter));
364 if (mpSearchView->IsVisible())
365 SearchUpdateHdl(NULL);
367 return 0;
370 void SfxTemplateManagerDlg::readSettings ()
372 OUString aLastFolder;
373 sal_uInt16 nPageId = FILTER_DOCS;
374 SvtViewOptions aViewSettings( E_DIALOG, TM_SETTING_MANAGER );
376 if ( aViewSettings.Exists() )
378 sal_uInt16 nFilter = 0;
379 aViewSettings.GetUserItem(TM_SETTING_LASTFOLDER) >>= aLastFolder;
380 aViewSettings.GetUserItem(TM_SETTING_FILTER) >>= nFilter;
382 switch (nFilter)
384 case FILTER_APP_WRITER:
385 nPageId = FILTER_DOCS;
386 break;
387 case FILTER_APP_IMPRESS:
388 nPageId = FILTER_PRESENTATIONS;
389 break;
390 case FILTER_APP_CALC:
391 nPageId = FILTER_SHEETS;
392 break;
393 case FILTER_APP_DRAW:
394 nPageId = FILTER_DRAWS;
395 break;
399 if (!aLastFolder.getLength())
400 mpLocalView->showRootRegion();
401 else
402 mpLocalView->showRegion(aLastFolder);
404 maTabControl.SelectTabPage(nPageId);
407 void SfxTemplateManagerDlg::writeSettings ()
409 Sequence< NamedValue > aSettings(2);
411 OUString aLastFolder;
413 if (mpCurView == mpLocalView && mpLocalView->getCurRegionId())
414 aLastFolder = mpLocalView->getRegionName(mpLocalView->getCurRegionId()-1);
416 // last folder
417 aSettings[0].Name = TM_SETTING_LASTFOLDER;
418 aSettings[0].Value <<= aLastFolder;
420 sal_uInt16 nFilter = FILTER_APP_WRITER;
421 switch (maTabControl.GetCurPageId())
423 case FILTER_DOCS:
424 nFilter = FILTER_APP_WRITER;
425 break;
426 case FILTER_PRESENTATIONS:
427 nFilter = FILTER_APP_IMPRESS;
428 break;
429 case FILTER_SHEETS:
430 nFilter = FILTER_APP_CALC;
431 break;
432 case FILTER_DRAWS:
433 nFilter = FILTER_APP_DRAW;
434 break;
437 aSettings[1].Name = TM_SETTING_FILTER;
438 aSettings[1].Value <<= nFilter;
440 // write
441 SvtViewOptions aViewSettings( E_DIALOG, TM_SETTING_MANAGER );
442 aViewSettings.SetUserData( aSettings );
445 void SfxTemplateManagerDlg::Resize()
447 // Fit the tab page control and the toolbars
448 maTabControl.SetSizePixel(GetSizePixel());
449 const Size aWinSize = maTabControl.GetTabPageSizePixel();
451 // Calculate toolboxes size and positions
452 Size aViewSize = mpViewBar->CalcMinimumWindowSizePixel();
453 Size aActionSize = mpActionBar->CalcMinimumWindowSizePixel();
454 Size aTemplateSize = mpTemplateBar->CalcMinimumWindowSizePixel();
456 long nToolbarsHeight = std::max(std::max(aViewSize.getHeight(), aActionSize.getHeight()), aTemplateSize.getHeight());
458 aActionSize.setWidth(3.35*aActionSize.getWidth());
459 aViewSize.setWidth(aWinSize.getWidth()-aActionSize.getWidth()-mpViewBar->GetPosPixel().X());
460 aTemplateSize.setWidth(aWinSize.getWidth());
462 Point aActionPos = mpActionBar->GetPosPixel();
463 aActionPos.setX(aWinSize.getWidth() - aActionSize.getWidth());
465 mpViewBar->SetSizePixel(aViewSize);
466 mpActionBar->SetPosSizePixel(aActionPos,aActionSize);
467 mpTemplateBar->SetSizePixel(aTemplateSize);
469 Point aViewPos = mpLocalView->GetPosPixel();
470 aViewPos.setY(nToolbarsHeight);
471 aViewPos.setX(0);
473 // Set search box position and size
474 Size aSearchSize = mpSearchEdit->CalcMinimumSize();
475 aSearchSize.setWidth(aWinSize.getWidth() - 2*PADDING_DLG_BORDER);
477 mpSearchEdit->SetSizePixel(aSearchSize);
478 mpSearchEdit->SetPosPixel(Point(PADDING_DLG_BORDER,aViewPos.Y()));
480 if (mpSearchEdit->IsVisible())
481 aViewPos.setY(aViewPos.getY() + mpSearchEdit->GetSizePixel().getHeight() );
483 // Set view position below toolbox and search box
484 Size aThumbSize(aWinSize.getWidth(), aWinSize.getHeight() - aViewPos.getY());
486 mpLocalView->SetPosSizePixel(aViewPos,aThumbSize);
487 mpRemoteView->SetPosSizePixel(aViewPos,aThumbSize);
488 mpSearchView->SetPosSizePixel(aViewPos,aThumbSize);
490 ModelessDialog::Resize();
493 IMPL_LINK_NOARG(SfxTemplateManagerDlg,TBXViewHdl)
495 switch(mpViewBar->GetCurItemId())
497 case TBI_TEMPLATE_IMPORT:
498 OnTemplateImport();
499 break;
500 case TBI_TEMPLATE_FOLDER_DEL:
501 if (mpCurView == mpLocalView)
502 OnFolderDelete();
503 else
504 OnRepositoryDelete();
505 break;
506 case TBI_TEMPLATE_FOLDER_NEW:
507 OnFolderNew();
508 break;
509 case TBI_TEMPLATE_SAVE:
510 OnTemplateSaveAs();
511 break;
512 default:
513 break;
516 return 0;
519 IMPL_LINK_NOARG(SfxTemplateManagerDlg,TBXActionHdl)
521 switch(mpActionBar->GetCurItemId())
523 case TBI_TEMPLATE_SEARCH:
524 OnTemplateSearch();
525 break;
526 case TBI_TEMPLATE_LINK:
527 OnTemplateLink();
528 break;
529 default:
530 break;
533 return 0;
536 IMPL_LINK_NOARG(SfxTemplateManagerDlg,TBXTemplateHdl)
538 switch(mpTemplateBar->GetCurItemId())
540 case TBI_TEMPLATE_OPEN:
541 OnTemplateOpen();
542 break;
543 case TBI_TEMPLATE_EDIT:
544 OnTemplateEdit();
545 break;
546 case TBI_TEMPLATE_PROPERTIES:
547 OnTemplateProperties();
548 break;
549 case TBI_TEMPLATE_DELETE:
550 OnTemplateDelete();
551 break;
552 case TBI_TEMPLATE_DEFAULT:
553 OnTemplateAsDefault();
554 break;
555 case TBI_TEMPLATE_EXPORT:
556 OnTemplateExport();
557 break;
558 default:
559 break;
562 return 0;
565 IMPL_LINK(SfxTemplateManagerDlg, TBXDropdownHdl, ToolBox*, pBox)
567 const sal_uInt16 nCurItemId = pBox->GetCurItemId();
569 switch(nCurItemId)
571 case TBI_TEMPLATE_ACTION:
572 pBox->SetItemDown( nCurItemId, true );
574 mpActionMenu->Execute(pBox,pBox->GetItemRect(TBI_TEMPLATE_ACTION),
575 POPUPMENU_EXECUTE_DOWN);
577 pBox->SetItemDown( nCurItemId, false );
578 pBox->EndSelection();
579 pBox->Invalidate();
580 break;
581 case TBI_TEMPLATE_MOVE:
583 pBox->SetItemDown( nCurItemId, true );
585 std::vector<OUString> aNames = mpLocalView->getFolderNames();
587 PopupMenu *pMoveMenu = new PopupMenu;
588 pMoveMenu->SetSelectHdl(LINK(this,SfxTemplateManagerDlg,MoveMenuSelectHdl));
590 if (!aNames.empty())
592 for (size_t i = 0, n = aNames.size(); i < n; ++i)
593 pMoveMenu->InsertItem(MNI_MOVE_FOLDER_BASE+i,aNames[i]);
596 pMoveMenu->InsertSeparator();
598 pMoveMenu->InsertItem(MNI_MOVE_NEW,SfxResId(STR_MOVE_NEW).toString());
600 pMoveMenu->Execute(pBox,pBox->GetItemRect(TBI_TEMPLATE_MOVE),
601 POPUPMENU_EXECUTE_DOWN);
603 delete pMoveMenu;
605 pBox->SetItemDown( nCurItemId, false );
606 pBox->EndSelection();
607 pBox->Invalidate();
608 break;
610 case TBI_TEMPLATE_REPOSITORY:
611 pBox->SetItemDown( nCurItemId, true );
613 mpRepositoryMenu->Execute(pBox,pBox->GetItemRect(TBI_TEMPLATE_REPOSITORY),
614 POPUPMENU_EXECUTE_DOWN);
616 pBox->SetItemDown( nCurItemId, false );
617 pBox->EndSelection();
618 pBox->Invalidate();
619 break;
620 default:
621 break;
624 return 0;
627 IMPL_LINK(SfxTemplateManagerDlg, TVItemStateHdl, const ThumbnailViewItem*, pItem)
629 const TemplateContainerItem *pCntItem = dynamic_cast<const TemplateContainerItem*>(pItem);
631 if (pCntItem)
632 OnRegionState(pItem);
633 else
634 OnTemplateState(pItem);
636 return 0;
639 IMPL_LINK(SfxTemplateManagerDlg, MenuSelectHdl, Menu*, pMenu)
641 sal_uInt16 nMenuId = pMenu->GetCurItemId();
643 switch(nMenuId)
645 case MNI_ACTION_SORT_NAME:
646 mpLocalView->sortItems(SortView_Name());
647 break;
648 case MNI_ACTION_REFRESH:
649 mpCurView->reload();
650 break;
651 default:
652 break;
655 return 0;
658 IMPL_LINK(SfxTemplateManagerDlg, MoveMenuSelectHdl, Menu*, pMenu)
660 sal_uInt16 nMenuId = pMenu->GetCurItemId();
662 if (mpSearchView->IsVisible())
664 // Check if we are searching the local or remote templates
665 if (mpCurView == mpLocalView)
666 localSearchMoveTo(nMenuId);
668 else
670 // Check if we are displaying the local or remote templates
671 if (mpCurView == mpLocalView)
672 localMoveTo(nMenuId);
673 else
674 remoteMoveTo(nMenuId);
677 return 0;
680 IMPL_LINK(SfxTemplateManagerDlg, RepositoryMenuSelectHdl, Menu*, pMenu)
682 sal_uInt16 nMenuId = pMenu->GetCurItemId();
684 if (nMenuId == MNI_REPOSITORY_LOCAL)
686 switchMainView(true);
688 else if (nMenuId == MNI_REPOSITORY_NEW)
690 PlaceEditDialog dlg(this);
692 if (dlg.Execute())
694 boost::shared_ptr<Place> pPlace = dlg.GetPlace();
696 if (insertRepository(pPlace->GetName(),pPlace->GetUrl()))
698 // update repository list menu.
699 createRepositoryMenu();
701 else
703 OUString aMsg(SfxResId(STR_MSG_ERROR_REPOSITORY_NAME).toString());
704 aMsg = aMsg.replaceFirst("$1",pPlace->GetName());
705 ErrorBox(this,WB_OK,aMsg).Execute();
709 else
711 sal_uInt16 nRepoId = nMenuId - MNI_REPOSITORY_BASE;
713 TemplateRepository *pRepository = NULL;
715 for (size_t i = 0, n = maRepositories.size(); i < n; ++i)
717 if (maRepositories[i]->mnId == nRepoId)
719 pRepository = maRepositories[i];
720 break;
724 if (mpRemoteView->loadRepository(pRepository,false))
725 switchMainView(false);
728 return 0;
731 IMPL_LINK(SfxTemplateManagerDlg, DefaultTemplateMenuSelectHdl, Menu*, pMenu)
733 sal_uInt16 nId = pMenu->GetCurItemId();
735 OUString aServiceName = SfxObjectShell::GetServiceNameFromFactory( mpTemplateDefaultMenu->GetItemCommand(nId));
736 SfxObjectFactory::SetStandardTemplate( aServiceName, OUString() );
738 createDefaultTemplateMenu();
740 return 0;
743 IMPL_LINK_NOARG(SfxTemplateManagerDlg, OpenRegionHdl)
745 maSelFolders.clear();
746 maSelTemplates.clear();
748 mpViewBar->ShowItem(TBI_TEMPLATE_FOLDER_NEW,mpCurView->isNestedRegionAllowed());
750 if (!mbIsSaveMode)
751 mpViewBar->ShowItem(TBI_TEMPLATE_IMPORT,mpCurView->isImportAllowed());
753 mpTemplateBar->Hide();
754 mpViewBar->Show();
755 mpActionBar->Show();
757 return 0;
760 IMPL_LINK(SfxTemplateManagerDlg, OpenTemplateHdl, ThumbnailViewItem*, pItem)
762 if (!mbIsSaveMode)
764 uno::Sequence< PropertyValue > aArgs(4);
765 aArgs[0].Name = "AsTemplate";
766 aArgs[0].Value <<= sal_True;
767 aArgs[1].Name = "MacroExecutionMode";
768 aArgs[1].Value <<= MacroExecMode::USE_CONFIG;
769 aArgs[2].Name = "UpdateDocMode";
770 aArgs[2].Value <<= UpdateDocMode::ACCORDING_TO_CONFIG;
771 aArgs[3].Name = "InteractionHandler";
772 aArgs[3].Value <<= task::InteractionHandler::createWithParent( ::comphelper::getProcessComponentContext(), 0 );
774 TemplateViewItem *pTemplateItem = static_cast<TemplateViewItem*>(pItem);
778 mxDesktop->loadComponentFromURL(pTemplateItem->getPath(),"_default", 0, aArgs );
780 catch( const uno::Exception& )
784 Close();
787 return 0;
790 IMPL_LINK_NOARG(SfxTemplateManagerDlg, SearchUpdateHdl)
792 OUString aKeyword = mpSearchEdit->GetText();
794 if (!aKeyword.isEmpty())
796 mpSearchView->Clear();
798 // if the search view is hidden, hide the folder view and display search one
799 if (!mpSearchView->IsVisible())
801 mpCurView->deselectItems();
802 mpSearchView->Show();
803 mpCurView->Hide();
806 bool bDisplayFolder = !mpCurView->isNonRootRegionVisible();
808 FILTER_APPLICATION eFilter = FILTER_APP_NONE;
809 switch (maTabControl.GetCurPageId())
811 case FILTER_DOCS:
812 eFilter = FILTER_APP_WRITER;
813 break;
814 case FILTER_PRESENTATIONS:
815 eFilter = FILTER_APP_IMPRESS;
816 break;
817 case FILTER_SHEETS:
818 eFilter = FILTER_APP_CALC;
819 break;
820 case FILTER_DRAWS:
821 eFilter = FILTER_APP_DRAW;
822 break;
825 std::vector<TemplateItemProperties> aItems =
826 mpLocalView->getFilteredItems(SearchView_Keyword(aKeyword,eFilter));
828 for (size_t i = 0; i < aItems.size(); ++i)
830 TemplateItemProperties *pItem = &aItems[i];
832 OUString aFolderName;
834 if (bDisplayFolder)
835 aFolderName = mpLocalView->getRegionName(pItem->nRegionId);
837 mpSearchView->AppendItem(pItem->nId,mpLocalView->getRegionId(pItem->nRegionId),
838 pItem->nDocId,
839 pItem->aName,
840 aFolderName,
841 pItem->aPath,
842 pItem->aThumbnail);
845 mpSearchView->Invalidate();
847 else
849 mpSearchView->Hide();
850 mpCurView->Show();
853 return 0;
856 void SfxTemplateManagerDlg::OnRegionState (const ThumbnailViewItem *pItem)
858 if (pItem->isSelected())
860 if (maSelFolders.empty() && !mbIsSaveMode)
862 mpViewBar->ShowItem(TBI_TEMPLATE_IMPORT);
863 mpViewBar->ShowItem(TBI_TEMPLATE_FOLDER_DEL);
864 mpViewBar->HideItem(TBI_TEMPLATE_FOLDER_NEW);
867 maSelFolders.insert(pItem);
869 else
871 maSelFolders.erase(pItem);
873 if (maSelFolders.empty() && !mbIsSaveMode)
875 mpViewBar->HideItem(TBI_TEMPLATE_IMPORT);
876 mpViewBar->HideItem(TBI_TEMPLATE_FOLDER_DEL);
877 mpViewBar->ShowItem(TBI_TEMPLATE_FOLDER_NEW);
882 void SfxTemplateManagerDlg::OnTemplateState (const ThumbnailViewItem *pItem)
884 bool bInSelection = maSelTemplates.find(pItem) != maSelTemplates.end();
886 if (pItem->isSelected())
888 if (maSelTemplates.empty())
890 mpViewBar->Show(false);
891 mpTemplateBar->Show();
893 else if (maSelTemplates.size() != 1 || !bInSelection)
895 if (!mbIsSaveMode)
897 mpTemplateBar->HideItem(TBI_TEMPLATE_OPEN);
898 mpTemplateBar->HideItem(TBI_TEMPLATE_EDIT);
899 mpTemplateBar->HideItem(TBI_TEMPLATE_PROPERTIES);
900 mpTemplateBar->HideItem(TBI_TEMPLATE_DEFAULT);
902 else
904 mpTemplateBar->HideItem(TBI_TEMPLATE_SAVE);
905 mpTemplateBar->HideItem(TBI_TEMPLATE_PROPERTIES);
906 mpTemplateBar->HideItem(TBI_TEMPLATE_DEFAULT);
910 if (!bInSelection)
911 maSelTemplates.insert(pItem);
913 else
915 if (bInSelection)
917 maSelTemplates.erase(pItem);
919 if (maSelTemplates.empty())
921 mpTemplateBar->Show(false);
922 mpViewBar->Show();
924 else if (maSelTemplates.size() == 1)
926 if (!mbIsSaveMode)
928 mpTemplateBar->ShowItem(TBI_TEMPLATE_OPEN);
929 mpTemplateBar->ShowItem(TBI_TEMPLATE_EDIT);
930 mpTemplateBar->ShowItem(TBI_TEMPLATE_PROPERTIES);
931 mpTemplateBar->ShowItem(TBI_TEMPLATE_DEFAULT);
933 else
935 mpTemplateBar->ShowItem(TBI_TEMPLATE_SAVE);
936 mpTemplateBar->ShowItem(TBI_TEMPLATE_PROPERTIES);
937 mpTemplateBar->ShowItem(TBI_TEMPLATE_DEFAULT);
944 void SfxTemplateManagerDlg::OnTemplateImport ()
946 sal_Int16 nDialogType =
947 com::sun::star::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE;
949 sfx2::FileDialogHelper aFileDlg(nDialogType, SFXWB_MULTISELECTION);
951 // add "All" filter
952 aFileDlg.AddFilter( SfxResId(STR_SFX_FILTERNAME_ALL).toString(),
953 OUString(FILEDIALOG_FILTER_ALL) );
955 // add template filter
956 OUString sFilterExt;
957 OUString sFilterName( SfxResId( STR_TEMPLATE_FILTER ).toString() );
959 // add filters of modules which are installed
960 SvtModuleOptions aModuleOpt;
961 if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
962 sFilterExt += "*.ott;*.stw;*.oth";
964 if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) )
966 if ( !sFilterExt.isEmpty() )
967 sFilterExt += ";";
969 sFilterExt += "*.ots;*.stc";
972 if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) )
974 if ( !sFilterExt.isEmpty() )
975 sFilterExt += ";";
977 sFilterExt += "*.otp;*.sti";
980 if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) )
982 if ( !sFilterExt.isEmpty() )
983 sFilterExt += ";";
985 sFilterExt += "*.otg;*.std";
988 if ( !sFilterExt.isEmpty() )
989 sFilterExt += ";";
991 sFilterExt += "*.vor";
993 sFilterName += " (";
994 sFilterName += sFilterExt;
995 sFilterName += ")";
997 aFileDlg.AddFilter( sFilterName, sFilterExt );
998 aFileDlg.SetCurrentFilter( sFilterName );
1000 ErrCode nCode = aFileDlg.Execute();
1002 if ( nCode == ERRCODE_NONE )
1004 com::sun::star::uno::Sequence<OUString> aFiles = aFileDlg.GetSelectedFiles();
1006 if (aFiles.hasElements())
1008 if (!maSelFolders.empty())
1010 //Import to the selected regions
1011 std::set<const ThumbnailViewItem*,selection_cmp_fn>::const_iterator pIter;
1012 for (pIter = maSelFolders.begin(); pIter != maSelFolders.end(); ++pIter)
1014 OUString aTemplateList;
1015 TemplateContainerItem *pFolder = (TemplateContainerItem*)(*pIter);
1017 for (size_t i = 0, n = aFiles.getLength(); i < n; ++i)
1019 if(!mpLocalView->copyFrom(pFolder,aFiles[i]))
1021 if (aTemplateList.isEmpty())
1022 aTemplateList = aFiles[i];
1023 else
1024 aTemplateList = aTemplateList + "\n" + aFiles[i];
1028 if (!aTemplateList.isEmpty())
1030 OUString aMsg(SfxResId(STR_MSG_ERROR_IMPORT).toString());
1031 aMsg = aMsg.replaceFirst("$1",pFolder->maTitle);
1032 ErrorBox(this,WB_OK,aMsg.replaceFirst("$2",aTemplateList));
1036 else
1038 //Import to current region
1039 OUString aTemplateList;
1040 for (size_t i = 0, n = aFiles.getLength(); i < n; ++i)
1042 if(!mpLocalView->copyFrom(aFiles[i]))
1044 if (aTemplateList.isEmpty())
1045 aTemplateList = aFiles[i];
1046 else
1047 aTemplateList = aTemplateList + "\n" + aFiles[i];
1051 if (!aTemplateList.isEmpty())
1053 OUString aMsg(SfxResId(STR_MSG_ERROR_IMPORT).toString());
1054 aMsg = aMsg.replaceFirst("$1",mpLocalView->getCurRegionName());
1055 ErrorBox(this,WB_OK,aMsg.replaceFirst("$2",aTemplateList));
1059 mpLocalView->Invalidate(INVALIDATE_NOERASE);
1064 void SfxTemplateManagerDlg::OnTemplateExport()
1066 uno::Reference<XComponentContext> xContext(comphelper::getProcessComponentContext());
1067 uno::Reference<XFolderPicker2> xFolderPicker = FolderPicker::create(xContext);
1069 xFolderPicker->setDisplayDirectory(SvtPathOptions().GetWorkPath());
1071 sal_Int16 nResult = xFolderPicker->execute();
1073 if( nResult == ExecutableDialogResults::OK )
1075 OUString aTemplateList;
1076 INetURLObject aPathObj(xFolderPicker->getDirectory());
1077 aPathObj.setFinalSlash();
1079 if (mpSearchView->IsVisible())
1081 sal_uInt16 i = 1;
1083 std::set<const ThumbnailViewItem*,selection_cmp_fn>::const_iterator pIter;
1084 for (pIter = maSelTemplates.begin(); pIter != maSelTemplates.end(); ++pIter, ++i)
1086 const TemplateSearchViewItem *pItem = static_cast<const TemplateSearchViewItem*>(*pIter);
1088 INetURLObject aItemPath(pItem->getPath());
1090 if ( 1 == i )
1091 aPathObj.Append(aItemPath.getName());
1092 else
1093 aPathObj.setName(aItemPath.getName());
1095 OUString aPath = aPathObj.GetMainURL( INetURLObject::NO_DECODE );
1097 if (!mpLocalView->exportTo(pItem->mnAssocId,pItem->mnRegionId,aPath))
1099 if (aTemplateList.isEmpty())
1100 aTemplateList = pItem->maTitle;
1101 else
1102 aTemplateList = aTemplateList + "\n" + pItem->maTitle;
1106 mpSearchView->deselectItems();
1108 else
1110 // export templates from the current view
1112 sal_uInt16 i = 1;
1113 sal_uInt16 nRegionItemId = mpLocalView->getCurRegionItemId();
1115 std::set<const ThumbnailViewItem*,selection_cmp_fn>::const_iterator pIter = maSelTemplates.begin();
1116 for (pIter = maSelTemplates.begin(); pIter != maSelTemplates.end(); ++pIter, ++i)
1118 const TemplateViewItem *pItem = static_cast<const TemplateViewItem*>(*pIter);
1120 INetURLObject aItemPath(pItem->getPath());
1122 if ( 1 == i )
1123 aPathObj.Append(aItemPath.getName());
1124 else
1125 aPathObj.setName(aItemPath.getName());
1127 OUString aPath = aPathObj.GetMainURL( INetURLObject::NO_DECODE );
1129 if (!mpLocalView->exportTo(pItem->mnId,nRegionItemId,aPath))
1131 if (aTemplateList.isEmpty())
1132 aTemplateList = pItem->maTitle;
1133 else
1134 aTemplateList = aTemplateList + "\n" + pItem->maTitle;
1138 mpLocalView->deselectItems();
1141 if (!aTemplateList.isEmpty())
1143 OUString aText( SfxResId(STR_MSG_ERROR_EXPORT).toString() );
1144 ErrorBox(this, WB_OK,aText.replaceFirst("$1",aTemplateList)).Execute();
1149 void SfxTemplateManagerDlg::OnTemplateSearch ()
1151 Point aPos = mpLocalView->GetPosPixel();
1152 bool bVisible = mpSearchEdit->IsVisible();
1153 Size aWinSize = GetSizePixel();
1154 long nEditHeight = mpSearchEdit->GetSizePixel().getHeight();
1156 if (bVisible)
1158 aWinSize.setHeight(aWinSize.getHeight() - nEditHeight );
1159 aPos.setY(aPos.getY() - nEditHeight );
1160 mpActionBar->SetItemState(TBI_TEMPLATE_SEARCH,STATE_NOCHECK);
1162 else
1164 aWinSize.setHeight(aWinSize.getHeight() + nEditHeight );
1165 aPos.setY(aPos.getY() + nEditHeight );
1166 mpActionBar->SetItemState(TBI_TEMPLATE_SEARCH,STATE_CHECK);
1169 // SetSizePixel(aWinSize);
1170 mpLocalView->SetPosPixel(aPos);
1171 mpRemoteView->SetPosPixel(aPos);
1172 mpSearchView->SetPosPixel(aPos);
1174 // Hide search view
1175 if (bVisible)
1177 mpSearchView->deselectItems();
1178 mpSearchView->Hide();
1179 mpCurView->Show();
1182 mpSearchEdit->Show(!bVisible);
1183 mpSearchEdit->SetText(OUString());
1184 if (!bVisible)
1185 mpSearchEdit->GrabFocus();
1188 void SfxTemplateManagerDlg::OnTemplateLink ()
1190 OUString sNode("TemplateRepositoryURL");
1191 OUString sNodePath("/org.openoffice.Office.Common/Help/StartCenter");
1194 Reference<lang::XMultiServiceFactory> xConfig = configuration::theDefaultProvider::get( comphelper::getProcessComponentContext() );
1195 Sequence<Any> args(1);
1196 PropertyValue val(
1197 "nodepath",
1199 Any(sNodePath),
1200 PropertyState_DIRECT_VALUE);
1201 args.getArray()[0] <<= val;
1202 Reference<container::XNameAccess> xNameAccess(xConfig->createInstanceWithArguments(SERVICENAME_CFGREADACCESS,args), UNO_QUERY);
1203 if( xNameAccess.is() )
1205 OUString sURL;
1206 //throws css::container::NoSuchElementException, css::lang::WrappedTargetException
1207 Any value( xNameAccess->getByName(sNode) );
1208 sURL = value.get<OUString> ();
1209 localizeWebserviceURI(sURL);
1211 Reference< com::sun::star::system::XSystemShellExecute > xSystemShellExecute(
1212 com::sun::star::system::SystemShellExecute::create(comphelper::getProcessComponentContext()));
1213 //throws css::lang::IllegalArgumentException, css::system::SystemShellExecuteException
1214 xSystemShellExecute->execute( sURL, OUString(), com::sun::star::system::SystemShellExecuteFlags::URIS_ONLY);
1217 catch (const Exception&)
1222 void SfxTemplateManagerDlg::OnTemplateOpen ()
1224 ThumbnailViewItem *pItem = const_cast<ThumbnailViewItem*>(*maSelTemplates.begin());
1226 OpenTemplateHdl(pItem);
1229 void SfxTemplateManagerDlg::OnTemplateEdit ()
1231 uno::Sequence< PropertyValue > aArgs(3);
1232 aArgs[0].Name = "AsTemplate";
1233 aArgs[0].Value <<= sal_False;
1234 aArgs[1].Name = "MacroExecutionMode";
1235 aArgs[1].Value <<= MacroExecMode::USE_CONFIG;
1236 aArgs[2].Name = "UpdateDocMode";
1237 aArgs[2].Value <<= UpdateDocMode::ACCORDING_TO_CONFIG;
1239 uno::Reference< XStorable > xStorable;
1240 std::set<const ThumbnailViewItem*,selection_cmp_fn> aSelTemplates(
1241 maSelTemplates); // Avoids invalid iterators from LoseFocus
1242 std::set<const ThumbnailViewItem*,selection_cmp_fn>::const_iterator pIter;
1243 for (pIter = aSelTemplates.begin(); pIter != aSelTemplates.end(); ++pIter)
1245 const TemplateViewItem *pItem = static_cast<const TemplateViewItem*>(*pIter);
1249 xStorable = uno::Reference< XStorable >(
1250 mxDesktop->loadComponentFromURL(pItem->getPath(),"_default", 0, aArgs ),
1251 uno::UNO_QUERY );
1253 catch( const uno::Exception& )
1258 Close();
1261 void SfxTemplateManagerDlg::OnTemplateProperties ()
1263 const TemplateViewItem *pItem = static_cast<const TemplateViewItem*>(*maSelTemplates.begin());
1265 SfxTemplateInfoDlg aDlg;
1266 aDlg.loadDocument(pItem->getPath());
1267 aDlg.Execute();
1270 void SfxTemplateManagerDlg::OnTemplateDelete ()
1272 // Store selected templates before calling a dialog/QueryBox
1273 // which will result in a deselection of all ThumbnailViewItem.
1274 // Also avoid invalid iterators
1275 std::set<const ThumbnailViewItem*,selection_cmp_fn> aSelTemplates = maSelTemplates;
1277 QueryBox aQueryDlg(this, WB_YES_NO | WB_DEF_YES, SfxResId(STR_QMSG_SEL_TEMPLATE_DELETE).toString());
1279 if ( aQueryDlg.Execute() == RET_NO )
1280 return;
1282 OUString aTemplateList;
1284 if (mpSearchView->IsVisible())
1286 std::set<const ThumbnailViewItem*,selection_cmp_fn>::const_iterator pIter;
1287 for (pIter = aSelTemplates.begin(); pIter != aSelTemplates.end(); ++pIter)
1289 const TemplateSearchViewItem *pItem =
1290 static_cast<const TemplateSearchViewItem*>(*pIter);
1292 if (!mpLocalView->removeTemplate(pItem->mnAssocId,pItem->mnRegionId))
1294 if (aTemplateList.isEmpty())
1295 aTemplateList = pItem->maTitle;
1296 else
1297 aTemplateList = aTemplateList + "\n" + pItem->maTitle;
1299 else
1300 mpSearchView->RemoveItem(pItem->mnId);
1303 else
1305 sal_uInt16 nRegionItemId = mpLocalView->getCurRegionItemId();
1307 std::set<const ThumbnailViewItem*,selection_cmp_fn>::const_iterator pIter;
1308 for (pIter = aSelTemplates.begin(); pIter != aSelTemplates.end(); ++pIter)
1310 if (!mpLocalView->removeTemplate((*pIter)->mnId,nRegionItemId))
1312 if (aTemplateList.isEmpty())
1313 aTemplateList = (*pIter)->maTitle;
1314 else
1315 aTemplateList = aTemplateList + "\n" + (*pIter)->maTitle;
1320 if (!aTemplateList.isEmpty())
1322 OUString aMsg( SfxResId(STR_MSG_ERROR_DELETE_TEMPLATE).toString() );
1323 ErrorBox(this, WB_OK,aMsg.replaceFirst("$1",aTemplateList)).Execute();
1327 void SfxTemplateManagerDlg::OnTemplateAsDefault ()
1329 if (!maSelTemplates.empty())
1331 const TemplateViewItem *pItem = static_cast<const TemplateViewItem*>(*(maSelTemplates.begin()));
1333 OUString aServiceName;
1334 if (lcl_getServiceName(pItem->getPath(),aServiceName))
1336 SfxObjectFactory::SetStandardTemplate(aServiceName,pItem->getPath());
1338 createDefaultTemplateMenu();
1343 void SfxTemplateManagerDlg::OnFolderNew()
1345 InputDialog dlg(SfxResId(STR_INPUT_NEW).toString(),this);
1347 int ret = dlg.Execute();
1349 if (ret)
1351 OUString aName = dlg.getEntryText();
1353 mpCurView->createRegion(aName);
1357 void SfxTemplateManagerDlg::OnFolderDelete()
1359 // Store selected folders before calling a dialog/QueryBox
1360 // which will result in a deselection of all ThumbnailViewItem.
1361 // Also copy to avoid invalidating an iterator
1362 std::set<const ThumbnailViewItem*,selection_cmp_fn> aSelFolders = maSelFolders;
1364 QueryBox aQueryDlg(this, WB_YES_NO | WB_DEF_YES, SfxResId(STR_QMSG_SEL_FOLDER_DELETE).toString());
1366 if ( aQueryDlg.Execute() == RET_NO )
1367 return;
1369 OUString aFolderList;
1371 std::set<const ThumbnailViewItem*,selection_cmp_fn>::const_iterator pIter;
1373 for (pIter = aSelFolders.begin(); pIter != aSelFolders.end(); ++pIter)
1375 if (!mpLocalView->removeRegion((*pIter)->mnId))
1377 if (aFolderList.isEmpty())
1378 aFolderList = (*pIter)->maTitle;
1379 else
1380 aFolderList = aFolderList + "\n" + (*pIter)->maTitle;
1382 ++pIter;
1386 if (!aFolderList.isEmpty())
1388 OUString aMsg( SfxResId(STR_MSG_ERROR_DELETE_FOLDER).toString() );
1389 ErrorBox(this, WB_OK,aMsg.replaceFirst("$1",aFolderList)).Execute();
1393 void SfxTemplateManagerDlg::OnRepositoryDelete()
1395 if(deleteRepository(mpRemoteView->getCurRegionId()))
1397 // switch to local view
1398 switchMainView(true);
1400 createRepositoryMenu();
1404 void SfxTemplateManagerDlg::OnTemplateSaveAs()
1406 // Store selected folders before calling a dialog/QueryBox
1407 // which will result in a deselection of all ThumbnailViewItem
1408 std::set<const ThumbnailViewItem*,selection_cmp_fn> aSelFolders = maSelFolders;
1410 assert(m_xModel.is());
1412 if (!mpLocalView->isNonRootRegionVisible() && maSelFolders.empty())
1414 ErrorBox(this, WB_OK,SfxResId(STR_MSG_ERROR_SELECT_FOLDER).toString()).Execute();
1415 return;
1418 InputDialog aDlg(SfxResId(STR_INPUT_TEMPLATE_NEW).toString(),this);
1420 if (aDlg.Execute())
1422 OUString aName = aDlg.getEntryText();
1424 if (!aName.isEmpty())
1426 OUString aFolderList;
1427 OUString aQMsg(SfxResId(STR_QMSG_TEMPLATE_OVERWRITE).toString());
1428 QueryBox aQueryDlg(this,WB_YES_NO | WB_DEF_YES, OUString());
1430 if (mpLocalView->isNonRootRegionVisible())
1432 sal_uInt16 nRegionItemId = mpLocalView->getRegionId(mpLocalView->getCurRegionId()-1);
1434 if (!mpLocalView->isTemplateNameUnique(nRegionItemId,aName))
1436 aQMsg = aQMsg.replaceFirst("$1",aName);
1437 aQueryDlg.SetMessText(aQMsg.replaceFirst("$2",mpLocalView->getCurRegionName()));
1439 if (aQueryDlg.Execute() == RET_NO)
1440 return;
1443 if (!mpLocalView->saveTemplateAs(nRegionItemId,m_xModel,aName))
1444 aFolderList = mpLocalView->getCurRegionName();
1446 else
1448 std::set<const ThumbnailViewItem*,selection_cmp_fn>::const_iterator pIter;
1449 for (pIter = aSelFolders.begin(); pIter != aSelFolders.end(); ++pIter)
1451 TemplateContainerItem *pItem = (TemplateContainerItem*)(*pIter);
1453 if (!mpLocalView->isTemplateNameUnique(pItem->mnId,aName))
1455 OUString aDQMsg = aQMsg.replaceFirst("$1",aName);
1456 aQueryDlg.SetMessText(aDQMsg.replaceFirst("$2",pItem->maTitle));
1458 if (aQueryDlg.Execute() == RET_NO)
1459 continue;
1462 if (!mpLocalView->saveTemplateAs(pItem,m_xModel,aName))
1464 if (aFolderList.isEmpty())
1465 aFolderList = (*pIter)->maTitle;
1466 else
1467 aFolderList = aFolderList + "\n" + (*pIter)->maTitle;
1472 if (!aFolderList.isEmpty())
1479 void SfxTemplateManagerDlg::createRepositoryMenu()
1481 mpRepositoryMenu->Clear();
1483 mpRepositoryMenu->InsertItem(MNI_REPOSITORY_LOCAL,SfxResId(STR_REPOSITORY_LOCAL).toString());
1485 const std::vector<TemplateRepository*> &rRepos = getRepositories();
1487 for (size_t i = 0, n = rRepos.size(); i < n; ++i)
1488 mpRepositoryMenu->InsertItem(MNI_REPOSITORY_BASE+rRepos[i]->mnId,rRepos[i]->maTitle);
1490 mpRepositoryMenu->InsertSeparator();
1491 mpRepositoryMenu->InsertItem(MNI_REPOSITORY_NEW,SfxResId(STR_REPOSITORY_NEW).toString());
1494 void SfxTemplateManagerDlg::createDefaultTemplateMenu ()
1496 std::vector<OUString> aList = lcl_getAllFactoryURLs();
1498 if (!aList.empty())
1500 mpTemplateDefaultMenu->Clear();
1502 sal_uInt16 nItemId = MNI_ACTION_DEFAULT + 1;
1503 for( std::vector<OUString>::const_iterator i = aList.begin(); i != aList.end(); ++i )
1505 INetURLObject aObj(*i);
1506 OUString aTitle = SvFileInformationManager::GetDescription(aObj);
1507 mpTemplateDefaultMenu->InsertItem(nItemId, aTitle, SvFileInformationManager::GetImage(aObj, false));
1508 mpTemplateDefaultMenu->SetItemCommand(nItemId++, *i);
1511 mpActionMenu->ShowItem(MNI_ACTION_DEFAULT);
1513 else
1514 mpActionMenu->HideItem(MNI_ACTION_DEFAULT);
1517 void SfxTemplateManagerDlg::switchMainView(bool bDisplayLocal)
1519 if (bDisplayLocal)
1521 mpCurView = mpLocalView;
1523 mpViewBar->HideItem(TBI_TEMPLATE_FOLDER_DEL);
1525 // Enable deleting and exporting items from the filesystem
1526 mpTemplateBar->ShowItem(TBI_TEMPLATE_EXPORT);
1527 mpTemplateBar->ShowItem(TBI_TEMPLATE_DELETE);
1529 mpRemoteView->Hide();
1530 mpLocalView->Show();
1532 else
1534 mpCurView = mpRemoteView;
1536 mpViewBar->ShowItem(TBI_TEMPLATE_FOLDER_DEL);
1538 // Disable deleting and exporting items from remote repositories
1539 mpTemplateBar->HideItem(TBI_TEMPLATE_EXPORT);
1540 mpTemplateBar->HideItem(TBI_TEMPLATE_DELETE);
1542 mpLocalView->Hide();
1543 mpRemoteView->Show();
1547 void SfxTemplateManagerDlg::localMoveTo(sal_uInt16 nMenuId)
1549 sal_uInt16 nItemId = 0;
1551 if (nMenuId == MNI_MOVE_NEW)
1553 InputDialog dlg(SfxResId(STR_INPUT_NEW).toString(),this);
1555 int ret = dlg.Execute();
1557 if (ret)
1559 OUString aName = dlg.getEntryText();
1561 if (!aName.isEmpty())
1562 nItemId = mpLocalView->createRegion(aName);
1565 else
1567 nItemId = mpLocalView->getRegionId(nMenuId-MNI_MOVE_FOLDER_BASE);
1570 if (nItemId)
1572 // Move templates to desired folder if for some reason move fails
1573 // try copying them.
1574 if (!mpLocalView->moveTemplates(maSelTemplates,nItemId))
1576 OUString aTemplateList;
1578 std::set<const ThumbnailViewItem*,selection_cmp_fn>::const_iterator pIter;
1579 for (pIter = maSelTemplates.begin(); pIter != maSelTemplates.end(); ++pIter)
1581 if (aTemplateList.isEmpty())
1582 aTemplateList = (*pIter)->maTitle;
1583 else
1584 aTemplateList = aTemplateList + "\n" + (*pIter)->maTitle;
1587 OUString aDst = mpLocalView->getRegionItemName(nItemId);
1588 OUString aMsg(SfxResId(STR_MSG_ERROR_LOCAL_MOVE).toString());
1589 aMsg = aMsg.replaceFirst("$1",aDst);
1590 ErrorBox(this, WB_OK,aMsg.replaceFirst( "$2",aTemplateList)).Execute();
1595 void SfxTemplateManagerDlg::remoteMoveTo(const sal_uInt16 nMenuId)
1597 sal_uInt16 nItemId = 0;
1599 if (nMenuId == MNI_MOVE_NEW)
1601 InputDialog dlg(SfxResId(STR_INPUT_NEW).toString(),this);
1603 int ret = dlg.Execute();
1605 if (ret)
1607 OUString aName = dlg.getEntryText();
1609 if (!aName.isEmpty())
1610 nItemId = mpLocalView->createRegion(aName);
1613 else
1615 nItemId = mpLocalView->getRegionId(nMenuId-MNI_MOVE_FOLDER_BASE);
1618 if (nItemId)
1620 OUString aTemplateList;
1622 std::set<const ThumbnailViewItem*,selection_cmp_fn>::const_iterator aIter;
1623 for (aIter = maSelTemplates.begin(); aIter != maSelTemplates.end(); ++aIter)
1625 const TemplateSearchViewItem *pItem =
1626 static_cast<const TemplateSearchViewItem*>(*aIter);
1628 if(!mpLocalView->copyFrom(nItemId,pItem->maPreview1,pItem->getPath()))
1630 if (aTemplateList.isEmpty())
1631 aTemplateList = pItem->maTitle;
1632 else
1633 aTemplateList = aTemplateList + "\n" + pItem->maTitle;
1637 mpLocalView->Invalidate(INVALIDATE_NOERASE);
1639 if (!aTemplateList.isEmpty())
1641 OUString aMsg(SfxResId(STR_MSG_ERROR_REMOTE_MOVE).toString());
1642 aMsg = aMsg.replaceFirst("$1",mpRemoteView->getCurRegionName());
1643 aMsg = aMsg.replaceFirst("$2",mpLocalView->getRegionItemName(nItemId));
1644 ErrorBox(this,WB_OK,aMsg.replaceFirst("$1",aTemplateList)).Execute();
1649 void SfxTemplateManagerDlg::localSearchMoveTo(sal_uInt16 nMenuId)
1651 sal_uInt16 nItemId = 0;
1653 if (nMenuId == MNI_MOVE_NEW)
1655 InputDialog dlg(SfxResId(STR_INPUT_NEW).toString(),this);
1657 int ret = dlg.Execute();
1659 if (ret)
1661 OUString aName = dlg.getEntryText();
1663 if (!aName.isEmpty())
1664 nItemId = mpLocalView->createRegion(aName);
1667 else
1669 nItemId = mpLocalView->getRegionId(nMenuId-MNI_MOVE_FOLDER_BASE);
1672 if (nItemId)
1674 OUString aTemplateList;
1676 // Move templates to desired folder if for some reason move fails
1677 // try copying them.
1678 std::set<const ThumbnailViewItem*,selection_cmp_fn>::const_iterator aIter;
1679 std::set<const ThumbnailViewItem*,selection_cmp_fn> aSelTemplates = maSelTemplates; //Copy to avoid invalidating an iterator
1681 for (aIter = aSelTemplates.begin(); aIter != aSelTemplates.end(); ++aIter)
1683 const TemplateSearchViewItem *pItem =
1684 static_cast<const TemplateSearchViewItem*>(*aIter);
1686 if(!mpLocalView->moveTemplate(pItem,pItem->mnRegionId,nItemId))
1688 if (aTemplateList.isEmpty())
1689 aTemplateList = (*aIter)->maTitle;
1690 else
1691 aTemplateList = aTemplateList + "\n" + (*aIter)->maTitle;
1695 if (!aTemplateList.isEmpty())
1697 OUString aDst = mpLocalView->getRegionItemName(nItemId);
1698 OUString aMsg(SfxResId(STR_MSG_ERROR_LOCAL_MOVE).toString());
1699 aMsg = aMsg.replaceFirst("$1",aDst);
1700 ErrorBox(this, WB_OK,aMsg.replaceFirst( "$2",aTemplateList)).Execute();
1704 // Deselect all items and update search results
1705 mpSearchView->deselectItems();
1707 SearchUpdateHdl(mpSearchEdit);
1710 void SfxTemplateManagerDlg::loadRepositories()
1712 uno::Reference < uno::XComponentContext > m_context(comphelper::getProcessComponentContext());
1714 // Load from user settings
1715 com::sun::star::uno::Sequence<OUString> aUrls =
1716 officecfg::Office::Common::Misc::TemplateRepositoryUrls::get(m_context);
1718 com::sun::star::uno::Sequence<OUString> aNames =
1719 officecfg::Office::Common::Misc::TemplateRepositoryNames::get(m_context);
1721 for (sal_Int32 i = 0; i < aUrls.getLength() && i < aNames.getLength(); ++i)
1723 TemplateRepository *pItem = new TemplateRepository();
1725 pItem->mnId = i+1;
1726 pItem->maTitle = aNames[i];
1727 pItem->setURL(aUrls[i]);
1729 maRepositories.push_back(pItem);
1733 bool SfxTemplateManagerDlg::insertRepository(const OUString &rName, const OUString &rURL)
1735 for (size_t i = 0, n = maRepositories.size(); i < n; ++i)
1737 if (maRepositories[i]->maTitle == rName)
1738 return false;
1741 TemplateRepository *pItem = new TemplateRepository();
1743 pItem->mnId = maRepositories.size()+1;
1744 pItem->maTitle = rName;
1745 pItem->setURL(rURL);
1747 maRepositories.push_back(pItem);
1749 mbIsSynced = false;
1750 return true;
1753 bool SfxTemplateManagerDlg::deleteRepository(const sal_uInt16 nRepositoryId)
1755 bool bRet = false;
1757 for (size_t i = 0, n = maRepositories.size(); i < n; ++i)
1759 if (maRepositories[i]->mnId == nRepositoryId)
1761 delete maRepositories[i];
1763 maRepositories.erase(maRepositories.begin() + i);
1764 mbIsSynced = false;
1765 bRet = true;
1766 break;
1770 return bRet;
1773 void SfxTemplateManagerDlg::syncRepositories() const
1775 if (!mbIsSynced)
1777 uno::Reference < uno::XComponentContext > pContext(comphelper::getProcessComponentContext());
1778 boost::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create(pContext));
1780 size_t nSize = maRepositories.size();
1781 uno::Sequence<OUString> aUrls(nSize);
1782 uno::Sequence<OUString> aNames(nSize);
1784 for(size_t i = 0; i < nSize; ++i)
1786 aUrls[i] = maRepositories[i]->getURL();
1787 aNames[i] = maRepositories[i]->maTitle;
1790 officecfg::Office::Common::Misc::TemplateRepositoryUrls::set(aUrls, batch, pContext);
1791 officecfg::Office::Common::Misc::TemplateRepositoryNames::set(aNames, batch, pContext);
1792 batch->commit();
1796 static bool lcl_getServiceName ( const OUString &rFileURL, OUString &rName )
1798 bool bRet = false;
1800 if ( !rFileURL.isEmpty() )
1804 uno::Reference< embed::XStorage > xStorage =
1805 comphelper::OStorageHelper::GetStorageFromURL( rFileURL, embed::ElementModes::READ );
1807 sal_uIntPtr nFormat = SotStorage::GetFormatID( xStorage );
1809 const SfxFilter* pFilter = SFX_APP()->GetFilterMatcher().GetFilter4ClipBoardId( nFormat );
1811 if ( pFilter )
1813 rName = pFilter->GetServiceName();
1814 bRet = true;
1817 catch( uno::Exception& )
1821 return bRet;
1824 static std::vector<OUString> lcl_getAllFactoryURLs ()
1826 SvtModuleOptions aModOpt;
1827 std::vector<OUString> aList;
1828 const ::com::sun::star::uno::Sequence<OUString> &aServiceNames = aModOpt.GetAllServiceNames();
1830 for( sal_Int32 i=0, nCount = aServiceNames.getLength(); i < nCount; ++i )
1832 if ( ! SfxObjectFactory::GetStandardTemplate( aServiceNames[i] ).isEmpty() )
1834 SvtModuleOptions::EFactory eFac = SvtModuleOptions::E_WRITER;
1835 SvtModuleOptions::ClassifyFactoryByName( aServiceNames[i], eFac );
1836 aList.push_back(aModOpt.GetFactoryEmptyDocumentURL(eFac));
1840 return aList;
1843 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */