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