Coverage Report

Created: 2026-03-31 11:00

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