LibreOffice Module cui (master)  1
SvxToolbarConfigPage.cxx
Go to the documentation of this file.
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  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <sal/config.h>
21 #include <sal/log.hxx>
22 
23 #include <vcl/event.hxx>
24 #include <vcl/weld.hxx>
25 #include <vcl/svapp.hxx>
26 #include <vcl/commandevent.hxx>
27 
28 #include <sfx2/sfxsids.hrc>
29 #include <svl/stritem.hxx>
30 #include <tools/diagnose_ex.h>
31 
32 #include <algorithm>
33 #include <helpids.h>
34 #include <strings.hrc>
35 
36 #include <cfg.hxx>
37 #include <SvxToolbarConfigPage.hxx>
38 #include <SvxConfigPageHelper.hxx>
39 #include <dialmgr.hxx>
40 
42 
43 #include <dlgname.hxx>
44 
46  weld::DialogController* pController,
47  const SfxItemSet& rSet)
48  : SvxConfigPage(pPage, pController, rSet)
49 {
50  m_xGearBtn = m_xBuilder->weld_menu_button("toolbargearbtn");
51  m_xGearBtn->show();
53 
54  m_xContentsListBox.reset(
55  new SvxToolbarEntriesListBox(m_xBuilder->weld_tree_view("toolcontents"), this));
56  m_xDropTargetHelper.reset(
57  new SvxConfigPageFunctionDropTarget(*this, m_xContentsListBox->get_widget()));
58 
59  weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
60  Size aSize(m_xFunctions->get_size_request());
61  rTreeView.set_size_request(aSize.Width(), aSize.Height());
62 
63  rTreeView.set_hexpand(true);
64  rTreeView.set_vexpand(true);
66  rTreeView.show();
67 
68  rTreeView.connect_changed(LINK(this, SvxToolbarConfigPage, SelectToolbarEntry));
69  rTreeView.connect_popup_menu(LINK(this, SvxToolbarConfigPage, ContentContextMenuHdl));
70 
71  m_xFunctions->get_widget().connect_popup_menu(
72  LINK(this, SvxToolbarConfigPage, FunctionContextMenuHdl));
73 
75  m_xSaveInListBox->set_help_id(HID_SVX_SAVE_IN);
79 
80  m_xCommandCategoryListBox->connect_changed(LINK(this, SvxToolbarConfigPage, SelectCategory));
81 
82  m_xGearBtn->connect_selected(LINK(this, SvxToolbarConfigPage, GearHdl));
83 
84  m_xMoveUpButton->connect_clicked(LINK(this, SvxToolbarConfigPage, MoveHdl));
85  m_xMoveDownButton->connect_clicked(LINK(this, SvxToolbarConfigPage, MoveHdl));
86  // Always enable Up and Down buttons
87  // added for issue i53677 by shizhoubo
88  m_xMoveDownButton->set_sensitive(true);
89  m_xMoveUpButton->set_sensitive(true);
90 
91  m_xAddCommandButton->connect_clicked(LINK(this, SvxToolbarConfigPage, AddCommandHdl));
92  m_xRemoveCommandButton->connect_clicked(LINK(this, SvxToolbarConfigPage, RemoveCommandHdl));
93 
94  m_xInsertBtn->connect_selected(LINK(this, SvxToolbarConfigPage, InsertHdl));
95  m_xModifyBtn->connect_selected(LINK(this, SvxToolbarConfigPage, ModifyItemHdl));
96  m_xResetBtn->connect_clicked(LINK(this, SvxToolbarConfigPage, ResetToolbarHdl));
97 
98  // "Insert Submenu" is irrelevant to the toolbars
99  m_xInsertBtn->remove_item("insertsubmenu");
100 
101  // Gear menu's "Move" action is irrelevant to the toolbars
102  m_xGearBtn->set_item_sensitive("toolbar_gear_move", false);
103 
104  // default toolbar to select is standardbar unless a different one
105  // has been passed in
107  m_aURLToSelect += "standardbar";
108 
109  const SfxPoolItem* pItem = rSet.GetItem(SID_CONFIG);
110 
111  if (pItem)
112  {
113  OUString text = static_cast<const SfxStringItem*>(pItem)->GetValue();
114  if (text.startsWith(ITEM_TOOLBAR_URL))
115  {
116  m_aURLToSelect = text.copy(0);
117  }
118  }
119 }
120 
122 {
123  // regenerate with the current ordering within the list
124  SvxEntries* pEntries = GetTopLevelSelection()->GetEntries();
125  pEntries->clear();
126 
127  for (int i = 0; i < m_xContentsListBox->n_children(); ++i)
128  pEntries->push_back(weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(i)));
129 
132 
133  SvxConfigEntry* pToolbar = GetTopLevelSelection();
134  if (pToolbar)
135  static_cast<ToolbarSaveInData*>(GetSaveInData())->ApplyToolbar(pToolbar);
136 }
137 
139 {
140  for (int i = 0, nCount = m_xSaveInListBox->get_count(); i < nCount; ++i)
141  {
142  ToolbarSaveInData* pData = weld::fromId<ToolbarSaveInData*>(m_xSaveInListBox->get_id(i));
143  delete pData;
144  }
145  m_xSaveInListBox->clear();
146 }
147 
149 {
150  const sal_Int32 nSelectionPos = m_xTopLevelListBox->get_active();
151  ToolbarSaveInData* pSaveInData = static_cast<ToolbarSaveInData*>(GetSaveInData());
152  pSaveInData->RemoveToolbar(GetTopLevelSelection());
153 
154  int nCount = m_xTopLevelListBox->get_count();
155  if (nCount > 1)
156  {
157  // select next entry after the one being deleted
158  // selection position is indexed from 0 so need to
159  // subtract one from the entry count
160  if (nSelectionPos != nCount - 1)
161  {
162  m_xTopLevelListBox->set_active(nSelectionPos + 1);
163  }
164  else
165  {
166  m_xTopLevelListBox->set_active(nSelectionPos - 1);
167  }
168  SelectElement();
169 
170  // and now remove the entry
171  m_xTopLevelListBox->remove(nSelectionPos);
172  }
173  else
174  {
176  }
177 }
178 
180 {
181  int nActEntry = m_xContentsListBox->get_selected_index();
182 
183  if (nActEntry == -1)
184  return;
185 
186  // get currently selected entry
187  SvxConfigEntry* pEntry = weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(nActEntry));
188 
189  SvxConfigEntry* pToolbar = GetTopLevelSelection();
190 
191  // remove entry from the list for this toolbar
192  SvxConfigPageHelper::RemoveEntry(pToolbar->GetEntries(), pEntry);
193 
194  // remove toolbar entry from UI
195  m_xContentsListBox->remove(nActEntry);
196 
197  // delete data for toolbar entry
198  delete pEntry;
199 
200  static_cast<ToolbarSaveInData*>(GetSaveInData())->ApplyToolbar(pToolbar);
202 
203  // if this is the last entry in the toolbar and it is a user
204  // defined toolbar pop up a dialog asking the user if they
205  // want to delete the toolbar
206  if (m_xContentsListBox->n_children() == 0 && GetTopLevelSelection()->IsDeletable())
207  {
208  std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(
209  GetFrameWeld(), VclMessageType::Question, VclButtonsType::YesNo,
210  CuiResId(RID_SXVSTR_CONFIRM_DELETE_TOOLBAR)));
211  if (xQueryBox->run() == RET_YES)
212  {
214  }
215  }
216 }
217 
218 IMPL_LINK(SvxToolbarConfigPage, MoveHdl, weld::Button&, rButton, void)
219 {
220  MoveEntry(&rButton == m_xMoveUpButton.get());
221 }
222 
224 {
225  SvxConfigPage::MoveEntry(bMoveUp);
226 
227  // Apply change to currently selected toolbar
228  SvxConfigEntry* pToolbar = GetTopLevelSelection();
229  if (pToolbar)
230  static_cast<ToolbarSaveInData*>(GetSaveInData())->ApplyToolbar(pToolbar);
231  else
232  {
233  SAL_WARN("cui.customize", "SvxToolbarConfigPage::MoveEntry(): no entry");
235  }
236 }
237 
239 {
240  // ensure that the UI is cleared before populating it
241  m_xTopLevelListBox->clear();
242  m_xContentsListBox->clear();
243 
245 
246  sal_Int32 nCount = m_xTopLevelListBox->get_count();
247  sal_Int32 nPos = nCount > 0 ? 0 : -1;
248 
249  if (!m_aURLToSelect.isEmpty())
250  {
251  for (sal_Int32 i = 0; i < nCount; ++i)
252  {
253  SvxConfigEntry* pData = weld::fromId<SvxConfigEntry*>(m_xTopLevelListBox->get_id(i));
254 
255  if (pData->GetCommand().equals(m_aURLToSelect))
256  {
257  nPos = i;
258  break;
259  }
260  }
261 
262  // in future select the default toolbar: Standard
264  m_aURLToSelect += "standardbar";
265  }
266 
267  m_xTopLevelListBox->set_active(nPos);
268  SelectElement();
269 
271  m_aModuleId);
272  m_xCommandCategoryListBox->categorySelected(m_xFunctions.get(), OUString(), GetSaveInData());
273  SelectFunctionHdl(m_xFunctions->get_widget());
274 }
275 
277  const css::uno::Reference<css::ui::XUIConfigurationManager>& xCfgMgr,
278  const css::uno::Reference<css::ui::XUIConfigurationManager>& xParentCfgMgr,
279  const OUString& aModuleId, bool bDocConfig)
280 {
281  return static_cast<SaveInData*>(
282  new ToolbarSaveInData(xCfgMgr, xParentCfgMgr, aModuleId, bDocConfig));
283 }
284 
286 {
287  UpdateButtonStates();
288 }
289 
290 IMPL_LINK(SvxToolbarConfigPage, GearHdl, const OString&, rIdent, void)
291 {
292  SvxConfigEntry* pCurrentToolbar = GetTopLevelSelection();
293 
294  if (rIdent == "toolbar_gear_add")
295  {
296  OUString prefix = CuiResId(RID_CUISTR_NEW_TOOLBAR);
297 
298  OUString aNewName
299  = SvxConfigPageHelper::generateCustomName(prefix, GetSaveInData()->GetEntries());
300 
301  OUString aNewURL = SvxConfigPageHelper::generateCustomURL(GetSaveInData()->GetEntries());
302 
303  SvxNewToolbarDialog aNameDialog(GetFrameWeld(), aNewName);
304 
305  // Reflect the actual m_xSaveInListBox into the new toolbar dialog
306  for (int i = 0, nCount = m_xSaveInListBox->get_count(); i < nCount; ++i)
307  aNameDialog.m_xSaveInListBox->append_text(m_xSaveInListBox->get_text(i));
308 
309  aNameDialog.m_xSaveInListBox->set_active(m_xSaveInListBox->get_active());
310 
311  if (aNameDialog.run() == RET_OK)
312  {
313  aNewName = aNameDialog.GetName();
314 
315  // Where to save the new toolbar? (i.e. Modulewise or documentwise)
316  int nInsertPos = aNameDialog.m_xSaveInListBox->get_active();
317 
319  = weld::fromId<ToolbarSaveInData*>(m_xSaveInListBox->get_id(nInsertPos));
320 
321  if (GetSaveInData() != pData)
322  {
323  m_xSaveInListBox->set_active(nInsertPos);
324  SelectSaveInLocation(*m_xSaveInListBox);
325  }
326 
327  SvxConfigEntry* pToolbar = new SvxConfigEntry(aNewName, aNewURL, true, false);
328 
329  pToolbar->SetUserDefined();
330  pToolbar->SetMain();
331 
332  pData->CreateToolbar(pToolbar);
333 
334  OUString sId(weld::toId(pToolbar));
335  m_xTopLevelListBox->append(sId, pToolbar->GetName());
336  m_xTopLevelListBox->set_active_id(sId);
337  SelectElement();
338 
339  pData->SetModified();
340  }
341  }
342  else if (rIdent == "toolbar_gear_delete")
343  {
344  if (pCurrentToolbar && pCurrentToolbar->IsDeletable())
345  {
346  DeleteSelectedTopLevel();
347  UpdateButtonStates();
348  }
349  }
350  else if (rIdent == "toolbar_gear_rename")
351  {
352  sal_Int32 nSelectionPos = m_xTopLevelListBox->get_active();
353  SvxConfigEntry* pToolbar
354  = weld::fromId<SvxConfigEntry*>(m_xTopLevelListBox->get_id(nSelectionPos));
355  ToolbarSaveInData* pSaveInData = static_cast<ToolbarSaveInData*>(GetSaveInData());
356 
357  //Rename the toolbar
358  OUString sCurrentName(SvxConfigPageHelper::stripHotKey(pToolbar->GetName()));
359  OUString sDesc = CuiResId(RID_CUISTR_LABEL_NEW_NAME);
360 
361  SvxNameDialog aNameDialog(GetFrameWeld(), sCurrentName, sDesc);
363  aNameDialog.set_title(CuiResId(RID_CUISTR_RENAME_TOOLBAR));
364 
365  if (aNameDialog.run() == RET_OK)
366  {
367  OUString sNewName = aNameDialog.GetName();
368 
369  if (sCurrentName == sNewName)
370  return;
371 
372  pToolbar->SetName(sNewName);
373  pSaveInData->ApplyToolbar(pToolbar);
374 
375  // have to use remove and insert to change the name
376  m_xTopLevelListBox->remove(nSelectionPos);
377  OUString sId(weld::toId(pToolbar));
378  m_xTopLevelListBox->insert(nSelectionPos, sNewName, &sId, nullptr, nullptr);
379  m_xTopLevelListBox->set_active_id(sId);
380  }
381  }
382  else if (rIdent == "toolbar_gear_iconOnly" || rIdent == "toolbar_gear_textOnly"
383  || rIdent == "toolbar_gear_iconAndText")
384  {
385  ToolbarSaveInData* pSaveInData = static_cast<ToolbarSaveInData*>(GetSaveInData());
386 
387  if (pCurrentToolbar == nullptr || pSaveInData == nullptr)
388  {
389  SAL_WARN("cui.customize", "NULL toolbar or savein data");
390  return;
391  }
392 
393  sal_Int32 nStyle = 0;
394  if (rIdent == "toolbar_gear_iconOnly")
395  nStyle = 0;
396  else if (rIdent == "toolbar_gear_textOnly")
397  nStyle = 1;
398  else if (rIdent == "toolbar_gear_iconAndText")
399  nStyle = 2;
400 
401  pCurrentToolbar->SetStyle(nStyle);
402  pSaveInData->SetSystemStyle(m_xFrame, pCurrentToolbar->GetCommand(), nStyle);
403 
404  SelectElement();
405  }
406  else
407  {
408  //This block should never be reached
409  SAL_WARN("cui.customize", "Unknown gear menu option: " << rIdent);
410  return;
411  }
412 }
413 
415 {
416  OUString aSearchTerm(m_xSearchEdit->get_text());
417 
418  m_xCommandCategoryListBox->categorySelected(m_xFunctions.get(), aSearchTerm, GetSaveInData());
419 
420  SelectFunctionHdl(m_xFunctions->get_widget());
421 }
422 
423 IMPL_LINK_NOARG(SvxToolbarConfigPage, AddCommandHdl, weld::Button&, void) { AddFunction(); }
424 
426 {
427  DeleteSelectedContent();
428 }
429 
430 IMPL_LINK(SvxToolbarConfigPage, InsertHdl, const OString&, rIdent, void)
431 {
432  if (rIdent == "insertseparator")
433  {
434  // Get the currently selected toolbar
435  SvxConfigEntry* pToolbar = GetTopLevelSelection();
436 
437  SvxConfigEntry* pNewEntryData = new SvxConfigEntry;
438  pNewEntryData->SetUserDefined();
439 
440  int nPos = AppendEntry(pNewEntryData, -1);
441  InsertEntryIntoUI(pNewEntryData, m_xContentsListBox->get_widget(), nPos);
442 
443  static_cast<ToolbarSaveInData*>(GetSaveInData())->ApplyToolbar(pToolbar);
444 
445  UpdateButtonStates();
446  }
447  else
448  {
449  //This block should never be reached
450  SAL_WARN("cui.customize", "Unknown insert option: " << rIdent);
451  return;
452  }
453 }
454 
455 IMPL_LINK(SvxToolbarConfigPage, ModifyItemHdl, const OString&, rIdent, void)
456 {
457  bool bNeedsApply = false;
458 
459  // get currently selected toolbar
460  SvxConfigEntry* pToolbar = GetTopLevelSelection();
461 
462  if (rIdent.isEmpty() || pToolbar == nullptr)
463  {
464  SAL_WARN("cui.customize", "No toolbar selected, or empty rIdent!");
465  return;
466  }
467 
468  if (rIdent == "renameItem")
469  {
470  int nActEntry = m_xContentsListBox->get_selected_index();
471  SvxConfigEntry* pEntry
472  = weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(nActEntry));
473 
474  OUString aNewName(SvxConfigPageHelper::stripHotKey(pEntry->GetName()));
475  OUString aDesc = CuiResId(RID_CUISTR_LABEL_NEW_NAME);
476 
477  SvxNameDialog aNameDialog(GetFrameWeld(), aNewName, aDesc);
479  aNameDialog.set_title(CuiResId(RID_CUISTR_RENAME_TOOLBAR));
480 
481  if (aNameDialog.run() == RET_OK)
482  {
483  aNewName = aNameDialog.GetName();
484 
485  if (aNewName.isEmpty()) // tdf#80758 - Accelerator character ("~") is passed as
486  pEntry->SetName("~"); // the button name in case of empty values.
487  else
488  pEntry->SetName(aNewName);
489 
490  m_xContentsListBox->set_text(nActEntry, aNewName, 0);
491  bNeedsApply = true;
492  }
493  }
494  else if (rIdent == "changeIcon")
495  {
496  int nActEntry = m_xContentsListBox->get_selected_index();
497  SvxConfigEntry* pEntry
498  = weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(nActEntry));
499 
500  SvxIconSelectorDialog aIconDialog(GetFrameWeld(), GetSaveInData()->GetImageManager(),
501  GetSaveInData()->GetParentImageManager());
502 
503  if (aIconDialog.run() == RET_OK)
504  {
505  css::uno::Reference<css::graphic::XGraphic> newgraphic = aIconDialog.GetSelectedIcon();
506 
507  if (newgraphic.is())
508  {
509  css::uno::Sequence<OUString> aURLSeq{ pEntry->GetCommand() };
510 
511  if (!pEntry->GetBackupGraphic().is())
512  {
513  css::uno::Reference<css::graphic::XGraphic> backup
514  = SvxConfigPageHelper::GetGraphic(GetSaveInData()->GetImageManager(),
515  aURLSeq[0]);
516 
517  if (backup.is())
518  {
519  pEntry->SetBackupGraphic(backup);
520  }
521  }
522 
523  css::uno::Sequence<css::uno::Reference<css::graphic::XGraphic>> aGraphicSeq{
524  newgraphic
525  };
526  try
527  {
528  GetSaveInData()->GetImageManager()->replaceImages(
529  SvxConfigPageHelper::GetImageType(), aURLSeq, aGraphicSeq);
530 
531  m_xContentsListBox->remove(nActEntry);
532 
533  OUString sId(weld::toId(pEntry));
534  m_xContentsListBox->insert(nActEntry, sId);
535  m_xContentsListBox->set_toggle(nActEntry, pEntry->IsVisible() ? TRISTATE_TRUE
536  : TRISTATE_FALSE);
537  InsertEntryIntoUI(pEntry, m_xContentsListBox->get_widget(), nActEntry);
538 
539  m_xContentsListBox->select(nActEntry);
540  m_xContentsListBox->scroll_to_row(nActEntry);
541 
542  GetSaveInData()->PersistChanges(GetSaveInData()->GetImageManager());
543  }
544  catch (const css::uno::Exception&)
545  {
546  TOOLS_WARN_EXCEPTION("cui.customize", "Error replacing image");
547  }
548  }
549  }
550  }
551  else if (rIdent == "resetIcon")
552  {
553  int nActEntry = m_xContentsListBox->get_selected_index();
554  SvxConfigEntry* pEntry
555  = weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(nActEntry));
556 
557  css::uno::Reference<css::graphic::XGraphic> backup = pEntry->GetBackupGraphic();
558 
559  css::uno::Sequence<css::uno::Reference<css::graphic::XGraphic>> aGraphicSeq{ backup };
560 
561  css::uno::Sequence<OUString> aURLSeq{ pEntry->GetCommand() };
562 
563  try
564  {
565  GetSaveInData()->GetImageManager()->replaceImages(SvxConfigPageHelper::GetImageType(),
566  aURLSeq, aGraphicSeq);
567 
568  m_xContentsListBox->remove(nActEntry);
569 
570  OUString sId(weld::toId(pEntry));
571  m_xContentsListBox->insert(nActEntry, sId);
572  m_xContentsListBox->set_toggle(nActEntry,
573  pEntry->IsVisible() ? TRISTATE_TRUE : TRISTATE_FALSE);
574  InsertEntryIntoUI(pEntry, m_xContentsListBox->get_widget(), nActEntry);
575 
576  m_xContentsListBox->select(nActEntry);
577  m_xContentsListBox->scroll_to_row(nActEntry);
578 
579  // reset backup in entry
580  pEntry->SetBackupGraphic(css::uno::Reference<css::graphic::XGraphic>());
581 
582  GetSaveInData()->PersistChanges(GetSaveInData()->GetImageManager());
583  }
584  catch (const css::uno::Exception&)
585  {
586  TOOLS_WARN_EXCEPTION("cui.customize", "Error resetting image");
587  }
588  }
589  else if (rIdent == "restoreItem")
590  {
591  int nActEntry = m_xContentsListBox->get_selected_index();
592  SvxConfigEntry* pEntry
593  = weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(nActEntry));
594 
595  ToolbarSaveInData* pSaveInData = static_cast<ToolbarSaveInData*>(GetSaveInData());
596 
597  OUString aSystemName = pSaveInData->GetSystemUIName(pEntry->GetCommand());
598 
599  if (!pEntry->GetName().equals(aSystemName))
600  {
601  pEntry->SetName(aSystemName);
602  m_xContentsListBox->set_text(nActEntry, SvxConfigPageHelper::stripHotKey(aSystemName),
603  0);
604  bNeedsApply = true;
605  }
606 
607  css::uno::Sequence<OUString> aURLSeq{ pEntry->GetCommand() };
608 
609  try
610  {
611  GetSaveInData()->GetImageManager()->removeImages(SvxConfigPageHelper::GetImageType(),
612  aURLSeq);
613 
614  // reset backup in entry
615  pEntry->SetBackupGraphic(css::uno::Reference<css::graphic::XGraphic>());
616 
617  GetSaveInData()->PersistChanges(GetSaveInData()->GetImageManager());
618 
619  m_xContentsListBox->remove(nActEntry);
620 
621  OUString sId(weld::toId(pEntry));
622  m_xContentsListBox->insert(nActEntry, sId);
623  m_xContentsListBox->set_toggle(nActEntry,
624  pEntry->IsVisible() ? TRISTATE_TRUE : TRISTATE_FALSE);
625  InsertEntryIntoUI(pEntry, m_xContentsListBox->get_widget(), nActEntry);
626 
627  m_xContentsListBox->select(nActEntry);
628  m_xContentsListBox->scroll_to_row(nActEntry);
629 
630  bNeedsApply = true;
631  }
632  catch (const css::uno::Exception&)
633  {
634  TOOLS_WARN_EXCEPTION("cui.customize", "Error restoring image");
635  }
636  }
637  else
638  {
639  //This block should never be reached
640  SAL_WARN("cui.customize", "Unknown insert option: " << rIdent);
641  return;
642  }
643 
644  if (bNeedsApply)
645  {
646  static_cast<ToolbarSaveInData*>(GetSaveInData())->ApplyToolbar(pToolbar);
647  UpdateButtonStates();
648  }
649 }
650 
652 {
653  sal_Int32 nSelectionPos = m_xTopLevelListBox->get_active();
654 
655  SvxConfigEntry* pToolbar
656  = weld::fromId<SvxConfigEntry*>(m_xTopLevelListBox->get_id(nSelectionPos));
657 
658  std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(
659  GetFrameWeld(), VclMessageType::Question, VclButtonsType::YesNo,
660  CuiResId(RID_CUISTR_CONFIRM_RESTORE_DEFAULT)));
661  if (xQueryBox->run() == RET_YES)
662  {
663  ToolbarSaveInData* pSaveInData = static_cast<ToolbarSaveInData*>(GetSaveInData());
664 
665  pSaveInData->RestoreToolbar(pToolbar);
666 
667  SelectElement();
668  }
669 }
670 
672 {
673  SvxConfigEntry* pToolbar = GetTopLevelSelection();
674  int selection = m_xContentsListBox->get_selected_index();
675 
676  bool bIsSeparator
677  = selection != -1
678  && weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(selection))->IsSeparator();
679  bool bIsValidSelection = (m_xContentsListBox->n_children() != 0 && selection != -1);
680 
681  m_xMoveUpButton->set_sensitive(bIsValidSelection);
682  m_xMoveDownButton->set_sensitive(bIsValidSelection);
683 
684  m_xRemoveCommandButton->set_sensitive(bIsValidSelection);
685 
686  m_xModifyBtn->set_sensitive(bIsValidSelection && !bIsSeparator);
687 
688  // Handle the gear button
689  // "toolbar_gear_add" option is always enabled
690  m_xGearBtn->set_item_sensitive("toolbar_gear_delete", pToolbar && pToolbar->IsDeletable());
691  m_xGearBtn->set_item_sensitive("toolbar_gear_rename", pToolbar && pToolbar->IsRenamable());
692 }
693 
695 {
696  OUString msg = CuiResId(RID_CUISTR_CONFIRM_TOOLBAR_RESET);
697 
698  OUString saveInName = m_xSaveInListBox->get_active_text();
699 
700  OUString label = SvxConfigPageHelper::replaceSaveInName(msg, saveInName);
701 
702  std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(
703  GetFrameWeld(), VclMessageType::Question, VclButtonsType::YesNo, label));
704  return xQueryBox->run();
705 }
706 
708 {
709  m_xContentsListBox->clear();
710 
711  SvxConfigEntry* pToolbar = GetTopLevelSelection();
712  if (pToolbar == nullptr)
713  {
714  //TODO: Disable related buttons
715  m_xInsertBtn->set_sensitive(false);
716  m_xResetBtn->set_sensitive(false);
717  m_xGearBtn->set_sensitive(false);
718 
719  return;
720  }
721  else
722  {
723  m_xInsertBtn->set_sensitive(true);
724  m_xResetBtn->set_sensitive(true);
725  m_xGearBtn->set_sensitive(true);
726  }
727 
728  switch (pToolbar->GetStyle())
729  {
730  case 0:
731  {
732  m_xGearBtn->set_item_active("toolbar_gear_iconOnly", true);
733  break;
734  }
735  case 1:
736  {
737  m_xGearBtn->set_item_active("toolbar_gear_textOnly", true);
738  break;
739  }
740  case 2:
741  {
742  m_xGearBtn->set_item_active("toolbar_gear_iconAndText", true);
743  break;
744  }
745  }
746 
747  int i = 0;
748  SvxEntries* pEntries = pToolbar->GetEntries();
749  for (auto const& entry : *pEntries)
750  {
751  OUString sId(weld::toId(entry));
752  m_xContentsListBox->insert(i, sId);
753  if (entry->IsBinding() && !entry->IsSeparator())
754  m_xContentsListBox->set_toggle(i, entry->IsVisible() ? TRISTATE_TRUE : TRISTATE_FALSE);
755  InsertEntryIntoUI(entry, m_xContentsListBox->get_widget(), i);
756  ++i;
757  }
758 
760 }
761 
763 {
764  SvxConfigEntry* pToolbar = GetTopLevelSelection();
765 
766  if (pToolbar == nullptr)
767  return;
768 
769  // Add the command to the contents listbox of the selected toolbar
770  int nNewLBEntry = SvxConfigPage::AddFunction(nTarget, true /*bAllowDuplicates*/);
771 
772  if (nNewLBEntry == -1)
773  return;
774 
775  SvxConfigEntry* pEntry = weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(nNewLBEntry));
776 
777  if (pEntry->IsBinding()) //TODO sep ?
778  {
779  pEntry->SetVisible(true);
780  m_xContentsListBox->set_toggle(nNewLBEntry, TRISTATE_TRUE);
781  }
782 
783  InsertEntryIntoUI(pEntry, m_xContentsListBox->get_widget(), nNewLBEntry);
784 
785  // Changes are not visible on the toolbar until this point
786  // TODO: Figure out a way to show the changes on the toolbar, but revert if
787  // the dialog is closed by pressing "Cancel"
788  // get currently selected toolbar and apply change
789  if (pToolbar != nullptr)
790  {
791  static_cast<ToolbarSaveInData*>(GetSaveInData())->ApplyToolbar(pToolbar);
792  }
793 }
794 
795 SvxToolbarEntriesListBox::SvxToolbarEntriesListBox(std::unique_ptr<weld::TreeView> xParent,
797  : SvxMenuEntriesListBox(std::move(xParent), pPg)
798 {
799  m_xControl->connect_toggled(LINK(this, SvxToolbarEntriesListBox, CheckButtonHdl));
800  m_xControl->connect_key_press(
801  Link<const KeyEvent&, bool>()); //acknowledge we first remove the old one
802  m_xControl->connect_key_press(
803  LINK(this, SvxToolbarEntriesListBox, KeyInputHdl)); // then add the new one
804 }
805 
807 
809 {
810  SvxConfigEntry* pEntryData = weld::fromId<SvxConfigEntry*>(m_xControl->get_id(nRow));
811 
812  if (pEntryData->IsBinding())
813  {
814  pEntryData->SetVisible(m_xControl->get_toggle(nRow) == TRISTATE_TRUE);
815 
817 
818  ToolbarSaveInData* pToolbarSaveInData
819  = static_cast<ToolbarSaveInData*>(m_pPage->GetSaveInData());
820 
821  pToolbarSaveInData->ApplyToolbar(pToolbar);
822  }
823 }
824 
825 IMPL_LINK(SvxToolbarEntriesListBox, CheckButtonHdl, const weld::TreeView::iter_col&, rRowCol, void)
826 {
827  ChangedVisibility(m_xControl->get_iter_index_in_parent(rRowCol.first));
828 }
829 
830 IMPL_LINK(SvxToolbarEntriesListBox, KeyInputHdl, const KeyEvent&, rKeyEvent, bool)
831 {
832  // space key will change visibility of toolbar items
833  if (rKeyEvent.GetKeyCode() == KEY_SPACE)
834  {
835  int nRow = m_xControl->get_selected_index();
836  SvxConfigEntry* pEntryData = weld::fromId<SvxConfigEntry*>(m_xControl->get_id(nRow));
837  if (pEntryData->IsBinding() && !pEntryData->IsSeparator())
838  {
839  m_xControl->set_toggle(nRow, m_xControl->get_toggle(nRow) == TRISTATE_TRUE
841  : TRISTATE_TRUE);
842  ChangedVisibility(nRow);
843  }
844  return true;
845  }
846  return SvxMenuEntriesListBox::KeyInputHdl(rKeyEvent);
847 }
848 
849 IMPL_LINK(SvxToolbarConfigPage, ContentContextMenuHdl, const CommandEvent&, rCEvt, bool)
850 {
851  if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
852  return false;
853 
854  weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
855 
856  // Select clicked entry
857  std::unique_ptr<weld::TreeIter> xIter(rTreeView.make_iterator());
858  if (!rTreeView.get_dest_row_at_pos(rCEvt.GetMousePosPixel(), xIter.get(), false))
859  return false;
860  rTreeView.select(*xIter);
861  SelectToolbarEntry(rTreeView);
862 
863  int nSelectIndex = m_xContentsListBox->get_selected_index();
864 
865  bool bIsSeparator
866  = nSelectIndex != -1
867  && weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(nSelectIndex))->IsSeparator();
868  bool bIsValidSelection = (m_xContentsListBox->n_children() != 0 && nSelectIndex != -1);
869 
870  std::unique_ptr<weld::Builder> xBuilder(
871  Application::CreateBuilder(&rTreeView, "cui/ui/entrycontextmenu.ui"));
872  auto xContextMenu = xBuilder->weld_menu("menu");
873  xContextMenu->set_visible("add", false);
874  xContextMenu->set_visible("remove", bIsValidSelection);
875  xContextMenu->set_visible("rename", bIsValidSelection && !bIsSeparator);
876  xContextMenu->set_visible("changeIcon", bIsValidSelection && !bIsSeparator);
877  xContextMenu->set_visible("resetIcon", bIsValidSelection && !bIsSeparator);
878  xContextMenu->set_visible("restoreDefault", bIsValidSelection && !bIsSeparator);
879  OString sCommand(xContextMenu->popup_at_rect(
880  &rTreeView, tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1, 1))));
881 
882  if (sCommand == "remove")
883  RemoveCommandHdl(*m_xRemoveCommandButton);
884  else if (sCommand == "rename")
885  ModifyItemHdl("renameItem");
886  else if (sCommand == "changeIcon")
887  ModifyItemHdl("changeIcon");
888  else if (sCommand == "resetIcon")
889  ModifyItemHdl("resetIcon");
890  else if (sCommand == "restoreDefault")
891  ModifyItemHdl("restoreItem");
892  else if (!sCommand.isEmpty())
893  SAL_WARN("cui.customize", "Unknown context menu action: " << sCommand);
894  return true;
895 }
896 
897 IMPL_LINK(SvxToolbarConfigPage, FunctionContextMenuHdl, const CommandEvent&, rCEvt, bool)
898 {
899  if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
900  return false;
901 
902  weld::TreeView& rTreeView = m_xFunctions->get_widget();
903 
904  // Select clicked entry
905  std::unique_ptr<weld::TreeIter> xIter(rTreeView.make_iterator());
906  if (!rTreeView.get_dest_row_at_pos(rCEvt.GetMousePosPixel(), xIter.get(), false))
907  return false;
908  rTreeView.select(*xIter);
909  SelectFunctionHdl(rTreeView);
910  std::unique_ptr<weld::Builder> xBuilder(
911  Application::CreateBuilder(&rTreeView, "cui/ui/entrycontextmenu.ui"));
912  auto xContextMenu = xBuilder->weld_menu("menu");
913  xContextMenu->set_visible("add", true);
914  xContextMenu->set_visible("remove", false);
915  xContextMenu->set_visible("rename", false);
916  xContextMenu->set_visible("changeIcon", false);
917  xContextMenu->set_visible("resetIcon", false);
918  xContextMenu->set_visible("restoreDefault", false);
919  OString sCommand(xContextMenu->popup_at_rect(
920  &rTreeView, tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1, 1))));
921 
922  if (sCommand == "add")
923  AddCommandHdl(*m_xAddCommandButton);
924  else if (!sCommand.isEmpty())
925  SAL_WARN("cui.customize", "Unknown context menu action: " << sCommand);
926  return true;
927 }
928 
929 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void RemoveToolbar(SvxConfigEntry *pToolbar)
Definition: cfg.cxx:2499
std::unique_ptr< CuiConfigFunctionListBox > m_xFunctions
Definition: cfg.hxx:387
constexpr OStringLiteral HID_SVX_DESCFIELD
Definition: helpids.h:49
SvxEntries * GetEntries() const
Definition: cfg.hxx:290
std::unique_ptr< weld::Button > m_xResetBtn
Definition: cfg.hxx:414
void AddFunction(int nTarget=-1)
void set_title(const OUString &rTitle)
const OUString & GetName() const
Definition: cfg.hxx:278
static OUString generateCustomURL(SvxEntries *entries)
Generates a custom resource URL for a new toolbar.
std::unique_ptr< weld::MenuButton > m_xModifyBtn
Definition: cfg.hxx:412
bool IsVisible() const
Definition: cfg.hxx:307
std::unique_ptr< CommandCategoryListBox > m_xCommandCategoryListBox
Definition: cfg.hxx:386
OUString m_aURLToSelect
the ResourceURL to select when opening the dialog
Definition: cfg.hxx:379
virtual ~SvxToolbarConfigPage() override
static OUString stripHotKey(const OUString &str)
Reference< XControl > m_xControl
void SetModified(bool bValue=true)
Definition: cfg.hxx:299
std::unique_ptr< SvxConfigPageFunctionDropTarget > m_xDropTargetHelper
Definition: cfg.hxx:404
OUString GetSystemUIName(const OUString &rResourceURL)
Definition: cfg.cxx:2086
std::unique_ptr< sal_Int32[]> pData
css::uno::Reference< css::frame::XFrame > m_xFrame
Definition: cfg.hxx:381
constexpr OStringLiteral HID_SVX_CONFIG_TOOLBAR
Definition: helpids.h:29
SvxConfigEntry * GetTopLevelSelection()
Definition: cfg.hxx:497
static sal_Int16 GetImageType()
std::unique_ptr< weld::Button > m_xRemoveCommandButton
Definition: cfg.hxx:418
css::uno::Reference< css::lang::XComponent > m_xFrame
void SetBackupGraphic(css::uno::Reference< css::graphic::XGraphic > const &graphic)
Definition: cfg.hxx:309
constexpr OStringLiteral HID_SVX_SAVE_IN
Definition: helpids.h:47
virtual void MoveEntry(bool bMoveUp)
Definition: cfg.cxx:1676
constexpr sal_uInt16 KEY_SPACE
OUString GetName() const
Definition: dlgname.hxx:39
std::unique_ptr< SvxMenuEntriesListBox > m_xContentsListBox
Definition: cfg.hxx:403
TRISTATE_TRUE
void ReloadTopLevelListBox(SvxConfigEntry const *pSelection=nullptr)
Definition: cfg.cxx:1335
Dialog for editing a name.
Definition: dlgname.hxx:24
static css::uno::Reference< css::graphic::XGraphic > GetGraphic(const css::uno::Reference< css::ui::XImageManager > &xImageManager, const OUString &rCommandURL)
virtual std::unique_ptr< TreeIter > make_iterator(const TreeIter *pOrig=nullptr) const =0
std::vector< SvxConfigEntry * > SvxEntries
Definition: cfg.hxx:62
std::unique_ptr< weld::ComboBox > m_xTopLevelListBox
Definition: cfg.hxx:400
bool IsRenamable() const
Definition: cfg.cxx:1932
const OUString & GetCommand() const
Definition: cfg.hxx:276
void DeleteSelectedContent() override
void connect_changed(const Link< TreeView &, void > &rLink)
Reference< XNameAccess > m_xContainer
RET_YES
virtual void show()=0
bool IsBinding() const
Definition: cfg.hxx:287
OUString GetName() const
Definition: cfg.hxx:609
std::unique_ptr< weld::TreeView > m_xControl
Definition: cfg.hxx:322
std::pair< const TreeIter &, int > iter_col
int nCount
static void RemoveEntry(SvxEntries *pEntries, SvxConfigEntry const *pChildEntry)
static OUString replaceSaveInName(const OUString &rMessage, std::u16string_view rSaveInName)
void SetName(const OUString &rStr)
Definition: cfg.hxx:279
void SetMain()
Definition: cfg.hxx:293
virtual void set_help_id(const OString &rName)=0
constexpr OUStringLiteral ITEM_TOOLBAR_URL
Definition: cfg.hxx:55
virtual void set_vexpand(bool bExpand)=0
SaveInData * CreateSaveInData(const css::uno::Reference< css::ui::XUIConfigurationManager > &, const css::uno::Reference< css::ui::XUIConfigurationManager > &, const OUString &aModuleId, bool docConfig) override
static OUString generateCustomName(const OUString &prefix, SvxEntries *entries, sal_Int32 suffix=1)
virtual void SelectElement() override
IMPL_LINK(SvxToolbarConfigPage, MoveHdl, weld::Button &, rButton, void)
virtual tools::Long GetValue() const override
exports com.sun.star. text
OUString CuiResId(TranslateId aKey)
Definition: cuiresmgr.cxx:23
const css::uno::Reference< css::graphic::XGraphic > & GetBackupGraphic() const
Definition: cfg.hxx:312
#define TOOLS_WARN_EXCEPTION(area, stream)
virtual bool get_dest_row_at_pos(const Point &rPos, weld::TreeIter *pResult, bool bDnDMode)=0
void SetSystemStyle(const OUString &rResourceURL, sal_Int32 nStyle)
Definition: cfg.cxx:2047
int i
void SetUserDefined(bool bOn=true)
Definition: cfg.hxx:284
virtual void ListModified() override
TRISTATE_FALSE
constexpr OStringLiteral HID_SVX_CONFIG_RENAME_TOOLBAR_ITEM
Definition: helpids.h:44
std::unique_ptr< weld::ComboBox > m_xSaveInListBox
Definition: cfg.hxx:604
constexpr OStringLiteral HID_SVX_CONFIG_RENAME_TOOLBAR
Definition: helpids.h:42
void SetVisible(bool b)
Definition: cfg.hxx:306
void SetStyle(sal_Int32 style)
Definition: cfg.hxx:316
virtual void set_hexpand(bool bExpand)=0
constexpr OStringLiteral HID_SVX_CONFIG_TOOLBAR_CONTENTS
Definition: helpids.h:31
void set_help_id(const OString &rHelpId)
constexpr OStringLiteral HID_SVX_TOPLEVELLISTBOX
Definition: helpids.h:48
std::unique_ptr< weld::MenuButton > m_xInsertBtn
Definition: cfg.hxx:411
constexpr OStringLiteral HID_SVX_DOWN_TOOLBAR_ITEM
Definition: helpids.h:46
sal_Int32 GetStyle() const
Definition: cfg.hxx:315
OUString toId(const void *pValue)
void RestoreToolbar(SvxConfigEntry *pToolbar)
Definition: cfg.cxx:2522
virtual void select(int pos)=0
weld::Window * GetFrameWeld() const
void UpdateButtonStates() override
void InsertEntryIntoUI(SvxConfigEntry *pNewEntryData, weld::TreeView &rTreeView, int nPos, bool bMenu=false)
Definition: cfg.cxx:1583
void SetModified(bool bValue=true)
Definition: cfg.hxx:126
int AddFunction(int nTarget, bool bAllowDuplicates)
Definition: cfg.cxx:1459
RET_OK
bool IsDeletable() const
Definition: cfg.cxx:1927
IMPL_LINK_NOARG(SvxToolbarConfigPage, SelectToolbarEntry, weld::TreeView &, void)
SvxToolbarConfigPage(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet &rItemSet)
virtual short run()
Reference< XComponentContext > getProcessComponentContext()
void CreateToolbar(SvxConfigEntry *pToolbar)
Definition: cfg.cxx:2472
virtual ~SvxToolbarEntriesListBox() override
std::unique_ptr< weld::ComboBox > m_xSaveInListBox
Definition: cfg.hxx:409
constexpr OStringLiteral HID_SVX_UP_TOOLBAR_ITEM
Definition: helpids.h:45
void ApplyToolbar(css::uno::Reference< css::container::XIndexContainer > const &rNewToolbarBar, css::uno::Reference< css::lang::XSingleComponentFactory > &rFactory, SvxConfigEntry const *pToolbar)
SvxConfigPage * m_pPage
Definition: cfg.hxx:324
std::unique_ptr< weld::TextView > m_xDescriptionField
Definition: cfg.hxx:391
std::unique_ptr< weld::Button > m_xMoveDownButton
Definition: cfg.hxx:407
#define SAL_WARN(area, stream)
void DeleteSelectedTopLevel() override
bool IsSeparator() const
Definition: cfg.hxx:288
std::unique_ptr< weld::Button > m_xMoveUpButton
Definition: cfg.hxx:406
def label(st)
OUString m_aModuleId
Definition: cfg.hxx:382
std::unique_ptr< weld::MenuButton > m_xGearBtn
Definition: cfg.hxx:402
virtual void set_size_request(int nWidth, int nHeight)=0
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
void MoveEntry(bool bMoveUp) override
virtual void connect_popup_menu(const Link< const CommandEvent &, bool > &rLink)
weld::Window * GetFrameWeld(const SfxFrame *pFrame)
SvxToolbarEntriesListBox(std::unique_ptr< weld::TreeView > xControl, SvxToolbarConfigPage *pPg)
SaveInData * GetSaveInData()
Definition: cfg.hxx:478
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, bool bMobile=false)
sal_uInt16 nPos
static std::unique_ptr< weld::Builder > CreateBuilder(weld::Widget *pParent, const OUString &rUIFile, bool bMobile=false, sal_uInt64 nLOKWindowId=0)
std::unique_ptr< weld::Button > m_xAddCommandButton
Definition: cfg.hxx:417
OUString sId