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