/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * 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 #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 #include #include #include #include #include #include #include #include #include #include const char TM_SETTING_MANAGER[] = "TemplateManager"; const char TM_SETTING_LASTFOLDER[] = "LastFolder"; const char TM_SETTING_LASTAPPLICATION[] = "LastApplication"; const char ACTIONBAR_ACTION[] = "action_menu"; #define MNI_ACTION_NEW_FOLDER 1 #define MNI_ACTION_RENAME_FOLDER 2 #define MNI_ACTION_DELETE_FOLDER 3 #define MNI_ACTION_REFRESH 4 #define MNI_ACTION_DEFAULT 5 #define MNI_WRITER 1 #define MNI_CALC 2 #define MNI_IMPRESS 3 #define MNI_DRAW 4 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; using namespace ::com::sun::star::document; static bool lcl_getServiceName (const OUString &rFileURL, OUString &rName ); static std::vector lcl_getAllFactoryURLs (); class SearchView_Keyword { public: SearchView_Keyword (const OUString &rKeyword, FILTER_APPLICATION App) : maKeyword(rKeyword.toAsciiLowerCase()), meApp(App) {} bool operator() (const TemplateItemProperties &rItem) { bool bRet = true; INetURLObject aUrl(rItem.aPath); OUString aExt = aUrl.getExtension(); if (meApp == FILTER_APPLICATION::WRITER) { bRet = aExt == "ott" || aExt == "stw" || aExt == "oth" || aExt == "dot" || aExt == "dotx"; } else if (meApp == FILTER_APPLICATION::CALC) { bRet = aExt == "ots" || aExt == "stc" || aExt == "xlt" || aExt == "xltm" || aExt == "xltx"; } else if (meApp == FILTER_APPLICATION::IMPRESS) { bRet = aExt == "otp" || aExt == "sti" || aExt == "pot" || aExt == "potm" || aExt == "potx"; } else if (meApp == FILTER_APPLICATION::DRAW) { bRet = aExt == "otg" || aExt == "std"; } return bRet && MatchSubstring(rItem.aName); } bool MatchSubstring( OUString const & sItemName ) { if(maKeyword.isEmpty()) return false; return sItemName.toAsciiLowerCase().indexOf(maKeyword) >= 0; } private: OUString maKeyword; FILTER_APPLICATION meApp; }; /*** * * Order items in ascending order (useful for the selection sets and move/copy operations since the associated ids * change when processed by the SfxDocumentTemplates class so we want to process to ones with higher id first) * ***/ static bool cmpSelectionItems (const ThumbnailViewItem *pItem1, const ThumbnailViewItem *pItem2) { return pItem1->mnId > pItem2->mnId; } SfxTemplateManagerDlg::SfxTemplateManagerDlg(vcl::Window *parent) : ModalDialog(parent, "TemplateDialog", "sfx/ui/templatedlg.ui"), maSelTemplates(cmpSelectionItems), mxDesktop( Desktop::create(comphelper::getProcessComponentContext()) ) { get(mpSearchFilter, "search_filter"); get(mpCBApp, "filter_application"); get(mpCBFolder, "filter_folder"); get(mpActionBar, "action_action"); get(mpLocalView, "template_view"); get(mpSearchView, "search_view"); get(mpOKButton, "ok"); get(mpMoveButton, "move_btn"); get(mpExportButton, "export_btn"); get(mpImportButton, "import_btn"); get(mpLinkButton, "online_link"); get(mpCBXHideDlg, "hidedialogcb"); // Create popup menus mpActionMenu = VclPtr::Create(); mpActionMenu->InsertItem(MNI_ACTION_NEW_FOLDER, SfxResId(STR_CATEGORY_NEW), Image(BitmapEx(BMP_ACTION_REFRESH))); mpActionMenu->InsertItem(MNI_ACTION_RENAME_FOLDER, SfxResId(STR_CATEGORY_RENAME)); mpActionMenu->InsertItem(MNI_ACTION_DELETE_FOLDER, SfxResId(STR_CATEGORY_DELETE)); mpActionMenu->InsertSeparator(); mpActionMenu->InsertItem(MNI_ACTION_REFRESH, SfxResId(STR_ACTION_REFRESH), Image(BitmapEx(BMP_ACTION_REFRESH))); mpActionMenu->InsertItem(MNI_ACTION_DEFAULT,SfxResId(STR_ACTION_DEFAULT)); mpActionMenu->SetSelectHdl(LINK(this,SfxTemplateManagerDlg,MenuSelectHdl)); mpTemplateDefaultMenu = VclPtr::Create(); mpTemplateDefaultMenu->SetSelectHdl(LINK(this,SfxTemplateManagerDlg,DefaultTemplateMenuSelectHdl)); mpActionMenu->SetPopupMenu(MNI_ACTION_DEFAULT,mpTemplateDefaultMenu); // Set toolbox button bits mpActionBar->SetItemBits(mpActionBar->GetItemId(ACTIONBAR_ACTION), ToolBoxItemBits::DROPDOWNONLY); // Set toolbox handlers mpActionBar->SetDropdownClickHdl(LINK(this,SfxTemplateManagerDlg,TBXDropdownHdl)); mpLocalView->SetStyle(mpLocalView->GetStyle() | WB_VSCROLL); mpLocalView->setItemMaxTextLength(TEMPLATE_ITEM_MAX_TEXT_LENGTH); mpLocalView->setItemDimensions(TEMPLATE_ITEM_MAX_WIDTH,TEMPLATE_ITEM_THUMBNAIL_MAX_HEIGHT, TEMPLATE_ITEM_MAX_HEIGHT-TEMPLATE_ITEM_THUMBNAIL_MAX_HEIGHT, TEMPLATE_ITEM_PADDING); mpLocalView->setItemStateHdl(LINK(this,SfxTemplateManagerDlg,TVItemStateHdl)); mpLocalView->setCreateContextMenuHdl(LINK(this,SfxTemplateManagerDlg, CreateContextMenuHdl)); mpLocalView->setOpenRegionHdl(LINK(this,SfxTemplateManagerDlg, OpenRegionHdl)); mpLocalView->setOpenTemplateHdl(LINK(this,SfxTemplateManagerDlg, OpenTemplateHdl)); mpLocalView->setEditTemplateHdl(LINK(this,SfxTemplateManagerDlg, EditTemplateHdl)); mpLocalView->setDeleteTemplateHdl(LINK(this,SfxTemplateManagerDlg, DeleteTemplateHdl)); mpLocalView->setDefaultTemplateHdl(LINK(this,SfxTemplateManagerDlg, DefaultTemplateHdl)); mpSearchView->setItemMaxTextLength(TEMPLATE_ITEM_MAX_TEXT_LENGTH); mpSearchView->setItemDimensions(TEMPLATE_ITEM_MAX_WIDTH,TEMPLATE_ITEM_THUMBNAIL_MAX_HEIGHT, TEMPLATE_ITEM_MAX_HEIGHT_SUB-TEMPLATE_ITEM_THUMBNAIL_MAX_HEIGHT, TEMPLATE_ITEM_PADDING); mpSearchView->setItemStateHdl(LINK(this,SfxTemplateManagerDlg,TVItemStateHdl)); mpSearchView->setCreateContextMenuHdl(LINK(this,SfxTemplateManagerDlg, CreateContextMenuHdl)); mpSearchView->setOpenTemplateHdl(LINK(this,SfxTemplateManagerDlg,OpenTemplateHdl)); mpSearchView->setEditTemplateHdl(LINK(this,SfxTemplateManagerDlg, EditTemplateHdl)); mpSearchView->setDeleteTemplateHdl(LINK(this,SfxTemplateManagerDlg, DeleteTemplateHdl)); mpSearchView->setDefaultTemplateHdl(LINK(this,SfxTemplateManagerDlg, DefaultTemplateHdl)); mpLocalView->ShowTooltips(true); mpSearchView->ShowTooltips(true); mpOKButton->SetClickHdl(LINK(this, SfxTemplateManagerDlg, OkClickHdl)); mpMoveButton->SetClickHdl(LINK(this, SfxTemplateManagerDlg, MoveClickHdl)); mpExportButton->SetClickHdl(LINK(this, SfxTemplateManagerDlg, ExportClickHdl)); mpImportButton->SetClickHdl(LINK(this, SfxTemplateManagerDlg, ImportClickHdl)); mpLinkButton->SetClickHdl(LINK(this, SfxTemplateManagerDlg, LinkClickHdl)); mpSearchFilter->SetUpdateDataHdl(LINK(this, SfxTemplateManagerDlg, SearchUpdateHdl)); mpSearchFilter->EnableUpdateData(); mpSearchFilter->SetGetFocusHdl(LINK( this, SfxTemplateManagerDlg, GetFocusHdl )); mpActionBar->Show(); createDefaultTemplateMenu(); mpLocalView->Populate(); mpLocalView->filterItems(ViewFilter_Application(FILTER_APPLICATION::NONE)); mpCBApp->SelectEntryPos(0); fillFolderComboBox(); mpExportButton->Disable(); mpMoveButton->Disable(); mpOKButton->SetText(SfxResId(STR_OPEN)); mpCBApp->SetSelectHdl(LINK(this, SfxTemplateManagerDlg, SelectApplicationHdl)); mpCBFolder->SetSelectHdl(LINK(this, SfxTemplateManagerDlg, SelectRegionHdl)); mpLocalView->Show(); } SfxTemplateManagerDlg::~SfxTemplateManagerDlg() { disposeOnce(); } void SfxTemplateManagerDlg::dispose() { writeSettings(); // Ignore view events since we are cleaning the object mpLocalView->setItemStateHdl(Link()); mpLocalView->setOpenRegionHdl(Link()); mpLocalView->setOpenTemplateHdl(Link()); mpSearchView->setItemStateHdl(Link()); mpSearchView->setOpenTemplateHdl(Link()); mpOKButton.clear(); mpMoveButton.clear(); mpExportButton.clear(); mpImportButton.clear(); mpLinkButton.clear(); mpCBXHideDlg.clear(); mpSearchFilter.clear(); mpCBApp.clear(); mpCBFolder.clear(); mpActionBar.clear(); mpSearchView.clear(); mpLocalView.clear(); mpActionMenu.disposeAndClear(); mpTemplateDefaultMenu.clear(); ModalDialog::dispose(); } short SfxTemplateManagerDlg::Execute() { //use application specific settings if there's no previous setting getApplicationSpecificSettings(); readSettings(); return ModalDialog::Execute(); } bool SfxTemplateManagerDlg::EventNotify( NotifyEvent& rNEvt ) { if (mpSearchFilter != nullptr && mpSearchFilter->HasControlFocus() && !mpSearchFilter->GetText().isEmpty() && rNEvt.GetType() == MouseNotifyEvent::KEYINPUT) { const KeyEvent* pKEvt = rNEvt.GetKeyEvent(); vcl::KeyCode aKeyCode = pKEvt->GetKeyCode(); sal_uInt16 nKeyCode = aKeyCode.GetCode(); if ( nKeyCode == KEY_ESCAPE ) { mpSearchFilter->SetText(""); mpSearchFilter->UpdateData(); return true; } } return ModalDialog::EventNotify(rNEvt); } void SfxTemplateManagerDlg::setDocumentModel(const uno::Reference &rModel) { m_xModel = rModel; } FILTER_APPLICATION SfxTemplateManagerDlg::getCurrentApplicationFilter() { const sal_Int16 nCurAppId = mpCBApp->GetSelectedEntryPos(); if (nCurAppId == MNI_WRITER) return FILTER_APPLICATION::WRITER; else if (nCurAppId == MNI_IMPRESS) return FILTER_APPLICATION::IMPRESS; else if (nCurAppId == MNI_CALC) return FILTER_APPLICATION::CALC; else if (nCurAppId == MNI_DRAW) return FILTER_APPLICATION::DRAW; return FILTER_APPLICATION::NONE; } void SfxTemplateManagerDlg::fillFolderComboBox() { std::vector aFolderNames = mpLocalView->getFolderNames(); if (!aFolderNames.empty()) { for (size_t i = 0, n = aFolderNames.size(); i < n; ++i) mpCBFolder->InsertEntry(aFolderNames[i], i+1); } mpCBFolder->SelectEntryPos(0); mpActionMenu->HideItem(MNI_ACTION_RENAME_FOLDER); } void SfxTemplateManagerDlg::getApplicationSpecificSettings() { if ( ! m_xModel.is() ) { mpCBApp->SelectEntryPos(0); mpCBFolder->SelectEntryPos(0); mpActionMenu->HideItem(MNI_ACTION_RENAME_FOLDER); mpLocalView->filterItems(ViewFilter_Application(getCurrentApplicationFilter())); mpLocalView->showAllTemplates(); return; } SvtModuleOptions::EFactory eFactory = SvtModuleOptions::ClassifyFactoryByModel(m_xModel); switch(eFactory) { case SvtModuleOptions::EFactory::WRITER: case SvtModuleOptions::EFactory::WRITERWEB: case SvtModuleOptions::EFactory::WRITERGLOBAL: mpCBApp->SelectEntryPos(MNI_WRITER); break; case SvtModuleOptions::EFactory::CALC: mpCBApp->SelectEntryPos(MNI_CALC); break; case SvtModuleOptions::EFactory::IMPRESS: mpCBApp->SelectEntryPos(MNI_IMPRESS); break; case SvtModuleOptions::EFactory::DRAW: mpCBApp->SelectEntryPos(MNI_DRAW); break; default: mpCBApp->SelectEntryPos(0); break; } mpLocalView->filterItems(ViewFilter_Application(getCurrentApplicationFilter())); mpCBFolder->SelectEntryPos(0); mpActionMenu->HideItem(MNI_ACTION_RENAME_FOLDER); mpLocalView->showAllTemplates(); } void SfxTemplateManagerDlg::readSettings () { OUString aLastFolder; SvtViewOptions aViewSettings( EViewType::Dialog, TM_SETTING_MANAGER ); if ( aViewSettings.Exists() ) { sal_uInt16 nTmp = 0; aViewSettings.GetUserItem(TM_SETTING_LASTFOLDER) >>= aLastFolder; aViewSettings.GetUserItem(TM_SETTING_LASTAPPLICATION) >>= nTmp; //open last remembered application only when application model is not set if(!m_xModel.is()) { switch (nTmp) { case MNI_WRITER: mpCBApp->SelectEntryPos(MNI_WRITER); break; case MNI_CALC: mpCBApp->SelectEntryPos(MNI_CALC); break; case MNI_IMPRESS: mpCBApp->SelectEntryPos(MNI_IMPRESS); break; case MNI_DRAW: mpCBApp->SelectEntryPos(MNI_DRAW); break; default: mpCBApp->SelectEntryPos(0); break; } } } mpLocalView->filterItems(ViewFilter_Application(getCurrentApplicationFilter())); if (aLastFolder.isEmpty()) { //show all categories mpCBFolder->SelectEntryPos(0); mpActionMenu->HideItem(MNI_ACTION_RENAME_FOLDER); mpLocalView->showAllTemplates(); } else { mpCBFolder->SelectEntry(aLastFolder); mpLocalView->showRegion(aLastFolder); mpActionMenu->ShowItem(MNI_ACTION_RENAME_FOLDER); } } void SfxTemplateManagerDlg::writeSettings () { OUString aLastFolder; if (mpLocalView->getCurRegionId()) aLastFolder = mpLocalView->getRegionName(mpLocalView->getCurRegionId()-1); // last folder Sequence< NamedValue > aSettings { { TM_SETTING_LASTFOLDER, css::uno::makeAny(aLastFolder) }, { TM_SETTING_LASTAPPLICATION, css::uno::makeAny(sal_uInt16(mpCBApp->GetSelectedEntryPos())) } }; // write SvtViewOptions aViewSettings(EViewType::Dialog, TM_SETTING_MANAGER); aViewSettings.SetUserData(aSettings); } IMPL_LINK_NOARG(SfxTemplateManagerDlg, SelectApplicationHdl, ListBox&, void) { if(mpLocalView->IsVisible()) { mpLocalView->filterItems(ViewFilter_Application(getCurrentApplicationFilter())); mpLocalView->showAllTemplates(); mpCBFolder->SelectEntryPos(0); mpActionMenu->HideItem(MNI_ACTION_RENAME_FOLDER); } if(mpSearchView->IsVisible()) SearchUpdateHdl(*mpSearchFilter); } IMPL_LINK_NOARG(SfxTemplateManagerDlg, SelectRegionHdl, ListBox&, void) { const OUString sSelectedRegion = mpCBFolder->GetSelectedEntry(); if(mpCBFolder->GetSelectedEntryPos() == 0) { mpLocalView->showAllTemplates(); mpActionMenu->HideItem(MNI_ACTION_RENAME_FOLDER); } else { mpLocalView->showRegion(sSelectedRegion); mpActionMenu->ShowItem(MNI_ACTION_RENAME_FOLDER); } if(mpSearchView->IsVisible()) SearchUpdateHdl(*mpSearchFilter); } IMPL_LINK_NOARG(SfxTemplateManagerDlg, TBXDropdownHdl, ToolBox*, void) { const sal_uInt16 nCurItemId = mpActionBar->GetCurItemId(); mpActionBar->SetItemDown( nCurItemId, true ); if (nCurItemId == mpActionBar->GetItemId(ACTIONBAR_ACTION)) mpActionMenu->Execute(mpActionBar, mpActionBar->GetItemRect(nCurItemId), PopupMenuFlags::ExecuteDown); mpActionBar->SetItemDown( nCurItemId, false ); mpActionBar->EndSelection(); mpActionBar->Invalidate(); } IMPL_LINK(SfxTemplateManagerDlg, TVItemStateHdl, const ThumbnailViewItem*, pItem, void) { const TemplateViewItem *pViewItem = dynamic_cast(pItem); if (pViewItem) OnTemplateState(pItem); } IMPL_LINK(SfxTemplateManagerDlg, MenuSelectHdl, Menu*, pMenu, bool) { sal_uInt16 nMenuId = pMenu->GetCurItemId(); switch(nMenuId) { case MNI_ACTION_NEW_FOLDER: OnCategoryNew(); break; case MNI_ACTION_RENAME_FOLDER: OnCategoryRename(); break; case MNI_ACTION_DELETE_FOLDER: OnCategoryDelete(); break; case MNI_ACTION_REFRESH: mpLocalView->reload(); break; default: break; } return false; } IMPL_LINK(SfxTemplateManagerDlg, DefaultTemplateMenuSelectHdl, Menu*, pMenu, bool) { sal_uInt16 nId = pMenu->GetCurItemId(); OUString aServiceName = SfxObjectShell::GetServiceNameFromFactory( mpTemplateDefaultMenu->GetItemCommand(nId)); OUString sPrevDefault = SfxObjectFactory::GetStandardTemplate( aServiceName ); if(!sPrevDefault.isEmpty()) mpLocalView->RemoveDefaultTemplateIcon(sPrevDefault); SfxObjectFactory::SetStandardTemplate( aServiceName, OUString() ); createDefaultTemplateMenu(); return false; } IMPL_LINK_NOARG(SfxTemplateManagerDlg, OkClickHdl, Button*, void) { OnTemplateOpen(); EndDialog(RET_OK); } IMPL_LINK_NOARG(SfxTemplateManagerDlg, MoveClickHdl, Button*, void) { // modal dialog to select templates category SfxTemplateCategoryDialog aDlg(GetFrameWeld()); aDlg.SetCategoryLBEntries(mpLocalView->getFolderNames()); size_t nItemId = 0; if (aDlg.run() == RET_OK) { OUString sCategory = aDlg.GetSelectedCategory(); bool bIsNewCategory = aDlg.IsNewCategoryCreated(); if(bIsNewCategory) { if (!sCategory.isEmpty()) { nItemId = mpLocalView->createRegion(sCategory); if(nItemId) mpCBFolder->InsertEntry(sCategory); } } else nItemId = mpLocalView->getRegionId(sCategory); } if(nItemId) { if (mpSearchView->IsVisible()) localSearchMoveTo(nItemId); else localMoveTo(nItemId); } mpLocalView->reload(); } IMPL_LINK_NOARG(SfxTemplateManagerDlg, ExportClickHdl, Button*, void) { OnTemplateExport(); } IMPL_LINK_NOARG(SfxTemplateManagerDlg, ImportClickHdl, Button*, void) { //Modal Dialog to select Category SfxTemplateCategoryDialog aDlg(GetFrameWeld()); aDlg.SetCategoryLBEntries(mpLocalView->getFolderNames()); if (aDlg.run() == RET_OK) { OUString sCategory = aDlg.GetSelectedCategory(); bool bIsNewCategory = aDlg.IsNewCategoryCreated(); if(bIsNewCategory) { if(mpLocalView->createRegion(sCategory)) { mpCBFolder->InsertEntry(sCategory); OnTemplateImportCategory(sCategory); } else { OUString aMsg( SfxResId(STR_CREATE_ERROR) ); std::unique_ptr xBox(Application::CreateMessageDialog(GetFrameWeld(), VclMessageType::Warning, VclButtonsType::Ok, aMsg.replaceFirst("$1", sCategory))); xBox->run(); return; } } else OnTemplateImportCategory(sCategory); } mpLocalView->reload(); mpLocalView->showAllTemplates(); mpCBApp->SelectEntryPos(0); mpCBFolder->SelectEntryPos(0); mpActionMenu->HideItem(MNI_ACTION_RENAME_FOLDER); } IMPL_STATIC_LINK_NOARG(SfxTemplateManagerDlg, LinkClickHdl, Button*, void) { OnTemplateLink(); } IMPL_LINK_NOARG(SfxTemplateManagerDlg, OpenRegionHdl, void*, void) { maSelTemplates.clear(); mpOKButton->Disable(); mpActionBar->Show(); } IMPL_LINK(SfxTemplateManagerDlg, CreateContextMenuHdl, ThumbnailViewItem*, pItem, void) { const TemplateViewItem *pViewItem = dynamic_cast(pItem); if (pViewItem) { if(mpSearchView->IsVisible()) mpSearchView->createContextMenu(pViewItem->IsDefaultTemplate()); else mpLocalView->createContextMenu(pViewItem->IsDefaultTemplate()); } } IMPL_LINK(SfxTemplateManagerDlg, OpenTemplateHdl, ThumbnailViewItem*, pItem, void) { uno::Sequence< PropertyValue > aArgs(5); aArgs[0].Name = "AsTemplate"; aArgs[0].Value <<= true; aArgs[1].Name = "MacroExecutionMode"; aArgs[1].Value <<= MacroExecMode::USE_CONFIG; aArgs[2].Name = "UpdateDocMode"; aArgs[2].Value <<= UpdateDocMode::ACCORDING_TO_CONFIG; aArgs[3].Name = "InteractionHandler"; aArgs[3].Value <<= task::InteractionHandler::createWithParent( ::comphelper::getProcessComponentContext(), nullptr ); aArgs[4].Name = "ReadOnly"; aArgs[4].Value <<= true; TemplateViewItem *pTemplateItem = static_cast(pItem); try { mxDesktop->loadComponentFromURL(pTemplateItem->getPath(),"_default", 0, aArgs ); } catch( const uno::Exception& ) { } Close(); } IMPL_LINK(SfxTemplateManagerDlg, EditTemplateHdl, ThumbnailViewItem*, pItem, void) { uno::Sequence< PropertyValue > aArgs(3); aArgs[0].Name = "AsTemplate"; aArgs[0].Value <<= false; aArgs[1].Name = "MacroExecutionMode"; aArgs[1].Value <<= MacroExecMode::USE_CONFIG; aArgs[2].Name = "UpdateDocMode"; aArgs[2].Value <<= UpdateDocMode::ACCORDING_TO_CONFIG; uno::Reference< XStorable > xStorable; TemplateViewItem *pViewItem = static_cast(pItem); try { xStorable.set( mxDesktop->loadComponentFromURL(pViewItem->getPath(),"_default", 0, aArgs ), uno::UNO_QUERY ); } catch( const uno::Exception& ) { } Close(); } IMPL_LINK(SfxTemplateManagerDlg, DeleteTemplateHdl, ThumbnailViewItem*, pItem, void) { OUString aDeletedTemplate; if(mpSearchView->IsVisible()) { TemplateSearchViewItem *pSrchItem = static_cast(pItem); if (!mpLocalView->removeTemplate(pSrchItem->mnAssocId, pSrchItem->mnRegionId)) { aDeletedTemplate = pSrchItem->maTitle; } } else { TemplateViewItem *pViewItem = static_cast(pItem); sal_uInt16 nRegionItemId = mpLocalView->getRegionId(pViewItem->mnRegionId); if (!mpLocalView->removeTemplate(pViewItem->mnDocId + 1, nRegionItemId))//mnId w.r.t. region is mnDocId + 1; { aDeletedTemplate = pItem->maTitle; } } if (!aDeletedTemplate.isEmpty()) { OUString aMsg( SfxResId(STR_MSG_ERROR_DELETE_TEMPLATE) ); std::unique_ptr xBox(Application::CreateMessageDialog(GetFrameWeld(), VclMessageType::Warning, VclButtonsType::Ok, aMsg.replaceFirst("$1",aDeletedTemplate))); xBox->run(); } } IMPL_LINK(SfxTemplateManagerDlg, DefaultTemplateHdl, ThumbnailViewItem*, pItem, void) { TemplateViewItem *pViewItem = static_cast(pItem); OUString aServiceName; if(!pViewItem->IsDefaultTemplate()) { if (lcl_getServiceName(pViewItem->getPath(),aServiceName)) { OUString sPrevDefault = SfxObjectFactory::GetStandardTemplate( aServiceName ); if(!sPrevDefault.isEmpty()) mpLocalView->RemoveDefaultTemplateIcon(sPrevDefault); SfxObjectFactory::SetStandardTemplate(aServiceName,pViewItem->getPath()); pViewItem->showDefaultIcon(true); } } else { if(lcl_getServiceName(pViewItem->getPath(),aServiceName)) { SfxObjectFactory::SetStandardTemplate( aServiceName, OUString() ); pViewItem->showDefaultIcon(false); } } createDefaultTemplateMenu(); } IMPL_LINK_NOARG(SfxTemplateManagerDlg, SearchUpdateHdl, Edit&, void) { OUString aKeyword = mpSearchFilter->GetText(); if (!aKeyword.isEmpty()) { mpSearchView->Clear(); // if the search view is hidden, hide the folder view and display search one if (!mpSearchView->IsVisible()) { mpLocalView->deselectItems(); mpSearchView->Show(); mpLocalView->Hide(); } std::vector aItems = mpLocalView->getFilteredItems(SearchView_Keyword(aKeyword, getCurrentApplicationFilter())); for (TemplateItemProperties& rItem : aItems) { OUString aFolderName; aFolderName = mpLocalView->getRegionName(rItem.nRegionId); mpSearchView->AppendItem(rItem.nId,mpLocalView->getRegionId(rItem.nRegionId), rItem.nDocId, rItem.aName, aFolderName, rItem.aPath, rItem.aThumbnail); } mpSearchView->Invalidate(); } else { mpSearchView->deselectItems(); mpSearchView->Hide(); mpLocalView->Show(); mpLocalView->filterItems(ViewFilter_Application(getCurrentApplicationFilter())); mpLocalView->reload(); OUString sLastFolder = mpCBFolder->GetSelectedEntry(); mpLocalView->showRegion(sLastFolder); mpActionMenu->ShowItem(MNI_ACTION_RENAME_FOLDER); } } IMPL_LINK_NOARG(SfxTemplateManagerDlg, GetFocusHdl, Control&, void) { mpLocalView->deselectItems(); mpSearchView->deselectItems(); maSelTemplates.clear(); } void SfxTemplateManagerDlg::OnTemplateState (const ThumbnailViewItem *pItem) { bool bInSelection = maSelTemplates.find(pItem) != maSelTemplates.end(); if (pItem->isSelected()) { if (maSelTemplates.empty()) { mpOKButton->Enable(); } else if (maSelTemplates.size() != 1 || !bInSelection) { mpOKButton->Disable(); } if (!bInSelection) maSelTemplates.insert(pItem); } else { if (bInSelection) { maSelTemplates.erase(pItem); if (maSelTemplates.empty()) { mpOKButton->Disable(); } else if (maSelTemplates.size() == 1) { mpOKButton->Enable(); } } } if(maSelTemplates.empty()) { mpMoveButton->Disable(); mpExportButton->Disable(); } else { mpMoveButton->Enable(); mpExportButton->Enable(); } } void SfxTemplateManagerDlg::OnTemplateImportCategory(const OUString& sCategory) { sfx2::FileDialogHelper aFileDlg(css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, FileDialogFlags::MultiSelection, GetFrameWeld()); // add "All" filter aFileDlg.AddFilter( SfxResId(STR_SFX_FILTERNAME_ALL), FILEDIALOG_FILTER_ALL ); // add template filter OUString sFilterExt; OUString sFilterName( SfxResId( STR_TEMPLATE_FILTER ) ); // add filters of modules which are installed SvtModuleOptions aModuleOpt; if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) ) sFilterExt += "*.ott;*.stw;*.oth;*.dotx;*.dot"; if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::CALC ) ) { if ( !sFilterExt.isEmpty() ) sFilterExt += ";"; sFilterExt += "*.ots;*.stc;*.xltx;*.xlt"; } if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::IMPRESS ) ) { if ( !sFilterExt.isEmpty() ) sFilterExt += ";"; sFilterExt += "*.otp;*.sti;*.pot;*.potx"; } if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::DRAW ) ) { 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 ) { css::uno::Sequence aFiles = aFileDlg.GetSelectedFiles(); if (aFiles.hasElements()) { //Import to the selected regions TemplateContainerItem* pContItem = mpLocalView->getRegion(sCategory); if(pContItem) { OUString aTemplateList; for (size_t i = 0, n = aFiles.getLength(); i < n; ++i) { if(!mpLocalView->copyFrom(pContItem,aFiles[i])) { if (aTemplateList.isEmpty()) aTemplateList = aFiles[i]; else aTemplateList = aTemplateList + "\n" + aFiles[i]; } } if (!aTemplateList.isEmpty()) { OUString aMsg(SfxResId(STR_MSG_ERROR_IMPORT)); aMsg = aMsg.replaceFirst("$1",pContItem->maTitle); std::unique_ptr xBox(Application::CreateMessageDialog(GetFrameWeld(), VclMessageType::Warning, VclButtonsType::Ok, aMsg.replaceFirst("$2",aTemplateList))); xBox->run(); } } } } } void SfxTemplateManagerDlg::OnTemplateExport() { uno::Reference xContext(comphelper::getProcessComponentContext()); uno::Reference xFolderPicker = FolderPicker::create(xContext); xFolderPicker->setDisplayDirectory(SvtPathOptions().GetWorkPath()); sal_Int16 nResult = xFolderPicker->execute(); sal_Int16 nCount = maSelTemplates.size(); if( nResult == ExecutableDialogResults::OK ) { OUString aTemplateList; INetURLObject aPathObj(xFolderPicker->getDirectory()); aPathObj.setFinalSlash(); if (mpSearchView->IsVisible()) { sal_uInt16 i = 1; for (auto const& selTemplate : maSelTemplates) { const TemplateSearchViewItem *pItem = static_cast(selTemplate); INetURLObject aItemPath(pItem->getPath()); if ( 1 == i ) aPathObj.Append(aItemPath.getName()); else aPathObj.setName(aItemPath.getName()); OUString aPath = aPathObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ); if (!mpLocalView->exportTo(pItem->mnAssocId,pItem->mnRegionId,aPath)) { if (aTemplateList.isEmpty()) aTemplateList = pItem->maTitle; else aTemplateList = aTemplateList + "\n" + pItem->maTitle; } ++i; } mpSearchView->deselectItems(); } else { // export templates from the current view sal_uInt16 i = 1; for (auto const& selTemplate : maSelTemplates) { const TemplateViewItem *pItem = static_cast(selTemplate); INetURLObject aItemPath(pItem->getPath()); if ( 1 == i ) aPathObj.Append(aItemPath.getName()); else aPathObj.setName(aItemPath.getName()); OUString aPath = aPathObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ); if (!mpLocalView->exportTo(pItem->mnDocId + 1, //mnId w.r.t. region = mDocId + 1 mpLocalView->getRegionId(pItem->mnRegionId), //pItem->mnRegionId does not store actual region Id aPath)) { if (aTemplateList.isEmpty()) aTemplateList = pItem->maTitle; else aTemplateList = aTemplateList + "\n" + pItem->maTitle; } ++i; } mpLocalView->deselectItems(); } if (!aTemplateList.isEmpty()) { OUString aText( SfxResId(STR_MSG_ERROR_EXPORT) ); std::unique_ptr xBox(Application::CreateMessageDialog(GetFrameWeld(), VclMessageType::Warning, VclButtonsType::Ok, aText.replaceFirst("$1",aTemplateList))); xBox->run(); } else { OUString sText( SfxResId(STR_MSG_EXPORT_SUCCESS) ); std::unique_ptr xBox(Application::CreateMessageDialog(GetFrameWeld(), VclMessageType::Info, VclButtonsType::Ok, sText.replaceFirst("$1", OUString::number(nCount)))); xBox->run(); } } } void SfxTemplateManagerDlg::OnTemplateLink () { OUString sNodePath("/org.openoffice.Office.Common/Help/StartCenter"); try { Reference xConfig = configuration::theDefaultProvider::get( comphelper::getProcessComponentContext() ); uno::Sequence args(comphelper::InitAnyPropertySequence( { {"nodepath", uno::Any(sNodePath)} })); Reference xNameAccess(xConfig->createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", args), UNO_QUERY); if( xNameAccess.is() ) { OUString sURL; //throws css::container::NoSuchElementException, css::lang::WrappedTargetException Any value( xNameAccess->getByName("TemplateRepositoryURL") ); sURL = value.get (); localizeWebserviceURI(sURL); Reference< css::system::XSystemShellExecute > xSystemShellExecute( css::system::SystemShellExecute::create(comphelper::getProcessComponentContext())); xSystemShellExecute->execute( sURL, OUString(), css::system::SystemShellExecuteFlags::URIS_ONLY); } } catch (const Exception&) { } } void SfxTemplateManagerDlg::OnTemplateOpen () { ThumbnailViewItem *pItem = const_cast(*maSelTemplates.begin()); OpenTemplateHdl(pItem); } void SfxTemplateManagerDlg::OnCategoryNew() { InputDialog dlg(GetFrameWeld(), SfxResId(STR_INPUT_NEW)); int ret = dlg.run(); if (ret) { OUString aName = dlg.GetEntryText(); if(mpLocalView->createRegion(aName)) mpCBFolder->InsertEntry(aName); else { OUString aMsg( SfxResId(STR_CREATE_ERROR) ); std::unique_ptr xBox(Application::CreateMessageDialog(GetFrameWeld(), VclMessageType::Warning, VclButtonsType::Ok, aMsg.replaceFirst("$1", aName))); xBox->run(); } } } void SfxTemplateManagerDlg::OnCategoryRename() { OUString sCategory = mpCBFolder->GetSelectedEntry(); InputDialog dlg(GetFrameWeld(), SfxResId(STR_INPUT_NEW)); dlg.SetEntryText(sCategory); int ret = dlg.run(); if (ret) { OUString aName = dlg.GetEntryText(); if(mpLocalView->renameRegion(sCategory, aName)) { sal_Int32 nPos = mpCBFolder->GetEntryPos(sCategory); mpCBFolder->RemoveEntry(nPos); mpCBFolder->InsertEntry(aName, nPos); mpCBFolder->SelectEntryPos(nPos); mpLocalView->reload(); mpLocalView->showRegion(aName); } else { OUString aMsg( SfxResId(STR_CREATE_ERROR) ); std::unique_ptr xBox(Application::CreateMessageDialog(GetFrameWeld(), VclMessageType::Warning, VclButtonsType::Ok, aMsg.replaceFirst("$1", aName))); xBox->run(); } } } void SfxTemplateManagerDlg::OnCategoryDelete() { SfxTemplateCategoryDialog aDlg(GetFrameWeld()); aDlg.SetCategoryLBEntries(mpLocalView->getFolderNames()); aDlg.HideNewCategoryOption(); aDlg.set_title(SfxResId(STR_CATEGORY_DELETE)); aDlg.SetSelectLabelText(SfxResId(STR_CATEGORY_SELECT)); if (aDlg.run() == RET_OK) { OUString sCategory = aDlg.GetSelectedCategory(); std::unique_ptr popupDlg(Application::CreateMessageDialog(GetFrameWeld(), VclMessageType::Question, VclButtonsType::YesNo, SfxResId(STR_QMSG_SEL_FOLDER_DELETE))); if (popupDlg->run() != RET_YES) return; sal_Int16 nItemId = mpLocalView->getRegionId(sCategory); if (!mpLocalView->removeRegion(nItemId)) { OUString sMsg( SfxResId(STR_MSG_ERROR_DELETE_FOLDER) ); std::unique_ptr xBox(Application::CreateMessageDialog(GetFrameWeld(), VclMessageType::Warning, VclButtonsType::Ok, sMsg.replaceFirst("$1",sCategory))); xBox->run(); } else { mpCBFolder->RemoveEntry(sCategory); } } mpLocalView->reload(); mpLocalView->showAllTemplates(); mpCBApp->SelectEntryPos(0); mpCBFolder->SelectEntryPos(0); mpActionMenu->HideItem(MNI_ACTION_RENAME_FOLDER); } void SfxTemplateManagerDlg::createDefaultTemplateMenu () { std::vector aList = lcl_getAllFactoryURLs(); if (!aList.empty()) { mpTemplateDefaultMenu->Clear(); sal_uInt16 nItemId = MNI_ACTION_DEFAULT + 1; for (auto const& elem : aList) { INetURLObject aObj(elem); OUString aTitle = SvFileInformationManager::GetDescription(aObj); mpTemplateDefaultMenu->InsertItem(nItemId, aTitle, SvFileInformationManager::GetImage(aObj)); mpTemplateDefaultMenu->SetItemCommand(nItemId++, elem); } mpActionMenu->ShowItem(MNI_ACTION_DEFAULT); } else mpActionMenu->HideItem(MNI_ACTION_DEFAULT); } void SfxTemplateManagerDlg::localMoveTo(sal_uInt16 nItemId) { if (nItemId) { // Move templates to desired folder if for some reason move fails // try copying them. mpLocalView->moveTemplates(maSelTemplates,nItemId); } } void SfxTemplateManagerDlg::localSearchMoveTo(sal_uInt16 nItemId) { if (nItemId) { // Move templates to desired folder if for some reason move fails // try copying them. std::set aSelTemplates = maSelTemplates; //Copy to avoid invalidating an iterator for (auto const& selTemplate : aSelTemplates) { const TemplateSearchViewItem *pItem = static_cast(selTemplate); if(!mpLocalView->moveTemplate(pItem,pItem->mnRegionId,nItemId)) { OUString sDst = mpLocalView->getRegionItemName(nItemId); OUString sMsg(SfxResId(STR_MSG_ERROR_LOCAL_MOVE)); sMsg = sMsg.replaceFirst("$1",sDst); std::unique_ptr xBox(Application::CreateMessageDialog(GetFrameWeld(), VclMessageType::Warning, VclButtonsType::Ok, sMsg.replaceFirst( "$2",pItem->maTitle))); xBox->run(); } } } // Deselect all items and update search results mpSearchView->deselectItems(); SearchUpdateHdl(*mpSearchFilter); } 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 ); SotClipboardFormatId nFormat = SotStorage::GetFormatID( xStorage ); std::shared_ptr pFilter = SfxGetpApp()->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 css::uno::Sequence &aServiceNames = aModOpt.GetAllServiceNames(); for( sal_Int32 i=0, nCount = aServiceNames.getLength(); i < nCount; ++i ) { if ( ! SfxObjectFactory::GetStandardTemplate( aServiceNames[i] ).isEmpty() ) { SvtModuleOptions::EFactory eFac = SvtModuleOptions::EFactory::WRITER; SvtModuleOptions::ClassifyFactoryByName( aServiceNames[i], eFac ); aList.push_back(aModOpt.GetFactoryEmptyDocumentURL(eFac)); } } return aList; } // Class SfxTemplateCategoryDialog -------------------------------------------------- SfxTemplateCategoryDialog::SfxTemplateCategoryDialog(weld::Window* pParent) : weld::GenericDialogController(pParent, "sfx/ui/templatecategorydlg.ui", "TemplatesCategoryDialog") , msSelectedCategory(OUString()) , mbIsNewCategory(false) , mxLBCategory(m_xBuilder->weld_tree_view("categorylb")) , mxSelectLabel(m_xBuilder->weld_label("select_label")) , mxNewCategoryEdit(m_xBuilder->weld_entry("category_entry")) , mxCreateLabel(m_xBuilder->weld_label("create_label")) , mxOKButton(m_xBuilder->weld_button("ok")) { mxNewCategoryEdit->connect_changed(LINK(this, SfxTemplateCategoryDialog, NewCategoryEditHdl)); mxLBCategory->set_size_request(mxLBCategory->get_approximate_digit_width() * 32, mxLBCategory->get_height_rows(8)); mxLBCategory->connect_changed(LINK(this, SfxTemplateCategoryDialog, SelectCategoryHdl)); mxOKButton->set_sensitive(false); } SfxTemplateCategoryDialog::~SfxTemplateCategoryDialog() { } IMPL_LINK_NOARG(SfxTemplateCategoryDialog, NewCategoryEditHdl, weld::Entry&, void) { OUString sParam = comphelper::string::strip(mxNewCategoryEdit->get_text(), ' '); mxLBCategory->set_sensitive(sParam.isEmpty()); if(!sParam.isEmpty()) { msSelectedCategory = sParam; mbIsNewCategory = true; mxOKButton->set_sensitive(true); } else { SelectCategoryHdl(*mxLBCategory); mbIsNewCategory = false; } } IMPL_LINK_NOARG(SfxTemplateCategoryDialog, SelectCategoryHdl, weld::TreeView&, void) { if (mxLBCategory->get_selected_index() == 0) { msSelectedCategory = OUString(); mxOKButton->set_sensitive(false); mxNewCategoryEdit->set_sensitive(true); } else { msSelectedCategory = mxLBCategory->get_selected_text(); mxNewCategoryEdit->set_sensitive(false); mxOKButton->set_sensitive(true); } mbIsNewCategory = false; } void SfxTemplateCategoryDialog::SetCategoryLBEntries(std::vector aFolderNames) { if (!aFolderNames.empty()) { for (size_t i = 0, n = aFolderNames.size(); i < n; ++i) mxLBCategory->append_text(aFolderNames[i]); } mxLBCategory->select(0); } void SfxTemplateCategoryDialog::HideNewCategoryOption() { mxCreateLabel->hide(); mxNewCategoryEdit->hide(); } // SfxTemplateSelectionDialog ----------------------------------------------------------------- SfxTemplateSelectionDlg::SfxTemplateSelectionDlg(vcl::Window* pParent): SfxTemplateManagerDlg(pParent), msTemplatePath(OUString()) { mpCBApp->SelectEntryPos(MNI_IMPRESS); mpCBFolder->SelectEntryPos(0); SetText(SfxResId(STR_TEMPLATE_SELECTION)); if(mpLocalView->IsVisible()) { mpLocalView->filterItems(ViewFilter_Application(getCurrentApplicationFilter())); mpLocalView->showAllTemplates(); } mpCBApp->Disable(); mpActionBar->Hide(); mpLinkButton->Hide(); mpMoveButton->Hide(); mpExportButton->Hide(); mpCBXHideDlg->Show(); mpCBXHideDlg->Check(); mpLocalView->setOpenTemplateHdl(LINK(this,SfxTemplateSelectionDlg, OpenTemplateHdl)); mpSearchView->setOpenTemplateHdl(LINK(this,SfxTemplateSelectionDlg, OpenTemplateHdl)); mpLocalView->SetMultiSelectionEnabled(false); mpSearchView->SetMultiSelectionEnabled(false); mpOKButton->SetClickHdl(LINK(this, SfxTemplateSelectionDlg, OkClickHdl)); } SfxTemplateSelectionDlg::~SfxTemplateSelectionDlg() { disposeOnce(); } void SfxTemplateSelectionDlg::dispose() { SfxTemplateManagerDlg::dispose(); } short SfxTemplateSelectionDlg::Execute() { return ModalDialog::Execute(); } IMPL_LINK(SfxTemplateSelectionDlg, OpenTemplateHdl, ThumbnailViewItem*, pItem, void) { TemplateViewItem *pViewItem = static_cast(pItem); msTemplatePath = pViewItem->getPath(); EndDialog(RET_OK); } IMPL_LINK_NOARG(SfxTemplateSelectionDlg, OkClickHdl, Button*, void) { TemplateViewItem *pViewItem = static_cast(const_cast(*maSelTemplates.begin())); msTemplatePath = pViewItem->getPath(); EndDialog(RET_OK); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */