ofz#44991 keep paragraph's that failed to load until import is complete
[LibreOffice.git] / sfx2 / source / control / templatedlglocalview.cxx
blob704468681fb8a31221c96fd0f3ca2018d623732e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
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()
40 mnCurRegionId = 0;
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());
63 break;
68 void TemplateDlgLocalView::reload()
70 mpDocTemplates->Update();
71 OUString sCurRegionName = getRegionItemName(mnCurRegionId);
72 Populate();
73 mnCurRegionId = getRegionId(sCurRegionName);
75 // Check if we are currently browsing a region or root folder
76 if (mnCurRegionId)
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());
85 break;
89 else
90 showAllTemplates();
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);
104 if (!bIsDefault)
105 mxContextMenu->append("default", SfxResId(STR_DEFAULT_TEMPLATE), rDefaultImg);
106 else
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);
116 if (!bIsSingleSel)
118 mxContextMenu->set_sensitive("open", false);
119 mxContextMenu->set_sensitive("edit", false);
120 mxContextMenu->set_sensitive("default", false);
121 mxContextMenu->set_sensitive("rename", false);
123 if (bIsBuiltIn)
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))));
132 Invalidate();
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)
160 return true;
161 for (const auto& rItem : aCurRegionItems)
163 if (rItem.aName == sNewTitle)
165 aTitleEditDlg.SetTooltip(sTooltip.replaceFirst("$1", sNewTitle));
166 return false;
169 return true;
171 if (!aTitleEditDlg.run())
172 return;
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)
187 return;
189 maDeleteTemplateHdl.Call(maSelectedItem);
190 reload();
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);
213 if (!pViewItem)
214 return;
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);
220 ListView::sort();
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();
240 else
242 ThumbnailView::Show();
243 ListView::HideListView();
245 syncCursor();
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();
263 int nIndex = -1;
265 for (auto it = mFilteredItemList.cbegin(); it != mFilteredItemList.cend(); ++it)
267 if ((*it)->mbSelected)
269 nIndex = -1;
270 nIndex = ListView::get_index((*it)->mnId);
271 if (nIndex >= 0)
273 ListView::set_cursor(nIndex);
274 ListView::select(nIndex);
275 break;
279 updateSelection();
281 else
283 ThumbnailView::deselectItems();
284 std::vector<int> aSelRows = ListView::get_selected_rows();
285 if (aSelRows.empty())
286 return;
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;
296 break;
300 size_t nPos = GetItemPos(nCursorId);
301 ThumbnailViewItem* pItem = ImplGetItem(nPos);
302 const TemplateViewItem* pViewItem = dynamic_cast<const TemplateViewItem*>(pItem);
303 if (pViewItem)
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);
320 if (pViewItem)
321 maSelectedItem = dynamic_cast<TemplateViewItem*>(pItem);
322 return;
325 IMPL_LINK_NOARG(TemplateDlgLocalView, RowActivatedHdl, weld::TreeView&, bool)
327 maOpenTemplateHdl.Call(maSelectedItem);
328 return true;
331 IMPL_LINK(TemplateDlgLocalView, PopupMenuHdl, const CommandEvent&, rCEvt, bool)
333 if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
334 return false;
336 if (rCEvt.IsMouseEvent())
338 if (ListView::get_selected_rows().empty())
339 return true;
340 Point aPosition(rCEvt.GetMousePosPixel());
341 maPosition = aPosition;
342 updateSelection();
343 if (maSelectedItem)
344 maCreateContextMenuHdl.Call(maSelectedItem);
345 return true;
347 else
349 if (ListView::get_selected_rows().empty())
350 return true;
351 maPosition = Point(0, 0);
352 updateSelection();
353 if (maSelectedItem)
354 maCreateContextMenuHdl.Call(maSelectedItem);
355 return true;
359 IMPL_LINK_NOARG(TemplateDlgLocalView, ListViewChangedHdl, weld::TreeView&, void)
361 updateSelection();
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())
380 Invalidate();
381 return true;
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)
389 return true;
391 maDeleteTemplateHdl.Call(maSelectedItem);
392 reload();
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)
409 return true;
411 maDeleteTemplateHdl.Call(maSelectedItem);
412 reload();
414 return false;
416 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */