LibreOffice Module vcl (master)  1
salvtables.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 
22 #include <string_view>
23 
24 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
25 #include <com/sun/star/awt/XWindow.hpp>
26 #include <com/sun/star/awt/XWindowPeer.hpp>
27 #include <o3tl/safeint.hxx>
28 #include <o3tl/sorted_vector.hxx>
29 #include <officecfg/Office/Common.hxx>
30 #include <salframe.hxx>
31 #include <salinst.hxx>
32 #include <salvd.hxx>
33 #include <salprn.hxx>
34 #include <saltimer.hxx>
35 #include <salsession.hxx>
36 #include <salsys.hxx>
37 #include <salbmp.hxx>
38 #include <salobj.hxx>
39 #include <salmenu.hxx>
40 #include <strings.hrc>
41 #include <svdata.hxx>
42 #include <svimpbox.hxx>
43 #include <messagedialog.hxx>
44 #include <treeglue.hxx>
46 #include <unotools/configmgr.hxx>
47 #include <utility>
48 #include <tools/helpers.hxx>
49 #include <vcl/abstdlg.hxx>
50 #include <vcl/builder.hxx>
51 #include <vcl/toolkit/combobox.hxx>
52 #include <vcl/toolkit/dialog.hxx>
53 #include <vcl/toolkit/fixed.hxx>
55 #include <vcl/toolkit/fmtfield.hxx>
56 #include <vcl/headbar.hxx>
57 #include <vcl/toolkit/ivctrl.hxx>
58 #include <vcl/layout.hxx>
59 #include <vcl/toolkit/menubtn.hxx>
60 #include <vcl/toolkit/prgsbar.hxx>
61 #include <vcl/ptrstyle.hxx>
62 #include <slider.hxx>
63 #include <vcl/sysdata.hxx>
64 #include <vcl/toolkit/svlbitm.hxx>
65 #include <vcl/toolkit/svtabbx.hxx>
66 #include <vcl/tabctrl.hxx>
67 #include <vcl/tabpage.hxx>
69 #include <vcl/toolkit/throbber.hxx>
70 #include <vcl/toolkit/unowrap.hxx>
71 #include <vcl/weld.hxx>
72 #include <vcl/weldutils.hxx>
73 #include <vcl/toolkit/vclmedit.hxx>
75 #include <vcl/virdev.hxx>
76 #include <bitmaps.hlst>
77 #include <calendar.hxx>
78 #include <menutogglebutton.hxx>
79 #include <verticaltabctrl.hxx>
80 #include <window.h>
81 #include <wizdlg.hxx>
82 #include <salvtables.hxx>
83 #include <comphelper/lok.hxx>
84 
86  : m_pWindow(nullptr)
87  , m_pProc(nullptr)
88 {
89 }
90 
91 // this file contains the virtual destructors of the sal interface
92 // compilers usually put their vtables where the destructor is
93 
95 
97 {
98  m_pWindow = pWindow;
99  m_pProc = pProc;
100 }
101 
102 // default to full-frame flushes
103 // on ports where partial-flushes are much cheaper this method should be overridden
105 
106 void SalFrame::SetRepresentedURL(const OUString&)
107 {
108  // currently this is Mac only functionality
109 }
110 
111 SalInstance::SalInstance(std::unique_ptr<comphelper::SolarMutex> pMutex)
112  : m_pYieldMutex(std::move(pMutex))
113 {
114 }
115 
117 
119 
120 sal_uInt32 SalInstance::ReleaseYieldMutexAll() { return m_pYieldMutex->release(true); }
121 
122 void SalInstance::AcquireYieldMutex(sal_uInt32 nCount) { m_pYieldMutex->acquire(nCount); }
123 
124 std::unique_ptr<SalSession> SalInstance::CreateSalSession() { return nullptr; }
125 
126 std::unique_ptr<SalMenu> SalInstance::CreateMenu(bool, Menu*)
127 {
128  // default: no native menus
129  return nullptr;
130 }
131 
132 std::unique_ptr<SalMenuItem> SalInstance::CreateMenuItem(const SalItemParams&) { return nullptr; }
133 
134 bool SalInstance::CallEventCallback(void const* pEvent, int nBytes)
135 {
136  return m_pEventInst.is() && m_pEventInst->dispatchEvent(pEvent, nBytes);
137 }
138 
139 SalTimer::~SalTimer() COVERITY_NOEXCEPT_FALSE {}
140 
142 {
143  if (ImplSVData* pSVData = ImplGetSVData())
144  {
145  auto& rCache = pSVData->maGDIData.maScaleCache;
146 
147  rCache.remove_if([this](const lru_scale_cache::key_value_pair_t& rKeyValuePair) {
148  return rKeyValuePair.first.mpBitmap == this;
149  });
150  }
151 }
152 
154 
156 
158 
159 bool SalPrinter::StartJob(const OUString*, const OUString&, const OUString&, ImplJobSetup*,
161 {
162  return false;
163 }
164 
166 
168 
170 
172 
174 {
175  return false;
176 }
177 
179 
180 bool SalMenu::AddMenuBarButton(const SalMenuButtonItem&) { return false; }
181 
182 void SalMenu::RemoveMenuBarButton(sal_uInt16) {}
183 
185 {
186  return tools::Rectangle();
187 }
188 
189 int SalMenu::GetMenuBarHeight() const { return 0; }
190 
192 
194 
196 {
197  if (!m_bEventListener)
198  {
199  m_xWidget->AddEventListener(LINK(this, SalInstanceWidget, EventListener));
200  m_bEventListener = true;
201  }
202 }
203 
204 // we want the ability to mark key events as handled, so use this variant
205 // for those, we get all keystrokes in this case, so we will need to filter
206 // them later
208 {
209  if (!m_bKeyEventListener)
210  {
211  Application::AddKeyListener(LINK(this, SalInstanceWidget, KeyEventListener));
212  m_bKeyEventListener = true;
213  }
214 }
215 
216 // we want the ability to know about mouse events that happen in our children
217 // so use this variant, we will need to filter them later
219 {
221  {
222  Application::AddEventListener(LINK(this, SalInstanceWidget, MouseEventListener));
223  m_bMouseEventListener = true;
224  }
225 }
226 
228 {
232  {
233  // turn off WB_CLIPCHILDREN otherwise the bg won't extend "under"
234  // transparent children of the widget e.g. expander in sidebar panel header
236  // and toggle mbClipChildren on instead otherwise the bg won't fill e.g.
237  // deck titlebar header when its width is stretched
239  pImpl->mbClipChildren = true;
240  }
241 }
242 
244  bool bTakeOwnership)
245  : m_xWidget(pWidget)
246  , m_pBuilder(pBuilder)
247  , m_bTakeOwnership(bTakeOwnership)
248  , m_bEventListener(false)
249  , m_bKeyEventListener(false)
250  , m_bMouseEventListener(false)
251  , m_nBlockNotify(0)
252 {
253 }
254 
255 void SalInstanceWidget::set_sensitive(bool sensitive) { m_xWidget->Enable(sensitive); }
256 
258 
260 
262 
264 {
265  auto nStyle = m_xWidget->GetStyle() & ~(WB_TABSTOP | WB_NOTABSTOP);
266  if (bCanFocus)
267  nStyle |= WB_TABSTOP;
268  else
269  nStyle |= WB_NOTABSTOP;
270  m_xWidget->SetStyle(nStyle);
271 }
272 
274 {
276  m_xWidget->GrabFocus();
278 }
279 
281 
283 
285 
287 {
288  m_xWidget->set_property("has-default", OUString::boolean(has_default));
289 }
290 
292 
294 
296 
297 void SalInstanceWidget::set_size_request(int nWidth, int nHeight)
298 {
299  m_xWidget->set_width_request(nWidth);
300  m_xWidget->set_height_request(nHeight);
301 }
302 
304 {
306 }
307 
309 
311 {
313 }
314 
316 
317 Size SalInstanceWidget::get_pixel_size(const OUString& rText) const
318 {
319  //TODO, or do I want GetTextBoundRect ?, just using width at the moment anyway
320  return Size(m_xWidget->GetTextWidth(rText), m_xWidget->GetTextHeight());
321 }
322 
324 
325 OString SalInstanceWidget::get_buildable_name() const { return m_xWidget->get_id().toUtf8(); }
326 
328 {
329  return m_xWidget->set_id(OUString::fromUtf8(rId));
330 }
331 
332 void SalInstanceWidget::set_help_id(const OString& rId) { return m_xWidget->SetHelpId(rId); }
333 
334 OString SalInstanceWidget::get_help_id() const { return m_xWidget->GetHelpId(); }
335 
337 {
339 }
340 
342 
344 
346 {
347  m_xWidget->set_grid_top_attach(nAttach);
348 }
349 
351 
352 void SalInstanceWidget::set_hexpand(bool bExpand) { m_xWidget->set_hexpand(bExpand); }
353 
355 
356 void SalInstanceWidget::set_vexpand(bool bExpand) { m_xWidget->set_vexpand(bExpand); }
357 
359 
360 void SalInstanceWidget::set_secondary(bool bSecondary) { m_xWidget->set_secondary(bSecondary); }
361 
363 
365 
367 
369 
371 
373 
375 
377 
378 void SalInstanceWidget::set_accessible_name(const OUString& rName)
379 {
381 }
382 
383 void SalInstanceWidget::set_accessible_description(const OUString& rDescription)
384 {
385  m_xWidget->SetAccessibleDescription(rDescription);
386 }
387 
389 
391 {
393 }
394 
396 {
397  vcl::Window* pAtkLabel
398  = pLabel ? dynamic_cast<SalInstanceWidget&>(*pLabel).getWidget() : nullptr;
400 }
401 
403 {
404  vcl::Window* pAtkLabeled
405  = pLabeled ? dynamic_cast<SalInstanceWidget&>(*pLabeled).getWidget() : nullptr;
407 }
408 
409 void SalInstanceWidget::set_tooltip_text(const OUString& rTip)
410 {
412 }
413 
415 
417 {
420 }
421 
423 {
424  m_xWidget->SetMnemonicActivateHdl(LINK(this, SalInstanceWidget, MnemonicActivateHdl));
426 }
427 
429 {
432 }
433 
435 {
438 }
439 
441 {
444 }
445 
447 {
450 }
451 
453 {
456 }
457 
459 {
462 }
463 
465 {
468 }
469 
470 bool SalInstanceWidget::get_extents_relative_to(const Widget& rRelative, int& x, int& y, int& width,
471  int& height) const
472 {
474  dynamic_cast<const SalInstanceWidget&>(rRelative).getWidget()));
475  x = aRect.Left();
476  y = aRect.Top();
477  width = aRect.GetWidth();
478  height = aRect.GetHeight();
479  return true;
480 }
481 
483 
485 
487 
489 
491 
493 
495 
497 {
498  if (bBusy)
499  m_xWidget->EnterWait();
500  else
501  m_xWidget->LeaveWait();
502 }
503 
505 
507 {
508  if (m_aMnemonicActivateHdl.IsSet())
511  Application::RemoveEventListener(LINK(this, SalInstanceWidget, MouseEventListener));
513  Application::RemoveKeyListener(LINK(this, SalInstanceWidget, KeyEventListener));
514  if (m_bEventListener)
515  m_xWidget->RemoveEventListener(LINK(this, SalInstanceWidget, EventListener));
516  if (m_bTakeOwnership)
518 }
519 
521 
523 
525 
527 
528 OUString SalInstanceWidget::strip_mnemonic(const OUString& rLabel) const
529 {
530  return rLabel.replaceFirst("~", "");
531 }
532 
534 {
535  // create with (annoying) separate alpha layer that LibreOffice itself uses
538 }
539 
540 css::uno::Reference<css::datatransfer::dnd::XDropTarget> SalInstanceWidget::get_drop_target()
541 {
542  return m_xWidget->GetDropTarget();
543 }
544 
546 {
548 }
549 
551 {
552  m_xWidget->DumpAsPropertyTree(rJsonWriter);
553 }
554 
556 {
558 }
559 
561 {
563 }
564 
566 {
569 }
570 
572 {
574 }
575 
577 
579 {
581  return;
582  if (rEvent.GetId() == VclEventId::WindowGetFocus)
583  m_aFocusInHdl.Call(*this);
584  else if (rEvent.GetId() == VclEventId::WindowLoseFocus)
585  m_aFocusOutHdl.Call(*this);
586  else if (rEvent.GetId() == VclEventId::WindowResize)
588 }
589 
590 namespace
591 {
592 MouseEvent TransformEvent(const MouseEvent& rEvent, const vcl::Window* pParent,
593  const vcl::Window* pChild)
594 {
595  return MouseEvent(
596  pParent->ScreenToOutputPixel(pChild->OutputToScreenPixel(rEvent.GetPosPixel())),
597  rEvent.GetClicks(), rEvent.GetMode(), rEvent.GetButtons(), rEvent.GetModifier());
598 }
599 }
600 
602 {
604  {
605  auto& rWinEvent = static_cast<VclWindowEvent&>(rEvent);
606  if (m_xWidget == rWinEvent.GetWindow())
607  {
608  const MouseEvent* pMouseEvent = static_cast<const MouseEvent*>(rWinEvent.GetData());
609  m_aMousePressHdl.Call(*pMouseEvent);
610  }
611  else if (m_xWidget->ImplIsChild(rWinEvent.GetWindow()))
612  {
613  const MouseEvent* pMouseEvent = static_cast<const MouseEvent*>(rWinEvent.GetData());
614  const MouseEvent aTransformedEvent(
615  TransformEvent(*pMouseEvent, m_xWidget, rWinEvent.GetWindow()));
616  m_aMousePressHdl.Call(aTransformedEvent);
617  }
618  }
619  else if (rEvent.GetId() == VclEventId::WindowMouseButtonUp)
620  {
621  auto& rWinEvent = static_cast<VclWindowEvent&>(rEvent);
622  if (m_xWidget == rWinEvent.GetWindow())
623  {
624  const MouseEvent* pMouseEvent = static_cast<const MouseEvent*>(rWinEvent.GetData());
625  m_aMouseReleaseHdl.Call(*pMouseEvent);
626  }
627  else if (m_xWidget->ImplIsChild(rWinEvent.GetWindow()))
628  {
629  const MouseEvent* pMouseEvent = static_cast<const MouseEvent*>(rWinEvent.GetData());
630  const MouseEvent aTransformedEvent(
631  TransformEvent(*pMouseEvent, m_xWidget, rWinEvent.GetWindow()));
632  m_aMouseReleaseHdl.Call(aTransformedEvent);
633  }
634  }
635  else if (rEvent.GetId() == VclEventId::WindowMouseMove)
636  {
637  auto& rWinEvent = static_cast<VclWindowEvent&>(rEvent);
638  if (m_xWidget == rWinEvent.GetWindow())
639  {
640  const MouseEvent* pMouseEvent = static_cast<const MouseEvent*>(rWinEvent.GetData());
641  m_aMouseMotionHdl.Call(*pMouseEvent);
642  }
643  else if (m_xWidget->ImplIsChild(rWinEvent.GetWindow()))
644  {
645  const MouseEvent* pMouseEvent = static_cast<const MouseEvent*>(rWinEvent.GetData());
646  const MouseEvent aTransformedEvent(
647  TransformEvent(*pMouseEvent, m_xWidget, rWinEvent.GetWindow()));
648  m_aMouseMotionHdl.Call(aTransformedEvent);
649  }
650  }
651 }
652 
654 {
655  // we get all key events here, ignore them unless we have focus
657  return false;
658  if (rEvent.GetId() == VclEventId::WindowKeyInput)
659  {
660  const KeyEvent* pKeyEvent = static_cast<const KeyEvent*>(rEvent.GetData());
661  return m_aKeyPressHdl.Call(*pKeyEvent);
662  }
663  else if (rEvent.GetId() == VclEventId::WindowKeyUp)
664  {
665  const KeyEvent* pKeyEvent = static_cast<const KeyEvent*>(rEvent.GetData());
666  return m_aKeyReleaseHdl.Call(*pKeyEvent);
667  }
668  return false;
669 }
670 
671 IMPL_LINK(SalInstanceWidget, EventListener, VclWindowEvent&, rEvent, void)
672 {
673  HandleEventListener(rEvent);
674 }
675 
676 IMPL_LINK(SalInstanceWidget, KeyEventListener, VclWindowEvent&, rEvent, bool)
677 {
678  return HandleKeyEventListener(rEvent);
679 }
680 
681 IMPL_LINK(SalInstanceWidget, MouseEventListener, VclSimpleEvent&, rEvent, void)
682 {
683  HandleMouseEventListener(rEvent);
684 }
685 
686 IMPL_LINK_NOARG(SalInstanceWidget, MnemonicActivateHdl, vcl::Window&, bool)
687 {
688  return m_aMnemonicActivateHdl.Call(*this);
689 }
690 
691 namespace
692 {
693 Image createImage(const OUString& rImage)
694 {
695  if (rImage.isEmpty())
696  return Image();
697  if (rImage.lastIndexOf('.') != rImage.getLength() - 4)
698  {
699  assert((rImage == "dialog-warning" || rImage == "dialog-error"
700  || rImage == "dialog-information")
701  && "unknown stock image");
702  if (rImage == "dialog-warning")
703  return Image(StockImage::Yes, IMG_WARN);
704  else if (rImage == "dialog-error")
705  return Image(StockImage::Yes, IMG_ERROR);
706  else if (rImage == "dialog-information")
707  return Image(StockImage::Yes, IMG_INFO);
708  }
709  return Image(StockImage::Yes, rImage);
710 }
711 
712 Image createImage(const VirtualDevice& rDevice)
713 {
714  return Image(rDevice.GetBitmapEx(Point(), rDevice.GetOutputSizePixel()));
715 }
716 
717 sal_uInt16 insert_to_menu(sal_uInt16 nLastId, PopupMenu* pMenu, int pos, std::u16string_view rId,
718  const OUString& rStr, const OUString* pIconName,
719  const VirtualDevice* pImageSurface,
720  const css::uno::Reference<css::graphic::XGraphic>& rImage,
721  TriState eCheckRadioFalse)
722 {
723  const sal_uInt16 nNewid = nLastId + 1;
724 
725  MenuItemBits nBits;
726  if (eCheckRadioFalse == TRISTATE_TRUE)
727  nBits = MenuItemBits::CHECKABLE;
728  else if (eCheckRadioFalse == TRISTATE_FALSE)
730  else
731  nBits = MenuItemBits::NONE;
732 
733  pMenu->InsertItem(nNewid, rStr, nBits, OUStringToOString(rId, RTL_TEXTENCODING_UTF8),
734  pos == -1 ? MENU_APPEND : pos);
735  if (pIconName)
736  {
737  pMenu->SetItemImage(nNewid, createImage(*pIconName));
738  }
739  else if (pImageSurface)
740  {
741  pMenu->SetItemImage(nNewid, createImage(*pImageSurface));
742  }
743  else if (rImage)
744  {
745  pMenu->SetItemImage(nNewid, Image(rImage));
746  }
747  return nNewid;
748 }
749 }
750 
751 SalInstanceMenu::SalInstanceMenu(PopupMenu* pMenu, bool bTakeOwnership)
752  : m_xMenu(pMenu)
753  , m_bTakeOwnership(bTakeOwnership)
754 {
755  const auto nCount = m_xMenu->GetItemCount();
756  m_nLastId = nCount ? pMenu->GetItemId(nCount - 1) : 0;
757  m_xMenu->SetSelectHdl(LINK(this, SalInstanceMenu, SelectMenuHdl));
758 }
760 {
761  SalInstanceWidget* pVclWidget = dynamic_cast<SalInstanceWidget*>(pParent);
762  assert(pVclWidget);
763  m_xMenu->Execute(pVclWidget->getWidget(), rRect,
765  return m_xMenu->GetCurItemIdent();
766 }
767 void SalInstanceMenu::set_sensitive(const OString& rIdent, bool bSensitive)
768 {
769  m_xMenu->EnableItem(rIdent, bSensitive);
770 }
771 bool SalInstanceMenu::get_sensitive(const OString& rIdent) const
772 {
773  return m_xMenu->IsItemEnabled(m_xMenu->GetItemId(rIdent));
774 }
775 void SalInstanceMenu::set_active(const OString& rIdent, bool bActive)
776 {
777  m_xMenu->CheckItem(rIdent, bActive);
778 }
779 bool SalInstanceMenu::get_active(const OString& rIdent) const
780 {
781  return m_xMenu->IsItemChecked(m_xMenu->GetItemId(rIdent));
782 }
783 void SalInstanceMenu::set_label(const OString& rIdent, const OUString& rLabel)
784 {
785  m_xMenu->SetItemText(m_xMenu->GetItemId(rIdent), rLabel);
786 }
787 OUString SalInstanceMenu::get_label(const OString& rIdent) const
788 {
789  return m_xMenu->GetItemText(m_xMenu->GetItemId(rIdent));
790 }
791 void SalInstanceMenu::set_visible(const OString& rIdent, bool bShow)
792 {
793  m_xMenu->ShowItem(m_xMenu->GetItemId(rIdent), bShow);
794 }
796 void SalInstanceMenu::insert(int pos, const OUString& rId, const OUString& rStr,
797  const OUString* pIconName, VirtualDevice* pImageSurface,
798  const css::uno::Reference<css::graphic::XGraphic>& rImage,
799  TriState eCheckRadioFalse)
800 {
801  m_nLastId = insert_to_menu(m_nLastId, m_xMenu, pos, rId, rStr, pIconName, pImageSurface, rImage,
802  eCheckRadioFalse);
803 }
804 void SalInstanceMenu::insert_separator(int pos, const OUString& rId)
805 {
806  auto nInsertPos = pos == -1 ? MENU_APPEND : pos;
807  m_xMenu->InsertSeparator(rId.toUtf8(), nInsertPos);
808 }
809 void SalInstanceMenu::remove(const OString& rId)
810 {
812 }
814 OString SalInstanceMenu::get_id(int pos) const
815 {
816  return m_xMenu->GetItemIdent(m_xMenu->GetItemId(pos));
817 }
820 {
822  if (m_bTakeOwnership)
824 }
825 
826 IMPL_LINK_NOARG(SalInstanceMenu, SelectMenuHdl, ::Menu*, bool)
827 {
828  signal_activate(m_xMenu->GetCurItemIdent());
829  /* tdf#131333 Menu::Select depends on a false here to allow
830  propagating a submens's selected id to its parent menu to become its
831  selected id.
832 
833  without this, while gen menus already have propagated this to its parent
834  in MenuFloatingWindow::EndExecute, SalMenus as used under kf5/macOS
835  won't propagate the selected id
836  */
837  return false;
838 }
839 
841  bool bTakeOwnership)
842  : SalInstanceWidget(pToolBox, pBuilder, bTakeOwnership)
843  , m_xToolBox(pToolBox)
844 {
845  m_xToolBox->SetSelectHdl(LINK(this, SalInstanceToolbar, ClickHdl));
846  m_xToolBox->SetDropdownClickHdl(LINK(this, SalInstanceToolbar, DropdownClick));
847 }
848 
849 void SalInstanceToolbar::set_item_sensitive(const OString& rIdent, bool bSensitive)
850 {
851  m_xToolBox->EnableItem(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), bSensitive);
852 }
853 
854 bool SalInstanceToolbar::get_item_sensitive(const OString& rIdent) const
855 {
856  return m_xToolBox->IsItemEnabled(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)));
857 }
858 
859 void SalInstanceToolbar::set_item_visible(const OString& rIdent, bool bVisible)
860 {
861  m_xToolBox->ShowItem(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), bVisible);
862 }
863 
864 void SalInstanceToolbar::set_item_help_id(const OString& rIdent, const OString& rHelpId)
865 {
866  m_xToolBox->SetHelpId(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), rHelpId);
867 }
868 
869 bool SalInstanceToolbar::get_item_visible(const OString& rIdent) const
870 {
871  return m_xToolBox->IsItemVisible(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)));
872 }
873 
874 void SalInstanceToolbar::set_item_active(const OString& rIdent, bool bActive)
875 {
876  ToolBoxItemId nItemId = m_xToolBox->GetItemId(OUString::fromUtf8(rIdent));
877  m_xToolBox->CheckItem(nItemId, bActive);
878 }
879 
880 bool SalInstanceToolbar::get_item_active(const OString& rIdent) const
881 {
882  return m_xToolBox->IsItemChecked(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)));
883 }
884 
885 void SalInstanceToolbar::set_menu_item_active(const OString& rIdent, bool bActive)
886 {
887  ToolBoxItemId nItemId = m_xToolBox->GetItemId(OUString::fromUtf8(rIdent));
889 
890  if (bActive)
891  {
892  m_sStartShowIdent = m_xToolBox->GetItemCommand(nItemId).toUtf8();
894  }
895 
896  auto pFloat = m_aFloats[nItemId];
897  if (pFloat)
898  {
899  if (bActive)
902  else
904  }
905  auto pPopup = m_aMenus[nItemId];
906  if (pPopup)
907  {
908  if (bActive)
909  {
910  tools::Rectangle aRect = m_xToolBox->GetItemRect(nItemId);
911  pPopup->Execute(m_xToolBox, aRect, PopupMenuFlags::ExecuteDown);
912  }
913  else
914  pPopup->EndExecute();
915  }
916 
917  m_sStartShowIdent.clear();
918 }
919 
920 bool SalInstanceToolbar::get_menu_item_active(const OString& rIdent) const
921 {
922  ToolBoxItemId nItemId = m_xToolBox->GetItemId(OUString::fromUtf8(rIdent));
924 
925  if (rIdent == m_sStartShowIdent)
926  return true;
927 
928  auto aFloat = m_aFloats.find(nItemId);
929  if (aFloat != m_aFloats.end())
930  {
931  return vcl::Window::GetDockingManager()->IsInPopupMode(aFloat->second);
932  }
933 
934  auto aPopup = m_aMenus.find(nItemId);
935  if (aPopup != m_aMenus.end())
936  {
937  return PopupMenu::GetActivePopupMenu() == aPopup->second;
938  }
939 
940  return false;
941 }
942 
943 void SalInstanceToolbar::set_item_popover(const OString& rIdent, weld::Widget* pPopover)
944 {
945  SalInstanceWidget* pPopoverWidget = dynamic_cast<SalInstanceWidget*>(pPopover);
946 
947  vcl::Window* pFloat = pPopoverWidget ? pPopoverWidget->getWidget() : nullptr;
948  if (pFloat)
949  {
950  pFloat->AddEventListener(LINK(this, SalInstanceToolbar, MenuToggleListener));
951  pFloat->EnableDocking();
952  }
953 
954  ToolBoxItemId nId = m_xToolBox->GetItemId(OUString::fromUtf8(rIdent));
955  auto xOldFloat = m_aFloats[nId];
956  if (xOldFloat)
957  {
958  xOldFloat->RemoveEventListener(LINK(this, SalInstanceToolbar, MenuToggleListener));
959  }
960  m_aFloats[nId] = pFloat;
961  m_aMenus[nId] = nullptr;
962 }
963 
964 void SalInstanceToolbar::set_item_menu(const OString& rIdent, weld::Menu* pMenu)
965 {
966  SalInstanceMenu* pInstanceMenu = dynamic_cast<SalInstanceMenu*>(pMenu);
967 
968  PopupMenu* pPopup = pInstanceMenu ? pInstanceMenu->getMenu() : nullptr;
969 
970  ToolBoxItemId nId = m_xToolBox->GetItemId(OUString::fromUtf8(rIdent));
971  m_aMenus[nId] = pPopup;
972  m_aFloats[nId] = nullptr;
973 }
974 
975 void SalInstanceToolbar::insert_item(int pos, const OUString& rId)
976 {
977  ToolBoxItemId nId(pos);
979  m_xToolBox->SetItemCommand(nId, rId);
980 }
981 
982 void SalInstanceToolbar::insert_separator(int pos, const OUString& /*rId*/)
983 {
984  auto nInsertPos = pos == -1 ? ToolBox::APPEND : pos;
985  m_xToolBox->InsertSeparator(nInsertPos, 5);
986 }
987 
989 
990 OString SalInstanceToolbar::get_item_ident(int nIndex) const
991 {
992  return m_xToolBox->GetItemCommand(m_xToolBox->GetItemId(nIndex)).toUtf8();
993 }
994 
995 void SalInstanceToolbar::set_item_ident(int nIndex, const OString& rIdent)
996 {
997  return m_xToolBox->SetItemCommand(m_xToolBox->GetItemId(nIndex), OUString::fromUtf8(rIdent));
998 }
999 
1000 void SalInstanceToolbar::set_item_label(int nIndex, const OUString& rLabel)
1001 {
1002  m_xToolBox->SetItemText(m_xToolBox->GetItemId(nIndex), rLabel);
1003 }
1004 
1005 OUString SalInstanceToolbar::get_item_label(const OString& rIdent) const
1006 {
1007  return m_xToolBox->GetItemText(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)));
1008 }
1009 
1010 void SalInstanceToolbar::set_item_label(const OString& rIdent, const OUString& rLabel)
1011 {
1012  m_xToolBox->SetItemText(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), rLabel);
1013 }
1014 
1015 void SalInstanceToolbar::set_item_icon_name(const OString& rIdent, const OUString& rIconName)
1016 {
1017  m_xToolBox->SetItemImage(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)),
1018  Image(StockImage::Yes, rIconName));
1019 }
1020 
1021 void SalInstanceToolbar::set_item_image(const OString& rIdent,
1022  const css::uno::Reference<css::graphic::XGraphic>& rIcon)
1023 {
1024  m_xToolBox->SetItemImage(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), Image(rIcon));
1025 }
1026 
1027 void SalInstanceToolbar::set_item_image(const OString& rIdent, VirtualDevice* pDevice)
1028 {
1029  if (pDevice)
1030  m_xToolBox->SetItemImage(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)),
1031  createImage(*pDevice));
1032  else
1033  m_xToolBox->SetItemImage(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), Image());
1034 }
1035 
1037  const css::uno::Reference<css::graphic::XGraphic>& rIcon)
1038 {
1039  m_xToolBox->SetItemImage(m_xToolBox->GetItemId(nIndex), Image(rIcon));
1040 }
1041 
1042 void SalInstanceToolbar::set_item_tooltip_text(int nIndex, const OUString& rTip)
1043 {
1045 }
1046 
1047 void SalInstanceToolbar::set_item_tooltip_text(const OString& rIdent, const OUString& rTip)
1048 {
1049  m_xToolBox->SetQuickHelpText(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), rTip);
1050 }
1051 
1052 OUString SalInstanceToolbar::get_item_tooltip_text(const OString& rIdent) const
1053 {
1054  return m_xToolBox->GetQuickHelpText(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)));
1055 }
1056 
1058 
1060 {
1062  switch (eType)
1063  {
1065  eButtonSize = ToolBoxButtonSize::Small;
1066  break;
1068  eButtonSize = ToolBoxButtonSize::Large;
1069  break;
1071  eButtonSize = ToolBoxButtonSize::Size32;
1072  break;
1073  }
1074  if (m_xToolBox->GetToolboxButtonSize() != eButtonSize)
1075  {
1076  m_xToolBox->SetToolboxButtonSize(eButtonSize);
1078  }
1079 }
1080 
1082 
1083 int SalInstanceToolbar::get_drop_index(const Point& rPoint) const
1084 {
1085  auto nRet = m_xToolBox->GetItemPos(rPoint);
1086  if (nRet == ToolBox::ITEM_NOTFOUND)
1087  return 0;
1088  return nRet;
1089 }
1090 
1092 {
1095 }
1096 
1098 {
1099  ToolBoxItemId nItemId = m_xToolBox->GetCurItemId();
1100  signal_clicked(m_xToolBox->GetItemCommand(nItemId).toUtf8());
1101 }
1102 
1104 {
1105  ToolBoxItemId nItemId = m_xToolBox->GetCurItemId();
1106  set_menu_item_active(m_xToolBox->GetItemCommand(nItemId).toUtf8(), true);
1107 }
1108 
1109 IMPL_LINK(SalInstanceToolbar, MenuToggleListener, VclWindowEvent&, rEvent, void)
1110 {
1111  if (rEvent.GetId() == VclEventId::WindowEndPopupMode)
1112  {
1113  for (auto& rFloat : m_aFloats)
1114  {
1115  if (rEvent.GetWindow() == rFloat.second)
1116  {
1117  ToolBoxItemId nItemId = rFloat.first;
1118  signal_toggle_menu(m_xToolBox->GetItemCommand(nItemId).toUtf8());
1119  break;
1120  }
1121  }
1122  }
1123 }
1124 
1125 namespace
1126 {
1127 class SalInstanceSizeGroup : public weld::SizeGroup
1128 {
1129 private:
1130  std::shared_ptr<VclSizeGroup> m_xGroup;
1131 
1132 public:
1133  SalInstanceSizeGroup()
1134  : m_xGroup(std::make_shared<VclSizeGroup>())
1135  {
1136  }
1137  virtual void add_widget(weld::Widget* pWidget) override
1138  {
1139  SalInstanceWidget* pVclWidget = dynamic_cast<SalInstanceWidget*>(pWidget);
1140  assert(pVclWidget && pVclWidget->getWidget());
1141  pVclWidget->getWidget()->add_to_size_group(m_xGroup);
1142  }
1143  virtual void set_mode(VclSizeGroupMode eMode) override { m_xGroup->set_mode(eMode); }
1144 };
1145 }
1146 
1148 {
1149  vcl::Window* pChildLoop = _pWindow->GetWindow(GetWindowType::FirstChild);
1150  while (pChildLoop)
1151  {
1152  // does the window participate in the tabbing order?
1153  if (pChildLoop->GetStyle() & WB_DIALOGCONTROL)
1154  implResetDefault(pChildLoop);
1155 
1156  // is it a button?
1157  WindowType eType = pChildLoop->GetType();
1158  if ((WindowType::PUSHBUTTON == eType) || (WindowType::OKBUTTON == eType)
1159  || (WindowType::CANCELBUTTON == eType) || (WindowType::HELPBUTTON == eType)
1160  || (WindowType::IMAGEBUTTON == eType) || (WindowType::MENUBUTTON == eType)
1161  || (WindowType::MOREBUTTON == eType))
1162  {
1163  pChildLoop->SetStyle(pChildLoop->GetStyle() & ~WB_DEFBUTTON);
1164  }
1165 
1166  // the next one ...
1167  pChildLoop = pChildLoop->GetWindow(GetWindowType::Next);
1168  }
1169 }
1170 
1172 {
1175 }
1176 
1178 {
1179  if (rEvent.GetId() == VclEventId::WindowActivate
1180  || rEvent.GetId() == VclEventId::WindowDeactivate)
1181  {
1183  return;
1184  }
1186 }
1187 
1189  bool bTakeOwnership)
1190  : SalInstanceWidget(pContainer, pBuilder, bTakeOwnership)
1191  , m_xContainer(pContainer)
1192 {
1193 }
1194 
1196 {
1197  SalInstanceWidget* pVclWidget = dynamic_cast<SalInstanceWidget*>(pWidget);
1198  assert(pVclWidget);
1199  SalInstanceContainer* pNewVclParent = dynamic_cast<SalInstanceContainer*>(pNewParent);
1200  assert(!pNewParent || pNewVclParent);
1201  if (pNewVclParent)
1202  pVclWidget->getWidget()->SetParent(pNewVclParent->getWidget());
1203  else
1204  pVclWidget->getWidget()->SetParentToDefaultWindow();
1205 }
1206 
1208 {
1212  pFirstChild->ImplControlFocus();
1214 }
1215 
1217 {
1219 }
1220 
1221 css::uno::Reference<css::awt::XWindow> SalInstanceContainer::CreateChildFrame()
1222 {
1223  auto xPage = VclPtr<VclBin>::Create(m_xContainer.get());
1224  xPage->set_expand(true);
1225  xPage->Show();
1226  return css::uno::Reference<css::awt::XWindow>(xPage->GetComponentInterface(),
1227  css::uno::UNO_QUERY);
1228 }
1229 
1230 std::unique_ptr<weld::Container> SalInstanceWidget::weld_parent() const
1231 {
1232  vcl::Window* pParent = m_xWidget->GetParent();
1233  if (!pParent)
1234  return nullptr;
1235  return std::make_unique<SalInstanceContainer>(pParent, m_pBuilder, false);
1236 }
1237 
1238 void SalInstanceWidget::DoRecursivePaint(vcl::Window* pWindow, const Point& rRenderLogicPos,
1239  OutputDevice& rOutput)
1240 {
1241  pWindow->Push();
1242  bool bOldMapModeEnabled = pWindow->IsMapModeEnabled();
1243 
1244  if (pWindow->GetMapMode().GetMapUnit() != rOutput.GetMapMode().GetMapUnit())
1245  {
1246  // This is needed for e.g. the scrollbar in writer comments in margins that has its map unit in pixels
1247  // as seen with bin/run gtktiledviewer --enable-tiled-annotations on a document containing a comment
1248  // long enough to need a scrollbar
1249  pWindow->EnableMapMode();
1250  MapMode aMapMode = pWindow->GetMapMode();
1251  aMapMode.SetMapUnit(rOutput.GetMapMode().GetMapUnit());
1252  aMapMode.SetScaleX(rOutput.GetMapMode().GetScaleX());
1253  aMapMode.SetScaleY(rOutput.GetMapMode().GetScaleY());
1254  pWindow->SetMapMode(aMapMode);
1255  }
1256 
1258  Size aChildSizePixel(pWindow->GetSizePixel());
1259  xOutput->SetOutputSizePixel(aChildSizePixel);
1260 
1261  MapMode aMapMode(xOutput->GetMapMode());
1262  aMapMode.SetMapUnit(rOutput.GetMapMode().GetMapUnit());
1263  aMapMode.SetScaleX(rOutput.GetMapMode().GetScaleX());
1264  aMapMode.SetScaleY(rOutput.GetMapMode().GetScaleY());
1265  xOutput->SetMapMode(aMapMode);
1266 
1267  Size aTempLogicSize(xOutput->PixelToLogic(aChildSizePixel));
1268  Size aRenderLogicSize(rOutput.PixelToLogic(aChildSizePixel));
1269 
1270  xOutput->DrawOutDev(Point(), aTempLogicSize, rRenderLogicPos, aRenderLogicSize, rOutput);
1271 
1272  //set ReallyVisible to match Visible, we restore the original state after Paint
1273  WindowImpl* pImpl = pWindow->ImplGetWindowImpl();
1274  bool bRVisible = pImpl->mbReallyVisible;
1275  pImpl->mbReallyVisible = pWindow->IsVisible();
1276 
1277  pWindow->ApplySettings(*xOutput);
1278  pWindow->Paint(*xOutput, tools::Rectangle(Point(), pWindow->PixelToLogic(aChildSizePixel)));
1279 
1280  pImpl->mbReallyVisible = bRVisible;
1281 
1282  rOutput.DrawOutDev(rRenderLogicPos, aRenderLogicSize, Point(), aTempLogicSize, *xOutput);
1283 
1284  xOutput.disposeAndClear();
1285 
1286  pWindow->EnableMapMode(bOldMapModeEnabled);
1287  pWindow->Pop();
1288 
1289  for (vcl::Window* pChild = pWindow->GetWindow(GetWindowType::FirstChild); pChild;
1290  pChild = pChild->GetWindow(GetWindowType::Next))
1291  {
1292  if (!pChild->IsVisible())
1293  continue;
1294  Point aRelPos(pChild->GetPosPixel());
1295  Size aRelLogicOffset(rOutput.PixelToLogic(Size(aRelPos.X(), aRelPos.Y())));
1296  DoRecursivePaint(pChild,
1297  rRenderLogicPos + Point(aRelLogicOffset.Width(), aRelLogicOffset.Height()),
1298  rOutput);
1299  }
1300 }
1301 
1302 void SalInstanceWidget::draw(OutputDevice& rOutput, const Point& rPos, const Size& rSizePixel)
1303 {
1304  Size aOrigSize(m_xWidget->GetSizePixel());
1305  bool bChangeSize = aOrigSize != rSizePixel;
1306  if (bChangeSize)
1307  m_xWidget->SetSizePixel(rSizePixel);
1308 
1309  DoRecursivePaint(m_xWidget, rPos, rOutput);
1310 
1311  if (bChangeSize)
1312  m_xWidget->SetSizePixel(aOrigSize);
1313 }
1314 
1315 namespace
1316 {
1317 class SalInstanceBox : public SalInstanceContainer, public virtual weld::Box
1318 {
1319 private:
1320  VclPtr<VclBox> m_xBox;
1321 
1322 public:
1323  SalInstanceBox(VclBox* pContainer, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
1324  : SalInstanceContainer(pContainer, pBuilder, bTakeOwnership)
1325  , m_xBox(pContainer)
1326  {
1327  }
1328  virtual void reorder_child(weld::Widget* pWidget, int nNewPosition) override
1329  {
1330  SalInstanceWidget* pVclWidget = dynamic_cast<SalInstanceWidget*>(pWidget);
1331  assert(pVclWidget);
1332  pVclWidget->getWidget()->reorderWithinParent(nNewPosition);
1333  }
1334  virtual void sort_native_button_order() override { ::sort_native_button_order(*m_xBox); }
1335 };
1336 
1337 void CollectChildren(const vcl::Window& rCurrent, const basegfx::B2IPoint& rTopLeft,
1338  weld::ScreenShotCollection& rControlDataCollection)
1339 {
1340  if (!rCurrent.IsVisible())
1341  return;
1342 
1343  const Point aCurrentPos(rCurrent.GetPosPixel());
1344  const Size aCurrentSize(rCurrent.GetSizePixel());
1345  const basegfx::B2IPoint aCurrentTopLeft(rTopLeft.getX() + aCurrentPos.X(),
1346  rTopLeft.getY() + aCurrentPos.Y());
1347  const basegfx::B2IRange aCurrentRange(
1348  aCurrentTopLeft,
1349  aCurrentTopLeft + basegfx::B2IPoint(aCurrentSize.Width(), aCurrentSize.Height()));
1350 
1351  if (!aCurrentRange.isEmpty())
1352  {
1353  rControlDataCollection.emplace_back(rCurrent.GetHelpId(), aCurrentRange);
1354  }
1355 
1356  for (sal_uInt16 a(0); a < rCurrent.GetChildCount(); a++)
1357  {
1358  vcl::Window* pChild = rCurrent.GetChild(a);
1359  if (nullptr != pChild)
1360  {
1361  CollectChildren(*pChild, aCurrentTopLeft, rControlDataCollection);
1362  }
1363  }
1364 }
1365 }
1366 
1368 {
1369  for (vcl::Window* pChild = pParent->GetWindow(GetWindowType::FirstChild); pChild;
1370  pChild = pChild->GetWindow(GetWindowType::Next))
1371  override_child_help(pChild);
1372  pParent->SetHelpHdl(LINK(this, SalInstanceWindow, HelpHdl));
1373 }
1374 
1376 {
1377  for (vcl::Window* pChild = pParent->GetWindow(GetWindowType::FirstChild); pChild;
1378  pChild = pChild->GetWindow(GetWindowType::Next))
1379  clear_child_help(pChild);
1381 }
1382 
1384  bool bTakeOwnership)
1385  : SalInstanceContainer(pWindow, pBuilder, bTakeOwnership)
1386  , m_xWindow(pWindow)
1387 {
1389 }
1390 
1391 void SalInstanceWindow::set_title(const OUString& rTitle) { m_xWindow->SetText(rTitle); }
1392 
1393 OUString SalInstanceWindow::get_title() const { return m_xWindow->GetText(); }
1394 
1395 css::uno::Reference<css::awt::XWindow> SalInstanceWindow::GetXWindow()
1396 {
1397  css::uno::Reference<css::awt::XWindow> xWindow(m_xWindow->GetComponentInterface(),
1398  css::uno::UNO_QUERY);
1399  return xWindow;
1400 }
1401 
1403 {
1404  if (SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(m_xWindow.get()))
1405  {
1406  pSysWin->setOptimalLayoutSize();
1407  return;
1408  }
1409  if (DockingWindow* pDockWin = dynamic_cast<DockingWindow*>(m_xWindow.get()))
1410  {
1411  pDockWin->setOptimalLayoutSize();
1412  return;
1413  }
1414  assert(false && "must be system or docking window");
1415 }
1416 
1418 
1420 
1422 
1424 
1426 
1428 {
1429  return m_xWindow->GetDesktopRectPixel();
1430 }
1431 
1432 void SalInstanceWindow::set_centered_on_parent(bool /*bTrackGeometryRequests*/)
1433 {
1434  if (vcl::Window* pParent = m_xWidget->GetParent())
1435  {
1436  Size aParentGeometry(pParent->GetSizePixel());
1437  Size aGeometry(m_xWidget->get_preferred_size());
1438  auto nX = (aParentGeometry.Width() - aGeometry.Width()) / 2;
1439  auto nY = (aParentGeometry.Height() - aGeometry.Height()) / 2;
1440  m_xWidget->SetPosPixel(Point(nX, nY));
1441  }
1442 }
1443 
1445 
1447 
1449 {
1451 }
1452 
1453 void SalInstanceWindow::set_window_state(const OString& rStr)
1454 {
1455  SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(m_xWindow.get());
1456  assert(pSysWin);
1457  pSysWin->SetWindowState(rStr);
1458 }
1459 
1461 {
1462  SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(m_xWindow.get());
1463  assert(pSysWin);
1464  return pSysWin->GetWindowState(nMask);
1465 }
1466 
1468 
1470 {
1471  SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(m_xWindow.get());
1472  assert(pSysWin);
1473  return pSysWin->createScreenshot();
1474 }
1475 
1477 {
1479 
1480  // collect all children. Choose start pos to be negative
1481  // of target dialog's position to get all positions relative to (0,0)
1482  const Point aParentPos(m_xWindow->GetPosPixel());
1483  const basegfx::B2IPoint aTopLeft(-aParentPos.X(), -aParentPos.Y());
1484  CollectChildren(*m_xWindow, aTopLeft, aRet);
1485 
1486  return aRet;
1487 }
1488 
1490 
1492 {
1493  help();
1494  return false;
1495 }
1496 
1497 typedef std::set<VclPtr<vcl::Window>> winset;
1498 
1499 namespace
1500 {
1501 void hideUnless(const vcl::Window* pTop, const winset& rVisibleWidgets,
1502  std::vector<VclPtr<vcl::Window>>& rWasVisibleWidgets)
1503 {
1504  for (vcl::Window* pChild = pTop->GetWindow(GetWindowType::FirstChild); pChild;
1505  pChild = pChild->GetWindow(GetWindowType::Next))
1506  {
1507  if (!pChild->IsVisible())
1508  continue;
1509  if (rVisibleWidgets.find(pChild) == rVisibleWidgets.end())
1510  {
1511  rWasVisibleWidgets.emplace_back(pChild);
1512  pChild->Hide();
1513  }
1514  else if (isContainerWindow(pChild))
1515  {
1516  hideUnless(pChild, rVisibleWidgets, rWasVisibleWidgets);
1517  }
1518  }
1519 }
1520 }
1521 
1523  bool bTakeOwnership)
1524  : SalInstanceWindow(pDialog, pBuilder, bTakeOwnership)
1525  , m_xDialog(pDialog)
1526  , m_nOldEditWidthReq(0)
1527  , m_nOldBorderWidth(0)
1528 {
1529  const bool bScreenshotMode(officecfg::Office::Common::Misc::ScreenshotMode::get());
1530  if (bScreenshotMode)
1531  {
1532  m_xDialog->SetPopupMenuHdl(LINK(this, SalInstanceDialog, PopupScreenShotMenuHdl));
1533  }
1534 }
1535 
1536 bool SalInstanceDialog::runAsync(std::shared_ptr<weld::DialogController> aOwner,
1537  const std::function<void(sal_Int32)>& rEndDialogFn)
1538 {
1540  aCtx.mxOwnerDialogController = aOwner;
1541  aCtx.maEndDialogFn = rEndDialogFn;
1542  VclButtonBox* pActionArea = m_xDialog->get_action_area();
1543  if (pActionArea)
1544  sort_native_button_order(*pActionArea);
1545  return m_xDialog->StartExecuteAsync(aCtx);
1546 }
1547 
1548 bool SalInstanceDialog::runAsync(std::shared_ptr<Dialog> const& rxSelf,
1549  const std::function<void(sal_Int32)>& rEndDialogFn)
1550 {
1551  assert(rxSelf.get() == this);
1553  // In order to store a shared_ptr to ourself, we have to have been constructed by make_shared,
1554  // which is that rxSelf enforces.
1555  aCtx.mxOwnerSelf = rxSelf;
1556  aCtx.maEndDialogFn = rEndDialogFn;
1557  VclButtonBox* pActionArea = m_xDialog->get_action_area();
1558  if (pActionArea)
1559  sort_native_button_order(*pActionArea);
1560  return m_xDialog->StartExecuteAsync(aCtx);
1561 }
1562 
1564 {
1565  SalInstanceWidget* pVclEdit = dynamic_cast<SalInstanceWidget*>(pEdit);
1566  assert(pVclEdit);
1567  SalInstanceWidget* pVclButton = dynamic_cast<SalInstanceWidget*>(pButton);
1568 
1569  vcl::Window* pRefEdit = pVclEdit->getWidget();
1570  vcl::Window* pRefBtn = pVclButton ? pVclButton->getWidget() : nullptr;
1571 
1572  auto nOldEditWidth = pRefEdit->GetSizePixel().Width();
1573  m_nOldEditWidthReq = pRefEdit->get_width_request();
1574 
1575  //We want just pRefBtn and pRefEdit to be shown
1576  //mark widgets we want to be visible, starting with pRefEdit
1577  //and all its direct parents.
1578  winset aVisibleWidgets;
1579  vcl::Window* pContentArea = m_xDialog->get_content_area();
1580  for (vcl::Window* pCandidate = pRefEdit;
1581  pCandidate && (pCandidate != pContentArea && pCandidate->IsVisible());
1582  pCandidate = pCandidate->GetWindow(GetWindowType::RealParent))
1583  {
1584  aVisibleWidgets.insert(pCandidate);
1585  }
1586  //same again with pRefBtn, except stop if there's a
1587  //shared parent in the existing widgets
1588  for (vcl::Window* pCandidate = pRefBtn;
1589  pCandidate && (pCandidate != pContentArea && pCandidate->IsVisible());
1590  pCandidate = pCandidate->GetWindow(GetWindowType::RealParent))
1591  {
1592  if (aVisibleWidgets.insert(pCandidate).second)
1593  break;
1594  }
1595 
1596  //hide everything except the aVisibleWidgets
1597  hideUnless(pContentArea, aVisibleWidgets, m_aHiddenWidgets);
1598 
1599  // the insert function case has an initially hidden edit widget, so it has
1600  // not start size, so take larger of actual size and size request
1601  pRefEdit->set_width_request(std::max(nOldEditWidth, m_nOldEditWidthReq));
1604  if (vcl::Window* pActionArea = m_xDialog->get_action_area())
1605  pActionArea->Hide();
1607  m_xRefEdit = pRefEdit;
1608 }
1609 
1611 {
1612  // All others: Show();
1613  for (VclPtr<vcl::Window> const& pWindow : m_aHiddenWidgets)
1614  {
1615  pWindow->Show();
1616  }
1617  m_aHiddenWidgets.clear();
1618 
1620  m_xRefEdit.clear();
1622  if (vcl::Window* pActionArea = m_xDialog->get_action_area())
1623  pActionArea->Show();
1625 }
1626 
1629 {
1631 }
1632 
1634 {
1635  VclButtonBox* pActionArea = m_xDialog->get_action_area();
1636  if (pActionArea)
1637  sort_native_button_order(*pActionArea);
1638  return m_xDialog->Execute();
1639 }
1640 
1641 void SalInstanceDialog::response(int nResponse) { m_xDialog->EndDialog(nResponse); }
1642 
1643 void SalInstanceDialog::add_button(const OUString& rText, int nResponse, const OString& rHelpId)
1644 {
1646  VclPtr<PushButton> xButton(
1648  xButton->SetText(rText);
1649  xButton->SetHelpId(rHelpId);
1650 
1651  switch (nResponse)
1652  {
1653  case RET_OK:
1654  xButton->set_id("ok");
1655  break;
1656  case RET_CLOSE:
1657  xButton->set_id("close");
1658  break;
1659  case RET_CANCEL:
1660  xButton->set_id("cancel");
1661  break;
1662  case RET_YES:
1663  xButton->set_id("yes");
1664  break;
1665  case RET_NO:
1666  xButton->set_id("no");
1667  break;
1668  }
1669 
1670  xButton->Show();
1671  m_xDialog->add_button(xButton, nResponse, true);
1672 }
1673 
1675 {
1676  if (get_modal() == bModal)
1677  return;
1678  m_xDialog->SetModalInputMode(bModal);
1679 }
1680 
1682 
1684 {
1685  m_xDialog->set_default_response(nResponse);
1686 }
1687 
1689 {
1691 }
1692 
1693 IMPL_LINK(SalInstanceDialog, PopupScreenShotMenuHdl, const CommandEvent&, rCEvt, bool)
1694 {
1695  if (CommandEventId::ContextMenu == rCEvt.GetCommand())
1696  {
1697  const Point aMenuPos(rCEvt.GetMousePosPixel());
1699  sal_uInt16 nLocalID(1);
1700 
1701  aMenu->InsertItem(nLocalID, VclResId(SV_BUTTONTEXT_SCREENSHOT));
1702  aMenu->SetHelpText(nLocalID, VclResId(SV_HELPTEXT_SCREENSHOT));
1703  aMenu->SetHelpId(nLocalID, "InteractiveScreenshotMode");
1704  aMenu->EnableItem(nLocalID);
1705 
1706  const sal_uInt16 nId(aMenu->Execute(m_xDialog, aMenuPos));
1707 
1708  // 0 == no selection (so not usable as ID)
1709  if (0 != nId)
1710  {
1711  // open screenshot annotation dialog
1714  = pFact->CreateScreenshotAnnotationDlg(*this);
1716 
1717  if (pDialog)
1718  {
1719  // currently just execute the dialog, no need to do
1720  // different things for ok/cancel. This may change later,
1721  // for that case use 'if (pDlg->Execute() == RET_OK)'
1722  pDialog->Execute();
1723  }
1724  }
1725 
1726  // consume event when:
1727  // - CommandEventId::ContextMenu
1728  // - bScreenshotMode
1729  return true;
1730  }
1731 
1732  return false;
1733 }
1734 
1736  SalInstanceBuilder* pBuilder,
1737  bool bTakeOwnership)
1738  : SalInstanceDialog(pDialog, pBuilder, bTakeOwnership)
1739  , m_xMessageDialog(pDialog)
1740 {
1741 }
1742 
1744 {
1746 }
1747 
1749 {
1751 }
1752 
1754 {
1756 }
1757 
1759 {
1761 }
1762 
1764 {
1766 }
1767 
1768 namespace
1769 {
1770 class SalInstanceAssistant : public SalInstanceDialog, public virtual weld::Assistant
1771 {
1772 private:
1773  VclPtr<vcl::RoadmapWizard> m_xWizard;
1774  std::vector<std::unique_ptr<SalInstanceContainer>> m_aPages;
1775  std::vector<VclPtr<TabPage>> m_aAddedPages;
1776  std::vector<int> m_aIds;
1777  std::vector<VclPtr<VclGrid>> m_aAddedGrids;
1778  Idle m_aUpdateRoadmapIdle;
1779 
1780  int find_page(std::string_view rIdent) const
1781  {
1782  for (size_t i = 0; i < m_aAddedPages.size(); ++i)
1783  {
1784  if (m_aAddedPages[i]->get_id().toUtf8() == rIdent)
1785  return i;
1786  }
1787  return -1;
1788  }
1789 
1790  int find_id(int nId) const
1791  {
1792  for (size_t i = 0; i < m_aIds.size(); ++i)
1793  {
1794  if (nId == m_aIds[i])
1795  return i;
1796  }
1797  return -1;
1798  }
1799 
1800  DECL_LINK(OnRoadmapItemSelected, LinkParamNone*, void);
1801  DECL_LINK(UpdateRoadmap_Hdl, Timer*, void);
1802 
1803 public:
1804  SalInstanceAssistant(vcl::RoadmapWizard* pDialog, SalInstanceBuilder* pBuilder,
1805  bool bTakeOwnership)
1806  : SalInstanceDialog(pDialog, pBuilder, bTakeOwnership)
1807  , m_xWizard(pDialog)
1808  {
1809  m_xWizard->SetItemSelectHdl(LINK(this, SalInstanceAssistant, OnRoadmapItemSelected));
1810 
1811  m_aUpdateRoadmapIdle.SetInvokeHandler(LINK(this, SalInstanceAssistant, UpdateRoadmap_Hdl));
1812  m_aUpdateRoadmapIdle.SetPriority(TaskPriority::HIGHEST);
1813  }
1814 
1815  virtual int get_current_page() const override { return find_id(m_xWizard->GetCurLevel()); }
1816 
1817  virtual int get_n_pages() const override { return m_aAddedPages.size(); }
1818 
1819  virtual OString get_page_ident(int nPage) const override
1820  {
1821  return m_aAddedPages[nPage]->get_id().toUtf8();
1822  }
1823 
1824  virtual OString get_current_page_ident() const override
1825  {
1826  return get_page_ident(get_current_page());
1827  }
1828 
1829  virtual void set_current_page(int nPage) override
1830  {
1832 
1833  // take the first shown page as the size for all pages
1834  if (m_xWizard->GetPageSizePixel().Width() == 0)
1835  {
1836  Size aFinalSize;
1837  for (int i = 0, nPages = get_n_pages(); i < nPages; ++i)
1838  {
1839  TabPage* pPage = m_xWizard->GetPage(m_aIds[i]);
1840  assert(pPage);
1841  Size aPageSize(pPage->get_preferred_size());
1842  if (aPageSize.Width() > aFinalSize.Width())
1843  aFinalSize.setWidth(aPageSize.Width());
1844  if (aPageSize.Height() > aFinalSize.Height())
1845  aFinalSize.setHeight(aPageSize.Height());
1846  }
1847  m_xWizard->SetPageSizePixel(aFinalSize);
1848  }
1849 
1850  (void)m_xWizard->ShowPage(m_aIds[nPage]);
1852  }
1853 
1854  virtual void set_current_page(const OString& rIdent) override
1855  {
1856  int nIndex = find_page(rIdent);
1857  if (nIndex == -1)
1858  return;
1859  set_current_page(nIndex);
1860  }
1861 
1862  virtual void set_page_index(const OString& rIdent, int nNewIndex) override
1863  {
1864  int nOldIndex = find_page(rIdent);
1865 
1866  if (nOldIndex == -1)
1867  return;
1868 
1869  if (nOldIndex == nNewIndex)
1870  return;
1871 
1873 
1874  auto entry = std::move(m_aAddedPages[nOldIndex]);
1875  m_aAddedPages.erase(m_aAddedPages.begin() + nOldIndex);
1876  m_aAddedPages.insert(m_aAddedPages.begin() + nNewIndex, std::move(entry));
1877 
1878  int nId = m_aIds[nOldIndex];
1879  m_aIds.erase(m_aIds.begin() + nOldIndex);
1880  m_aIds.insert(m_aIds.begin() + nNewIndex, nId);
1881 
1882  m_aUpdateRoadmapIdle.Start();
1883 
1885  }
1886 
1887  virtual weld::Container* append_page(const OString& rIdent) override
1888  {
1889  VclPtrInstance<TabPage> xPage(m_xWizard);
1890  VclPtrInstance<VclGrid> xGrid(xPage);
1891  xPage->set_id(OUString::fromUtf8(rIdent));
1892  xPage->Show();
1893  xGrid->set_hexpand(true);
1894  xGrid->set_vexpand(true);
1895  xGrid->Show();
1896  m_xWizard->AddPage(xPage);
1897  m_aIds.push_back(m_aAddedPages.size());
1898  m_xWizard->SetPage(m_aIds.back(), xPage);
1899  m_aAddedPages.push_back(xPage);
1900  m_aAddedGrids.push_back(xGrid);
1901 
1902  m_aUpdateRoadmapIdle.Start();
1903 
1904  m_aPages.emplace_back(new SalInstanceContainer(xGrid, m_pBuilder, false));
1905  return m_aPages.back().get();
1906  }
1907 
1908  virtual OUString get_page_title(const OString& rIdent) const override
1909  {
1910  int nIndex = find_page(rIdent);
1911  if (nIndex == -1)
1912  return OUString();
1913  return m_aAddedPages[nIndex]->GetText();
1914  }
1915 
1916  virtual void set_page_title(const OString& rIdent, const OUString& rTitle) override
1917  {
1918  int nIndex = find_page(rIdent);
1919  if (nIndex == -1)
1920  return;
1921  if (m_aAddedPages[nIndex]->GetText() != rTitle)
1922  {
1924  m_aAddedPages[nIndex]->SetText(rTitle);
1925  m_aUpdateRoadmapIdle.Start();
1927  }
1928  }
1929 
1930  virtual void set_page_sensitive(const OString& rIdent, bool bSensitive) override
1931  {
1932  int nIndex = find_page(rIdent);
1933  if (nIndex == -1)
1934  return;
1935  if (m_aAddedPages[nIndex]->IsEnabled() != bSensitive)
1936  {
1938  m_aAddedPages[nIndex]->Enable(bSensitive);
1939  m_aUpdateRoadmapIdle.Start();
1941  }
1942  }
1943 
1944  virtual void set_page_side_help_id(const OString& rHelpId) override
1945  {
1946  m_xWizard->SetRoadmapHelpId(rHelpId);
1947  }
1948 
1949  weld::Button* weld_widget_for_response(int nResponse) override;
1950 
1951  virtual ~SalInstanceAssistant() override
1952  {
1953  for (auto& rGrid : m_aAddedGrids)
1954  rGrid.disposeAndClear();
1955  for (auto& rPage : m_aAddedPages)
1956  rPage.disposeAndClear();
1957  }
1958 };
1959 }
1960 
1961 IMPL_LINK_NOARG(SalInstanceAssistant, OnRoadmapItemSelected, LinkParamNone*, void)
1962 {
1963  if (notify_events_disabled())
1964  return;
1965  auto nCurItemId = m_xWizard->GetCurrentRoadmapItemID();
1966  int nPageIndex(find_id(nCurItemId));
1967  if (!signal_jump_page(get_page_ident(nPageIndex)) && nCurItemId != m_xWizard->GetCurLevel())
1968  m_xWizard->SelectRoadmapItemByID(m_xWizard->GetCurLevel());
1969 }
1970 
1971 IMPL_LINK_NOARG(SalInstanceAssistant, UpdateRoadmap_Hdl, Timer*, void)
1972 {
1973  disable_notify_events();
1974 
1975  m_xWizard->DeleteRoadmapItems();
1976 
1977  int nPos = 0;
1978  for (size_t i = 0; i < m_aAddedPages.size(); ++i)
1979  {
1980  const OUString& rLabel = m_aAddedPages[i]->GetText();
1981  bool bSensitive = m_aAddedPages[i]->IsEnabled();
1982  if (rLabel.isEmpty())
1983  continue;
1984  m_xWizard->InsertRoadmapItem(nPos++, rLabel, m_aIds[i], bSensitive);
1985  }
1986 
1987  m_xWizard->SelectRoadmapItemByID(m_aIds[get_current_page()], false);
1988 
1989  m_xWizard->ShowRoadmap(nPos != 0);
1990 
1991  enable_notify_events();
1992 }
1993 
1994 namespace
1995 {
1996 class SalInstanceFrame : public SalInstanceContainer, public virtual weld::Frame
1997 {
1998 private:
2000 
2001 public:
2002  SalInstanceFrame(VclFrame* pFrame, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2003  : SalInstanceContainer(pFrame, pBuilder, bTakeOwnership)
2004  , m_xFrame(pFrame)
2005  {
2006  }
2007 
2008  virtual void set_label(const OUString& rText) override { m_xFrame->set_label(rText); }
2009 
2010  virtual OUString get_label() const override { return m_xFrame->get_label(); }
2011 
2012  virtual std::unique_ptr<weld::Label> weld_label_widget() const override;
2013 };
2014 
2015 class SalInstancePaned : public SalInstanceContainer, public virtual weld::Paned
2016 {
2017 private:
2018  VclPtr<VclPaned> m_xPaned;
2019 
2020 public:
2021  SalInstancePaned(VclPaned* pPaned, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2022  : SalInstanceContainer(pPaned, pBuilder, bTakeOwnership)
2023  , m_xPaned(pPaned)
2024  {
2025  }
2026 
2027  virtual void set_position(int nPos) override { m_xPaned->set_position(nPos); }
2028 
2029  virtual int get_position() const override { return m_xPaned->get_position(); }
2030 };
2031 
2032 class SalInstanceScrolledWindow : public SalInstanceContainer, public virtual weld::ScrolledWindow
2033 {
2034 private:
2035  VclPtr<VclScrolledWindow> m_xScrolledWindow;
2036  Link<ScrollBar*, void> m_aOrigVScrollHdl;
2037  Link<ScrollBar*, void> m_aOrigHScrollHdl;
2038  bool m_bUserManagedScrolling;
2039 
2040  DECL_LINK(VscrollHdl, ScrollBar*, void);
2041  DECL_LINK(HscrollHdl, ScrollBar*, void);
2042 
2043  static void customize_scrollbars(ScrollBar& rScrollBar, const Color& rButtonTextColor,
2044  const Color& rBackgroundColor, const Color& rShadowColor,
2045  const Color& rFaceColor)
2046  {
2047  rScrollBar.EnableNativeWidget(false);
2048  AllSettings aSettings = rScrollBar.GetSettings();
2049  StyleSettings aStyleSettings = aSettings.GetStyleSettings();
2050  aStyleSettings.SetButtonTextColor(rButtonTextColor);
2051  aStyleSettings.SetCheckedColor(rBackgroundColor); // background
2052  aStyleSettings.SetShadowColor(rShadowColor);
2053  aStyleSettings.SetFaceColor(rFaceColor);
2054  aSettings.SetStyleSettings(aStyleSettings);
2055  rScrollBar.SetSettings(aSettings);
2056  }
2057 
2058 public:
2059  SalInstanceScrolledWindow(VclScrolledWindow* pScrolledWindow, SalInstanceBuilder* pBuilder,
2060  bool bTakeOwnership, bool bUserManagedScrolling)
2061  : SalInstanceContainer(pScrolledWindow, pBuilder, bTakeOwnership)
2062  , m_xScrolledWindow(pScrolledWindow)
2063  , m_bUserManagedScrolling(bUserManagedScrolling)
2064  {
2065  ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2066  m_aOrigVScrollHdl = rVertScrollBar.GetScrollHdl();
2067  rVertScrollBar.SetScrollHdl(LINK(this, SalInstanceScrolledWindow, VscrollHdl));
2068  ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2069  m_aOrigHScrollHdl = rHorzScrollBar.GetScrollHdl();
2070  rHorzScrollBar.SetScrollHdl(LINK(this, SalInstanceScrolledWindow, HscrollHdl));
2071  m_xScrolledWindow->setUserManagedScrolling(m_bUserManagedScrolling);
2072  }
2073 
2074  virtual void hadjustment_configure(int value, int lower, int upper, int step_increment,
2075  int page_increment, int page_size) override
2076  {
2077  ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2078  rHorzScrollBar.SetRangeMin(lower);
2079  rHorzScrollBar.SetRangeMax(upper);
2080  rHorzScrollBar.SetLineSize(step_increment);
2081  rHorzScrollBar.SetPageSize(page_increment);
2082  rHorzScrollBar.SetThumbPos(value);
2083  rHorzScrollBar.SetVisibleSize(page_size);
2084  }
2085 
2086  virtual int hadjustment_get_value() const override
2087  {
2088  ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2089  return rHorzScrollBar.GetThumbPos();
2090  }
2091 
2092  virtual void hadjustment_set_value(int value) override
2093  {
2094  ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2095  rHorzScrollBar.SetThumbPos(value);
2096  if (!m_bUserManagedScrolling)
2097  m_aOrigHScrollHdl.Call(&rHorzScrollBar);
2098  }
2099 
2100  virtual int hadjustment_get_upper() const override
2101  {
2102  ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2103  return rHorzScrollBar.GetRangeMax();
2104  }
2105 
2106  virtual void hadjustment_set_upper(int upper) override
2107  {
2108  ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2109  rHorzScrollBar.SetRangeMax(upper);
2110  }
2111 
2112  virtual int hadjustment_get_page_size() const override
2113  {
2114  ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2115  return rHorzScrollBar.GetVisibleSize();
2116  }
2117 
2118  virtual void hadjustment_set_page_size(int size) override
2119  {
2120  ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2121  return rHorzScrollBar.SetVisibleSize(size);
2122  }
2123 
2124  virtual void hadjustment_set_page_increment(int size) override
2125  {
2126  ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2127  return rHorzScrollBar.SetPageSize(size);
2128  }
2129 
2130  virtual void hadjustment_set_step_increment(int size) override
2131  {
2132  ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2133  return rHorzScrollBar.SetLineSize(size);
2134  }
2135 
2136  virtual void set_hpolicy(VclPolicyType eHPolicy) override
2137  {
2138  WinBits nWinBits = m_xScrolledWindow->GetStyle() & ~(WB_AUTOHSCROLL | WB_HSCROLL);
2139  if (eHPolicy == VclPolicyType::ALWAYS)
2140  nWinBits |= WB_HSCROLL;
2141  else if (eHPolicy == VclPolicyType::AUTOMATIC)
2142  nWinBits |= WB_AUTOHSCROLL;
2143  m_xScrolledWindow->SetStyle(nWinBits);
2144  m_xScrolledWindow->queue_resize();
2145  }
2146 
2147  virtual VclPolicyType get_hpolicy() const override
2148  {
2149  WinBits nWinBits = m_xScrolledWindow->GetStyle();
2150  if (nWinBits & WB_AUTOHSCROLL)
2151  return VclPolicyType::AUTOMATIC;
2152  else if (nWinBits & WB_HSCROLL)
2153  return VclPolicyType::ALWAYS;
2154  return VclPolicyType::NEVER;
2155  }
2156 
2157  virtual void vadjustment_configure(int value, int lower, int upper, int step_increment,
2158  int page_increment, int page_size) override
2159  {
2160  ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2161  rVertScrollBar.SetRangeMin(lower);
2162  rVertScrollBar.SetRangeMax(upper);
2163  rVertScrollBar.SetLineSize(step_increment);
2164  rVertScrollBar.SetPageSize(page_increment);
2165  rVertScrollBar.SetThumbPos(value);
2166  rVertScrollBar.SetVisibleSize(page_size);
2167  }
2168 
2169  virtual int vadjustment_get_value() const override
2170  {
2171  ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2172  return rVertScrollBar.GetThumbPos();
2173  }
2174 
2175  virtual void vadjustment_set_value(int value) override
2176  {
2177  ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2178  rVertScrollBar.SetThumbPos(value);
2179  if (!m_bUserManagedScrolling)
2180  m_aOrigVScrollHdl.Call(&rVertScrollBar);
2181  }
2182 
2183  virtual int vadjustment_get_upper() const override
2184  {
2185  ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2186  return rVertScrollBar.GetRangeMax();
2187  }
2188 
2189  virtual void vadjustment_set_upper(int upper) override
2190  {
2191  ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2192  rVertScrollBar.SetRangeMax(upper);
2193  }
2194 
2195  virtual int vadjustment_get_lower() const override
2196  {
2197  ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2198  return rVertScrollBar.GetRangeMin();
2199  }
2200 
2201  virtual void vadjustment_set_lower(int lower) override
2202  {
2203  ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2204  rVertScrollBar.SetRangeMin(lower);
2205  }
2206 
2207  virtual int vadjustment_get_page_size() const override
2208  {
2209  ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2210  return rVertScrollBar.GetVisibleSize();
2211  }
2212 
2213  virtual void vadjustment_set_page_size(int size) override
2214  {
2215  ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2216  return rVertScrollBar.SetVisibleSize(size);
2217  }
2218 
2219  virtual void vadjustment_set_page_increment(int size) override
2220  {
2221  ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2222  return rVertScrollBar.SetPageSize(size);
2223  }
2224 
2225  virtual void vadjustment_set_step_increment(int size) override
2226  {
2227  ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2228  return rVertScrollBar.SetLineSize(size);
2229  }
2230 
2231  virtual void set_vpolicy(VclPolicyType eVPolicy) override
2232  {
2233  WinBits nWinBits = m_xScrolledWindow->GetStyle() & ~(WB_AUTOVSCROLL | WB_VSCROLL);
2234  if (eVPolicy == VclPolicyType::ALWAYS)
2235  nWinBits |= WB_VSCROLL;
2236  else if (eVPolicy == VclPolicyType::AUTOMATIC)
2237  nWinBits |= WB_AUTOVSCROLL;
2238  m_xScrolledWindow->SetStyle(nWinBits);
2239  m_xScrolledWindow->queue_resize();
2240  }
2241 
2242  virtual VclPolicyType get_vpolicy() const override
2243  {
2244  WinBits nWinBits = m_xScrolledWindow->GetStyle();
2245  if (nWinBits & WB_AUTOVSCROLL)
2246  return VclPolicyType::AUTOMATIC;
2247  else if (nWinBits & WB_VSCROLL)
2248  return VclPolicyType::ALWAYS;
2249  return VclPolicyType::NEVER;
2250  }
2251 
2252  virtual int get_scroll_thickness() const override
2253  {
2254  return m_xScrolledWindow->getVertScrollBar().get_preferred_size().Width();
2255  }
2256 
2257  virtual void set_scroll_thickness(int nThickness) override
2258  {
2259  ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2260  ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2261  rHorzScrollBar.set_height_request(nThickness);
2262  rVertScrollBar.set_width_request(nThickness);
2263  }
2264 
2265  virtual void customize_scrollbars(const Color& rBackgroundColor, const Color& rShadowColor,
2266  const Color& rFaceColor) override
2267  {
2268  ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2269  ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2270  customize_scrollbars(rHorzScrollBar, Color(0, 0, 0), rBackgroundColor, rShadowColor,
2271  rFaceColor);
2272  customize_scrollbars(rVertScrollBar, Color(0, 0, 0), rBackgroundColor, rShadowColor,
2273  rFaceColor);
2274  }
2275 
2276  virtual ~SalInstanceScrolledWindow() override
2277  {
2278  ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2279  rVertScrollBar.SetScrollHdl(m_aOrigVScrollHdl);
2280  }
2281 };
2282 }
2283 
2284 IMPL_LINK(SalInstanceScrolledWindow, VscrollHdl, ScrollBar*, pScrollBar, void)
2285 {
2286  signal_vadjustment_changed();
2287  if (!m_bUserManagedScrolling)
2288  m_aOrigVScrollHdl.Call(pScrollBar);
2289 }
2290 
2291 IMPL_LINK_NOARG(SalInstanceScrolledWindow, HscrollHdl, ScrollBar*, void)
2292 {
2293  signal_hadjustment_changed();
2294  if (!m_bUserManagedScrolling)
2295  m_aOrigHScrollHdl.Call(&m_xScrolledWindow->getHorzScrollBar());
2296 }
2297 
2299  bool bTakeOwnership)
2300  : SalInstanceContainer(pNotebook, pBuilder, bTakeOwnership)
2301  , m_xNotebook(pNotebook)
2302 {
2303  m_xNotebook->SetActivatePageHdl(LINK(this, SalInstanceNotebook, ActivatePageHdl));
2304  m_xNotebook->SetDeactivatePageHdl(LINK(this, SalInstanceNotebook, DeactivatePageHdl));
2305 }
2306 
2308 {
2310 }
2311 
2312 OString SalInstanceNotebook::get_page_ident(int nPage) const
2313 {
2314  return m_xNotebook->GetPageName(m_xNotebook->GetPageId(nPage));
2315 }
2316 
2318 {
2320 }
2321 
2322 int SalInstanceNotebook::get_page_index(const OString& rIdent) const
2323 {
2324  sal_uInt16 nPageId = m_xNotebook->GetPageId(rIdent);
2325  sal_uInt16 nPageIndex = m_xNotebook->GetPagePos(nPageId);
2326  if (nPageIndex == TAB_PAGE_NOTFOUND)
2327  return -1;
2328  return nPageIndex;
2329 }
2330 
2331 weld::Container* SalInstanceNotebook::get_page(const OString& rIdent) const
2332 {
2333  int nPageIndex = get_page_index(rIdent);
2334  if (nPageIndex == -1)
2335  return nullptr;
2336  sal_uInt16 nPageId = m_xNotebook->GetPageId(rIdent);
2337  TabPage* pPage = m_xNotebook->GetTabPage(nPageId);
2338  vcl::Window* pChild = pPage->GetChild(0);
2339  if (m_aPages.size() < nPageIndex + 1U)
2340  m_aPages.resize(nPageIndex + 1U);
2341  if (!m_aPages[nPageIndex])
2342  m_aPages[nPageIndex] = std::make_shared<SalInstanceContainer>(pChild, m_pBuilder, false);
2343  return m_aPages[nPageIndex].get();
2344 }
2345 
2347 {
2349 }
2350 
2351 void SalInstanceNotebook::set_current_page(const OString& rIdent)
2352 {
2354 }
2355 
2356 void SalInstanceNotebook::remove_page(const OString& rIdent)
2357 {
2358  sal_uInt16 nPageId = m_xNotebook->GetPageId(rIdent);
2359  sal_uInt16 nPageIndex = m_xNotebook->GetPagePos(nPageId);
2360  if (nPageIndex == TAB_PAGE_NOTFOUND)
2361  return;
2362 
2363  m_xNotebook->RemovePage(nPageId);
2364  if (nPageIndex < m_aPages.size())
2365  m_aPages.erase(m_aPages.begin() + nPageIndex);
2366 
2367  auto iter = m_aAddedPages.find(rIdent);
2368  if (iter != m_aAddedPages.end())
2369  {
2370  iter->second.second.disposeAndClear();
2371  iter->second.first.disposeAndClear();
2372  m_aAddedPages.erase(iter);
2373  }
2374 }
2375 
2376 void SalInstanceNotebook::insert_page(const OString& rIdent, const OUString& rLabel, int nPos)
2377 {
2378  sal_uInt16 nPageCount = m_xNotebook->GetPageCount();
2379  sal_uInt16 nLastPageId = nPageCount ? m_xNotebook->GetPageId(nPageCount - 1) : 0;
2380  sal_uInt16 nNewPageId = nLastPageId + 1;
2381  while (m_xNotebook->GetPagePos(nNewPageId) != TAB_PAGE_NOTFOUND)
2382  ++nNewPageId;
2383  m_xNotebook->InsertPage(nNewPageId, rLabel, nPos == -1 ? TAB_APPEND : nPos);
2385  VclPtrInstance<VclGrid> xGrid(xPage);
2386  xPage->Show();
2387  xGrid->set_hexpand(true);
2388  xGrid->set_vexpand(true);
2389  xGrid->Show();
2390  m_xNotebook->SetTabPage(nNewPageId, xPage);
2391  m_xNotebook->SetPageName(nNewPageId, rIdent);
2392  m_aAddedPages.try_emplace(rIdent, xPage, xGrid);
2393 
2394  if (nPos != -1)
2395  {
2396  unsigned int nPageIndex = static_cast<unsigned int>(nPos);
2397  if (nPageIndex < m_aPages.size())
2398  m_aPages.insert(m_aPages.begin() + nPageIndex, nullptr);
2399  }
2400 }
2401 
2403 
2404 OUString SalInstanceNotebook::get_tab_label_text(const OString& rIdent) const
2405 {
2406  return m_xNotebook->GetPageText(m_xNotebook->GetPageId(rIdent));
2407 }
2408 
2409 void SalInstanceNotebook::set_tab_label_text(const OString& rIdent, const OUString& rText)
2410 {
2411  return m_xNotebook->SetPageText(m_xNotebook->GetPageId(rIdent), rText);
2412 }
2413 
2415 {
2416  for (auto& rItem : m_aAddedPages)
2417  {
2418  rItem.second.second.disposeAndClear();
2419  rItem.second.first.disposeAndClear();
2420  }
2423 }
2424 
2426 {
2427  return !m_aLeavePageHdl.IsSet() || m_aLeavePageHdl.Call(get_current_page_ident());
2428 }
2429 
2431 {
2432  m_aEnterPageHdl.Call(get_current_page_ident());
2433 }
2434 
2435 namespace
2436 {
2437 class SalInstanceVerticalNotebook : public SalInstanceContainer, public virtual weld::Notebook
2438 {
2439 private:
2440  VclPtr<VerticalTabControl> m_xNotebook;
2441  mutable std::vector<std::unique_ptr<SalInstanceContainer>> m_aPages;
2442 
2443  DECL_LINK(DeactivatePageHdl, VerticalTabControl*, bool);
2444  DECL_LINK(ActivatePageHdl, VerticalTabControl*, void);
2445 
2446 public:
2447  SalInstanceVerticalNotebook(VerticalTabControl* pNotebook, SalInstanceBuilder* pBuilder,
2448  bool bTakeOwnership)
2449  : SalInstanceContainer(pNotebook, pBuilder, bTakeOwnership)
2450  , m_xNotebook(pNotebook)
2451  {
2452  m_xNotebook->SetActivatePageHdl(LINK(this, SalInstanceVerticalNotebook, ActivatePageHdl));
2453  m_xNotebook->SetDeactivatePageHdl(
2454  LINK(this, SalInstanceVerticalNotebook, DeactivatePageHdl));
2455  }
2456 
2457  virtual int get_current_page() const override
2458  {
2459  return m_xNotebook->GetPagePos(m_xNotebook->GetCurPageId());
2460  }
2461 
2462  virtual OString get_page_ident(int nPage) const override
2463  {
2464  return m_xNotebook->GetPageId(nPage);
2465  }
2466 
2467  virtual OString get_current_page_ident() const override { return m_xNotebook->GetCurPageId(); }
2468 
2469  virtual int get_page_index(const OString& rIdent) const override
2470  {
2471  sal_uInt16 nPageIndex = m_xNotebook->GetPagePos(rIdent);
2472  if (nPageIndex == TAB_PAGE_NOTFOUND)
2473  return -1;
2474  return nPageIndex;
2475  }
2476 
2477  virtual weld::Container* get_page(const OString& rIdent) const override
2478  {
2479  int nPageIndex = get_page_index(rIdent);
2480  if (nPageIndex == -1)
2481  return nullptr;
2482  auto pChild = m_xNotebook->GetPage(rIdent);
2483  if (m_aPages.size() < nPageIndex + 1U)
2484  m_aPages.resize(nPageIndex + 1U);
2485  if (!m_aPages[nPageIndex])
2486  m_aPages[nPageIndex].reset(new SalInstanceContainer(pChild, m_pBuilder, false));
2487  return m_aPages[nPageIndex].get();
2488  }
2489 
2490  virtual void set_current_page(int nPage) override
2491  {
2492  m_xNotebook->SetCurPageId(m_xNotebook->GetPageId(nPage));
2493  }
2494 
2495  virtual void set_current_page(const OString& rIdent) override
2496  {
2497  m_xNotebook->SetCurPageId(rIdent);
2498  }
2499 
2500  virtual void remove_page(const OString& rIdent) override
2501  {
2502  sal_uInt16 nPageIndex = m_xNotebook->GetPagePos(rIdent);
2503  if (nPageIndex == TAB_PAGE_NOTFOUND)
2504  return;
2505  m_xNotebook->RemovePage(rIdent);
2506  if (nPageIndex < m_aPages.size())
2507  m_aPages.erase(m_aPages.begin() + nPageIndex);
2508  }
2509 
2510  virtual void insert_page(const OString& rIdent, const OUString& rLabel, int nPos) override
2511  {
2512  VclPtrInstance<VclGrid> xGrid(m_xNotebook->GetPageParent());
2513  xGrid->set_hexpand(true);
2514  xGrid->set_vexpand(true);
2515  m_xNotebook->InsertPage(rIdent, rLabel, Image(), "", xGrid, nPos);
2516 
2517  if (nPos != -1)
2518  {
2519  unsigned int nPageIndex = static_cast<unsigned int>(nPos);
2520  if (nPageIndex < m_aPages.size())
2521  m_aPages.insert(m_aPages.begin() + nPageIndex, nullptr);
2522  }
2523  }
2524 
2525  virtual int get_n_pages() const override { return m_xNotebook->GetPageCount(); }
2526 
2527  virtual void set_tab_label_text(const OString& rIdent, const OUString& rText) override
2528  {
2529  return m_xNotebook->SetPageText(rIdent, rText);
2530  }
2531 
2532  virtual OUString get_tab_label_text(const OString& rIdent) const override
2533  {
2534  return m_xNotebook->GetPageText(rIdent);
2535  }
2536 
2537  virtual ~SalInstanceVerticalNotebook() override
2538  {
2541  }
2542 };
2543 }
2544 
2545 IMPL_LINK_NOARG(SalInstanceVerticalNotebook, DeactivatePageHdl, VerticalTabControl*, bool)
2546 {
2547  return !m_aLeavePageHdl.IsSet() || m_aLeavePageHdl.Call(get_current_page_ident());
2548 }
2549 
2550 IMPL_LINK_NOARG(SalInstanceVerticalNotebook, ActivatePageHdl, VerticalTabControl*, void)
2551 {
2552  m_aEnterPageHdl.Call(get_current_page_ident());
2553 }
2554 
2556  bool bTakeOwnership)
2557  : SalInstanceContainer(pButton, pBuilder, bTakeOwnership)
2558  , m_xButton(pButton)
2559  , m_aOldClickHdl(pButton->GetClickHdl())
2560 {
2561  m_xButton->SetClickHdl(LINK(this, SalInstanceButton, ClickHdl));
2562 }
2563 
2564 void SalInstanceButton::set_label(const OUString& rText) { m_xButton->SetText(rText); }
2565 
2567 {
2568  m_xButton->SetImageAlign(ImageAlign::Left);
2569  if (pDevice)
2570  m_xButton->SetModeImage(createImage(*pDevice));
2571  else
2573 }
2574 
2575 void SalInstanceButton::set_image(const css::uno::Reference<css::graphic::XGraphic>& rImage)
2576 {
2577  m_xButton->SetImageAlign(ImageAlign::Left);
2578  m_xButton->SetModeImage(Image(rImage));
2579 }
2580 
2581 void SalInstanceButton::set_from_icon_name(const OUString& rIconName)
2582 {
2584 }
2585 
2587 {
2588  WinBits nBits = m_xButton->GetStyle();
2589  nBits &= ~WB_WORDBREAK;
2590  if (wrap)
2591  nBits |= WB_WORDBREAK;
2592  m_xButton->SetStyle(nBits);
2594 }
2595 
2597 {
2598  m_xButton->SetControlFont(rFont);
2599  m_xButton->Invalidate();
2600 }
2601 
2603 {
2604  if (pDevice)
2605  m_xButton->SetCustomButtonImage(createImage(*pDevice));
2606  else
2608  m_xButton->Invalidate();
2609 }
2610 
2611 OUString SalInstanceButton::get_label() const { return m_xButton->GetText(); }
2612 
2614 
2615 IMPL_LINK(SalInstanceButton, ClickHdl, ::Button*, pButton, void)
2616 {
2617  //if there's no handler set, disengage our intercept and
2618  //run the click again to get default behaviour for cancel/ok
2619  //etc buttons.
2620  if (!m_aClickHdl.IsSet())
2621  {
2622  pButton->SetClickHdl(m_aOldClickHdl);
2623  pButton->Click();
2624  pButton->SetClickHdl(LINK(this, SalInstanceButton, ClickHdl));
2625  return;
2626  }
2627  signal_clicked();
2628 }
2629 
2631 {
2632  PushButton* pButton = dynamic_cast<PushButton*>(m_xDialog->get_widget_for_response(nResponse));
2633  return pButton ? new SalInstanceButton(pButton, nullptr, false) : nullptr;
2634 }
2635 
2636 weld::Button* SalInstanceAssistant::weld_widget_for_response(int nResponse)
2637 {
2638  PushButton* pButton = nullptr;
2639  if (nResponse == RET_YES)
2640  pButton = m_xWizard->m_pNextPage;
2641  else if (nResponse == RET_NO)
2642  pButton = m_xWizard->m_pPrevPage;
2643  else if (nResponse == RET_OK)
2644  pButton = m_xWizard->m_pFinish;
2645  else if (nResponse == RET_CANCEL)
2646  pButton = m_xWizard->m_pCancel;
2647  else if (nResponse == RET_HELP)
2648  pButton = m_xWizard->m_pHelp;
2649  if (pButton)
2650  return new SalInstanceButton(pButton, nullptr, false);
2651  return nullptr;
2652 }
2653 
2654 namespace
2655 {
2656 class SalInstanceMenuButton : public SalInstanceButton, public virtual weld::MenuButton
2657 {
2658 private:
2659  VclPtr<::MenuButton> m_xMenuButton;
2660  sal_uInt16 m_nLastId;
2661 
2662  DECL_LINK(MenuSelectHdl, ::MenuButton*, void);
2663  DECL_LINK(ActivateHdl, ::MenuButton*, void);
2664 
2665 public:
2666  SalInstanceMenuButton(::MenuButton* pButton, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2667  : SalInstanceButton(pButton, pBuilder, bTakeOwnership)
2668  , m_xMenuButton(pButton)
2669  , m_nLastId(0)
2670  {
2671  m_xMenuButton->SetActivateHdl(LINK(this, SalInstanceMenuButton, ActivateHdl));
2672  m_xMenuButton->SetSelectHdl(LINK(this, SalInstanceMenuButton, MenuSelectHdl));
2673  if (PopupMenu* pMenu = m_xMenuButton->GetPopupMenu())
2674  {
2676  const auto nCount = pMenu->GetItemCount();
2677  m_nLastId = nCount ? pMenu->GetItemId(nCount - 1) : 0;
2678  }
2679  }
2680 
2681  virtual void set_active(bool active) override
2682  {
2683  if (active == get_active())
2684  return;
2685  if (active)
2686  m_xMenuButton->ExecuteMenu();
2687  else
2688  m_xMenuButton->CancelMenu();
2689  }
2690 
2691  virtual bool get_active() const override { return m_xMenuButton->InPopupMode(); }
2692 
2693  virtual void set_inconsistent(bool /*inconsistent*/) override
2694  {
2695  //not available
2696  }
2697 
2698  virtual bool get_inconsistent() const override { return false; }
2699 
2700  virtual void insert_item(int pos, const OUString& rId, const OUString& rStr,
2701  const OUString* pIconName, VirtualDevice* pImageSurface,
2702  TriState eCheckRadioFalse) override
2703  {
2704  m_nLastId = insert_to_menu(m_nLastId, m_xMenuButton->GetPopupMenu(), pos, rId, rStr,
2705  pIconName, pImageSurface, nullptr, eCheckRadioFalse);
2706  }
2707 
2708  virtual void insert_separator(int pos, const OUString& rId) override
2709  {
2710  auto nInsertPos = pos == -1 ? MENU_APPEND : pos;
2711  m_xMenuButton->GetPopupMenu()->InsertSeparator(rId.toUtf8(), nInsertPos);
2712  }
2713 
2714  virtual void set_item_sensitive(const OString& rIdent, bool bSensitive) override
2715  {
2716  PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2717  pMenu->EnableItem(rIdent, bSensitive);
2718  }
2719 
2720  virtual void remove_item(const OString& rId) override
2721  {
2722  PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2723  pMenu->RemoveItem(pMenu->GetItemPos(pMenu->GetItemId(rId)));
2724  }
2725 
2726  virtual void clear() override
2727  {
2728  PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2729  pMenu->Clear();
2730  }
2731 
2732  virtual void set_item_active(const OString& rIdent, bool bActive) override
2733  {
2734  PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2735  pMenu->CheckItem(rIdent, bActive);
2736  }
2737 
2738  virtual void set_item_label(const OString& rIdent, const OUString& rText) override
2739  {
2740  PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2741  pMenu->SetItemText(pMenu->GetItemId(rIdent), rText);
2742  }
2743 
2744  virtual OUString get_item_label(const OString& rIdent) const override
2745  {
2746  PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2747  return pMenu->GetItemText(pMenu->GetItemId(rIdent));
2748  }
2749 
2750  virtual void set_item_visible(const OString& rIdent, bool bShow) override
2751  {
2752  PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2753  pMenu->ShowItem(pMenu->GetItemId(rIdent), bShow);
2754  }
2755 
2756  virtual void set_item_help_id(const OString& rIdent, const OString& rHelpId) override
2757  {
2758  PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2759  pMenu->SetHelpId(pMenu->GetItemId(rIdent), rHelpId);
2760  }
2761 
2762  virtual OString get_item_help_id(const OString& rIdent) const override
2763  {
2764  PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2765  return pMenu->GetHelpId(pMenu->GetItemId(rIdent));
2766  }
2767 
2768  virtual void set_popover(weld::Widget* pPopover) override
2769  {
2770  SalInstanceWidget* pPopoverWidget = dynamic_cast<SalInstanceWidget*>(pPopover);
2771  m_xMenuButton->SetPopover(pPopoverWidget ? pPopoverWidget->getWidget() : nullptr);
2772  }
2773 
2774  virtual ~SalInstanceMenuButton() override
2775  {
2776  m_xMenuButton->SetSelectHdl(Link<::MenuButton*, void>());
2777  m_xMenuButton->SetActivateHdl(Link<::MenuButton*, void>());
2778  }
2779 };
2780 }
2781 
2782 IMPL_LINK_NOARG(SalInstanceMenuButton, MenuSelectHdl, ::MenuButton*, void)
2783 {
2784  signal_selected(m_xMenuButton->GetCurItemIdent());
2785 }
2786 
2787 IMPL_LINK_NOARG(SalInstanceMenuButton, ActivateHdl, ::MenuButton*, void)
2788 {
2789  if (notify_events_disabled())
2790  return;
2791  signal_toggled();
2792 }
2793 
2794 namespace
2795 {
2796 class SalInstanceMenuToggleButton : public SalInstanceMenuButton,
2797  public virtual weld::MenuToggleButton
2798 {
2799 private:
2800  VclPtr<::MenuToggleButton> m_xMenuToggleButton;
2801 
2802 public:
2803  SalInstanceMenuToggleButton(::MenuToggleButton* pButton, SalInstanceBuilder* pBuilder,
2804  bool bTakeOwnership)
2805  : SalInstanceMenuButton(pButton, pBuilder, bTakeOwnership)
2806  , m_xMenuToggleButton(pButton)
2807  {
2808  m_xMenuToggleButton->SetDelayMenu(true);
2810  }
2811 
2812  virtual void set_active(bool active) override
2813  {
2814  disable_notify_events();
2815  m_xMenuToggleButton->SetActive(active);
2816  enable_notify_events();
2817  }
2818 
2819  virtual bool get_active() const override { return m_xMenuToggleButton->GetActive(); }
2820 };
2821 }
2822 
2823 namespace
2824 {
2825 class SalInstanceLinkButton : public SalInstanceContainer, public virtual weld::LinkButton
2826 {
2827 private:
2828  VclPtr<FixedHyperlink> m_xButton;
2829  Link<FixedHyperlink&, void> m_aOrigClickHdl;
2830 
2831  DECL_LINK(ClickHdl, FixedHyperlink&, void);
2832 
2833 public:
2834  SalInstanceLinkButton(FixedHyperlink* pButton, SalInstanceBuilder* pBuilder,
2835  bool bTakeOwnership)
2836  : SalInstanceContainer(pButton, pBuilder, bTakeOwnership)
2837  , m_xButton(pButton)
2838  {
2839  m_aOrigClickHdl = m_xButton->GetClickHdl();
2840  m_xButton->SetClickHdl(LINK(this, SalInstanceLinkButton, ClickHdl));
2841  }
2842 
2843  virtual void set_label(const OUString& rText) override { m_xButton->SetText(rText); }
2844 
2845  virtual OUString get_label() const override { return m_xButton->GetText(); }
2846 
2847  virtual void set_uri(const OUString& rUri) override { m_xButton->SetURL(rUri); }
2848 
2849  virtual OUString get_uri() const override { return m_xButton->GetURL(); }
2850 
2851  virtual ~SalInstanceLinkButton() override { m_xButton->SetClickHdl(m_aOrigClickHdl); }
2852 };
2853 }
2854 
2855 IMPL_LINK(SalInstanceLinkButton, ClickHdl, FixedHyperlink&, rButton, void)
2856 {
2857  bool bConsumed = signal_activate_link();
2858  if (!bConsumed)
2859  m_aOrigClickHdl.Call(rButton);
2860 }
2861 
2863  bool bTakeOwnership)
2864  : SalInstanceButton(pButton, pBuilder, bTakeOwnership)
2865  , m_xRadioButton(pButton)
2866 {
2868 }
2869 
2871 {
2873  m_xRadioButton->Check(active);
2875 }
2876 
2878 
2880 {
2881  m_xRadioButton->SetImageAlign(ImageAlign::Center);
2882  if (pDevice)
2883  m_xRadioButton->SetModeImage(createImage(*pDevice));
2884  else
2886 }
2887 
2888 void SalInstanceRadioButton::set_image(const css::uno::Reference<css::graphic::XGraphic>& rImage)
2889 {
2890  m_xRadioButton->SetImageAlign(ImageAlign::Center);
2891  m_xRadioButton->SetModeImage(Image(rImage));
2892 }
2893 
2894 void SalInstanceRadioButton::set_from_icon_name(const OUString& rIconName)
2895 {
2897 }
2898 
2899 void SalInstanceRadioButton::set_inconsistent(bool /*inconsistent*/)
2900 {
2901  //not available
2902 }
2903 
2904 bool SalInstanceRadioButton::get_inconsistent() const { return false; }
2905 
2907 {
2909 }
2910 
2912 {
2913  if (notify_events_disabled())
2914  return;
2915  signal_toggled();
2916 }
2917 
2918 namespace
2919 {
2920 class SalInstanceToggleButton : public SalInstanceButton, public virtual weld::ToggleButton
2921 {
2922 private:
2923  VclPtr<PushButton> m_xToggleButton;
2924 
2925  DECL_LINK(ToggleListener, VclWindowEvent&, void);
2926 
2927 public:
2928  SalInstanceToggleButton(PushButton* pButton, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2929  : SalInstanceButton(pButton, pBuilder, bTakeOwnership)
2930  , m_xToggleButton(pButton)
2931  {
2932  }
2933 
2934  virtual void connect_toggled(const Link<ToggleButton&, void>& rLink) override
2935  {
2936  assert(!m_aToggleHdl.IsSet());
2937  m_xToggleButton->AddEventListener(LINK(this, SalInstanceToggleButton, ToggleListener));
2939  }
2940 
2941  virtual void set_active(bool active) override
2942  {
2944  m_xToggleButton->Check(active);
2946  }
2947 
2948  virtual bool get_active() const override { return m_xToggleButton->IsChecked(); }
2949 
2950  virtual void set_inconsistent(bool inconsistent) override
2951  {
2953  m_xToggleButton->SetState(inconsistent ? TRISTATE_INDET : TRISTATE_FALSE);
2955  }
2956 
2957  virtual bool get_inconsistent() const override
2958  {
2959  return m_xToggleButton->GetState() == TRISTATE_INDET;
2960  }
2961 
2962  virtual ~SalInstanceToggleButton() override
2963  {
2964  if (m_aToggleHdl.IsSet())
2965  m_xToggleButton->RemoveEventListener(
2966  LINK(this, SalInstanceToggleButton, ToggleListener));
2967  }
2968 };
2969 }
2970 
2971 IMPL_LINK(SalInstanceToggleButton, ToggleListener, VclWindowEvent&, rEvent, void)
2972 {
2973  if (notify_events_disabled())
2974  return;
2975  if (rEvent.GetId() == VclEventId::PushbuttonToggle)
2976  signal_toggled();
2977 }
2978 
2980  bool bTakeOwnership)
2981  : SalInstanceButton(pButton, pBuilder, bTakeOwnership)
2982  , m_xCheckButton(pButton)
2983 {
2985 }
2986 
2988 {
2991  m_xCheckButton->Check(active);
2993 }
2994 
2996 
2998 {
3003 }
3004 
3006 {
3007  return m_xCheckButton->GetState() == TRISTATE_INDET;
3008 }
3009 
3011 {
3013 }
3014 
3016 {
3017  if (notify_events_disabled())
3018  return;
3019  m_xCheckButton->EnableTriState(false);
3020  signal_toggled();
3021 }
3022 
3023 namespace
3024 {
3025 class SalInstanceScale : public SalInstanceWidget, public virtual weld::Scale
3026 {
3027 private:
3028  VclPtr<Slider> m_xScale;
3029 
3030  DECL_LINK(SlideHdl, Slider*, void);
3031 
3032 public:
3033  SalInstanceScale(Slider* pScale, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3034  : SalInstanceWidget(pScale, pBuilder, bTakeOwnership)
3035  , m_xScale(pScale)
3036  {
3037  m_xScale->SetSlideHdl(LINK(this, SalInstanceScale, SlideHdl));
3038  }
3039 
3040  virtual void set_value(int value) override { m_xScale->SetThumbPos(value); }
3041 
3042  virtual void set_range(int min, int max) override
3043  {
3044  m_xScale->SetRangeMin(min);
3045  m_xScale->SetRangeMax(max);
3046  }
3047 
3048  virtual int get_value() const override { return m_xScale->GetThumbPos(); }
3049 
3050  virtual void set_increments(int step, int page) override
3051  {
3052  m_xScale->SetLineSize(step);
3053  m_xScale->SetPageSize(page);
3054  }
3055 
3056  virtual void get_increments(int& step, int& page) const override
3057  {
3058  step = m_xScale->GetLineSize();
3059  page = m_xScale->GetPageSize();
3060  }
3061 
3062  virtual ~SalInstanceScale() override { m_xScale->SetSlideHdl(Link<Slider*, void>()); }
3063 };
3064 }
3065 
3066 IMPL_LINK_NOARG(SalInstanceScale, SlideHdl, Slider*, void) { signal_value_changed(); }
3067 
3068 namespace
3069 {
3070 class SalInstanceSpinner : public SalInstanceWidget, public virtual weld::Spinner
3071 {
3072 private:
3073  VclPtr<Throbber> m_xThrobber;
3074 
3075 public:
3076  SalInstanceSpinner(Throbber* pThrobber, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3077  : SalInstanceWidget(pThrobber, pBuilder, bTakeOwnership)
3078  , m_xThrobber(pThrobber)
3079  {
3080  }
3081 
3082  virtual void start() override { m_xThrobber->start(); }
3083 
3084  virtual void stop() override { m_xThrobber->stop(); }
3085 };
3086 
3087 class SalInstanceProgressBar : public SalInstanceWidget, public virtual weld::ProgressBar
3088 {
3089 private:
3090  VclPtr<::ProgressBar> m_xProgressBar;
3091 
3092 public:
3093  SalInstanceProgressBar(::ProgressBar* pProgressBar, SalInstanceBuilder* pBuilder,
3094  bool bTakeOwnership)
3095  : SalInstanceWidget(pProgressBar, pBuilder, bTakeOwnership)
3096  , m_xProgressBar(pProgressBar)
3097  {
3098  }
3099 
3100  virtual void set_percentage(int value) override { m_xProgressBar->SetValue(value); }
3101 
3102  virtual OUString get_text() const override { return m_xProgressBar->GetText(); }
3103 
3104  virtual void set_text(const OUString& rText) override { m_xProgressBar->SetText(rText); }
3105 };
3106 
3107 class SalInstanceImage : public SalInstanceWidget, public virtual weld::Image
3108 {
3109 private:
3110  VclPtr<FixedImage> m_xImage;
3111 
3112 public:
3113  SalInstanceImage(FixedImage* pImage, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3114  : SalInstanceWidget(pImage, pBuilder, bTakeOwnership)
3115  , m_xImage(pImage)
3116  {
3117  }
3118 
3119  virtual void set_from_icon_name(const OUString& rIconName) override
3120  {
3121  m_xImage->SetImage(::Image(StockImage::Yes, rIconName));
3122  }
3123 
3124  virtual void set_image(VirtualDevice* pDevice) override
3125  {
3126  if (pDevice)
3127  m_xImage->SetImage(createImage(*pDevice));
3128  else
3129  m_xImage->SetImage(::Image());
3130  }
3131 
3132  virtual void set_image(const css::uno::Reference<css::graphic::XGraphic>& rImage) override
3133  {
3134  m_xImage->SetImage(::Image(rImage));
3135  }
3136 };
3137 
3138 class SalInstanceCalendar : public SalInstanceWidget, public virtual weld::Calendar
3139 {
3140 private:
3141  VclPtr<::Calendar> m_xCalendar;
3142 
3143  DECL_LINK(SelectHdl, ::Calendar*, void);
3144  DECL_LINK(ActivateHdl, ::Calendar*, void);
3145 
3146 public:
3147  SalInstanceCalendar(::Calendar* pCalendar, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3148  : SalInstanceWidget(pCalendar, pBuilder, bTakeOwnership)
3149  , m_xCalendar(pCalendar)
3150  {
3151  m_xCalendar->SetSelectHdl(LINK(this, SalInstanceCalendar, SelectHdl));
3152  m_xCalendar->SetActivateHdl(LINK(this, SalInstanceCalendar, ActivateHdl));
3153  }
3154 
3155  virtual void set_date(const Date& rDate) override { m_xCalendar->SetCurDate(rDate); }
3156 
3157  virtual Date get_date() const override { return m_xCalendar->GetFirstSelectedDate(); }
3158 
3159  virtual ~SalInstanceCalendar() override
3160  {
3161  m_xCalendar->SetSelectHdl(Link<::Calendar*, void>());
3162  m_xCalendar->SetActivateHdl(Link<::Calendar*, void>());
3163  }
3164 };
3165 }
3166 
3167 IMPL_LINK_NOARG(SalInstanceCalendar, SelectHdl, ::Calendar*, void)
3168 {
3169  if (notify_events_disabled())
3170  return;
3171  signal_selected();
3172 }
3173 
3174 IMPL_LINK_NOARG(SalInstanceCalendar, ActivateHdl, ::Calendar*, void)
3175 {
3176  if (notify_events_disabled())
3177  return;
3178  signal_activated();
3179 }
3180 
3182  : TextFilter(OUString())
3183  , m_rInsertTextHdl(rInsertTextHdl)
3184 {
3185 }
3186 
3187 OUString WeldTextFilter::filter(const OUString& rText)
3188 {
3189  if (!m_rInsertTextHdl.IsSet())
3190  return rText;
3191  OUString sText(rText);
3192  const bool bContinue = m_rInsertTextHdl.Call(sText);
3193  if (!bContinue)
3194  return OUString();
3195  return sText;
3196 }
3197 
3198 SalInstanceEntry::SalInstanceEntry(Edit* pEntry, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3199  : SalInstanceWidget(pEntry, pBuilder, bTakeOwnership)
3200  , m_xEntry(pEntry)
3201  , m_aTextFilter(m_aInsertTextHdl)
3202 {
3203  m_xEntry->SetModifyHdl(LINK(this, SalInstanceEntry, ChangeHdl));
3204  m_xEntry->SetActivateHdl(LINK(this, SalInstanceEntry, ActivateHdl));
3206 }
3207 
3208 void SalInstanceEntry::set_text(const OUString& rText)
3209 {
3211  m_xEntry->SetText(rText);
3213 }
3214 
3215 OUString SalInstanceEntry::get_text() const { return m_xEntry->GetText(); }
3216 
3218 
3220 
3222 
3223 void SalInstanceEntry::select_region(int nStartPos, int nEndPos)
3224 {
3226  tools::Long nStart = nStartPos < 0 ? SELECTION_MAX : nStartPos;
3227  tools::Long nEnd = nEndPos < 0 ? SELECTION_MAX : nEndPos;
3228  m_xEntry->SetSelection(Selection(nStart, nEnd));
3230 }
3231 
3232 bool SalInstanceEntry::get_selection_bounds(int& rStartPos, int& rEndPos)
3233 {
3234  const Selection& rSelection = m_xEntry->GetSelection();
3235  rStartPos = rSelection.Min();
3236  rEndPos = rSelection.Max();
3237  return rSelection.Len();
3238 }
3239 
3240 void SalInstanceEntry::replace_selection(const OUString& rText)
3241 {
3242  m_xEntry->ReplaceSelected(rText);
3243 }
3244 
3246 {
3248  if (nCursorPos < 0)
3250  else
3251  m_xEntry->SetSelection(Selection(nCursorPos, nCursorPos));
3253 }
3254 
3256 
3257 void SalInstanceEntry::set_editable(bool bEditable) { m_xEntry->SetReadOnly(!bEditable); }
3258 
3260 
3262 
3264 
3266 {
3267  switch (eType)
3268  {
3273  break;
3275  // tdf#114603: enable setting the background to a different color;
3276  // relevant for GTK; see also #i75179#
3280  break;
3282  // tdf#114603: enable setting the background to a different color;
3283  // relevant for GTK; see also #i75179#
3286  m_xEntry->SetControlBackground(0xff6563);
3287  break;
3288  }
3289 }
3290 
3292 {
3293  m_xEntry->SetPointFont(*m_xEntry, rFont);
3294  m_xEntry->Invalidate();
3295 }
3296 
3298 {
3299  if (rColor == COL_AUTO)
3301  else
3302  m_xEntry->SetControlForeground(rColor);
3303 }
3304 
3306 {
3307  assert(!m_aCursorPositionHdl.IsSet());
3308  m_xEntry->AddEventListener(LINK(this, SalInstanceEntry, CursorListener));
3310 }
3311 
3312 void SalInstanceEntry::set_placeholder_text(const OUString& rText)
3313 {
3314  m_xEntry->SetPlaceholderText(rText);
3315 }
3316 
3318 
3320 
3322 
3324 
3326 
3327 namespace
3328 {
3329 void set_alignment(Edit& rEntry, TxtAlign eXAlign)
3330 {
3331  WinBits nAlign(0);
3332  switch (eXAlign)
3333  {
3334  case TxtAlign::Left:
3335  nAlign = WB_LEFT;
3336  break;
3337  case TxtAlign::Center:
3338  nAlign = WB_CENTER;
3339  break;
3340  case TxtAlign::Right:
3341  nAlign = WB_RIGHT;
3342  break;
3343  }
3344  WinBits nBits = rEntry.GetStyle();
3345  nBits &= ~(WB_LEFT | WB_CENTER | WB_RIGHT);
3346  rEntry.SetStyle(nBits | nAlign);
3347 }
3348 }
3349 
3351 
3353 {
3354  if (m_aCursorPositionHdl.IsSet())
3355  m_xEntry->RemoveEventListener(LINK(this, SalInstanceEntry, CursorListener));
3356  m_xEntry->SetTextFilter(nullptr);
3359 }
3360 
3361 IMPL_LINK_NOARG(SalInstanceEntry, ChangeHdl, Edit&, void) { signal_changed(); }
3362 
3363 IMPL_LINK(SalInstanceEntry, CursorListener, VclWindowEvent&, rEvent, void)
3364 {
3365  if (notify_events_disabled())
3366  return;
3367  if (rEvent.GetId() == VclEventId::EditSelectionChanged
3368  || rEvent.GetId() == VclEventId::EditCaretChanged)
3369  signal_cursor_position();
3370 }
3371 
3372 IMPL_LINK_NOARG(SalInstanceEntry, ActivateHdl, Edit&, bool) { return m_aActivateHdl.Call(*this); }
3373 
3375 
3377 
3378 namespace
3379 {
3380 // tdf#131581 if the TreeView is hidden then there are possibly additional
3381 // optimizations available
3382 class UpdateGuardIfHidden
3383 {
3384 private:
3385  SvTabListBox& m_rTreeView;
3386  bool m_bOrigUpdate;
3387  bool m_bOrigEnableInvalidate;
3388 
3389 public:
3390  UpdateGuardIfHidden(SvTabListBox& rTreeView)
3391  : m_rTreeView(rTreeView)
3392  // tdf#136962 only do SetUpdateMode(false) optimization if the widget is currently hidden
3393  , m_bOrigUpdate(!m_rTreeView.IsVisible() && m_rTreeView.IsUpdateMode())
3394  // tdf#137432 only do EnableInvalidate(false) optimization if the widget is currently hidden
3395  , m_bOrigEnableInvalidate(!m_rTreeView.IsVisible()
3396  && m_rTreeView.GetModel()->IsEnableInvalidate())
3397  {
3398  if (m_bOrigUpdate)
3399  m_rTreeView.SetUpdateMode(false);
3400  if (m_bOrigEnableInvalidate)
3401  m_rTreeView.GetModel()->EnableInvalidate(false);
3402  }
3403 
3404  ~UpdateGuardIfHidden()
3405  {
3406  if (m_bOrigEnableInvalidate)
3407  m_rTreeView.GetModel()->EnableInvalidate(true);
3408  if (m_bOrigUpdate)
3409  m_rTreeView.SetUpdateMode(true);
3410  }
3411 };
3412 }
3413 
3414 // Each row has a cell for the expander image, (and an optional cell for a
3415 // checkbutton if enable_toggle_buttons has been called) which precede
3416 // index 0
3418 {
3420  ++col; // skip checkbutton column
3421  ++col; //skip expander column
3422  return col;
3423 }
3424 
3426 {
3428  --col; // skip checkbutton column
3429  --col; //skip expander column
3430  return col;
3431 }
3432 
3434 {
3435  return m_xTreeView->GetEntryText(pEntry).trim() == "<dummy>";
3436 }
3437 
3439 {
3440  if (pEntry->HasChildren())
3441  {
3442  auto pChild = m_xTreeView->FirstChild(pEntry);
3443  assert(pChild);
3444  if (IsDummyEntry(pChild))
3445  return pChild;
3446  }
3447  return nullptr;
3448 }
3449 
3451 {
3452  if (rColor == COL_AUTO)
3453  pEntry->SetTextColor(std::optional<Color>());
3454  else
3455  pEntry->SetTextColor(rColor);
3456 }
3457 
3458 void SalInstanceTreeView::AddStringItem(SvTreeListEntry* pEntry, const OUString& rStr, int nCol)
3459 {
3460  auto xCell = std::make_unique<SvLBoxString>(rStr);
3461  if (m_aCustomRenders.count(nCol))
3462  xCell->SetCustomRender();
3463  pEntry->AddItem(std::move(xCell));
3464 }
3465 
3466 void SalInstanceTreeView::do_insert(const weld::TreeIter* pParent, int pos, const OUString* pStr,
3467  const OUString* pId, const OUString* pIconName,
3468  const VirtualDevice* pImageSurface, bool bChildrenOnDemand,
3469  weld::TreeIter* pRet, bool bIsSeparator)
3470 {
3472  const SalInstanceTreeIter* pVclIter = static_cast<const SalInstanceTreeIter*>(pParent);
3473  SvTreeListEntry* iter = pVclIter ? pVclIter->iter : nullptr;
3474  auto nInsertPos = pos == -1 ? TREELIST_APPEND : pos;
3475  void* pUserData;
3476  if (pId)
3477  {
3478  m_aUserData.emplace_back(std::make_unique<OUString>(*pId));
3479  pUserData = m_aUserData.back().get();
3480  }
3481  else
3482  pUserData = nullptr;
3483 
3484  SvTreeListEntry* pEntry = new SvTreeListEntry;
3485  if (bIsSeparator)
3486  pEntry->SetFlags(pEntry->GetFlags() | SvTLEntryFlags::IS_SEPARATOR);
3487 
3489  AddStringItem(pEntry, "", -1);
3490 
3491  if (pIconName || pImageSurface)
3492  {
3493  Image aImage(pIconName ? createImage(*pIconName) : createImage(*pImageSurface));
3494  pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(aImage, aImage, false));
3495  }
3496  else
3497  {
3498  Image aDummy;
3499  pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(aDummy, aDummy, false));
3500  }
3501  if (pStr)
3502  AddStringItem(pEntry, *pStr, 0);
3503  pEntry->SetUserData(pUserData);
3504  m_xTreeView->Insert(pEntry, iter, nInsertPos);
3505 
3506  if (pRet)
3507  {
3508  SalInstanceTreeIter* pVclRetIter = static_cast<SalInstanceTreeIter*>(pRet);
3509  pVclRetIter->iter = pEntry;
3510  }
3511 
3512  if (bChildrenOnDemand)
3513  {
3514  SvTreeListEntry* pPlaceHolder
3515  = m_xTreeView->InsertEntry("<dummy>", pEntry, false, 0, nullptr);
3516  SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pPlaceHolder);
3517  pViewData->SetSelectable(false);
3518  }
3519 
3520  if (bIsSeparator)
3521  {
3522  SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry);
3523  pViewData->SetSelectable(false);
3524  }
3525 
3527 }
3528 
3530 {
3531  SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry);
3532  m_xTreeView->InitViewData(pViewData, pEntry);
3533  m_xTreeView->CheckBoxInserted(pEntry);
3534 }
3535 
3537 {
3539  return;
3541 }
3542 
3544 {
3545  assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
3546  // if its the placeholder to allow a blank column, replace it now
3547  if (pEntry->GetItem(col).GetType() != SvLBoxItemType::Button)
3548  {
3550  pEntry->ReplaceItem(std::make_unique<SvLBoxButton>(pData), 0);
3552  }
3553  SvLBoxItem& rItem = pEntry->GetItem(col);
3554  assert(dynamic_cast<SvLBoxButton*>(&rItem));
3555  switch (eState)
3556  {
3557  case TRISTATE_TRUE:
3558  static_cast<SvLBoxButton&>(rItem).SetStateChecked();
3559  break;
3560  case TRISTATE_FALSE:
3561  static_cast<SvLBoxButton&>(rItem).SetStateUnchecked();
3562  break;
3563  case TRISTATE_INDET:
3564  static_cast<SvLBoxButton&>(rItem).SetStateTristate();
3565  break;
3566  }
3567 
3568  InvalidateModelEntry(pEntry);
3569 }
3570 
3572 {
3573  if (static_cast<size_t>(col) == pEntry->ItemCount())
3574  return TRISTATE_FALSE;
3575 
3576  assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
3577  SvLBoxItem& rItem = pEntry->GetItem(col);
3578  assert(dynamic_cast<SvLBoxButton*>(&rItem));
3579  SvLBoxButton& rToggle = static_cast<SvLBoxButton&>(rItem);
3580  if (rToggle.IsStateTristate())
3581  return TRISTATE_INDET;
3582  else if (rToggle.IsStateChecked())
3583  return TRISTATE_TRUE;
3584  return TRISTATE_FALSE;
3585 }
3586 
3588 {
3589  if (col == -1)
3590  {
3592  return do_get_toggle(pEntry, 0);
3593  }
3594  col = to_internal_model(col);
3595  return do_get_toggle(pEntry, col);
3596 }
3597 
3599 {
3600  if (col == -1)
3601  {
3603  do_set_toggle(pEntry, eState, 0);
3604  return;
3605  }
3606 
3607  col = to_internal_model(col);
3608 
3609  // blank out missing entries
3610  for (int i = pEntry->ItemCount(); i < col; ++i)
3611  AddStringItem(pEntry, "", i - 1);
3612 
3613  if (static_cast<size_t>(col) == pEntry->ItemCount())
3614  {
3616  pEntry->AddItem(std::make_unique<SvLBoxButton>(pData));
3618  }
3619 
3620  do_set_toggle(pEntry, eState, col);
3621 }
3622 
3624 {
3625  col = to_internal_model(col);
3626 
3627  assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
3628  SvLBoxItem& rItem = pEntry->GetItem(col);
3629  assert(dynamic_cast<SvLBoxString*>(&rItem));
3630  return static_cast<SvLBoxString&>(rItem).IsEmphasized();
3631 }
3632 
3633 void SalInstanceTreeView::set_header_item_width(const std::vector<int>& rWidths)
3634 {
3635  LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
3636  if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
3637  {
3638  for (size_t i = 0; i < rWidths.size(); ++i)
3639  pHeaderBar->SetItemSize(pHeaderBar->GetItemId(i), rWidths[i]);
3640  }
3641 }
3642 
3644  bool bTakeOwnership)
3645  : SalInstanceContainer(pTreeView, pBuilder, bTakeOwnership)
3646  , m_xTreeView(pTreeView)
3647  , m_aCheckButtonData(pTreeView, false)
3648  , m_aRadioButtonData(pTreeView, true)
3649  , m_bTogglesAsRadio(false)
3650  , m_nSortColumn(-1)
3651 {
3654  m_xTreeView->SetSelectHdl(LINK(this, SalInstanceTreeView, SelectHdl));
3655  m_xTreeView->SetDeselectHdl(LINK(this, SalInstanceTreeView, DeSelectHdl));
3656  m_xTreeView->SetDoubleClickHdl(LINK(this, SalInstanceTreeView, DoubleClickHdl));
3657  m_xTreeView->SetExpandingHdl(LINK(this, SalInstanceTreeView, ExpandingHdl));
3658  m_xTreeView->SetPopupMenuHdl(LINK(this, SalInstanceTreeView, PopupMenuHdl));
3659  m_xTreeView->SetCustomRenderHdl(LINK(this, SalInstanceTreeView, CustomRenderHdl));
3660  m_xTreeView->SetCustomMeasureHdl(LINK(this, SalInstanceTreeView, CustomMeasureHdl));
3661  const tools::Long aTabPositions[] = { 0 };
3662  m_xTreeView->SetTabs(SAL_N_ELEMENTS(aTabPositions), aTabPositions);
3663  LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
3664 
3665  if (pHeaderBox)
3666  {
3667  if (HeaderBar* pHeaderBar = pHeaderBox->GetHeaderBar())
3668  {
3669  //make the last entry fill available space
3670  pHeaderBar->SetItemSize(pHeaderBar->GetItemId(pHeaderBar->GetItemCount() - 1),
3672  pHeaderBar->SetEndDragHdl(LINK(this, SalInstanceTreeView, EndDragHdl));
3673  pHeaderBar->SetSelectHdl(LINK(this, SalInstanceTreeView, HeaderBarClickedHdl));
3674  }
3675  pHeaderBox->SetEditingEntryHdl(LINK(this, SalInstanceTreeView, EditingEntryHdl));
3676  pHeaderBox->SetEditedEntryHdl(LINK(this, SalInstanceTreeView, EditedEntryHdl));
3677  }
3678  else
3679  {
3680  static_cast<LclTabListBox&>(*m_xTreeView)
3681  .SetModelChangedHdl(LINK(this, SalInstanceTreeView, ModelChangedHdl));
3682  static_cast<LclTabListBox&>(*m_xTreeView)
3683  .SetStartDragHdl(LINK(this, SalInstanceTreeView, StartDragHdl));
3684  static_cast<LclTabListBox&>(*m_xTreeView)
3685  .SetEndDragHdl(LINK(this, SalInstanceTreeView, FinishDragHdl));
3686  static_cast<LclTabListBox&>(*m_xTreeView)
3687  .SetEditingEntryHdl(LINK(this, SalInstanceTreeView, EditingEntryHdl));
3688  static_cast<LclTabListBox&>(*m_xTreeView)
3689  .SetEditedEntryHdl(LINK(this, SalInstanceTreeView, EditedEntryHdl));
3690  }
3693 }
3694 
3696 {
3698  m_xTreeView->SetTooltipHdl(LINK(this, SalInstanceTreeView, TooltipHdl));
3699 }
3700 
3702 {
3703  std::vector<tools::Long> aWidths;
3705  if (aWidths.size() > 2)
3706  {
3707  std::vector<int> aColWidths;
3708  for (size_t i = 1; i < aWidths.size() - 1; ++i)
3709  aColWidths.push_back(aWidths[i] - aWidths[i - 1]);
3710  set_column_fixed_widths(aColWidths);
3711  }
3712 }
3713 
3715 {
3717  m_xTreeView->SetUpdateMode(false);
3719 }
3720 
3722 {
3724  m_xTreeView->SetUpdateMode(true);
3726 }
3727 
3728 void SalInstanceTreeView::set_column_fixed_widths(const std::vector<int>& rWidths)
3729 {
3730  std::vector<tools::Long> aTabPositions;
3731  aTabPositions.push_back(0);
3732  for (size_t i = 0; i < rWidths.size(); ++i)
3733  aTabPositions.push_back(aTabPositions[i] + rWidths[i]);
3734  m_xTreeView->SetTabs(aTabPositions.size(), aTabPositions.data(), MapUnit::MapPixel);
3735  set_header_item_width(rWidths);
3736  // call Resize to recalculate based on the new tabs
3737  m_xTreeView->Resize();
3738 }
3739 
3740 void SalInstanceTreeView::set_column_editables(const std::vector<bool>& rEditables)
3741 {
3742  size_t nTabCount = rEditables.size();
3743  for (size_t i = 0; i < nTabCount; ++i)
3744  m_xTreeView->SetTabEditable(i, rEditables[i]);
3745 }
3746 
3748 {
3750 }
3751 
3753 {
3754  LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
3755  if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
3756  return pHeaderBar->GetItemSize(pHeaderBar->GetItemId(nColumn));
3757  // GetTab(0) gives the position of the bitmap which is automatically inserted by the TabListBox.
3758  // So the first text column's width is Tab(2)-Tab(1).
3759  auto nWidthPixel
3760  = m_xTreeView->GetLogicTab(nColumn + 2) - m_xTreeView->GetLogicTab(nColumn + 1);
3761  nWidthPixel -= SV_TAB_BORDER;
3762  return nWidthPixel;
3763 }
3764 
3765 OUString SalInstanceTreeView::get_column_title(int nColumn) const
3766 {
3767  LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
3768  if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
3769  {
3770  return pHeaderBar->GetItemText(pHeaderBar->GetItemId(nColumn));
3771  }
3772  return OUString();
3773 }
3774 
3775 void SalInstanceTreeView::set_column_title(int nColumn, const OUString& rTitle)
3776 {
3777  LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
3778  if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
3779  {
3780  return pHeaderBar->SetItemText(pHeaderBar->GetItemId(nColumn), rTitle);
3781  }
3782 }
3783 
3785 {
3786  assert(n_children() == 0 && "tree must be empty");
3787  if (bEnable)
3788  m_aCustomRenders.insert(nColumn);
3789  else
3790  m_aCustomRenders.erase(nColumn);
3791 }
3792 
3794 {
3795  // invalidate the entries
3796  SvTreeList* pModel = m_xTreeView->GetModel();
3797  for (SvTreeListEntry* pEntry = m_xTreeView->First(); pEntry; pEntry = m_xTreeView->Next(pEntry))
3798  pModel->InvalidateEntry(pEntry);
3799 }
3800 
3802 {
3803  if (LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get()))
3804  pHeaderBox->GetParent()->Show();
3806 }
3807 
3809 {
3810  if (LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get()))
3811  pHeaderBox->GetParent()->Hide();
3813 }
3814 
3815 void SalInstanceTreeView::insert(const weld::TreeIter* pParent, int pos, const OUString* pStr,
3816  const OUString* pId, const OUString* pIconName,
3817  VirtualDevice* pImageSurface, bool bChildrenOnDemand,
3818  weld::TreeIter* pRet)
3819 {
3820  do_insert(pParent, pos, pStr, pId, pIconName, pImageSurface, bChildrenOnDemand, pRet, false);
3821 }
3822 
3823 void SalInstanceTreeView::insert_separator(int pos, const OUString& /*rId*/)
3824 {
3825  OUString sSep(VclResId(STR_SEPARATOR));
3826  do_insert(nullptr, pos, &sSep, nullptr, nullptr, nullptr, false, nullptr, true);
3827 }
3828 
3830  int nSourceCount, const std::function<void(weld::TreeIter&, int nSourceIndex)>& func,
3831  const std::vector<int>* pFixedWidths)
3832 {
3833  freeze();
3834  clear();
3835  SalInstanceTreeIter aVclIter(static_cast<SvTreeListEntry*>(nullptr));
3836 
3838 
3839  if (pFixedWidths)
3840  set_header_item_width(*pFixedWidths);
3841 
3842  bool bHasAutoCheckButton(m_xTreeView->nTreeFlags & SvTreeFlags::CHKBTN);
3843  size_t nExtraCols = bHasAutoCheckButton ? 2 : 1;
3844 
3845  Image aDummy;
3846  for (int i = 0; i < nSourceCount; ++i)
3847  {
3848  aVclIter.iter = new SvTreeListEntry;
3849  if (bHasAutoCheckButton)
3850  AddStringItem(aVclIter.iter, "", -1);
3851  aVclIter.iter->AddItem(std::make_unique<SvLBoxContextBmp>(aDummy, aDummy, false));
3852  m_xTreeView->Insert(aVclIter.iter, nullptr, TREELIST_APPEND);
3853  func(aVclIter, i);
3854 
3855  if (!pFixedWidths)
3856  continue;
3857 
3858  size_t nFixedWidths = std::min(pFixedWidths->size(), aVclIter.iter->ItemCount());
3859  for (size_t j = 0; j < nFixedWidths; ++j)
3860  {
3861  SvLBoxItem& rItem = aVclIter.iter->GetItem(j + nExtraCols);
3862  SvViewDataItem* pViewDataItem = m_xTreeView->GetViewDataItem(aVclIter.iter, &rItem);
3863  pViewDataItem->mnWidth = (*pFixedWidths)[j];
3864  }
3865  }
3866 
3868 
3869  thaw();
3870 }
3871 
3872 void SalInstanceTreeView::set_font_color(int pos, const Color& rColor)
3873 {
3874  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
3875  set_font_color(pEntry, rColor);
3876 }
3877 
3879 {
3880  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
3881  set_font_color(rVclIter.iter, rColor);
3882 }
3883 
3885 {
3887  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
3888  m_xTreeView->RemoveEntry(pEntry);
3890 }
3891 
3892 int SalInstanceTreeView::find_text(const OUString& rText) const
3893 {
3894  for (SvTreeListEntry* pEntry = m_xTreeView->First(); pEntry; pEntry = m_xTreeView->Next(pEntry))
3895  {
3896  if (SvTabListBox::GetEntryText(pEntry, 0) == rText)
3897  return SvTreeList::GetRelPos(pEntry);
3898  }
3899  return -1;
3900 }
3901 
3902 int SalInstanceTreeView::find_id(const OUString& rId) const
3903 {
3904  for (SvTreeListEntry* pEntry = m_xTreeView->First(); pEntry; pEntry = m_xTreeView->Next(pEntry))
3905  {
3906  const OUString* pId = static_cast<const OUString*>(pEntry->GetUserData());
3907  if (!pId)
3908  continue;
3909  if (rId == *pId)
3910  return SvTreeList::GetRelPos(pEntry);
3911  }
3912  return -1;
3913 }
3914 
3915 void SalInstanceTreeView::swap(int pos1, int pos2)
3916 {
3917  int min = std::min(pos1, pos2);
3918  int max = std::max(pos1, pos2);
3919  SvTreeList* pModel = m_xTreeView->GetModel();
3920  SvTreeListEntry* pEntry1 = pModel->GetEntry(nullptr, min);
3921  SvTreeListEntry* pEntry2 = pModel->GetEntry(nullptr, max);
3922  pModel->Move(pEntry1, pEntry2);
3923 }
3924 
3926 {
3928  m_xTreeView->Clear();
3929  m_aUserData.clear();
3931 }
3932 
3934 {
3935  return m_xTreeView->GetModel()->GetChildList(nullptr).size();
3936 }
3937 
3939 {
3940  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
3941  return m_xTreeView->GetModel()->GetChildList(rVclIter.iter).size();
3942 }
3943 
3945 {
3947  && "don't select when frozen, select after thaw. Note selection doesn't survive a "
3948  "freeze");
3950  if (pos == -1 || (pos == 0 && n_children() == 0))
3951  m_xTreeView->SelectAll(false);
3952  else
3953  {
3954  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
3955  assert(pEntry && "bad pos?");
3956  m_xTreeView->Select(pEntry, true);
3957  m_xTreeView->MakeVisible(pEntry);
3958  }
3960 }
3961 
3963 {
3965  if (!pEntry)
3966  return -1;
3967  return SvTreeList::GetRelPos(pEntry);
3968 }
3969 
3971 {
3973  if (pos == -1)
3974  m_xTreeView->SetCurEntry(nullptr);
3975  else
3976  {
3977  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
3978  m_xTreeView->SetCurEntry(pEntry);
3979  }
3981 }
3982 
3984 {
3986  && "don't select when frozen, select after thaw. Note selection doesn't survive a "
3987  "freeze");
3989  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
3990  m_xTreeView->MakeVisible(pEntry);
3992 }
3993 
3995 {
3996  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
3997  return m_xTreeView->IsSelected(pEntry);
3998 }
3999 
4001 {
4003  && "don't select when frozen, select after thaw. Note selection doesn't survive a "
4004  "freeze");
4006  if (pos == -1)
4007  m_xTreeView->SelectAll(true);
4008  else
4009  {
4010  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4011  m_xTreeView->Select(pEntry, false);
4012  }
4014 }
4015 
4017 {
4018  std::vector<int> aRows;
4019 
4020  aRows.reserve(m_xTreeView->GetSelectionCount());
4021  for (SvTreeListEntry* pEntry = m_xTreeView->FirstSelected(); pEntry;
4022  pEntry = m_xTreeView->NextSelected(pEntry))
4023  aRows.push_back(SvTreeList::GetRelPos(pEntry));
4024 
4025  return aRows;
4026 }
4027 
4028 OUString SalInstanceTreeView::get_text(SvTreeListEntry* pEntry, int col) const
4029 {
4030  if (col == -1)
4031  return SvTabListBox::GetEntryText(pEntry, 0);
4032 
4033  col = to_internal_model(col);
4034 
4035  if (static_cast<size_t>(col) == pEntry->ItemCount())
4036  return OUString();
4037 
4038  assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
4039  SvLBoxItem& rItem = pEntry->GetItem(col);
4040  assert(dynamic_cast<SvLBoxString*>(&rItem));
4041  return static_cast<SvLBoxString&>(rItem).GetText();
4042 }
4043 
4044 OUString SalInstanceTreeView::get_text(int pos, int col) const
4045 {
4046  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4047  return get_text(pEntry, col);
4048 }
4049 
4050 void SalInstanceTreeView::set_text(SvTreeListEntry* pEntry, const OUString& rText, int col)
4051 {
4052  if (col == -1)
4053  {
4054  m_xTreeView->SetEntryText(pEntry, rText);
4055  return;
4056  }
4057 
4058  col = to_internal_model(col);
4059 
4060  // blank out missing entries
4061  for (int i = pEntry->ItemCount(); i < col; ++i)
4062  AddStringItem(pEntry, "", i - 1);
4063 
4064  if (static_cast<size_t>(col) == pEntry->ItemCount())
4065  {
4066  AddStringItem(pEntry, rText, col - 1);
4067  SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry);
4068  m_xTreeView->InitViewData(pViewData, pEntry);
4069  }
4070  else
4071  {
4072  assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
4073  SvLBoxItem& rItem = pEntry->GetItem(col);
4074  assert(dynamic_cast<SvLBoxString*>(&rItem));
4075  static_cast<SvLBoxString&>(rItem).SetText(rText);
4076  }
4077 
4078  InvalidateModelEntry(pEntry);
4079 }
4080 
4081 void SalInstanceTreeView::set_text(int pos, const OUString& rText, int col)
4082 {
4083  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4084  set_text(pEntry, rText, col);
4085 }
4086 
4087 void SalInstanceTreeView::set_sensitive(SvTreeListEntry* pEntry, bool bSensitive, int col)
4088 {
4089  if (col == -1)
4090  {
4091  auto nFlags = pEntry->GetFlags() & ~SvTLEntryFlags::SEMITRANSPARENT;
4092  if (!bSensitive)
4093  nFlags = nFlags | SvTLEntryFlags::SEMITRANSPARENT;
4094  pEntry->SetFlags(nFlags);
4095  const sal_uInt16 nCount = pEntry->ItemCount();
4096  for (sal_uInt16 nCur = 0; nCur < nCount; ++nCur)
4097  {
4098  SvLBoxItem& rItem = pEntry->GetItem(nCur);
4099  if (rItem.GetType() == SvLBoxItemType::String)
4100  {
4101  rItem.Enable(bSensitive);
4102  InvalidateModelEntry(pEntry);
4103  break;
4104  }
4105  }
4106  return;
4107  }
4108 
4109  col = to_internal_model(col);
4110 
4111  assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
4112  SvLBoxItem& rItem = pEntry->GetItem(col);
4113  rItem.Enable(bSensitive);
4114 
4115  InvalidateModelEntry(pEntry);
4116 }
4117 
4118 void SalInstanceTreeView::set_sensitive(int pos, bool bSensitive, int col)
4119 {
4120  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4121  set_sensitive(pEntry, bSensitive, col);
4122 }
4123 
4124 void SalInstanceTreeView::set_sensitive(const weld::TreeIter& rIter, bool bSensitive, int col)
4125 {
4126  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4127  set_sensitive(rVclIter.iter, bSensitive, col);
4128 }
4129 
4131 {
4132  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4133  return get_toggle(pEntry, col);
4134 }
4135 
4137 {
4138  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4139  return get_toggle(rVclIter.iter, col);
4140 }
4141 
4143 {
4144  assert(n_children() == 0 && "tree must be empty");
4146 
4149  // EnableCheckButton clobbered this, restore it
4150  pData->SetLink(LINK(this, SalInstanceTreeView, ToggleHdl));
4151 }
4152 
4153 void SalInstanceTreeView::set_toggle(int pos, TriState eState, int col)
4154 {
4155  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4156  set_toggle(pEntry, eState, col);
4157 }
4158 
4159 void SalInstanceTreeView::set_toggle(const weld::TreeIter& rIter, TriState eState, int col)
4160 {
4161  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4162  set_toggle(rVclIter.iter, eState, col);
4163 }
4164 
4166 {
4167  m_xTreeView->SetClicksToToggle(nToggleBehavior);
4168 }
4169 
4170 void SalInstanceTreeView::set_extra_row_indent(const weld::TreeIter& rIter, int nIndentLevel)
4171 {
4172  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4173  rVclIter.iter->SetExtraIndent(nIndentLevel);
4174 }
4175 
4177 {
4178  col = to_internal_model(col);
4179 
4180  assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
4181  SvLBoxItem& rItem = pEntry->GetItem(col);
4182  assert(dynamic_cast<SvLBoxString*>(&rItem));
4183  static_cast<SvLBoxString&>(rItem).Emphasize(bOn);
4184 
4185  InvalidateModelEntry(pEntry);
4186 }
4187 
4188 void SalInstanceTreeView::set_text_emphasis(const weld::TreeIter& rIter, bool bOn, int col)
4189 {
4190  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4191  set_text_emphasis(rVclIter.iter, bOn, col);
4192 }
4193 
4194 void SalInstanceTreeView::set_text_emphasis(int pos, bool bOn, int col)
4195 {
4196  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4197  set_text_emphasis(pEntry, bOn, col);
4198 }
4199 
4201 {
4202  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4203  return get_text_emphasis(rVclIter.iter, col);
4204 }
4205 
4206 bool SalInstanceTreeView::get_text_emphasis(int pos, int col) const
4207 {
4208  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4209  return get_text_emphasis(pEntry, col);
4210 }
4211 
4212 void SalInstanceTreeView::set_text_align(SvTreeListEntry* pEntry, double fAlign, int col)
4213 {
4214  col = to_internal_model(col);
4215 
4216  assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
4217  SvLBoxItem& rItem = pEntry->GetItem(col);
4218  assert(dynamic_cast<SvLBoxString*>(&rItem));
4219  static_cast<SvLBoxString&>(rItem).Align(fAlign);
4220 
4221  InvalidateModelEntry(pEntry);
4222 }
4223 
4224 void SalInstanceTreeView::set_text_align(const weld::TreeIter& rIter, double fAlign, int col)
4225 {
4226  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4227  set_text_align(rVclIter.iter, fAlign, col);
4228 }
4229 
4230 void SalInstanceTreeView::set_text_align(int pos, double fAlign, int col)
4231 {
4232  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4233  set_text_align(pEntry, fAlign, col);
4234 }
4235 
4237  const Link<const iter_string&, bool>& rEndLink)
4238 {
4239  m_xTreeView->EnableInplaceEditing(rStartLink.IsSet() || rEndLink.IsSet());
4240  weld::TreeView::connect_editing(rStartLink, rEndLink);
4241 }
4242 
4244 {
4245  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4246  m_xTreeView->EditEntry(rVclIter.iter);
4247 }
4248 
4250 
4251 void SalInstanceTreeView::set_image(SvTreeListEntry* pEntry, const Image& rImage, int col)
4252 {
4253  if (col == -1)
4254  {
4255  m_xTreeView->SetExpandedEntryBmp(pEntry, rImage);
4256  m_xTreeView->SetCollapsedEntryBmp(pEntry, rImage);
4257  return;
4258  }
4259 
4260  col = to_internal_model(col);
4261 
4262  // blank out missing entries
4263  for (int i = pEntry->ItemCount(); i < col; ++i)
4264  AddStringItem(pEntry, "", i - 1);
4265 
4266  if (static_cast<size_t>(col) == pEntry->ItemCount())
4267  {
4268  pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(rImage, rImage, false));
4269  SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry);
4270  m_xTreeView->InitViewData(pViewData, pEntry);
4271  }
4272  else
4273  {
4274  assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
4275  SvLBoxItem& rItem = pEntry->GetItem(col);
4276  assert(dynamic_cast<SvLBoxContextBmp*>(&rItem));
4277  static_cast<SvLBoxContextBmp&>(rItem).SetBitmap1(rImage);
4278  static_cast<SvLBoxContextBmp&>(rItem).SetBitmap2(rImage);
4279  }
4280 
4281  m_xTreeView->SetEntryHeight(pEntry);
4282  InvalidateModelEntry(pEntry);
4283 }
4284 
4285 void SalInstanceTreeView::set_image(int pos, const OUString& rImage, int col)
4286 {
4287  set_image(m_xTreeView->GetEntry(nullptr, pos), createImage(rImage), col);
4288 }
4289 
4291  const css::uno::Reference<css::graphic::XGraphic>& rImage,
4292  int col)
4293 {
4294  set_image(m_xTreeView->GetEntry(nullptr, pos), Image(rImage), col);
4295 }
4296 
4297 void SalInstanceTreeView::set_image(int pos, VirtualDevice& rImage, int col)
4298 {
4299  set_image(m_xTreeView->GetEntry(nullptr, pos), createImage(rImage), col);
4300 }
4301 
4302 void SalInstanceTreeView::set_image(const weld::TreeIter& rIter, const OUString& rImage, int col)
4303 {
4304  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4305  set_image(rVclIter.iter, createImage(rImage), col);
4306 }
4307 
4309  const css::uno::Reference<css::graphic::XGraphic>& rImage,
4310  int col)
4311 {
4312  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4313  set_image(rVclIter.iter, Image(rImage), col);
4314 }
4315 
4317 {
4318  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4319  set_image(rVclIter.iter, createImage(rImage), col);
4320 }
4321 
4322 const OUString* SalInstanceTreeView::getEntryData(int index) const
4323 {
4324  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, index);
4325  return pEntry ? static_cast<const OUString*>(pEntry->GetUserData()) : nullptr;
4326 }
4327 
4328 OUString SalInstanceTreeView::get_id(int pos) const
4329 {
4330  const OUString* pRet = getEntryData(pos);
4331  if (!pRet)
4332  return OUString();
4333  return *pRet;
4334 }
4335 
4336 void SalInstanceTreeView::set_id(SvTreeListEntry* pEntry, const OUString& rId)
4337 {
4338  m_aUserData.emplace_back(std::make_unique<OUString>(rId));
4339  pEntry->SetUserData(m_aUserData.back().get());
4340 }
4341 
4342 void SalInstanceTreeView::set_id(int pos, const OUString& rId)
4343 {
4344  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4345  set_id(pEntry, rId);
4346 }
4347 
4349 {
4350  assert(m_xTreeView->IsUpdateMode() && "don't request selection when frozen");
4352  if (!pEntry)
4353  return -1;
4354  return SvTreeList::GetRelPos(pEntry);
4355 }
4356 
4358 {
4359  assert(m_xTreeView->IsUpdateMode() && "don't request selection when frozen");
4360  if (SvTreeListEntry* pEntry = m_xTreeView->FirstSelected())
4361  return SvTabListBox::GetEntryText(pEntry, 0);
4362  return OUString();
4363 }
4364 
4366 {
4367  assert(m_xTreeView->IsUpdateMode() && "don't request selection when frozen");
4368  if (SvTreeListEntry* pEntry = m_xTreeView->FirstSelected())
4369  {
4370  if (const OUString* pStr = static_cast<const OUString*>(pEntry->GetUserData()))
4371  return *pStr;
4372  }
4373  return OUString();
4374 }
4375 
4376 std::unique_ptr<weld::TreeIter>
4378 {
4379  return std::unique_ptr<weld::TreeIter>(
4380  new SalInstanceTreeIter(static_cast<const SalInstanceTreeIter*>(pOrig)));
4381 }
4382 
4384 {
4385  const SalInstanceTreeIter& rVclSource(static_cast<const SalInstanceTreeIter&>(rSource));
4386  SalInstanceTreeIter& rVclDest(static_cast<SalInstanceTreeIter&>(rDest));
4387  rVclDest.iter = rVclSource.iter;
4388 }
4389 
4391 {
4393  auto pVclIter = static_cast<SalInstanceTreeIter*>(pIter);
4394  if (pVclIter)
4395  pVclIter->iter = pEntry;
4396  return pEntry != nullptr;
4397 }
4398 
4400 {
4402  auto pVclIter = static_cast<SalInstanceTreeIter*>(pIter);
4403  if (pVclIter)
4404  pVclIter->iter = pEntry;
4405  return pEntry != nullptr;
4406 }
4407 
4409 {
4410  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4412  m_xTreeView->SetCurEntry(rVclIter.iter);
4414 }
4415 
4417 {
4418  SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
4419  rVclIter.iter = m_xTreeView->GetEntry(0);
4420  return rVclIter.iter != nullptr;
4421 }
4422 
4424 {
4425  SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
4426  rVclIter.iter = m_xTreeView->GetEntryAtAbsPos(nAbsPos);
4427  return rVclIter.iter != nullptr;
4428 }
4429 
4431 {
4432  SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
4433  rVclIter.iter = rVclIter.iter->NextSibling();
4434  return rVclIter.iter != nullptr;
4435 }
4436 
4438 {
4439  SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
4440  rVclIter.iter = rVclIter.iter->PrevSibling();
4441  return rVclIter.iter != nullptr;
4442 }
4443 
4445 {
4446  SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
4447  rVclIter.iter = m_xTreeView->Next(rVclIter.iter);
4448  if (rVclIter.iter && IsDummyEntry(rVclIter.iter))
4449  return iter_next(rVclIter);
4450  return rVclIter.iter != nullptr;
4451 }
4452 
4454 {
4455  SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
4456  rVclIter.iter = m_xTreeView->Prev(rVclIter.iter);
4457  if (rVclIter.iter && IsDummyEntry(rVclIter.iter))
4458  return iter_previous(rVclIter);
4459  return rVclIter.iter != nullptr;
4460 }
4461 
4463 {
4464  SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
4465  rVclIter.iter = m_xTreeView->FirstChild(rVclIter.iter);
4466  bool bRet = rVclIter.iter != nullptr;
4467  if (bRet)
4468  {
4469  //on-demand dummy entry doesn't count
4470  return !IsDummyEntry(rVclIter.iter);
4471  }
4472  return bRet;
4473 }
4474 
4476 {
4477  SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
4478  rVclIter.iter = m_xTreeView->GetParent(rVclIter.iter);
4479  return rVclIter.iter != nullptr;
4480 }
4481 
4483 {
4485  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4486  m_xTreeView->RemoveEntry(rVclIter.iter);
4488 }
4489 
4491 {
4493  && "don't select when frozen, select after thaw. Note selection doesn't survive a "
4494  "freeze");
4496  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4497  m_xTreeView->Select(rVclIter.iter, true);
4499 }
4500 
4502 {
4504  && "don't select when frozen, select after thaw. Note selection doesn't survive a "
4505  "freeze");
4507  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4508  m_xTreeView->MakeVisible(rVclIter.iter);
4510 }
4511 
4513 {
4514  assert(m_xTreeView->IsUpdateMode() && "don't unselect when frozen");
4516  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4517  m_xTreeView->Select(rVclIter.iter, false);
4519 }
4520 
4522 {
4523  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4524  return m_xTreeView->GetModel()->GetDepth(rVclIter.iter);
4525 }
4526 
4528 {
4529  SalInstanceTreeIter aTempCopy(static_cast<const SalInstanceTreeIter*>(&rIter));
4530  return iter_children(aTempCopy);
4531 }
4532 
4534 {
4535  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4536  return m_xTreeView->IsExpanded(rVclIter.iter);
4537 }
4538 
4540 {
4541  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4543  return true;
4544  return GetPlaceHolderChild(rVclIter.iter) != nullptr;
4545 }
4546 
4548  bool bChildrenOnDemand)
4549 {
4551 
4552  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4553 
4554  SvTreeListEntry* pPlaceHolder = GetPlaceHolderChild(rVclIter.iter);
4555 
4556  if (bChildrenOnDemand && !pPlaceHolder)
4557  {
4558  pPlaceHolder = m_xTreeView->InsertEntry("<dummy>", rVclIter.iter, false, 0, nullptr);
4559  SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pPlaceHolder);
4560  pViewData->SetSelectable(false);
4561  }
4562  else if (!bChildrenOnDemand && pPlaceHolder)
4563  m_xTreeView->RemoveEntry(pPlaceHolder);
4564 
4566 }
4567 
4569 {
4570  assert(m_xTreeView->IsUpdateMode() && "don't expand when frozen");
4571  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4572  if (!m_xTreeView->IsExpanded(rVclIter.iter) && signal_expanding(rIter))
4573  m_xTreeView->Expand(rVclIter.iter);
4574 }
4575 
4577 {
4578  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4579  if (m_xTreeView->IsExpanded(rVclIter.iter) && signal_collapsing(rIter))
4580  m_xTreeView->Collapse(rVclIter.iter);
4581 }
4582 
4583 OUString SalInstanceTreeView::get_text(const weld::TreeIter& rIter, int col) const
4584 {
4585  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4586  return get_text(rVclIter.iter, col);
4587 }
4588 
4589 void SalInstanceTreeView::set_text(const weld::TreeIter& rIter, const OUString& rText, int col)
4590 {
4591  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4592  set_text(rVclIter.iter, rText, col);
4593 }
4594 
4595 OUString SalInstanceTreeView::get_id(const weld::TreeIter& rIter) const
4596 {
4597  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4598  const OUString* pStr = static_cast<const OUString*>(rVclIter.iter->GetUserData());
4599  if (pStr)
4600  return *pStr;
4601  return OUString();
4602 }
4603 
4604 void SalInstanceTreeView::set_id(const weld::TreeIter& rIter, const OUString& rId)
4605 {
4606  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4607  set_id(rVclIter.iter, rId);
4608 }
4609 
4611  sal_uInt8 eDNDConstants)
4612 {
4613  m_xTreeView->SetDragHelper(rHelper, eDNDConstants);
4614 }
4615 
4617 {
4618  m_xTreeView->SetSelectionMode(eMode);
4619 }
4620 
4621 void SalInstanceTreeView::all_foreach(const std::function<bool(weld::TreeIter&)>& func)
4622 {
4623  UpdateGuardIfHidden aGuard(*m_xTreeView);
4624 
4625  SalInstanceTreeIter aVclIter(m_xTreeView->First());
4626  while (aVclIter.iter)
4627  {
4628  if (func(aVclIter))
4629  return;
4630  iter_next(aVclIter);
4631  }
4632 }
4633 
4634 void SalInstanceTreeView::selected_foreach(const std::function<bool(weld::TreeIter&)>& func)
4635 {
4636  UpdateGuardIfHidden aGuard(*m_xTreeView);
4637 
4639  while (aVclIter.iter)
4640  {
4641  if (func(aVclIter))
4642  return;
4643  aVclIter.iter = m_xTreeView->NextSelected(aVclIter.iter);
4644  }
4645 }
4646 
4647 void SalInstanceTreeView::visible_foreach(const std::function<bool(weld::TreeIter&)>& func)
4648 {
4649  UpdateGuardIfHidden aGuard(*m_xTreeView);
4650 
4652  while (aVclIter.iter)
4653  {
4654  if (func(aVclIter))
4655  return;
4656  aVclIter.iter = m_xTreeView->GetNextEntryInView(aVclIter.iter);
4657  }
4658 }
4659 
4661 {
4663  m_xTreeView->SetScrolledHdl(LINK(this, SalInstanceTreeView, VisibleRangeChangedHdl));
4664 }
4665 
4667 {
4669  SvTreeListEntry* pSelected = m_xTreeView->FirstSelected();
4670  while (pSelected)
4671  {
4672  SvTreeListEntry* pNextSelected = m_xTreeView->NextSelected(pSelected);
4673  m_xTreeView->RemoveEntry(pSelected);
4674  pSelected = pNextSelected;
4675  }
4677 }
4678 
4680 {
4681  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4682  return m_xTreeView->IsSelected(rVclIter.iter);
4683 }
4684 
4686 {
4687  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4688  return SvTreeList::GetRelPos(rVclIter.iter);
4689 }
4690 
4692 {
4693  const SalInstanceTreeIter& rVclIterA = static_cast<const SalInstanceTreeIter&>(a);
4694  const SalInstanceTreeIter& rVclIterB = static_cast<const SalInstanceTreeIter&>(b);
4695  const SvTreeList* pModel = m_xTreeView->GetModel();
4696  auto nAbsPosA = pModel->GetAbsPos(rVclIterA.iter);
4697  auto nAbsPosB = pModel->GetAbsPos(rVclIterB.iter);
4698  if (nAbsPosA < nAbsPosB)
4699  return -1;
4700  if (nAbsPosA > nAbsPosB)
4701  return 1;
4702  return 0;
4703 }
4704 
4706  int nIndexInNewParent)
4707 {
4708  SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rNode);
4709  const SalInstanceTreeIter* pVclParentIter = static_cast<const SalInstanceTreeIter*>(pNewParent);
4710  m_xTreeView->GetModel()->Move(rVclIter.iter, pVclParentIter ? pVclParentIter->iter : nullptr,
4711  nIndexInNewParent);
4712 }
4713 
4715 
4717 {
4718  return m_xTreeView->GetEntryHeight() * nRows;
4719 }
4720 
4722 {
4723  assert(m_xTreeView->IsUpdateMode() && "don't sort when frozen");
4724  m_xTreeView->