a11y: Simplify OCommonAccessibleComponent::getAccessibleIndexInParent
[LibreOffice.git] / cui / source / customize / SvxToolbarConfigPage.cxx
blob95afc2e1235930e92015ee8a6b596173044ba3a3
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/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
21 #include <sal/log.hxx>
23 #include <vcl/event.hxx>
24 #include <vcl/weld.hxx>
25 #include <vcl/svapp.hxx>
26 #include <vcl/commandevent.hxx>
28 #include <sfx2/sfxsids.hrc>
29 #include <svl/stritem.hxx>
30 #include <comphelper/diagnose_ex.hxx>
32 #include <algorithm>
33 #include <helpids.h>
34 #include <strings.hrc>
36 #include <cfg.hxx>
37 #include <SvxToolbarConfigPage.hxx>
38 #include <SvxConfigPageHelper.hxx>
39 #include <dialmgr.hxx>
41 #include <dlgname.hxx>
42 #include <comphelper/processfactory.hxx>
44 SvxToolbarConfigPage::SvxToolbarConfigPage(weld::Container* pPage,
45 weld::DialogController* pController,
46 const SfxItemSet& rSet)
47 : SvxConfigPage(pPage, pController, rSet)
49 m_xGearBtn = m_xBuilder->weld_menu_button(u"toolbargearbtn"_ustr);
50 m_xGearBtn->show();
51 m_xContainer->set_help_id(HID_SVX_CONFIG_TOOLBAR);
53 m_xContentsListBox.reset(
54 new SvxToolbarEntriesListBox(m_xBuilder->weld_tree_view(u"toolcontents"_ustr), this));
55 m_xDropTargetHelper.reset(
56 new SvxConfigPageFunctionDropTarget(*this, m_xContentsListBox->get_widget()));
58 weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
59 Size aSize(m_xFunctions->get_size_request());
60 rTreeView.set_size_request(aSize.Width(), aSize.Height());
62 rTreeView.set_hexpand(true);
63 rTreeView.set_vexpand(true);
64 rTreeView.set_help_id(HID_SVX_CONFIG_TOOLBAR_CONTENTS);
65 rTreeView.show();
67 rTreeView.connect_selection_changed(LINK(this, SvxToolbarConfigPage, SelectToolbarEntry));
68 rTreeView.connect_popup_menu(LINK(this, SvxToolbarConfigPage, ContentContextMenuHdl));
70 m_xFunctions->get_widget().connect_popup_menu(
71 LINK(this, SvxToolbarConfigPage, FunctionContextMenuHdl));
73 m_xTopLevelListBox->set_help_id(HID_SVX_TOPLEVELLISTBOX);
74 m_xSaveInListBox->set_help_id(HID_SVX_SAVE_IN);
75 m_xMoveUpButton->set_help_id(HID_SVX_UP_TOOLBAR_ITEM);
76 m_xMoveDownButton->set_help_id(HID_SVX_DOWN_TOOLBAR_ITEM);
77 m_xDescriptionField->set_help_id(HID_SVX_DESCFIELD);
79 m_xCommandCategoryListBox->connect_changed(LINK(this, SvxToolbarConfigPage, SelectCategory));
81 m_xGearBtn->connect_selected(LINK(this, SvxToolbarConfigPage, GearHdl));
83 m_xMoveUpButton->connect_clicked(LINK(this, SvxToolbarConfigPage, MoveHdl));
84 m_xMoveDownButton->connect_clicked(LINK(this, SvxToolbarConfigPage, MoveHdl));
85 // Always enable Up and Down buttons
86 // added for issue i53677 by shizhoubo
87 m_xMoveDownButton->set_sensitive(true);
88 m_xMoveUpButton->set_sensitive(true);
90 m_xAddCommandButton->connect_clicked(LINK(this, SvxToolbarConfigPage, AddCommandHdl));
91 m_xRemoveCommandButton->connect_clicked(LINK(this, SvxToolbarConfigPage, RemoveCommandHdl));
93 m_xInsertBtn->connect_selected(LINK(this, SvxToolbarConfigPage, InsertHdl));
94 m_xModifyBtn->connect_selected(LINK(this, SvxToolbarConfigPage, ModifyItemHdl));
95 m_xResetBtn->connect_clicked(LINK(this, SvxToolbarConfigPage, ResetToolbarHdl));
97 // "Insert Submenu" is irrelevant to the toolbars
98 m_xInsertBtn->remove_item(u"insertsubmenu"_ustr);
100 // Gear menu's "Move" action is irrelevant to the toolbars
101 m_xGearBtn->set_item_sensitive(u"toolbar_gear_move"_ustr, false);
103 // default toolbar to select is standardbar unless a different one
104 // has been passed in
105 m_aURLToSelect = ITEM_TOOLBAR_URL;
106 m_aURLToSelect += "standardbar";
108 const SfxPoolItem* pItem = rSet.GetItem(SID_CONFIG);
110 if (pItem)
112 OUString text = static_cast<const SfxStringItem*>(pItem)->GetValue();
113 if (text.startsWith(ITEM_TOOLBAR_URL))
115 m_aURLToSelect = text.copy(0);
120 void SvxToolbarConfigPage::ListModified()
122 // regenerate with the current ordering within the list
123 SvxEntries* pEntries = GetTopLevelSelection()->GetEntries();
124 pEntries->clear();
126 for (int i = 0; i < m_xContentsListBox->n_children(); ++i)
127 pEntries->push_back(weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(i)));
129 GetSaveInData()->SetModified();
130 GetTopLevelSelection()->SetModified();
132 SvxConfigEntry* pToolbar = GetTopLevelSelection();
133 if (pToolbar)
134 static_cast<ToolbarSaveInData*>(GetSaveInData())->ApplyToolbar(pToolbar);
137 SvxToolbarConfigPage::~SvxToolbarConfigPage()
139 for (int i = 0, nCount = m_xSaveInListBox->get_count(); i < nCount; ++i)
141 ToolbarSaveInData* pData = weld::fromId<ToolbarSaveInData*>(m_xSaveInListBox->get_id(i));
142 delete pData;
144 m_xSaveInListBox->clear();
147 void SvxToolbarConfigPage::DeleteSelectedTopLevel()
149 const sal_Int32 nSelectionPos = m_xTopLevelListBox->get_active();
150 ToolbarSaveInData* pSaveInData = static_cast<ToolbarSaveInData*>(GetSaveInData());
151 pSaveInData->RemoveToolbar(GetTopLevelSelection());
153 int nCount = m_xTopLevelListBox->get_count();
154 if (nCount > 1)
156 // select next entry after the one being deleted
157 // selection position is indexed from 0 so need to
158 // subtract one from the entry count
159 if (nSelectionPos != nCount - 1)
161 m_xTopLevelListBox->set_active(nSelectionPos + 1);
163 else
165 m_xTopLevelListBox->set_active(nSelectionPos - 1);
167 SelectElement();
169 // and now remove the entry
170 m_xTopLevelListBox->remove(nSelectionPos);
172 else
174 ReloadTopLevelListBox();
178 void SvxToolbarConfigPage::DeleteSelectedContent()
180 int nActEntry = m_xContentsListBox->get_selected_index();
182 if (nActEntry == -1)
183 return;
185 // get currently selected entry
186 SvxConfigEntry* pEntry = weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(nActEntry));
188 SvxConfigEntry* pToolbar = GetTopLevelSelection();
190 // remove entry from the list for this toolbar
191 SvxConfigPageHelper::RemoveEntry(pToolbar->GetEntries(), pEntry);
193 // remove toolbar entry from UI
194 m_xContentsListBox->remove(nActEntry);
196 // delete data for toolbar entry
197 delete pEntry;
199 static_cast<ToolbarSaveInData*>(GetSaveInData())->ApplyToolbar(pToolbar);
200 UpdateButtonStates();
202 // if this is the last entry in the toolbar and it is a user
203 // defined toolbar pop up a dialog asking the user if they
204 // want to delete the toolbar
205 if (m_xContentsListBox->n_children() == 0 && GetTopLevelSelection()->IsDeletable())
207 std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(
208 GetFrameWeld(), VclMessageType::Question, VclButtonsType::YesNo,
209 CuiResId(RID_SXVSTR_CONFIRM_DELETE_TOOLBAR)));
210 if (xQueryBox->run() == RET_YES)
212 DeleteSelectedTopLevel();
217 IMPL_LINK(SvxToolbarConfigPage, MoveHdl, weld::Button&, rButton, void)
219 MoveEntry(&rButton == m_xMoveUpButton.get());
222 void SvxToolbarConfigPage::MoveEntry(bool bMoveUp)
224 SvxConfigPage::MoveEntry(bMoveUp);
226 // Apply change to currently selected toolbar
227 SvxConfigEntry* pToolbar = GetTopLevelSelection();
228 if (pToolbar)
229 static_cast<ToolbarSaveInData*>(GetSaveInData())->ApplyToolbar(pToolbar);
230 else
232 SAL_WARN("cui.customize", "SvxToolbarConfigPage::MoveEntry(): no entry");
233 UpdateButtonStates();
237 void SvxToolbarConfigPage::Init()
239 // ensure that the UI is cleared before populating it
240 m_xTopLevelListBox->clear();
241 m_xContentsListBox->clear();
243 ReloadTopLevelListBox();
245 sal_Int32 nCount = m_xTopLevelListBox->get_count();
246 sal_Int32 nPos = nCount > 0 ? 0 : -1;
248 if (!m_aURLToSelect.isEmpty())
250 for (sal_Int32 i = 0; i < nCount; ++i)
252 SvxConfigEntry* pData = weld::fromId<SvxConfigEntry*>(m_xTopLevelListBox->get_id(i));
254 if (pData->GetCommand().equals(m_aURLToSelect))
256 nPos = i;
257 break;
261 // in future select the default toolbar: Standard
262 m_aURLToSelect = ITEM_TOOLBAR_URL;
263 m_aURLToSelect += "standardbar";
266 m_xTopLevelListBox->set_active(nPos);
267 SelectElement();
269 m_xCommandCategoryListBox->Init(comphelper::getProcessComponentContext(), m_xFrame,
270 m_aModuleId);
271 m_xCommandCategoryListBox->categorySelected(m_xFunctions.get(), OUString(), GetSaveInData());
272 SelectFunctionHdl(m_xFunctions->get_widget());
275 SaveInData* SvxToolbarConfigPage::CreateSaveInData(
276 const css::uno::Reference<css::ui::XUIConfigurationManager>& xCfgMgr,
277 const css::uno::Reference<css::ui::XUIConfigurationManager>& xParentCfgMgr,
278 const OUString& aModuleId, bool bDocConfig)
280 return static_cast<SaveInData*>(
281 new ToolbarSaveInData(xCfgMgr, xParentCfgMgr, aModuleId, bDocConfig));
284 IMPL_LINK_NOARG(SvxToolbarConfigPage, SelectToolbarEntry, weld::TreeView&, void)
286 UpdateButtonStates();
289 IMPL_LINK(SvxToolbarConfigPage, GearHdl, const OUString&, rIdent, void)
291 SvxConfigEntry* pCurrentToolbar = GetTopLevelSelection();
293 if (rIdent == "toolbar_gear_add")
295 OUString prefix = CuiResId(RID_CUISTR_NEW_TOOLBAR);
297 OUString aNewName
298 = SvxConfigPageHelper::generateCustomName(prefix, GetSaveInData()->GetEntries());
300 OUString aNewURL = SvxConfigPageHelper::generateCustomURL(GetSaveInData()->GetEntries());
302 SvxNewToolbarDialog aNameDialog(GetFrameWeld(), aNewName);
304 // Reflect the actual m_xSaveInListBox into the new toolbar dialog
305 for (int i = 0, nCount = m_xSaveInListBox->get_count(); i < nCount; ++i)
306 aNameDialog.m_xSaveInListBox->append_text(m_xSaveInListBox->get_text(i));
308 aNameDialog.m_xSaveInListBox->set_active(m_xSaveInListBox->get_active());
310 if (aNameDialog.run() == RET_OK)
312 aNewName = aNameDialog.GetName();
314 // Where to save the new toolbar? (i.e. Modulewise or documentwise)
315 int nInsertPos = aNameDialog.m_xSaveInListBox->get_active();
317 ToolbarSaveInData* pData
318 = weld::fromId<ToolbarSaveInData*>(m_xSaveInListBox->get_id(nInsertPos));
320 if (GetSaveInData() != pData)
322 m_xSaveInListBox->set_active(nInsertPos);
323 SelectSaveInLocation(*m_xSaveInListBox);
326 SvxConfigEntry* pToolbar = new SvxConfigEntry(aNewName, aNewURL, true, false);
328 pToolbar->SetUserDefined();
329 pToolbar->SetMain();
331 pData->CreateToolbar(pToolbar);
333 OUString sId(weld::toId(pToolbar));
334 m_xTopLevelListBox->append(sId, pToolbar->GetName());
335 m_xTopLevelListBox->set_active_id(sId);
336 SelectElement();
338 pData->SetModified();
341 else if (rIdent == "toolbar_gear_delete")
343 if (pCurrentToolbar && pCurrentToolbar->IsDeletable())
345 DeleteSelectedTopLevel();
346 UpdateButtonStates();
349 else if (rIdent == "toolbar_gear_rename")
351 sal_Int32 nSelectionPos = m_xTopLevelListBox->get_active();
352 SvxConfigEntry* pToolbar
353 = weld::fromId<SvxConfigEntry*>(m_xTopLevelListBox->get_id(nSelectionPos));
354 ToolbarSaveInData* pSaveInData = static_cast<ToolbarSaveInData*>(GetSaveInData());
356 //Rename the toolbar
357 OUString sCurrentName(SvxConfigPageHelper::stripHotKey(pToolbar->GetName()));
358 OUString sDesc = CuiResId(RID_CUISTR_LABEL_NEW_NAME);
360 SvxNameDialog aNameDialog(GetFrameWeld(), sCurrentName, sDesc);
361 aNameDialog.set_help_id(HID_SVX_CONFIG_RENAME_TOOLBAR);
362 aNameDialog.set_title(CuiResId(RID_CUISTR_RENAME_TOOLBAR));
364 if (aNameDialog.run() == RET_OK)
366 OUString sNewName = aNameDialog.GetName();
368 if (sCurrentName == sNewName)
369 return;
371 pToolbar->SetName(sNewName);
372 pSaveInData->ApplyToolbar(pToolbar);
374 // have to use remove and insert to change the name
375 m_xTopLevelListBox->remove(nSelectionPos);
376 OUString sId(weld::toId(pToolbar));
377 m_xTopLevelListBox->insert(nSelectionPos, sNewName, &sId, nullptr, nullptr);
378 m_xTopLevelListBox->set_active_id(sId);
381 else if (rIdent == "toolbar_gear_iconOnly" || rIdent == "toolbar_gear_textOnly"
382 || rIdent == "toolbar_gear_iconAndText")
384 ToolbarSaveInData* pSaveInData = static_cast<ToolbarSaveInData*>(GetSaveInData());
386 if (pCurrentToolbar == nullptr || pSaveInData == nullptr)
388 SAL_WARN("cui.customize", "NULL toolbar or savein data");
389 return;
392 sal_Int32 nStyle = 0;
393 if (rIdent == "toolbar_gear_iconOnly")
394 nStyle = 0;
395 else if (rIdent == "toolbar_gear_textOnly")
396 nStyle = 1;
397 else if (rIdent == "toolbar_gear_iconAndText")
398 nStyle = 2;
400 pCurrentToolbar->SetStyle(nStyle);
401 pSaveInData->SetSystemStyle(m_xFrame, pCurrentToolbar->GetCommand(), nStyle);
403 SelectElement();
405 else
407 //This block should never be reached
408 SAL_WARN("cui.customize", "Unknown gear menu option: " << rIdent);
409 return;
413 IMPL_LINK_NOARG(SvxToolbarConfigPage, SelectCategory, weld::ComboBox&, void)
415 OUString aSearchTerm(m_xSearchEdit->get_text());
417 m_xCommandCategoryListBox->categorySelected(m_xFunctions.get(), aSearchTerm, GetSaveInData());
419 SelectFunctionHdl(m_xFunctions->get_widget());
422 IMPL_LINK_NOARG(SvxToolbarConfigPage, AddCommandHdl, weld::Button&, void) { AddFunction(); }
424 IMPL_LINK_NOARG(SvxToolbarConfigPage, RemoveCommandHdl, weld::Button&, void)
426 DeleteSelectedContent();
429 IMPL_LINK(SvxToolbarConfigPage, InsertHdl, const OUString&, rIdent, void)
431 if (rIdent == "insertseparator")
433 // Get the currently selected toolbar
434 SvxConfigEntry* pToolbar = GetTopLevelSelection();
436 SvxConfigEntry* pNewEntryData = new SvxConfigEntry;
437 pNewEntryData->SetUserDefined();
439 int nPos = AppendEntry(pNewEntryData, -1);
440 InsertEntryIntoUI(pNewEntryData, m_xContentsListBox->get_widget(), nPos);
442 static_cast<ToolbarSaveInData*>(GetSaveInData())->ApplyToolbar(pToolbar);
444 UpdateButtonStates();
446 else
448 //This block should never be reached
449 SAL_WARN("cui.customize", "Unknown insert option: " << rIdent);
450 return;
454 IMPL_LINK(SvxToolbarConfigPage, ModifyItemHdl, const OUString&, rIdent, void)
456 bool bNeedsApply = false;
458 // get currently selected toolbar
459 SvxConfigEntry* pToolbar = GetTopLevelSelection();
461 if (rIdent.isEmpty() || pToolbar == nullptr)
463 SAL_WARN("cui.customize", "No toolbar selected, or empty rIdent!");
464 return;
467 if (rIdent == "renameItem")
469 int nActEntry = m_xContentsListBox->get_selected_index();
470 SvxConfigEntry* pEntry
471 = weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(nActEntry));
473 OUString aNewName(SvxConfigPageHelper::stripHotKey(pEntry->GetName()));
474 OUString aDesc = CuiResId(RID_CUISTR_LABEL_NEW_NAME);
476 SvxNameDialog aNameDialog(GetFrameWeld(), aNewName, aDesc);
477 aNameDialog.set_help_id(HID_SVX_CONFIG_RENAME_TOOLBAR_ITEM);
478 aNameDialog.set_title(CuiResId(RID_CUISTR_RENAME_TOOLBAR));
480 if (aNameDialog.run() == RET_OK)
482 aNewName = aNameDialog.GetName();
484 if (aNewName.isEmpty()) // tdf#80758 - Accelerator character ("~") is passed as
485 pEntry->SetName(u"~"_ustr); // the button name in case of empty values.
486 else
487 pEntry->SetName(aNewName);
489 m_xContentsListBox->set_text(nActEntry, aNewName, 0);
490 bNeedsApply = true;
493 else if (rIdent == "changeIcon")
495 int nActEntry = m_xContentsListBox->get_selected_index();
496 SvxConfigEntry* pEntry
497 = weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(nActEntry));
499 SvxIconSelectorDialog aIconDialog(GetFrameWeld(), GetSaveInData()->GetImageManager(),
500 GetSaveInData()->GetParentImageManager());
502 if (aIconDialog.run() == RET_OK)
504 css::uno::Reference<css::graphic::XGraphic> newgraphic = aIconDialog.GetSelectedIcon();
506 if (newgraphic.is())
508 css::uno::Sequence<OUString> aURLSeq{ pEntry->GetCommand() };
510 if (!pEntry->GetBackupGraphic().is())
512 css::uno::Reference<css::graphic::XGraphic> backup
513 = SvxConfigPageHelper::GetGraphic(GetSaveInData()->GetImageManager(),
514 aURLSeq[0]);
516 if (backup.is())
518 pEntry->SetBackupGraphic(backup);
522 css::uno::Sequence<css::uno::Reference<css::graphic::XGraphic>> aGraphicSeq{
523 newgraphic
527 GetSaveInData()->GetImageManager()->replaceImages(
528 SvxConfigPageHelper::GetImageType(), aURLSeq, aGraphicSeq);
530 m_xContentsListBox->remove(nActEntry);
532 OUString sId(weld::toId(pEntry));
533 m_xContentsListBox->insert(nActEntry, sId);
534 m_xContentsListBox->set_toggle(nActEntry, pEntry->IsVisible() ? TRISTATE_TRUE
535 : TRISTATE_FALSE);
536 InsertEntryIntoUI(pEntry, m_xContentsListBox->get_widget(), nActEntry);
538 m_xContentsListBox->select(nActEntry);
539 m_xContentsListBox->scroll_to_row(nActEntry);
541 GetSaveInData()->PersistChanges(GetSaveInData()->GetImageManager());
543 catch (const css::uno::Exception&)
545 TOOLS_WARN_EXCEPTION("cui.customize", "Error replacing image");
550 else if (rIdent == "resetIcon")
552 int nActEntry = m_xContentsListBox->get_selected_index();
553 SvxConfigEntry* pEntry
554 = weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(nActEntry));
556 css::uno::Sequence<css::uno::Reference<css::graphic::XGraphic>> aGraphicSeq{
557 pEntry->GetBackupGraphic()
560 css::uno::Sequence<OUString> aURLSeq{ pEntry->GetCommand() };
564 GetSaveInData()->GetImageManager()->replaceImages(SvxConfigPageHelper::GetImageType(),
565 aURLSeq, aGraphicSeq);
567 m_xContentsListBox->remove(nActEntry);
569 OUString sId(weld::toId(pEntry));
570 m_xContentsListBox->insert(nActEntry, sId);
571 m_xContentsListBox->set_toggle(nActEntry,
572 pEntry->IsVisible() ? TRISTATE_TRUE : TRISTATE_FALSE);
573 InsertEntryIntoUI(pEntry, m_xContentsListBox->get_widget(), nActEntry);
575 m_xContentsListBox->select(nActEntry);
576 m_xContentsListBox->scroll_to_row(nActEntry);
578 // reset backup in entry
579 pEntry->SetBackupGraphic(css::uno::Reference<css::graphic::XGraphic>());
581 GetSaveInData()->PersistChanges(GetSaveInData()->GetImageManager());
583 catch (const css::uno::Exception&)
585 TOOLS_WARN_EXCEPTION("cui.customize", "Error resetting image");
588 else if (rIdent == "restoreItem")
590 int nActEntry = m_xContentsListBox->get_selected_index();
591 SvxConfigEntry* pEntry
592 = weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(nActEntry));
594 ToolbarSaveInData* pSaveInData = static_cast<ToolbarSaveInData*>(GetSaveInData());
596 OUString aSystemName = pSaveInData->GetSystemUIName(pEntry->GetCommand());
598 if (!pEntry->GetName().equals(aSystemName))
600 pEntry->SetName(aSystemName);
601 m_xContentsListBox->set_text(nActEntry, SvxConfigPageHelper::stripHotKey(aSystemName),
603 bNeedsApply = true;
606 css::uno::Sequence<OUString> aURLSeq{ pEntry->GetCommand() };
610 GetSaveInData()->GetImageManager()->removeImages(SvxConfigPageHelper::GetImageType(),
611 aURLSeq);
613 // reset backup in entry
614 pEntry->SetBackupGraphic(css::uno::Reference<css::graphic::XGraphic>());
616 GetSaveInData()->PersistChanges(GetSaveInData()->GetImageManager());
618 m_xContentsListBox->remove(nActEntry);
620 OUString sId(weld::toId(pEntry));
621 m_xContentsListBox->insert(nActEntry, sId);
622 m_xContentsListBox->set_toggle(nActEntry,
623 pEntry->IsVisible() ? TRISTATE_TRUE : TRISTATE_FALSE);
624 InsertEntryIntoUI(pEntry, m_xContentsListBox->get_widget(), nActEntry);
626 m_xContentsListBox->select(nActEntry);
627 m_xContentsListBox->scroll_to_row(nActEntry);
629 bNeedsApply = true;
631 catch (const css::uno::Exception&)
633 TOOLS_WARN_EXCEPTION("cui.customize", "Error restoring image");
636 else
638 //This block should never be reached
639 SAL_WARN("cui.customize", "Unknown insert option: " << rIdent);
640 return;
643 if (bNeedsApply)
645 static_cast<ToolbarSaveInData*>(GetSaveInData())->ApplyToolbar(pToolbar);
646 UpdateButtonStates();
650 IMPL_LINK_NOARG(SvxToolbarConfigPage, ResetToolbarHdl, weld::Button&, void)
652 sal_Int32 nSelectionPos = m_xTopLevelListBox->get_active();
654 SvxConfigEntry* pToolbar
655 = weld::fromId<SvxConfigEntry*>(m_xTopLevelListBox->get_id(nSelectionPos));
657 std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(
658 GetFrameWeld(), VclMessageType::Question, VclButtonsType::YesNo,
659 CuiResId(RID_CUISTR_CONFIRM_RESTORE_DEFAULT)));
660 if (xQueryBox->run() == RET_YES)
662 ToolbarSaveInData* pSaveInData = static_cast<ToolbarSaveInData*>(GetSaveInData());
664 pSaveInData->RestoreToolbar(pToolbar);
666 SelectElement();
670 void SvxToolbarConfigPage::UpdateButtonStates()
672 SvxConfigEntry* pToolbar = GetTopLevelSelection();
673 int selection = m_xContentsListBox->get_selected_index();
675 bool bIsSeparator
676 = selection != -1
677 && weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(selection))->IsSeparator();
678 bool bIsValidSelection = (m_xContentsListBox->n_children() != 0 && selection != -1);
680 m_xMoveUpButton->set_sensitive(bIsValidSelection);
681 m_xMoveDownButton->set_sensitive(bIsValidSelection);
683 m_xRemoveCommandButton->set_sensitive(bIsValidSelection);
685 m_xModifyBtn->set_sensitive(bIsValidSelection && !bIsSeparator);
687 // Handle the gear button
688 // "toolbar_gear_add" option is always enabled
689 m_xGearBtn->set_item_sensitive(u"toolbar_gear_delete"_ustr,
690 pToolbar && pToolbar->IsDeletable());
691 m_xGearBtn->set_item_sensitive(u"toolbar_gear_rename"_ustr,
692 pToolbar && pToolbar->IsRenamable());
695 short SvxToolbarConfigPage::QueryReset()
697 OUString msg = CuiResId(RID_CUISTR_CONFIRM_TOOLBAR_RESET);
699 OUString saveInName = m_xSaveInListBox->get_active_text();
701 OUString label = SvxConfigPageHelper::replaceSaveInName(msg, saveInName);
703 std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(
704 GetFrameWeld(), VclMessageType::Question, VclButtonsType::YesNo, label));
705 return xQueryBox->run();
708 void SvxToolbarConfigPage::SelectElement()
710 m_xContentsListBox->clear();
712 SvxConfigEntry* pToolbar = GetTopLevelSelection();
713 if (pToolbar == nullptr)
715 //TODO: Disable related buttons
716 m_xInsertBtn->set_sensitive(false);
717 m_xResetBtn->set_sensitive(false);
718 m_xGearBtn->set_sensitive(false);
720 return;
722 else
724 m_xInsertBtn->set_sensitive(true);
725 m_xResetBtn->set_sensitive(true);
726 m_xGearBtn->set_sensitive(true);
729 switch (pToolbar->GetStyle())
731 case 0:
733 m_xGearBtn->set_item_active(u"toolbar_gear_iconOnly"_ustr, true);
734 break;
736 case 1:
738 m_xGearBtn->set_item_active(u"toolbar_gear_textOnly"_ustr, true);
739 break;
741 case 2:
743 m_xGearBtn->set_item_active(u"toolbar_gear_iconAndText"_ustr, true);
744 break;
748 int i = 0;
749 SvxEntries* pEntries = pToolbar->GetEntries();
750 for (auto const& entry : *pEntries)
752 OUString sId(weld::toId(entry));
753 m_xContentsListBox->insert(i, sId);
754 if (entry->IsBinding() && !entry->IsSeparator())
755 m_xContentsListBox->set_toggle(i, entry->IsVisible() ? TRISTATE_TRUE : TRISTATE_FALSE);
756 InsertEntryIntoUI(entry, m_xContentsListBox->get_widget(), i);
757 ++i;
760 UpdateButtonStates();
763 void SvxToolbarConfigPage::AddFunction(int nTarget)
765 SvxConfigEntry* pToolbar = GetTopLevelSelection();
767 if (pToolbar == nullptr)
768 return;
770 // Add the command to the contents listbox of the selected toolbar
771 int nNewLBEntry = SvxConfigPage::AddFunction(nTarget, true /*bAllowDuplicates*/);
773 if (nNewLBEntry == -1)
774 return;
776 SvxConfigEntry* pEntry = weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(nNewLBEntry));
778 if (pEntry->IsBinding()) //TODO sep ?
780 pEntry->SetVisible(true);
781 m_xContentsListBox->set_toggle(nNewLBEntry, TRISTATE_TRUE);
784 InsertEntryIntoUI(pEntry, m_xContentsListBox->get_widget(), nNewLBEntry);
786 // Changes are not visible on the toolbar until this point
787 // TODO: Figure out a way to show the changes on the toolbar, but revert if
788 // the dialog is closed by pressing "Cancel"
789 // get currently selected toolbar and apply change
790 if (pToolbar != nullptr)
792 static_cast<ToolbarSaveInData*>(GetSaveInData())->ApplyToolbar(pToolbar);
796 SvxToolbarEntriesListBox::SvxToolbarEntriesListBox(std::unique_ptr<weld::TreeView> xParent,
797 SvxToolbarConfigPage* pPg)
798 : SvxMenuEntriesListBox(std::move(xParent), pPg)
800 m_xControl->connect_toggled(LINK(this, SvxToolbarEntriesListBox, CheckButtonHdl));
801 m_xControl->connect_key_press(
802 Link<const KeyEvent&, bool>()); //acknowledge we first remove the old one
803 m_xControl->connect_key_press(
804 LINK(this, SvxToolbarEntriesListBox, KeyInputHdl)); // then add the new one
807 SvxToolbarEntriesListBox::~SvxToolbarEntriesListBox() {}
809 void SvxToolbarEntriesListBox::ChangedVisibility(int nRow)
811 SvxConfigEntry* pEntryData = weld::fromId<SvxConfigEntry*>(m_xControl->get_id(nRow));
813 if (pEntryData->IsBinding())
815 pEntryData->SetVisible(m_xControl->get_toggle(nRow) == TRISTATE_TRUE);
817 SvxConfigEntry* pToolbar = m_pPage->GetTopLevelSelection();
819 ToolbarSaveInData* pToolbarSaveInData
820 = static_cast<ToolbarSaveInData*>(m_pPage->GetSaveInData());
822 pToolbarSaveInData->ApplyToolbar(pToolbar);
826 IMPL_LINK(SvxToolbarEntriesListBox, CheckButtonHdl, const weld::TreeView::iter_col&, rRowCol, void)
828 ChangedVisibility(m_xControl->get_iter_index_in_parent(rRowCol.first));
831 IMPL_LINK(SvxToolbarEntriesListBox, KeyInputHdl, const KeyEvent&, rKeyEvent, bool)
833 // space key will change visibility of toolbar items
834 if (rKeyEvent.GetKeyCode() == KEY_SPACE)
836 int nRow = m_xControl->get_selected_index();
837 SvxConfigEntry* pEntryData = weld::fromId<SvxConfigEntry*>(m_xControl->get_id(nRow));
838 if (pEntryData->IsBinding() && !pEntryData->IsSeparator())
840 m_xControl->set_toggle(nRow, m_xControl->get_toggle(nRow) == TRISTATE_TRUE
841 ? TRISTATE_FALSE
842 : TRISTATE_TRUE);
843 ChangedVisibility(nRow);
845 return true;
847 return SvxMenuEntriesListBox::KeyInputHdl(rKeyEvent);
850 IMPL_LINK(SvxToolbarConfigPage, ContentContextMenuHdl, const CommandEvent&, rCEvt, bool)
852 if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
853 return false;
855 weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
857 // Select clicked entry
858 std::unique_ptr<weld::TreeIter> xIter(rTreeView.make_iterator());
859 if (!rTreeView.get_dest_row_at_pos(rCEvt.GetMousePosPixel(), xIter.get(), false))
860 return false;
861 rTreeView.select(*xIter);
862 SelectToolbarEntry(rTreeView);
864 int nSelectIndex = m_xContentsListBox->get_selected_index();
866 bool bIsSeparator
867 = nSelectIndex != -1
868 && weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(nSelectIndex))->IsSeparator();
869 bool bIsValidSelection = (m_xContentsListBox->n_children() != 0 && nSelectIndex != -1);
871 std::unique_ptr<weld::Builder> xBuilder(
872 Application::CreateBuilder(&rTreeView, u"cui/ui/entrycontextmenu.ui"_ustr));
873 auto xContextMenu = xBuilder->weld_menu(u"menu"_ustr);
874 xContextMenu->set_visible(u"add"_ustr, false);
875 xContextMenu->set_visible(u"remove"_ustr, bIsValidSelection);
876 xContextMenu->set_visible(u"rename"_ustr, bIsValidSelection && !bIsSeparator);
877 xContextMenu->set_visible(u"changeIcon"_ustr, bIsValidSelection && !bIsSeparator);
878 xContextMenu->set_visible(u"resetIcon"_ustr, bIsValidSelection && !bIsSeparator);
879 xContextMenu->set_visible(u"restoreDefault"_ustr, bIsValidSelection && !bIsSeparator);
880 OUString sCommand(xContextMenu->popup_at_rect(
881 &rTreeView, tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1, 1))));
883 if (sCommand == "remove")
884 RemoveCommandHdl(*m_xRemoveCommandButton);
885 else if (sCommand == "rename")
886 ModifyItemHdl(u"renameItem"_ustr);
887 else if (sCommand == "changeIcon")
888 ModifyItemHdl(u"changeIcon"_ustr);
889 else if (sCommand == "resetIcon")
890 ModifyItemHdl(u"resetIcon"_ustr);
891 else if (sCommand == "restoreDefault")
892 ModifyItemHdl(u"restoreItem"_ustr);
893 else if (!sCommand.isEmpty())
894 SAL_WARN("cui.customize", "Unknown context menu action: " << sCommand);
895 return true;
898 IMPL_LINK(SvxToolbarConfigPage, FunctionContextMenuHdl, const CommandEvent&, rCEvt, bool)
900 if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
901 return false;
903 weld::TreeView& rTreeView = m_xFunctions->get_widget();
905 // Select clicked entry
906 std::unique_ptr<weld::TreeIter> xIter(rTreeView.make_iterator());
907 if (!rTreeView.get_dest_row_at_pos(rCEvt.GetMousePosPixel(), xIter.get(), false))
908 return false;
909 rTreeView.select(*xIter);
910 SelectFunctionHdl(rTreeView);
911 std::unique_ptr<weld::Builder> xBuilder(
912 Application::CreateBuilder(&rTreeView, u"cui/ui/entrycontextmenu.ui"_ustr));
913 auto xContextMenu = xBuilder->weld_menu(u"menu"_ustr);
914 xContextMenu->set_visible(u"add"_ustr, true);
915 xContextMenu->set_visible(u"remove"_ustr, false);
916 xContextMenu->set_visible(u"rename"_ustr, false);
917 xContextMenu->set_visible(u"changeIcon"_ustr, false);
918 xContextMenu->set_visible(u"resetIcon"_ustr, false);
919 xContextMenu->set_visible(u"restoreDefault"_ustr, false);
920 OUString sCommand(xContextMenu->popup_at_rect(
921 &rTreeView, tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1, 1))));
923 if (sCommand == "add")
924 AddCommandHdl(*m_xAddCommandButton);
925 else if (!sCommand.isEmpty())
926 SAL_WARN("cui.customize", "Unknown context menu action: " << sCommand);
927 return true;
930 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */