    /* -*- 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 <sfx2/templatedlg.hxx>

    #include <sfx2/inputdlg.hxx>
    #include <templatesearchview.hxx>
    #include <templatesearchviewitem.hxx>

    #include <comphelper/processfactory.hxx>
    #include <comphelper/propertysequence.hxx>
    #include <comphelper/string.hxx>
    #include <comphelper/storagehelper.hxx>
    #include <officecfg/Office/Common.hxx>
    #include <sfx2/app.hxx>
    #include <sfx2/docfac.hxx>
    #include <sfx2/fcontnr.hxx>
    #include <sfx2/filedlghelper.hxx>
    #include <sfx2/sfxresid.hxx>
    #include <sfx2/templatelocalview.hxx>
    #include <sfx2/templatecontaineritem.hxx>
    #include <sfx2/templateviewitem.hxx>
    #include <sfx2/thumbnailviewitem.hxx>
    #include <sot/storage.hxx>
    #include <svtools/imagemgr.hxx>
    #include <svtools/langhelp.hxx>
    #include <svtools/miscopt.hxx>
    #include <tools/urlobj.hxx>
    #include <unotools/moduleoptions.hxx>
    #include <unotools/pathoptions.hxx>
    #include <unotools/viewoptions.hxx>
    #include <vcl/edit.hxx>
    #include <vcl/toolbox.hxx>
    #include <vcl/lstbox.hxx>
    #include <vcl/weld.hxx>

    #include <com/sun/star/beans/PropertyValue.hpp>
    #include <com/sun/star/configuration/theDefaultProvider.hpp>
    #include <com/sun/star/document/MacroExecMode.hpp>
    #include <com/sun/star/document/UpdateDocMode.hpp>
    #include <com/sun/star/embed/XStorage.hpp>
    #include <com/sun/star/embed/ElementModes.hpp>
    #include <com/sun/star/frame/Desktop.hpp>
    #include <com/sun/star/frame/XStorable.hpp>
    #include <com/sun/star/lang/XComponent.hpp>
    #include <com/sun/star/lang/XMultiServiceFactory.hpp>
    #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
    #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
    #include <com/sun/star/ui/dialogs/FolderPicker.hpp>
    #include <com/sun/star/system/SystemShellExecute.hpp>
    #include <com/sun/star/system/SystemShellExecuteFlags.hpp>
    #include <com/sun/star/task/InteractionHandler.hpp>

    #include <sfx2/strings.hrc>
    #include <bitmaps.hlst>

    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<OUString> 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<PopupMenu>::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<PopupMenu>::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<const ThumbnailViewItem*,void>());
        mpLocalView->setOpenRegionHdl(Link<void*,void>());
        mpLocalView->setOpenTemplateHdl(Link<ThumbnailViewItem*, void>());

        mpSearchView->setItemStateHdl(Link<const ThumbnailViewItem*,void>());
        mpSearchView->setOpenTemplateHdl(Link<ThumbnailViewItem*, void>());

        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<frame::XModel> &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<OUString> 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<const TemplateViewItem*>(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<weld::MessageDialog> 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<TemplateViewItem*>(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<TemplateViewItem*>(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<TemplateViewItem*>(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<TemplateSearchViewItem*>(pItem);

            if (!mpLocalView->removeTemplate(pSrchItem->mnAssocId, pSrchItem->mnRegionId))
            {
                aDeletedTemplate = pSrchItem->maTitle;
            }
        }
        else
        {
            TemplateViewItem *pViewItem = static_cast<TemplateViewItem*>(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<weld::MessageDialog> 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<TemplateViewItem*>(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<TemplateItemProperties> 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<OUString> 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<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(), VclMessageType::Warning, VclButtonsType::Ok,
                                                                  aMsg.replaceFirst("$2",aTemplateList)));
                        xBox->run();
                    }
                }
            }
        }
    }

    void SfxTemplateManagerDlg::OnTemplateExport()
    {
        uno::Reference<XComponentContext> xContext(comphelper::getProcessComponentContext());
        uno::Reference<XFolderPicker2> 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<const TemplateSearchViewItem*>(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<const TemplateViewItem*>(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<weld::MessageDialog> 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<weld::MessageDialog> 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<lang::XMultiServiceFactory> xConfig = configuration::theDefaultProvider::get( comphelper::getProcessComponentContext() );
            uno::Sequence<uno::Any> args(comphelper::InitAnyPropertySequence(
            {
                {"nodepath", uno::Any(sNodePath)}
            }));
            Reference<container::XNameAccess> 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<OUString> ();
                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<ThumbnailViewItem*>(*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<weld::MessageDialog> 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<weld::MessageDialog> 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<weld::MessageDialog> 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<weld::MessageDialog> 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<OUString> 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<const ThumbnailViewItem*,selection_cmp_fn> aSelTemplates = maSelTemplates; //Copy to avoid invalidating an iterator

            for (auto const& selTemplate : aSelTemplates)
            {
                const TemplateSearchViewItem *pItem =
                        static_cast<const TemplateSearchViewItem*>(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<weld::MessageDialog> 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<const SfxFilter> pFilter = SfxGetpApp()->GetFilterMatcher().GetFilter4ClipBoardId( nFormat );

                if ( pFilter )
                {
                    rName = pFilter->GetServiceName();
                    bRet = true;
                }
            }
            catch( uno::Exception& )
            {}
        }

        return bRet;
    }

    static std::vector<OUString> lcl_getAllFactoryURLs ()
    {
        SvtModuleOptions aModOpt;
        std::vector<OUString> aList;
        const css::uno::Sequence<OUString> &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<OUString> 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<TemplateViewItem*>(pItem);
        msTemplatePath = pViewItem->getPath();

        EndDialog(RET_OK);
    }

    IMPL_LINK_NOARG(SfxTemplateSelectionDlg, OkClickHdl, Button*, void)
    {
       TemplateViewItem *pViewItem = static_cast<TemplateViewItem*>(const_cast<ThumbnailViewItem*>(*maSelTemplates.begin()));
       msTemplatePath = pViewItem->getPath();

       EndDialog(RET_OK);
    }

    /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

↑ V1029 Numeric Truncation Error. Result of the 'size' function is written to the 16-bit variable.