bump product version to 7.6.3.2-android
[LibreOffice.git] / cui / source / customize / SvxToolbarConfigPage.cxx
blobbe34445cf19f97088607acb53975d0f94fc9a086
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 <cui/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("toolbargearbtn");
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("toolcontents"), 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_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("insertsubmenu");
100 // Gear menu's "Move" action is irrelevant to the toolbars
101 m_xGearBtn->set_item_sensitive("toolbar_gear_move", 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("~"); // 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::Reference<css::graphic::XGraphic> backup = pEntry->GetBackupGraphic();
558 css::uno::Sequence<css::uno::Reference<css::graphic::XGraphic>> aGraphicSeq{ backup };
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("toolbar_gear_delete", pToolbar && pToolbar->IsDeletable());
690 m_xGearBtn->set_item_sensitive("toolbar_gear_rename", pToolbar && pToolbar->IsRenamable());
693 short SvxToolbarConfigPage::QueryReset()
695 OUString msg = CuiResId(RID_CUISTR_CONFIRM_TOOLBAR_RESET);
697 OUString saveInName = m_xSaveInListBox->get_active_text();
699 OUString label = SvxConfigPageHelper::replaceSaveInName(msg, saveInName);
701 std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(
702 GetFrameWeld(), VclMessageType::Question, VclButtonsType::YesNo, label));
703 return xQueryBox->run();
706 void SvxToolbarConfigPage::SelectElement()
708 m_xContentsListBox->clear();
710 SvxConfigEntry* pToolbar = GetTopLevelSelection();
711 if (pToolbar == nullptr)
713 //TODO: Disable related buttons
714 m_xInsertBtn->set_sensitive(false);
715 m_xResetBtn->set_sensitive(false);
716 m_xGearBtn->set_sensitive(false);
718 return;
720 else
722 m_xInsertBtn->set_sensitive(true);
723 m_xResetBtn->set_sensitive(true);
724 m_xGearBtn->set_sensitive(true);
727 switch (pToolbar->GetStyle())
729 case 0:
731 m_xGearBtn->set_item_active("toolbar_gear_iconOnly", true);
732 break;
734 case 1:
736 m_xGearBtn->set_item_active("toolbar_gear_textOnly", true);
737 break;
739 case 2:
741 m_xGearBtn->set_item_active("toolbar_gear_iconAndText", true);
742 break;
746 int i = 0;
747 SvxEntries* pEntries = pToolbar->GetEntries();
748 for (auto const& entry : *pEntries)
750 OUString sId(weld::toId(entry));
751 m_xContentsListBox->insert(i, sId);
752 if (entry->IsBinding() && !entry->IsSeparator())
753 m_xContentsListBox->set_toggle(i, entry->IsVisible() ? TRISTATE_TRUE : TRISTATE_FALSE);
754 InsertEntryIntoUI(entry, m_xContentsListBox->get_widget(), i);
755 ++i;
758 UpdateButtonStates();
761 void SvxToolbarConfigPage::AddFunction(int nTarget)
763 SvxConfigEntry* pToolbar = GetTopLevelSelection();
765 if (pToolbar == nullptr)
766 return;
768 // Add the command to the contents listbox of the selected toolbar
769 int nNewLBEntry = SvxConfigPage::AddFunction(nTarget, true /*bAllowDuplicates*/);
771 if (nNewLBEntry == -1)
772 return;
774 SvxConfigEntry* pEntry = weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(nNewLBEntry));
776 if (pEntry->IsBinding()) //TODO sep ?
778 pEntry->SetVisible(true);
779 m_xContentsListBox->set_toggle(nNewLBEntry, TRISTATE_TRUE);
782 InsertEntryIntoUI(pEntry, m_xContentsListBox->get_widget(), nNewLBEntry);
784 // Changes are not visible on the toolbar until this point
785 // TODO: Figure out a way to show the changes on the toolbar, but revert if
786 // the dialog is closed by pressing "Cancel"
787 // get currently selected toolbar and apply change
788 if (pToolbar != nullptr)
790 static_cast<ToolbarSaveInData*>(GetSaveInData())->ApplyToolbar(pToolbar);
794 SvxToolbarEntriesListBox::SvxToolbarEntriesListBox(std::unique_ptr<weld::TreeView> xParent,
795 SvxToolbarConfigPage* pPg)
796 : SvxMenuEntriesListBox(std::move(xParent), pPg)
798 m_xControl->connect_toggled(LINK(this, SvxToolbarEntriesListBox, CheckButtonHdl));
799 m_xControl->connect_key_press(
800 Link<const KeyEvent&, bool>()); //acknowledge we first remove the old one
801 m_xControl->connect_key_press(
802 LINK(this, SvxToolbarEntriesListBox, KeyInputHdl)); // then add the new one
805 SvxToolbarEntriesListBox::~SvxToolbarEntriesListBox() {}
807 void SvxToolbarEntriesListBox::ChangedVisibility(int nRow)
809 SvxConfigEntry* pEntryData = weld::fromId<SvxConfigEntry*>(m_xControl->get_id(nRow));
811 if (pEntryData->IsBinding())
813 pEntryData->SetVisible(m_xControl->get_toggle(nRow) == TRISTATE_TRUE);
815 SvxConfigEntry* pToolbar = m_pPage->GetTopLevelSelection();
817 ToolbarSaveInData* pToolbarSaveInData
818 = static_cast<ToolbarSaveInData*>(m_pPage->GetSaveInData());
820 pToolbarSaveInData->ApplyToolbar(pToolbar);
824 IMPL_LINK(SvxToolbarEntriesListBox, CheckButtonHdl, const weld::TreeView::iter_col&, rRowCol, void)
826 ChangedVisibility(m_xControl->get_iter_index_in_parent(rRowCol.first));
829 IMPL_LINK(SvxToolbarEntriesListBox, KeyInputHdl, const KeyEvent&, rKeyEvent, bool)
831 // space key will change visibility of toolbar items
832 if (rKeyEvent.GetKeyCode() == KEY_SPACE)
834 int nRow = m_xControl->get_selected_index();
835 SvxConfigEntry* pEntryData = weld::fromId<SvxConfigEntry*>(m_xControl->get_id(nRow));
836 if (pEntryData->IsBinding() && !pEntryData->IsSeparator())
838 m_xControl->set_toggle(nRow, m_xControl->get_toggle(nRow) == TRISTATE_TRUE
839 ? TRISTATE_FALSE
840 : TRISTATE_TRUE);
841 ChangedVisibility(nRow);
843 return true;
845 return SvxMenuEntriesListBox::KeyInputHdl(rKeyEvent);
848 IMPL_LINK(SvxToolbarConfigPage, ContentContextMenuHdl, const CommandEvent&, rCEvt, bool)
850 if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
851 return false;
853 weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
855 // Select clicked entry
856 std::unique_ptr<weld::TreeIter> xIter(rTreeView.make_iterator());
857 if (!rTreeView.get_dest_row_at_pos(rCEvt.GetMousePosPixel(), xIter.get(), false))
858 return false;
859 rTreeView.select(*xIter);
860 SelectToolbarEntry(rTreeView);
862 int nSelectIndex = m_xContentsListBox->get_selected_index();
864 bool bIsSeparator
865 = nSelectIndex != -1
866 && weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(nSelectIndex))->IsSeparator();
867 bool bIsValidSelection = (m_xContentsListBox->n_children() != 0 && nSelectIndex != -1);
869 std::unique_ptr<weld::Builder> xBuilder(
870 Application::CreateBuilder(&rTreeView, "cui/ui/entrycontextmenu.ui"));
871 auto xContextMenu = xBuilder->weld_menu("menu");
872 xContextMenu->set_visible("add", false);
873 xContextMenu->set_visible("remove", bIsValidSelection);
874 xContextMenu->set_visible("rename", bIsValidSelection && !bIsSeparator);
875 xContextMenu->set_visible("changeIcon", bIsValidSelection && !bIsSeparator);
876 xContextMenu->set_visible("resetIcon", bIsValidSelection && !bIsSeparator);
877 xContextMenu->set_visible("restoreDefault", bIsValidSelection && !bIsSeparator);
878 OUString sCommand(xContextMenu->popup_at_rect(
879 &rTreeView, tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1, 1))));
881 if (sCommand == "remove")
882 RemoveCommandHdl(*m_xRemoveCommandButton);
883 else if (sCommand == "rename")
884 ModifyItemHdl("renameItem");
885 else if (sCommand == "changeIcon")
886 ModifyItemHdl("changeIcon");
887 else if (sCommand == "resetIcon")
888 ModifyItemHdl("resetIcon");
889 else if (sCommand == "restoreDefault")
890 ModifyItemHdl("restoreItem");
891 else if (!sCommand.isEmpty())
892 SAL_WARN("cui.customize", "Unknown context menu action: " << sCommand);
893 return true;
896 IMPL_LINK(SvxToolbarConfigPage, FunctionContextMenuHdl, const CommandEvent&, rCEvt, bool)
898 if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
899 return false;
901 weld::TreeView& rTreeView = m_xFunctions->get_widget();
903 // Select clicked entry
904 std::unique_ptr<weld::TreeIter> xIter(rTreeView.make_iterator());
905 if (!rTreeView.get_dest_row_at_pos(rCEvt.GetMousePosPixel(), xIter.get(), false))
906 return false;
907 rTreeView.select(*xIter);
908 SelectFunctionHdl(rTreeView);
909 std::unique_ptr<weld::Builder> xBuilder(
910 Application::CreateBuilder(&rTreeView, "cui/ui/entrycontextmenu.ui"));
911 auto xContextMenu = xBuilder->weld_menu("menu");
912 xContextMenu->set_visible("add", true);
913 xContextMenu->set_visible("remove", false);
914 xContextMenu->set_visible("rename", false);
915 xContextMenu->set_visible("changeIcon", false);
916 xContextMenu->set_visible("resetIcon", false);
917 xContextMenu->set_visible("restoreDefault", false);
918 OUString sCommand(xContextMenu->popup_at_rect(
919 &rTreeView, tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1, 1))));
921 if (sCommand == "add")
922 AddCommandHdl(*m_xAddCommandButton);
923 else if (!sCommand.isEmpty())
924 SAL_WARN("cui.customize", "Unknown context menu action: " << sCommand);
925 return true;
928 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */