/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * Copyright 2012 LibreOffice contributors. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "templatedlg.hxx" #include "inputdlg.hxx" #include "templatesearchview.hxx" #include "templatesearchviewitem.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "doc.hrc" #include "templatedlg.hrc" #define PADDING_DLG_BORDER 10 using namespace ::com::sun::star; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::embed; using namespace ::com::sun::star::frame; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::ui::dialogs; static bool lcl_getServiceName (const OUString &rFileURL, OUString &rName ); static std::vector lcl_getAllFactoryURLs (); // Sort by name in ascending order class SortView_Name { public: bool operator() (const ThumbnailViewItem *pItem1, const ThumbnailViewItem *pItem2) { return (pItem1->maTitle.compareTo(pItem2->maTitle) < 0); } }; class SearchView_Keyword { public: SearchView_Keyword (const OUString &rKeyword) : maKeyword(rKeyword) {} bool operator() (const TemplateItemProperties &rItem) { return rItem.aName.matchIgnoreAsciiCase(maKeyword); } private: OUString maKeyword; }; SfxTemplateManagerDlg::SfxTemplateManagerDlg (Window *parent) : ModelessDialog(parent, SfxResId(DLG_TEMPLATE_MANAGER)), maTabControl(this,SfxResId(TAB_CONTROL)), mpToolbars( new Control(&maTabControl,SfxResId(TOOLBARS))), mpSearchEdit(new Edit(this,WB_HIDE | WB_BORDER)), mpViewBar( new ToolBox(mpToolbars, SfxResId(TBX_ACTION_VIEW))), mpActionBar( new ToolBox(mpToolbars, SfxResId(TBX_ACTION_ACTION))), mpTemplateBar( new ToolBox(mpToolbars, SfxResId(TBX_ACTION_TEMPLATES))), mpSearchView(new TemplateSearchView(this)), maView(new TemplateLocalView(this,SfxResId(TEMPLATE_VIEW))), mpOnlineView(new TemplateRemoteView(this, WB_VSCROLL,false)), mbIsSaveMode(false), mxDesktop( Desktop::create(comphelper::getProcessComponentContext()) ), mbIsSynced(false), maRepositories() { // Create popup menus mpActionMenu = new PopupMenu; mpActionMenu->InsertItem(MNI_ACTION_SORT_NAME,SfxResId(STR_ACTION_SORT_NAME).toString(),SfxResId(IMG_ACTION_SORT)); mpActionMenu->InsertItem(MNI_ACTION_REFRESH,SfxResId(STR_ACTION_REFRESH).toString(),SfxResId(IMG_ACTION_REFRESH)); mpActionMenu->InsertItem(MNI_ACTION_DEFAULT,SfxResId(STR_ACTION_DEFAULT).toString()); mpActionMenu->SetSelectHdl(LINK(this,SfxTemplateManagerDlg,MenuSelectHdl)); mpRepositoryMenu = new PopupMenu; mpRepositoryMenu->SetSelectHdl(LINK(this,SfxTemplateManagerDlg,RepositoryMenuSelectHdl)); mpTemplateDefaultMenu = new PopupMenu; mpTemplateDefaultMenu->SetSelectHdl(LINK(this,SfxTemplateManagerDlg,DefaultTemplateMenuSelectHdl)); mpActionMenu->SetPopupMenu(MNI_ACTION_DEFAULT,mpTemplateDefaultMenu); // Set toolbox styles mpViewBar->SetButtonType(BUTTON_SYMBOLTEXT); mpTemplateBar->SetButtonType(BUTTON_SYMBOLTEXT); // Set toolbox button bits mpViewBar->SetItemBits(TBI_TEMPLATE_REPOSITORY, TIB_DROPDOWNONLY); mpActionBar->SetItemBits(TBI_TEMPLATE_ACTION, TIB_DROPDOWNONLY); mpTemplateBar->SetItemBits(TBI_TEMPLATE_MOVE,TIB_DROPDOWNONLY); // Set toolbox handlers mpViewBar->SetClickHdl(LINK(this,SfxTemplateManagerDlg,TBXViewHdl)); mpViewBar->SetDropdownClickHdl(LINK(this,SfxTemplateManagerDlg,TBXDropdownHdl)); mpActionBar->SetClickHdl(LINK(this,SfxTemplateManagerDlg,TBXActionHdl)); mpActionBar->SetDropdownClickHdl(LINK(this,SfxTemplateManagerDlg,TBXDropdownHdl)); mpTemplateBar->SetClickHdl(LINK(this,SfxTemplateManagerDlg,TBXTemplateHdl)); mpTemplateBar->SetDropdownClickHdl(LINK(this,SfxTemplateManagerDlg,TBXDropdownHdl)); mpSearchEdit->SetUpdateDataHdl(LINK(this,SfxTemplateManagerDlg,SearchUpdateHdl)); mpSearchEdit->EnableUpdateData(); maView->SetStyle(WB_VSCROLL); maView->setItemMaxTextLength(TEMPLATE_ITEM_MAX_TEXT_LENGTH); maView->setItemDimensions(TEMPLATE_ITEM_MAX_WIDTH,TEMPLATE_ITEM_THUMBNAIL_MAX_HEIGHT, TEMPLATE_ITEM_MAX_HEIGHT-TEMPLATE_ITEM_THUMBNAIL_MAX_HEIGHT, TEMPLATE_ITEM_PADDING); maView->setItemStateHdl(LINK(this,SfxTemplateManagerDlg,TVFolderStateHdl)); maView->setOverlayItemStateHdl(LINK(this,SfxTemplateManagerDlg,TVTemplateStateHdl)); maView->setOpenHdl(LINK(this,SfxTemplateManagerDlg,OpenTemplateHdl)); maView->setOverlayCloseHdl(LINK(this,SfxTemplateManagerDlg,CloseOverlayHdl)); // Set online view position and dimensions mpOnlineView->setItemMaxTextLength(TEMPLATE_ITEM_MAX_TEXT_LENGTH); mpOnlineView->setItemDimensions(TEMPLATE_ITEM_MAX_WIDTH,TEMPLATE_ITEM_THUMBNAIL_MAX_HEIGHT, TEMPLATE_ITEM_MAX_HEIGHT-TEMPLATE_ITEM_THUMBNAIL_MAX_HEIGHT, TEMPLATE_ITEM_PADDING); mpOnlineView->setOverlayItemStateHdl(LINK(this,SfxTemplateManagerDlg,TVTemplateStateHdl)); mpOnlineView->setOpenHdl(LINK(this,SfxTemplateManagerDlg,OpenTemplateHdl)); mpOnlineView->setOverlayCloseHdl(LINK(this,SfxTemplateManagerDlg,CloseOverlayHdl)); mpSearchView->setItemMaxTextLength(TEMPLATE_ITEM_MAX_TEXT_LENGTH); mpSearchView->setItemDimensions(TEMPLATE_ITEM_MAX_WIDTH,TEMPLATE_ITEM_THUMBNAIL_MAX_HEIGHT, TEMPLATE_ITEM_MAX_HEIGHT-TEMPLATE_ITEM_THUMBNAIL_MAX_HEIGHT, TEMPLATE_ITEM_PADDING); mpSearchView->setItemStateHdl(LINK(this,SfxTemplateManagerDlg,TVTemplateStateHdl)); maTabControl.SetActivatePageHdl(LINK(this,SfxTemplateManagerDlg,ActivatePageHdl)); SvtMiscOptions aMiscOptions; if ( !aMiscOptions.IsExperimentalMode() ) { sal_uInt16 nPos = mpViewBar->GetItemId(TBI_TEMPLATE_REPOSITORY); mpViewBar->RemoveItem(nPos); } mpViewBar->Show(); mpActionBar->Show(); switchMainView(true); loadRepositories(); createRepositoryMenu(); createDefaultTemplateMenu(); maView->Populate(); maView->Show(); mpCurView->filterTemplatesByApp(FILTER_APP_WRITER); FreeResource(); } SfxTemplateManagerDlg::~SfxTemplateManagerDlg () { // Synchronize the config before deleting it syncRepositories(); for (size_t i = 0, n = maRepositories.size(); i < n; ++i) delete maRepositories[i]; delete mpSearchEdit; delete mpViewBar; delete mpActionBar; delete mpTemplateBar; delete mpSearchView; delete maView; delete mpOnlineView; delete mpTemplateDefaultMenu; delete mpActionMenu; delete mpRepositoryMenu; delete mpToolbars; } void SfxTemplateManagerDlg::setSaveMode(bool bMode) { mbIsSaveMode = bMode; maTabControl.Clear(); mpCurView->filterTemplatesByApp(FILTER_APP_NONE); if (bMode) { mpViewBar->ShowItem(TBI_TEMPLATE_SAVE); mpViewBar->HideItem(TBI_TEMPLATE_IMPORT); mpViewBar->HideItem(TBI_TEMPLATE_REPOSITORY); } else { mpViewBar->HideItem(TBI_TEMPLATE_SAVE); mpViewBar->ShowItem(TBI_TEMPLATE_IMPORT); mpViewBar->ShowItem(TBI_TEMPLATE_REPOSITORY); } } void SfxTemplateManagerDlg::setDocumentModel(const uno::Reference &rModel) { m_xModel = rModel; } IMPL_LINK_NOARG(SfxTemplateManagerDlg,ActivatePageHdl) { FILTER_APPLICATION eFilter = FILTER_APP_NONE; switch (maTabControl.GetCurPageId()) { case FILTER_DOCS: eFilter = FILTER_APP_WRITER; break; case FILTER_PRESENTATIONS: eFilter = FILTER_APP_IMPRESS; break; case FILTER_SHEETS: eFilter = FILTER_APP_CALC; break; case FILTER_DRAWS: eFilter = FILTER_APP_DRAW; break; } mpCurView->filterTemplatesByApp(eFilter); return 0; } void SfxTemplateManagerDlg::MouseButtonDown( const MouseEvent& rMEvt ) { if (!maView->GetActiveClipRegion().IsInside(rMEvt.GetPosPixel()) && maView->isOverlayVisible()) { maSelTemplates.clear(); mpTemplateBar->Hide(); mpViewBar->Show(); maView->showOverlay(false); } } void SfxTemplateManagerDlg::Resize() { Size aWinSize = GetSizePixel(); // Fit the tab page control and the toolbars Size aTabSize = maTabControl.GetSizePixel(); aTabSize.setWidth(aWinSize.getWidth()); maTabControl.SetSizePixel(aTabSize); Size aTabPageSize = maTabControl.GetTabPageSizePixel(); Point aToolbarsPos(0, aTabSize.getHeight() - aTabPageSize.getHeight()); mpToolbars->SetPosPixel(aToolbarsPos); aTabPageSize.setHeight(mpToolbars->GetSizePixel().getHeight() + 3); maTabControl.SetTabPageSizePixel(aTabPageSize); Size aToolbarsSize = mpToolbars->GetSizePixel(); aToolbarsSize.setWidth(aWinSize.getWidth()); mpToolbars->SetSizePixel(aToolbarsSize); // Calculate toolboxes size and positions Size aViewSize = mpViewBar->CalcMinimumWindowSizePixel(); Size aActionSize = mpActionBar->CalcMinimumWindowSizePixel(); Size aTemplateSize = mpTemplateBar->CalcMinimumWindowSizePixel(); aActionSize.setWidth(3*aActionSize.getWidth()); aViewSize.setWidth(aWinSize.getWidth()-aActionSize.getWidth()-mpViewBar->GetPosPixel().X()); aTemplateSize.setWidth(aWinSize.getWidth()); Point aActionPos = mpActionBar->GetPosPixel(); aActionPos.setX(aWinSize.getWidth() - aActionSize.getWidth()); mpViewBar->SetSizePixel(aViewSize); mpActionBar->SetPosSizePixel(aActionPos,aActionSize); mpTemplateBar->SetSizePixel(aTemplateSize); // Set view position below toolbox Point aViewPos = maView->GetPosPixel(); aViewPos.setY(maTabControl.GetPosPixel().Y() + maTabControl.GetSizePixel().getHeight()); aViewPos.setX(0); Size aThumbSize(aWinSize.getWidth(), aWinSize.getHeight() - aViewPos.getY()); maView->SetPosSizePixel(aViewPos, aThumbSize); if (aWinSize.getHeight() < aViewPos.getY() + aThumbSize.getHeight() + PADDING_DLG_BORDER) aWinSize.setHeight(aViewPos.getY() + aThumbSize.getHeight() + PADDING_DLG_BORDER); // Set search box position and size Size aSearchSize = mpSearchEdit->CalcMinimumSize(); aSearchSize.setWidth(aWinSize.getWidth() - 2*PADDING_DLG_BORDER); mpSearchEdit->SetSizePixel(aSearchSize); mpSearchEdit->SetPosPixel(Point(PADDING_DLG_BORDER,aViewPos.Y())); maView->SetSizePixel(aThumbSize); mpOnlineView->SetPosSizePixel(aViewPos,aThumbSize); mpSearchView->SetSizePixel(aThumbSize); mpCurView->Resize(); ModelessDialog::Resize(); } IMPL_LINK_NOARG(SfxTemplateManagerDlg, CloseOverlayHdl) { maSelTemplates.clear(); mpTemplateBar->Hide(); mpViewBar->Show(); mpActionBar->Show(); if (mpCurView == maView) mpCurView->showOverlay(false); else switchMainView(true); return 0; } IMPL_LINK_NOARG(SfxTemplateManagerDlg,TBXViewHdl) { switch(mpViewBar->GetCurItemId()) { case TBI_TEMPLATE_IMPORT: OnTemplateImport(); break; case TBI_TEMPLATE_FOLDER_DEL: if (mpCurView == maView) OnFolderDelete(); else OnRepositoryDelete(); break; case TBI_TEMPLATE_SAVE: OnTemplateSaveAs(); break; default: break; } return 0; } IMPL_LINK_NOARG(SfxTemplateManagerDlg,TBXActionHdl) { switch(mpActionBar->GetCurItemId()) { case TBI_TEMPLATE_SEARCH: OnTemplateSearch(); break; default: break; } return 0; } IMPL_LINK_NOARG(SfxTemplateManagerDlg,TBXTemplateHdl) { switch(mpTemplateBar->GetCurItemId()) { case TBI_TEMPLATE_EDIT: OnTemplateEdit(); break; case TBI_TEMPLATE_PROPERTIES: OnTemplateProperties(); break; case TBI_TEMPLATE_DELETE: OnTemplateDelete(); break; case TBI_TEMPLATE_DEFAULT: OnTemplateAsDefault(); break; case TBI_TEMPLATE_EXPORT: OnTemplateExport(); break; default: break; } return 0; } IMPL_LINK(SfxTemplateManagerDlg, TBXDropdownHdl, ToolBox*, pBox) { const sal_uInt16 nCurItemId = pBox->GetCurItemId(); switch(nCurItemId) { case TBI_TEMPLATE_ACTION: pBox->SetItemDown( nCurItemId, true ); mpActionMenu->Execute(pBox,pBox->GetItemRect(TBI_TEMPLATE_ACTION), POPUPMENU_EXECUTE_DOWN); pBox->SetItemDown( nCurItemId, false ); pBox->EndSelection(); pBox->Invalidate(); break; case TBI_TEMPLATE_MOVE: { pBox->SetItemDown( nCurItemId, true ); std::vector aNames = maView->getFolderNames(); PopupMenu *pMoveMenu = new PopupMenu; pMoveMenu->SetSelectHdl(LINK(this,SfxTemplateManagerDlg,MoveMenuSelectHdl)); if (!aNames.empty()) { for (size_t i = 0, n = aNames.size(); i < n; ++i) pMoveMenu->InsertItem(MNI_MOVE_FOLDER_BASE+i,aNames[i]); } pMoveMenu->InsertSeparator(); pMoveMenu->InsertItem(MNI_MOVE_NEW,SfxResId(STR_MOVE_NEW).toString()); pMoveMenu->Execute(pBox,pBox->GetItemRect(TBI_TEMPLATE_MOVE), POPUPMENU_EXECUTE_DOWN); delete pMoveMenu; pBox->SetItemDown( nCurItemId, false ); pBox->EndSelection(); pBox->Invalidate(); break; } case TBI_TEMPLATE_REPOSITORY: pBox->SetItemDown( nCurItemId, true ); mpRepositoryMenu->Execute(pBox,pBox->GetItemRect(TBI_TEMPLATE_REPOSITORY), POPUPMENU_EXECUTE_DOWN); pBox->SetItemDown( nCurItemId, false ); pBox->EndSelection(); pBox->Invalidate(); break; default: break; } return 0; } IMPL_LINK(SfxTemplateManagerDlg, TVFolderStateHdl, const ThumbnailViewItem*, pItem) { if (pItem->isSelected()) { if (maSelFolders.empty() && !mbIsSaveMode) { mpViewBar->ShowItem(TBI_TEMPLATE_IMPORT); mpViewBar->ShowItem(TBI_TEMPLATE_FOLDER_DEL); } maSelFolders.insert(pItem); } else { maSelFolders.erase(pItem); if (maSelFolders.empty() && !mbIsSaveMode) { mpViewBar->HideItem(TBI_TEMPLATE_IMPORT); mpViewBar->HideItem(TBI_TEMPLATE_FOLDER_DEL); } } return 0; } IMPL_LINK(SfxTemplateManagerDlg, TVTemplateStateHdl, const ThumbnailViewItem*, pItem) { bool bInSelection = maSelTemplates.find(pItem) != maSelTemplates.end(); if (pItem->isSelected()) { if (!mbIsSaveMode) { if (maSelTemplates.empty()) { mpViewBar->Show(false); mpActionBar->Show(false); mpTemplateBar->Show(); } else if (maSelTemplates.size() != 1 || !bInSelection) { mpTemplateBar->HideItem(TBI_TEMPLATE_EDIT); mpTemplateBar->HideItem(TBI_TEMPLATE_PROPERTIES); mpTemplateBar->HideItem(TBI_TEMPLATE_DEFAULT); } } if (!bInSelection) maSelTemplates.insert(pItem); } else { if (bInSelection) { maSelTemplates.erase(pItem); if (!mbIsSaveMode) { if (maSelTemplates.empty()) { mpTemplateBar->Show(false); mpViewBar->Show(); mpActionBar->Show(); } else if (maSelTemplates.size() == 1) { mpTemplateBar->ShowItem(TBI_TEMPLATE_EDIT); mpTemplateBar->ShowItem(TBI_TEMPLATE_PROPERTIES); mpTemplateBar->ShowItem(TBI_TEMPLATE_DEFAULT); } } } } return 0; } IMPL_LINK(SfxTemplateManagerDlg, MenuSelectHdl, Menu*, pMenu) { sal_uInt16 nMenuId = pMenu->GetCurItemId(); switch(nMenuId) { case MNI_ACTION_SORT_NAME: if (maView->isOverlayVisible()) maView->sortOverlayItems(SortView_Name()); else maView->sortItems(SortView_Name()); break; case MNI_ACTION_REFRESH: mpCurView->reload(); break; default: break; } return 0; } IMPL_LINK(SfxTemplateManagerDlg, MoveMenuSelectHdl, Menu*, pMenu) { sal_uInt16 nMenuId = pMenu->GetCurItemId(); if (mpSearchView->IsVisible()) { // Check if we are searching the local or remote templates if (mpCurView == maView) localSearchMoveTo(nMenuId); } else { // Check if we are displaying the local or remote templates if (mpCurView == maView) localMoveTo(nMenuId); else remoteMoveTo(nMenuId); } return 0; } IMPL_LINK(SfxTemplateManagerDlg, RepositoryMenuSelectHdl, Menu*, pMenu) { sal_uInt16 nMenuId = pMenu->GetCurItemId(); if (nMenuId == MNI_REPOSITORY_LOCAL) { switchMainView(true); } else if (nMenuId == MNI_REPOSITORY_NEW) { PlaceEditDialog dlg(this); if (dlg.Execute()) { boost::shared_ptr pPlace = dlg.GetPlace(); if (insertRepository(pPlace->GetName(),pPlace->GetUrl())) { // update repository list menu. createRepositoryMenu(); } else { OUString aMsg(SfxResId(STR_MSG_ERROR_REPOSITORY_NAME).toString()); aMsg = aMsg.replaceFirst("$1",pPlace->GetName()); ErrorBox(this,WB_OK,aMsg).Execute(); } } } else { sal_uInt16 nRepoId = nMenuId - MNI_REPOSITORY_BASE; TemplateRepository *pRepository = NULL; for (size_t i = 0, n = maRepositories.size(); i < n; ++i) { if (maRepositories[i]->mnId == nRepoId) { pRepository = maRepositories[i]; break; } } if (mpOnlineView->loadRepository(pRepository,false)) { switchMainView(false); mpOnlineView->showOverlay(true); } } return 0; } IMPL_LINK(SfxTemplateManagerDlg, DefaultTemplateMenuSelectHdl, Menu*, pMenu) { sal_uInt16 nId = pMenu->GetCurItemId(); OUString aServiceName = SfxObjectShell::GetServiceNameFromFactory( mpTemplateDefaultMenu->GetItemCommand(nId)); SfxObjectFactory::SetStandardTemplate( aServiceName, OUString() ); createDefaultTemplateMenu(); return 0; } IMPL_LINK(SfxTemplateManagerDlg, OpenTemplateHdl, ThumbnailViewItem*, pItem) { if (!mbIsSaveMode) { uno::Sequence< PropertyValue > aArgs(1); aArgs[0].Name = "AsTemplate"; aArgs[0].Value <<= sal_True; TemplateViewItem *pTemplateItem = static_cast(pItem); try { mxDesktop->loadComponentFromURL(pTemplateItem->getPath(),"_default", 0, aArgs ); } catch( const uno::Exception& ) { } Close(); } return 0; } IMPL_LINK_NOARG(SfxTemplateManagerDlg, SearchUpdateHdl) { // if the search view is hidden, hide the folder view and display search one if (!mpCurView->isOverlayVisible() && !mpSearchView->IsVisible()) { mpSearchView->Clear(); mpSearchView->Show(); mpCurView->Hide(); } OUString aKeyword = mpSearchEdit->GetText(); if (!aKeyword.isEmpty()) { if (mpCurView->isOverlayVisible()) { mpCurView->filterTemplatesByKeyword(aKeyword); } else { mpSearchView->Clear(); std::vector aItems = maView->getFilteredItems(SearchView_Keyword(aKeyword)); size_t nCounter = 0; for (size_t i = 0; i < aItems.size(); ++i) { TemplateItemProperties *pItem = &aItems[i]; mpSearchView->AppendItem(++nCounter,pItem->nRegionId, pItem->nId-1, pItem->aName, maView->GetItemText(pItem->nRegionId+1), pItem->aPath, pItem->aThumbnail); } mpSearchView->Invalidate(); } } else { if (mpCurView->isOverlayVisible()) { mpCurView->filterTemplatesByApp(FILTER_APP_NONE); } else { mpSearchView->Hide(); mpCurView->Show(); } } return 0; } void SfxTemplateManagerDlg::OnTemplateImport () { sal_Int16 nDialogType = com::sun::star::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE; sfx2::FileDialogHelper aFileDlg(nDialogType, SFXWB_MULTISELECTION); // add "All" filter aFileDlg.AddFilter( String(SfxResId( STR_SFX_FILTERNAME_ALL) ), OUString(FILEDIALOG_FILTER_ALL) ); // add template filter OUString sFilterExt; OUString sFilterName( SfxResId( STR_TEMPLATE_FILTER ).toString() ); // add filters of modules which are installed SvtModuleOptions aModuleOpt; if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) ) sFilterExt += "*.ott;*.stw;*.oth"; if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) ) { if ( !sFilterExt.isEmpty() ) sFilterExt += ";"; sFilterExt += "*.ots;*.stc"; } if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) ) { if ( !sFilterExt.isEmpty() ) sFilterExt += ";"; sFilterExt += "*.otp;*.sti"; } if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) ) { if ( !sFilterExt.isEmpty() ) sFilterExt += ";"; sFilterExt += "*.otg;*.std"; } if ( !sFilterExt.isEmpty() ) sFilterExt += ";"; sFilterExt += "*.vor"; sFilterName += " ("; sFilterName += sFilterExt; sFilterName += ")"; aFileDlg.AddFilter( sFilterName, sFilterExt ); aFileDlg.SetCurrentFilter( sFilterName ); ErrCode nCode = aFileDlg.Execute(); if ( nCode == ERRCODE_NONE ) { com::sun::star::uno::Sequence aFiles = aFileDlg.GetSelectedFiles(); if (aFiles.hasElements()) { std::set::const_iterator pIter; for (pIter = maSelFolders.begin(); pIter != maSelFolders.end(); ++pIter) { OUString aTemplateList; TemplateContainerItem *pFolder = (TemplateContainerItem*)(*pIter); for (size_t i = 0, n = aFiles.getLength(); i < n; ++i) { if(!maView->copyFrom(pFolder,aFiles[i])) { if (aTemplateList.isEmpty()) aTemplateList = aFiles[i]; else aTemplateList = aTemplateList + "\n" + aFiles[i]; } } if (!aTemplateList.isEmpty()) { OUString aMsg(SfxResId(STR_MSG_ERROR_IMPORT).toString()); aMsg = aMsg.replaceFirst("$1",pFolder->maTitle); ErrorBox(this,WB_OK,aMsg.replaceFirst("$2",aTemplateList)); } } maView->Invalidate(INVALIDATE_NOERASE); } } } void SfxTemplateManagerDlg::OnTemplateExport() { uno::Reference xContext(comphelper::getProcessComponentContext()); uno::Reference xFolderPicker = FolderPicker::create(xContext); xFolderPicker->setDisplayDirectory(SvtPathOptions().GetWorkPath()); sal_Int16 nResult = xFolderPicker->execute(); if( nResult == ExecutableDialogResults::OK ) { OUString aTemplateList; INetURLObject aPathObj(xFolderPicker->getDirectory()); aPathObj.setFinalSlash(); if (mpSearchView->IsVisible()) { sal_uInt16 i = 1; std::set::const_iterator pIter = maSelTemplates.begin(); for (pIter = maSelTemplates.begin(); pIter != maSelTemplates.end(); ++pIter, ++i) { const TemplateSearchViewItem *pItem = static_cast(*pIter); INetURLObject aItemPath(pItem->getPath()); if ( 1 == i ) aPathObj.Append(aItemPath.getName()); else aPathObj.setName(aItemPath.getName()); OUString aPath = aPathObj.GetMainURL( INetURLObject::NO_DECODE ); if (!maView->exportTo(pItem->mnIdx+1,pItem->mnRegionId+1,aPath)) { if (aTemplateList.isEmpty()) aTemplateList = pItem->maTitle; else aTemplateList = aTemplateList + "\n" + pItem->maTitle; } } mpSearchView->deselectItems(); } else { // export templates from the current open overlay sal_uInt16 i = 1; sal_uInt16 nRegionItemId = maView->getOverlayRegionId() + 1; std::set::const_iterator pIter = maSelTemplates.begin(); for (pIter = maSelTemplates.begin(); pIter != maSelTemplates.end(); ++pIter, ++i) { const TemplateViewItem *pItem = static_cast(*pIter); INetURLObject aItemPath(pItem->getPath()); if ( 1 == i ) aPathObj.Append(aItemPath.getName()); else aPathObj.setName(aItemPath.getName()); OUString aPath = aPathObj.GetMainURL( INetURLObject::NO_DECODE ); if (!maView->exportTo(pItem->mnId,nRegionItemId,aPath)) { if (aTemplateList.isEmpty()) aTemplateList = pItem->maTitle; else aTemplateList = aTemplateList + "\n" + pItem->maTitle; } } maView->deselectOverlayItems(); } if (!aTemplateList.isEmpty()) { OUString aText( SfxResId(STR_MSG_ERROR_EXPORT).toString() ); ErrorBox(this, WB_OK,aText.replaceFirst("$1",aTemplateList)).Execute(); } } } void SfxTemplateManagerDlg::OnTemplateSearch () { Point aPos = maView->GetPosPixel(); bool bVisible = mpSearchEdit->IsVisible(); Size aWinSize = GetSizePixel(); long nEditHeight = mpSearchEdit->GetSizePixel().getHeight(); if (bVisible) { aWinSize.setHeight(aWinSize.getHeight() - nEditHeight ); aPos.setY(aPos.getY() - nEditHeight ); mpActionBar->SetItemState(TBI_TEMPLATE_SEARCH,STATE_NOCHECK); } else { aWinSize.setHeight(aWinSize.getHeight() + nEditHeight ); aPos.setY(aPos.getY() + nEditHeight ); mpActionBar->SetItemState(TBI_TEMPLATE_SEARCH,STATE_CHECK); } // SetSizePixel(aWinSize); maView->SetPosPixel(aPos); mpOnlineView->SetPosPixel(aPos); mpSearchView->SetPosPixel(aPos); // Hide search view if (bVisible) { mpSearchView->Hide(); mpCurView->Show(); } mpSearchEdit->Show(!bVisible); mpSearchEdit->SetText(OUString()); if (!bVisible) mpSearchEdit->GrabFocus(); // display all templates if we hide the search bar if (bVisible && mpCurView->isOverlayVisible()) mpCurView->filterTemplatesByApp(FILTER_APP_NONE); } void SfxTemplateManagerDlg::OnTemplateEdit () { uno::Sequence< PropertyValue > aArgs(1); aArgs[0].Name = "AsTemplate"; aArgs[0].Value <<= sal_False; uno::Reference< XStorable > xStorable; std::set::const_iterator pIter; for (pIter = maSelTemplates.begin(); pIter != maSelTemplates.end(); ++pIter) { const TemplateViewItem *pItem = static_cast(*pIter); try { xStorable = uno::Reference< XStorable >( mxDesktop->loadComponentFromURL(pItem->getPath(),"_default", 0, aArgs ), uno::UNO_QUERY ); } catch( const uno::Exception& ) { } } Close(); } void SfxTemplateManagerDlg::OnTemplateProperties () { const TemplateViewItem *pItem = static_cast(*maSelTemplates.begin()); SfxTemplateInfoDlg aDlg; aDlg.loadDocument(pItem->getPath()); aDlg.Execute(); } void SfxTemplateManagerDlg::OnTemplateDelete () { OUString aTemplateList; if (mpSearchView->IsVisible()) { std::set::const_iterator pIter; for (pIter = maSelTemplates.begin(); pIter != maSelTemplates.end();) { const TemplateSearchViewItem *pItem = static_cast(*pIter); sal_uInt16 nItemId = pItem->mnIdx + 1; sal_uInt16 nItemRegionId = pItem->mnRegionId + 1; if (maView->removeTemplate(nItemId,nItemRegionId)) maSelTemplates.erase(pIter++); else { if (aTemplateList.isEmpty()) aTemplateList = pItem->maTitle; else aTemplateList = aTemplateList + "\n" + pItem->maTitle; ++pIter; } } // Update search results if (maSelTemplates.empty()) { mpTemplateBar->Show(false); mpViewBar->Show(); mpActionBar->Show(); } SearchUpdateHdl(mpSearchEdit); } else { std::set::const_iterator pIter; for (pIter = maSelTemplates.begin(); pIter != maSelTemplates.end();) { if (maView->removeTemplate((*pIter)->mnId,maView->getOverlayRegionId()+1)) maSelTemplates.erase(pIter++); else { if (aTemplateList.isEmpty()) aTemplateList = (*pIter)->maTitle; else aTemplateList = aTemplateList + "\n" + (*pIter)->maTitle; ++pIter; } } if (maSelTemplates.empty()) { mpTemplateBar->SetItemDown(TBI_TEMPLATE_DELETE,false); mpTemplateBar->Show(false); mpViewBar->Show(); mpActionBar->Show(); } } if (!aTemplateList.isEmpty()) { OUString aMsg( SfxResId(STR_MSG_ERROR_DELETE_TEMPLATE).toString() ); ErrorBox(this, WB_OK,aMsg.replaceFirst("$1",aTemplateList)).Execute(); } } void SfxTemplateManagerDlg::OnTemplateAsDefault () { if (!maSelTemplates.empty()) { const TemplateViewItem *pItem = static_cast(*(maSelTemplates.begin())); OUString aServiceName; if (lcl_getServiceName(pItem->getPath(),aServiceName)) { SfxObjectFactory::SetStandardTemplate(aServiceName,pItem->getPath()); createDefaultTemplateMenu(); } } } void SfxTemplateManagerDlg::OnFolderDelete() { QueryBox aQueryDlg(this, WB_YES_NO | WB_DEF_YES, SfxResId(STR_QMSG_SEL_FOLDER_DELETE).toString()); if ( aQueryDlg.Execute() == RET_NO ) return; OUString aFolderList; std::set::const_iterator pIter; for (pIter = maSelFolders.begin(); pIter != maSelFolders.end();) { if (maView->removeRegion((*pIter)->mnId)) maSelFolders.erase(pIter++); else { if (aFolderList.isEmpty()) aFolderList = (*pIter)->maTitle; else aFolderList = aFolderList + "\n" + (*pIter)->maTitle; ++pIter; } } if (maSelFolders.empty()) { mpViewBar->HideItem(TBI_TEMPLATE_IMPORT); mpViewBar->HideItem(TBI_TEMPLATE_FOLDER_DEL); } if (!aFolderList.isEmpty()) { OUString aMsg( SfxResId(STR_MSG_ERROR_DELETE_FOLDER).toString() ); ErrorBox(this, WB_OK,aMsg.replaceFirst("$1",aFolderList)).Execute(); } } void SfxTemplateManagerDlg::OnRepositoryDelete() { if(deleteRepository(mpOnlineView->getOverlayRegionId())) { // close overlay and switch to local view switchMainView(true); createRepositoryMenu(); } } void SfxTemplateManagerDlg::OnTemplateSaveAs() { assert(m_xModel.is()); if (!maView->isOverlayVisible() && maSelFolders.empty()) { ErrorBox(this, WB_OK,SfxResId(STR_MSG_ERROR_SELECT_FOLDER).toString()).Execute(); return; } InputDialog aDlg(SfxResId(STR_INPUT_TEMPLATE_NEW).toString(),this); if (aDlg.Execute()) { OUString aName = aDlg.getEntryText(); if (!aName.isEmpty()) { OUString aFolderList; OUString aQMsg(SfxResId(STR_QMSG_TEMPLATE_OVERWRITE).toString()); QueryBox aQueryDlg(this,WB_YES_NO | WB_DEF_YES, OUString()); if (maView->isOverlayVisible()) { sal_uInt16 nRegionItemId = maView->getOverlayRegionId()+1; if (!maView->isTemplateNameUnique(nRegionItemId,aName)) { aQMsg = aQMsg.replaceFirst("$1",aName); aQueryDlg.SetMessText(aQMsg.replaceFirst("$2",maView->getOverlayName())); if (aQueryDlg.Execute() == RET_NO) return; } if (!maView->saveTemplateAs(nRegionItemId,m_xModel,aName)) aFolderList = maView->getOverlayName(); } else { std::set::const_iterator pIter; for (pIter = maSelFolders.begin(); pIter != maSelFolders.end(); ++pIter) { TemplateContainerItem *pItem = (TemplateContainerItem*)(*pIter); if (!maView->isTemplateNameUnique(pItem->mnId,aName)) { OUString aDQMsg = aQMsg.replaceFirst("$1",aName); aQueryDlg.SetMessText(aDQMsg.replaceFirst("$2",pItem->maTitle)); if (aQueryDlg.Execute() == RET_NO) continue; } if (!maView->saveTemplateAs(pItem,m_xModel,aName)) { if (aFolderList.isEmpty()) aFolderList = (*pIter)->maTitle; else aFolderList = aFolderList + "\n" + (*pIter)->maTitle; } } } maView->reload(); if (!aFolderList.isEmpty()) { } } } } void SfxTemplateManagerDlg::createRepositoryMenu() { mpRepositoryMenu->Clear(); mpRepositoryMenu->InsertItem(MNI_REPOSITORY_LOCAL,SfxResId(STR_REPOSITORY_LOCAL).toString()); const std::vector &rRepos = getRepositories(); for (size_t i = 0, n = rRepos.size(); i < n; ++i) mpRepositoryMenu->InsertItem(MNI_REPOSITORY_BASE+rRepos[i]->mnId,rRepos[i]->maTitle); mpRepositoryMenu->InsertSeparator(); mpRepositoryMenu->InsertItem(MNI_REPOSITORY_NEW,SfxResId(STR_REPOSITORY_NEW).toString()); } void SfxTemplateManagerDlg::createDefaultTemplateMenu () { std::vector aList = lcl_getAllFactoryURLs(); if (!aList.empty()) { mpTemplateDefaultMenu->Clear(); sal_uInt16 nItemId = MNI_ACTION_DEFAULT + 1; for( std::vector::const_iterator i = aList.begin(); i != aList.end(); ++i ) { INetURLObject aObj(*i); OUString aTitle = SvFileInformationManager::GetDescription(aObj); mpTemplateDefaultMenu->InsertItem(nItemId, aTitle, SvFileInformationManager::GetImage(aObj, false)); mpTemplateDefaultMenu->SetItemCommand(nItemId++, *i); } mpActionMenu->ShowItem(MNI_ACTION_DEFAULT); } else mpActionMenu->HideItem(MNI_ACTION_DEFAULT); } void SfxTemplateManagerDlg::switchMainView(bool bDisplayLocal) { if (bDisplayLocal) { mpCurView = maView; mpViewBar->HideItem(TBI_TEMPLATE_FOLDER_DEL); // Enable deleting and exporting items from the filesystem mpTemplateBar->ShowItem(TBI_TEMPLATE_EXPORT); mpTemplateBar->ShowItem(TBI_TEMPLATE_DELETE); mpOnlineView->Hide(); maView->Show(); } else { mpCurView = mpOnlineView; mpViewBar->ShowItem(TBI_TEMPLATE_FOLDER_DEL); // Disable deleting and exporting items from remote repositories mpTemplateBar->HideItem(TBI_TEMPLATE_EXPORT); mpTemplateBar->HideItem(TBI_TEMPLATE_DELETE); maView->Hide(); mpOnlineView->Show(); } } void SfxTemplateManagerDlg::localMoveTo(sal_uInt16 nMenuId) { sal_uInt16 nItemId = 0; if (nMenuId == MNI_MOVE_NEW) { InputDialog dlg(SfxResId(STR_INPUT_NEW).toString(),this); int ret = dlg.Execute(); if (ret) { OUString aName = dlg.getEntryText(); if (!aName.isEmpty()) nItemId = maView->createRegion(aName); } } else { nItemId = maView->GetItemId(nMenuId-MNI_MOVE_FOLDER_BASE); } if (nItemId) { // Move templates to desired folder if for some reason move fails // try copying them. if (!maView->moveTemplates(maSelTemplates,nItemId,false) && !maView->moveTemplates(maSelTemplates,nItemId,true)) { OUString aTemplateList; std::set::const_iterator pIter; for (pIter = maSelFolders.begin(); pIter != maSelFolders.end(); ++pIter) { if (aTemplateList.isEmpty()) aTemplateList = (*pIter)->maTitle; else aTemplateList = aTemplateList + "\n" + (*pIter)->maTitle; } OUString aDst = maView->GetItemText(nItemId); OUString aMsg(SfxResId(STR_MSG_ERROR_LOCAL_MOVE).toString()); aMsg = aMsg.replaceFirst("$1",aDst); ErrorBox(this, WB_OK,aMsg.replaceFirst( "$2",aTemplateList)).Execute(); } } } void SfxTemplateManagerDlg::remoteMoveTo(const sal_uInt16 nMenuId) { sal_uInt16 nItemId = 0; if (nMenuId == MNI_MOVE_NEW) { InputDialog dlg(SfxResId(STR_INPUT_NEW).toString(),this); int ret = dlg.Execute(); if (ret) { OUString aName = dlg.getEntryText(); if (!aName.isEmpty()) nItemId = maView->createRegion(aName); } } else { nItemId = maView->GetItemId(nMenuId-MNI_MOVE_FOLDER_BASE); } if (nItemId) { OUString aTemplateList; std::set::const_iterator aIter; for (aIter = maSelTemplates.begin(); aIter != maSelTemplates.end(); ++aIter) { const TemplateSearchViewItem *pItem = static_cast(*aIter); if(!maView->copyFrom(nItemId,pItem->maPreview1,pItem->getPath())) { if (aTemplateList.isEmpty()) aTemplateList = pItem->maTitle; else aTemplateList = aTemplateList + "\n" + pItem->maTitle; } } maView->Invalidate(INVALIDATE_NOERASE); if (!aTemplateList.isEmpty()) { OUString aMsg(SfxResId(STR_MSG_ERROR_REMOTE_MOVE).toString()); aMsg = aMsg.replaceFirst("$1",mpOnlineView->getOverlayName()); aMsg = aMsg.replaceFirst("$2",maView->GetItemText(nItemId)); ErrorBox(this,WB_OK,aMsg.replaceFirst("$1",aTemplateList)).Execute(); } } } void SfxTemplateManagerDlg::localSearchMoveTo(sal_uInt16 nMenuId) { sal_uInt16 nItemId = 0; if (nMenuId == MNI_MOVE_NEW) { InputDialog dlg(SfxResId(STR_INPUT_NEW).toString(),this); int ret = dlg.Execute(); if (ret) { OUString aName = dlg.getEntryText(); if (!aName.isEmpty()) nItemId = maView->createRegion(aName); } } else { nItemId = maView->GetItemId(nMenuId-MNI_MOVE_FOLDER_BASE); } if (nItemId) { OUString aTemplateList; // Move templates to desired folder if for some reason move fails // try copying them. std::set::const_iterator aIter; for (aIter = maSelTemplates.begin(); aIter != maSelTemplates.end(); ++aIter) { const TemplateSearchViewItem *pItem = static_cast(*aIter); if(!maView->moveTemplate(pItem,pItem->mnRegionId+1,nItemId,false) && !maView->moveTemplate(pItem,pItem->mnRegionId+1,nItemId,true)) { if (aTemplateList.isEmpty()) aTemplateList = (*aIter)->maTitle; else aTemplateList = aTemplateList + "\n" + (*aIter)->maTitle; } } if (!aTemplateList.isEmpty()) { OUString aDst = maView->GetItemText(nItemId); OUString aMsg(SfxResId(STR_MSG_ERROR_LOCAL_MOVE).toString()); aMsg = aMsg.replaceFirst("$1",aDst); ErrorBox(this, WB_OK,aMsg.replaceFirst( "$2",aTemplateList)).Execute(); } } // Deselect all items and update search results mpSearchView->deselectItems(); SearchUpdateHdl(mpSearchEdit); } void SfxTemplateManagerDlg::loadRepositories() { uno::Reference < uno::XComponentContext > m_context(comphelper::getProcessComponentContext()); // Load from user settings com::sun::star::uno::Sequence aUrls = officecfg::Office::Common::Misc::TemplateRepositoryUrls::get(m_context); com::sun::star::uno::Sequence aNames = officecfg::Office::Common::Misc::TemplateRepositoryNames::get(m_context); for (sal_Int32 i = 0; i < aUrls.getLength() && i < aNames.getLength(); ++i) { TemplateRepository *pItem = new TemplateRepository(); pItem->mnId = i+1; pItem->maTitle = aNames[i]; pItem->setURL(aUrls[i]); maRepositories.push_back(pItem); } } bool SfxTemplateManagerDlg::insertRepository(const OUString &rName, const OUString &rURL) { for (size_t i = 0, n = maRepositories.size(); i < n; ++i) { if (maRepositories[i]->maTitle == rName) return false; } TemplateRepository *pItem = new TemplateRepository(); pItem->mnId = maRepositories.size()+1; pItem->maTitle = rName; pItem->setURL(rURL); maRepositories.push_back(pItem); mbIsSynced = false; return true; } bool SfxTemplateManagerDlg::deleteRepository(const sal_uInt16 nRepositoryId) { bool bRet = false; for (size_t i = 0, n = maRepositories.size(); i < n; ++i) { if (maRepositories[i]->mnId == nRepositoryId) { delete maRepositories[i]; maRepositories.erase(maRepositories.begin() + i); mbIsSynced = false; bRet = true; break; } } return bRet; } void SfxTemplateManagerDlg::syncRepositories() const { if (!mbIsSynced) { uno::Reference < uno::XComponentContext > pContext(comphelper::getProcessComponentContext()); boost::shared_ptr batch(comphelper::ConfigurationChanges::create(pContext)); size_t nSize = maRepositories.size(); uno::Sequence aUrls(nSize); uno::Sequence aNames(nSize); for(size_t i = 0; i < nSize; ++i) { aUrls[i] = maRepositories[i]->getURL(); aNames[i] = maRepositories[i]->maTitle; } officecfg::Office::Common::Misc::TemplateRepositoryUrls::set(aUrls, batch, pContext); officecfg::Office::Common::Misc::TemplateRepositoryNames::set(aNames, batch, pContext); batch->commit(); } } BitmapEx SfxTemplateManagerDlg::getDefaultThumbnail( const OUString& rPath ) { INetURLObject aUrl(rPath); OUString aExt = aUrl.getExtension(); BitmapEx aImg; if ( aExt == "ott" || aExt == "stw" || aExt == "oth" || aExt == "dot" || aExt == "dotx" ) { aImg = BitmapEx ( SfxResId( SFX_THUMBNAIL_TEXT ) ); } else if ( aExt == "ots" || aExt == "stc" || aExt == "xlt" || aExt == "xltm" || aExt == "xltx" ) { aImg = BitmapEx ( SfxResId( SFX_THUMBNAIL_SHEET ) ); } else if ( aExt == "otp" || aExt == "sti" || aExt == "pot" || aExt == "potm" || aExt == "potx" ) { aImg = BitmapEx ( SfxResId( SFX_THUMBNAIL_PRESENTATION ) ); } else if ( aExt == "otg" || aExt == "std" ) { aImg = BitmapEx ( SfxResId( SFX_THUMBNAIL_DRAWING ) ); } return aImg; } static bool lcl_getServiceName ( const OUString &rFileURL, OUString &rName ) { bool bRet = false; if ( !rFileURL.isEmpty() ) { try { uno::Reference< embed::XStorage > xStorage = comphelper::OStorageHelper::GetStorageFromURL( rFileURL, embed::ElementModes::READ ); sal_uIntPtr nFormat = SotStorage::GetFormatID( xStorage ); const SfxFilter* pFilter = SFX_APP()->GetFilterMatcher().GetFilter4ClipBoardId( nFormat ); if ( pFilter ) { rName = pFilter->GetServiceName(); bRet = true; } } catch( uno::Exception& ) {} } return bRet; } static std::vector lcl_getAllFactoryURLs () { SvtModuleOptions aModOpt; std::vector aList; const ::com::sun::star::uno::Sequence &aServiceNames = aModOpt.GetAllServiceNames(); for( sal_Int32 i=0, nCount = aServiceNames.getLength(); i < nCount; ++i ) { if ( SfxObjectFactory::GetStandardTemplate( aServiceNames[i] ).Len() > 0 ) { SvtModuleOptions::EFactory eFac = SvtModuleOptions::E_WRITER; SvtModuleOptions::ClassifyFactoryByName( aServiceNames[i], eFac ); aList.push_back(aModOpt.GetFactoryEmptyDocumentURL(eFac)); } } return aList; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */