1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include <sfx2/templatedlglocalview.hxx>
12 #include <comphelper/string.hxx>
13 #include <sfx2/inputdlg.hxx>
14 #include <templateviewitem.hxx>
15 #include <sfx2/sfxresid.hxx>
16 #include <templatecontaineritem.hxx>
17 #include <sfx2/strings.hrc>
18 #include <vcl/commandevent.hxx>
19 #include <vcl/svapp.hxx>
20 #include <vcl/event.hxx>
21 #include <sfx2/doctempl.hxx>
22 #include <bitmaps.hlst>
24 TemplateDlgLocalView::TemplateDlgLocalView(std::unique_ptr
<weld::ScrolledWindow
> xWindow
,
25 std::unique_ptr
<weld::Menu
> xMenu
,
26 std::unique_ptr
<weld::TreeView
> xTreeView
)
27 : TemplateLocalView(std::move(xWindow
), std::move(xMenu
))
28 , ListView(std::move(xTreeView
))
29 , mViewMode(TemplateViewMode::eThumbnailView
)
31 mxTreeView
->connect_row_activated(LINK(this, TemplateDlgLocalView
, RowActivatedHdl
));
32 mxTreeView
->connect_column_clicked(LINK(this, ListView
, ColumnClickedHdl
));
33 mxTreeView
->connect_changed(LINK(this, TemplateDlgLocalView
, ListViewChangedHdl
));
34 mxTreeView
->connect_popup_menu(LINK(this, TemplateDlgLocalView
, PopupMenuHdl
));
35 mxTreeView
->connect_key_press(LINK(this, TemplateDlgLocalView
, KeyPressHdl
));
38 void TemplateDlgLocalView::showAllTemplates()
42 insertItems(maAllTemplates
, false, true);
44 maOpenRegionHdl
.Call(nullptr);
47 void TemplateDlgLocalView::showRegion(TemplateContainerItem
const* pItem
)
49 mnCurRegionId
= pItem
->mnRegionId
+ 1;
51 insertItems(pItem
->maTemplates
, true, false);
53 maOpenRegionHdl
.Call(nullptr);
56 void TemplateDlgLocalView::showRegion(std::u16string_view rName
)
58 for (auto const& pRegion
: maRegions
)
60 if (pRegion
->maTitle
== rName
)
62 showRegion(pRegion
.get());
68 void TemplateDlgLocalView::reload()
70 mpDocTemplates
->Update();
71 OUString sCurRegionName
= getRegionItemName(mnCurRegionId
);
73 mnCurRegionId
= getRegionId(sCurRegionName
);
75 // Check if we are currently browsing a region or root folder
78 sal_uInt16 nRegionId
= mnCurRegionId
- 1; //Is offset by 1
80 for (auto const& pRegion
: maRegions
)
82 if (pRegion
->mnRegionId
== nRegionId
)
84 showRegion(pRegion
.get());
92 //No items should be selected by default
93 ThumbnailView::deselectItems();
94 ListView::unselect_all();
97 void TemplateDlgLocalView::createContextMenu(const bool bIsDefault
, const bool bIsBuiltIn
,
98 const bool bIsSingleSel
, const OUString
& rDefaultImg
)
100 mxContextMenu
->clear();
101 mxContextMenu
->append("open", SfxResId(STR_OPEN
), BMP_MENU_OPEN
);
102 mxContextMenu
->append("edit", SfxResId(STR_EDIT_TEMPLATE
), BMP_MENU_EDIT
);
105 mxContextMenu
->append("default", SfxResId(STR_DEFAULT_TEMPLATE
), rDefaultImg
);
107 mxContextMenu
->append("default", SfxResId(STR_RESET_DEFAULT
), rDefaultImg
);
109 mxContextMenu
->append_separator("separator1");
110 mxContextMenu
->append("rename", SfxResId(STR_SFX_RENAME
), BMP_MENU_RENAME
);
111 mxContextMenu
->append("delete", SfxResId(STR_DELETE_TEMPLATE
), BMP_MENU_DELETE
);
112 mxContextMenu
->append_separator("separator2");
113 mxContextMenu
->append("move", SfxResId(STR_MOVE
), BMP_MENU_MOVE
);
114 mxContextMenu
->append("export", SfxResId(STR_EXPORT
), BMP_MENU_EXPORT
);
118 mxContextMenu
->set_sensitive("open", false);
119 mxContextMenu
->set_sensitive("edit", false);
120 mxContextMenu
->set_sensitive("default", false);
121 mxContextMenu
->set_sensitive("rename", false);
125 mxContextMenu
->set_sensitive("rename", false);
126 mxContextMenu
->set_sensitive("delete", false);
128 if (mViewMode
== TemplateViewMode::eThumbnailView
)
130 ContextMenuSelectHdl(mxContextMenu
->popup_at_rect(
131 GetDrawingArea(), tools::Rectangle(maPosition
, Size(1, 1))));
134 else if (mViewMode
== TemplateViewMode::eListView
)
135 ContextMenuSelectHdl(mxContextMenu
->popup_at_rect(
136 mxTreeView
.get(), tools::Rectangle(maPosition
, Size(1, 1))));
139 void TemplateDlgLocalView::ContextMenuSelectHdl(std::string_view rIdent
)
141 if (rIdent
== "open")
142 maOpenTemplateHdl
.Call(maSelectedItem
);
143 else if (rIdent
== "edit")
144 maEditTemplateHdl
.Call(maSelectedItem
);
145 else if (rIdent
== "rename")
147 InputDialog
aTitleEditDlg(GetDrawingArea(), SfxResId(STR_RENAME_TEMPLATE
));
148 aTitleEditDlg
.set_title(SfxResId(STR_WINDOW_TITLE_RENAME_TEMPLATE
));
149 OUString sOldTitle
= maSelectedItem
->getTitle();
150 aTitleEditDlg
.SetEntryText(sOldTitle
);
151 aTitleEditDlg
.HideHelpBtn();
153 auto aCurRegionItems
= getFilteredItems([&](const TemplateItemProperties
& rItem
) {
154 return rItem
.aRegionName
== getRegionName(maSelectedItem
->mnRegionId
);
156 OUString
sTooltip(SfxResId(STR_TOOLTIP_ERROR_RENAME_TEMPLATE
));
157 sTooltip
= sTooltip
.replaceFirst("$2", getRegionName(maSelectedItem
->mnRegionId
));
158 aTitleEditDlg
.setCheckEntry([&](OUString sNewTitle
) {
159 if (sNewTitle
.isEmpty() || sNewTitle
== sOldTitle
)
161 for (const auto& rItem
: aCurRegionItems
)
163 if (rItem
.aName
== sNewTitle
)
165 aTitleEditDlg
.SetTooltip(sTooltip
.replaceFirst("$1", sNewTitle
));
171 if (!aTitleEditDlg
.run())
173 OUString sNewTitle
= comphelper::string::strip(aTitleEditDlg
.GetEntryText(), ' ');
175 if (!sNewTitle
.isEmpty() && sNewTitle
!= sOldTitle
)
177 maSelectedItem
->setTitle(sNewTitle
);
178 ListView::rename(OUString::number(maSelectedItem
->mnId
), maSelectedItem
->maTitle
);
181 else if (rIdent
== "delete")
183 std::unique_ptr
<weld::MessageDialog
> xQueryDlg(Application::CreateMessageDialog(
184 GetDrawingArea(), VclMessageType::Question
, VclButtonsType::YesNo
,
185 SfxResId(STR_QMSG_SEL_TEMPLATE_DELETE
)));
186 if (xQueryDlg
->run() != RET_YES
)
189 maDeleteTemplateHdl
.Call(maSelectedItem
);
192 else if (rIdent
== "default")
194 maDefaultTemplateHdl
.Call(maSelectedItem
);
195 ListView::refreshDefaultColumn();
197 else if (rIdent
== "move")
199 maMoveTemplateHdl
.Call(maSelectedItem
);
201 else if (rIdent
== "export")
203 maExportTemplateHdl
.Call(maSelectedItem
);
207 void TemplateDlgLocalView::insertFilteredItems()
209 ListView::clearListView();
210 for (const ThumbnailViewItem
* rItem
: mFilteredItemList
)
212 const TemplateViewItem
* pViewItem
= static_cast<const TemplateViewItem
*>(rItem
);
215 bool isDefault
= pViewItem
->IsDefaultTemplate();
216 OUString sId
= OUString::number(pViewItem
->mnId
);
217 ListView::AppendItem(sId
, rItem
->maTitle
, getRegionName(pViewItem
->mnRegionId
),
218 pViewItem
->getPath(), isDefault
);
223 void TemplateDlgLocalView::insertItems(const std::vector
<TemplateItemProperties
>& rTemplates
,
224 bool isRegionSelected
= true,
225 bool bShowCategoryInTooltip
= false)
227 TemplateLocalView::insertItems(rTemplates
, isRegionSelected
, bShowCategoryInTooltip
);
228 insertFilteredItems();
231 void TemplateDlgLocalView::setTemplateViewMode(TemplateViewMode eMode
) { mViewMode
= eMode
; }
233 void TemplateDlgLocalView::Show()
235 if (mViewMode
== TemplateViewMode::eListView
)
237 ThumbnailView::Hide();
238 ListView::ShowListView();
242 ThumbnailView::Show();
243 ListView::HideListView();
247 void TemplateDlgLocalView::Hide()
249 ThumbnailView::Hide();
250 ListView::HideListView();
253 bool TemplateDlgLocalView::IsVisible() const
255 return ThumbnailView::IsVisible() || ListView::IsListViewVisible();
258 void TemplateDlgLocalView::syncCursor()
260 if (mViewMode
== TemplateViewMode::eListView
)
262 ListView::unselect_all();
265 for (auto it
= mFilteredItemList
.cbegin(); it
!= mFilteredItemList
.cend(); ++it
)
267 if ((*it
)->mbSelected
)
270 nIndex
= ListView::get_index((*it
)->mnId
);
273 ListView::set_cursor(nIndex
);
274 ListView::select(nIndex
);
283 ThumbnailView::deselectItems();
284 std::vector
<int> aSelRows
= ListView::get_selected_rows();
285 if (aSelRows
.empty())
287 sal_uInt16 nCursorId
= ListView::get_cursor_nId();
288 ThumbnailView::SelectItem(nCursorId
);
289 MakeItemVisible(nCursorId
);
291 for (auto it
= mFilteredItemList
.begin(); it
!= mFilteredItemList
.end(); ++it
)
293 if ((*it
)->mnId
== nCursorId
)
295 mpStartSelRange
= it
;
300 size_t nPos
= GetItemPos(nCursorId
);
301 ThumbnailViewItem
* pItem
= ImplGetItem(nPos
);
302 const TemplateViewItem
* pViewItem
= dynamic_cast<const TemplateViewItem
*>(pItem
);
304 maSelectedItem
= dynamic_cast<TemplateViewItem
*>(pItem
);
308 void TemplateDlgLocalView::updateSelection()
310 ThumbnailView::deselectItems();
311 for (auto nIndex
: ListView::get_selected_rows())
313 ThumbnailView::SelectItem(ListView::get_nId(nIndex
));
316 sal_uInt16 nCursorId
= ListView::get_cursor_nId();
317 size_t nPos
= GetItemPos(nCursorId
);
318 ThumbnailViewItem
* pItem
= ImplGetItem(nPos
);
319 const TemplateViewItem
* pViewItem
= dynamic_cast<const TemplateViewItem
*>(pItem
);
321 maSelectedItem
= dynamic_cast<TemplateViewItem
*>(pItem
);
325 IMPL_LINK_NOARG(TemplateDlgLocalView
, RowActivatedHdl
, weld::TreeView
&, bool)
327 maOpenTemplateHdl
.Call(maSelectedItem
);
331 IMPL_LINK(TemplateDlgLocalView
, PopupMenuHdl
, const CommandEvent
&, rCEvt
, bool)
333 if (rCEvt
.GetCommand() != CommandEventId::ContextMenu
)
336 if (rCEvt
.IsMouseEvent())
338 if (ListView::get_selected_rows().empty())
340 Point
aPosition(rCEvt
.GetMousePosPixel());
341 maPosition
= aPosition
;
344 maCreateContextMenuHdl
.Call(maSelectedItem
);
349 if (ListView::get_selected_rows().empty())
351 maPosition
= Point(0, 0);
354 maCreateContextMenuHdl
.Call(maSelectedItem
);
359 IMPL_LINK_NOARG(TemplateDlgLocalView
, ListViewChangedHdl
, weld::TreeView
&, void)
364 bool TemplateDlgLocalView::KeyInput(const KeyEvent
& rKEvt
)
366 vcl::KeyCode aKeyCode
= rKEvt
.GetKeyCode();
368 if (aKeyCode
== (KEY_MOD1
| KEY_A
))
370 for (ThumbnailViewItem
* pItem
: mFilteredItemList
)
372 if (!pItem
->isSelected())
374 pItem
->setSelection(true);
375 maItemStateHdl
.Call(pItem
);
379 if (IsReallyVisible() && IsUpdateMode())
383 else if (aKeyCode
== KEY_DELETE
&& !mFilteredItemList
.empty())
385 std::unique_ptr
<weld::MessageDialog
> xQueryDlg(Application::CreateMessageDialog(
386 GetDrawingArea(), VclMessageType::Question
, VclButtonsType::YesNo
,
387 SfxResId(STR_QMSG_SEL_TEMPLATE_DELETE
)));
388 if (xQueryDlg
->run() != RET_YES
)
391 maDeleteTemplateHdl
.Call(maSelectedItem
);
395 return ThumbnailView::KeyInput(rKEvt
);
398 IMPL_LINK(TemplateDlgLocalView
, KeyPressHdl
, const KeyEvent
&, rKEvt
, bool)
400 vcl::KeyCode aKeyCode
= rKEvt
.GetKeyCode();
402 if (aKeyCode
== KEY_DELETE
&& !mFilteredItemList
.empty()
403 && !ListView::get_selected_rows().empty())
405 std::unique_ptr
<weld::MessageDialog
> xQueryDlg(Application::CreateMessageDialog(
406 mxTreeView
.get(), VclMessageType::Question
, VclButtonsType::YesNo
,
407 SfxResId(STR_QMSG_SEL_TEMPLATE_DELETE
)));
408 if (xQueryDlg
->run() != RET_YES
)
411 maDeleteTemplateHdl
.Call(maSelectedItem
);
416 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */