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 <com/sun/star/accessibility/AccessibleRelationType.hpp>
21 #include <com/sun/star/awt/XWindow.hpp>
22 #include <officecfg/Office/Common.hxx>
23 #include <iconview.hxx>
24 #include <salframe.hxx>
25 #include <salinst.hxx>
26 #include <salvd.hxx>
27 #include <salprn.hxx>
28 #include <saltimer.hxx>
29 #include <salsession.hxx>
30 #include <salsys.hxx>
31 #include <salbmp.hxx>
32 #include <salobj.hxx>
33 #include <salmenu.hxx>
34 #include <strings.hrc>
35 #include <svdata.hxx>
36 #include <svimpbox.hxx>
37 #include <messagedialog.hxx>
38 #include <treeglue.hxx>
40 #include <unotools/configmgr.hxx>
41 #include <utility>
42 #include <tools/helpers.hxx>
43 #include <vcl/abstdlg.hxx>
44 #include <vcl/builder.hxx>
45 #include <vcl/calendar.hxx>
46 #include <vcl/combobox.hxx>
47 #include <vcl/lstbox.hxx>
48 #include <vcl/dialog.hxx>
49 #include <vcl/fixed.hxx>
51 #include <vcl/fmtfield.hxx>
52 #include <vcl/headbar.hxx>
53 #include <vcl/ivctrl.hxx>
54 #include <vcl/layout.hxx>
55 #include <vcl/menubtn.hxx>
56 #include <vcl/toolkit/prgsbar.hxx>
57 #include <vcl/ptrstyle.hxx>
58 #include <vcl/slider.hxx>
59 #include <vcl/sysdata.hxx>
60 #include <vcl/svlbitm.hxx>
61 #include <vcl/svtabbx.hxx>
62 #include <vcl/tabctrl.hxx>
63 #include <vcl/tabpage.hxx>
64 #include <vcl/treelistentry.hxx>
65 #include <vcl/toolkit/throbber.hxx>
66 #include <vcl/toolkit/unowrap.hxx>
67 #include <vcl/weld.hxx>
68 #include <vcl/vclmedit.hxx>
69 #include <vcl/viewdataentry.hxx>
70 #include <vcl/virdev.hxx>
71 #include <aboutdialog.hxx>
72 #include <bitmaps.hlst>
73 #include <wizdlg.hxx>
74 
76  : m_pWindow(nullptr)
77  , m_pProc(nullptr)
78 {
79 }
80 
81 // this file contains the virtual destructors of the sal interface
82 // compilers usually put their vtables where the destructor is
83 
85 {
86 }
87 
89 {
90  m_pWindow = pWindow;
91  m_pProc = pProc;
92 }
93 
94 // default to full-frame flushes
95 // on ports where partial-flushes are much cheaper this method should be overridden
97 {
98  Flush();
99 }
100 
101 void SalFrame::SetRepresentedURL( const OUString& )
102 {
103  // currently this is Mac only functionality
104 }
105 
106 SalInstance::SalInstance(std::unique_ptr<comphelper::SolarMutex> pMutex)
107  : m_pYieldMutex(std::move(pMutex))
108 {
109 }
110 
112 {
113 }
114 
116 {
117  return m_pYieldMutex.get();
118 }
119 
121 {
122  return m_pYieldMutex->release(true);
123 }
124 
125 void SalInstance::AcquireYieldMutex(sal_uInt32 nCount)
126 {
127  m_pYieldMutex->acquire(nCount);
128 }
129 
130 std::unique_ptr<SalSession> SalInstance::CreateSalSession()
131 {
132  return nullptr;
133 }
134 
135 std::unique_ptr<SalMenu> SalInstance::CreateMenu( bool, Menu* )
136 {
137  // default: no native menus
138  return nullptr;
139 }
140 
141 std::unique_ptr<SalMenuItem> SalInstance::CreateMenuItem( const SalItemParams & )
142 {
143  return nullptr;
144 }
145 
146 bool SalInstance::CallEventCallback( void const * pEvent, int nBytes )
147 {
148  return m_pEventInst.is() && m_pEventInst->dispatchEvent( pEvent, nBytes );
149 }
150 
151 SalTimer::~SalTimer() COVERITY_NOEXCEPT_FALSE
152 {
153 }
154 
156 {
157  if (ImplSVData* pSVData = ImplGetSVData())
158  {
159  auto& rCache = pSVData->maGDIData.maScaleCache;
160  rCache.remove_if([this] (const o3tl::lru_map<SalBitmap*, BitmapEx>::key_value_pair_t& rKeyValuePair)
161  { return rKeyValuePair.first == this; });
162  }
163 }
164 
166 {
167  DropScaledCache();
168 }
169 
171 {
172 }
173 
175 {
176 }
177 
178 bool SalPrinter::StartJob( const OUString*, const OUString&, const OUString&,
180 {
181  return false;
182 }
183 
185 {
186 }
187 
189 {
190 }
191 
193 {
194 }
195 
197 {
198 }
199 
201 {
202  return false;
203 }
204 
206 {
207 }
208 
210 {
211  return false;
212 }
213 
215 {
216 }
217 
219 {
220  return tools::Rectangle();
221 }
222 
224 {
225  return 0;
226 }
227 
229 {
230 }
231 
233 {
234 }
235 
236 class SalInstanceBuilder;
237 
238 namespace {
239 
240 class SalInstanceWidget : public virtual weld::Widget
241 {
242 protected:
243  VclPtr<vcl::Window> m_xWidget;
244  SalInstanceBuilder* m_pBuilder;
245 
246 private:
247  DECL_LINK(EventListener, VclWindowEvent&, void);
248  DECL_LINK(KeyEventListener, VclWindowEvent&, bool);
249  DECL_LINK(MouseEventListener, VclSimpleEvent&, void);
250  DECL_LINK(MnemonicActivateHdl, vcl::Window&, bool);
251 
252  const bool m_bTakeOwnership;
253  bool m_bEventListener;
254  bool m_bKeyEventListener;
255  bool m_bMouseEventListener;
256  int m_nBlockNotify;
257 
258 protected:
259  void ensure_event_listener()
260  {
261  if (!m_bEventListener)
262  {
263  m_xWidget->AddEventListener(LINK(this, SalInstanceWidget, EventListener));
264  m_bEventListener = true;
265  }
266  }
267 
268  // we want the ability to mark key events as handled, so use this variant
269  // for those, we get all keystrokes in this case, so we will need to filter
270  // them later
271  void ensure_key_listener()
272  {
273  if (!m_bKeyEventListener)
274  {
275  Application::AddKeyListener(LINK(this, SalInstanceWidget, KeyEventListener));
276  m_bKeyEventListener = true;
277  }
278  }
279 
280  // we want the ability to know about mouse events that happen in our children
281  // so use this variant, we will need to filter them later
282  void ensure_mouse_listener()
283  {
284  if (!m_bMouseEventListener)
285  {
286  Application::AddEventListener(LINK(this, SalInstanceWidget, MouseEventListener));
287  m_bMouseEventListener = true;
288  }
289  }
290 
291  virtual void HandleEventListener(VclWindowEvent& rEvent);
292  virtual bool HandleKeyEventListener(VclWindowEvent& rEvent);
293  virtual void HandleMouseEventListener(VclSimpleEvent& rEvent);
294 
295  void set_background(const Color& rColor)
296  {
297  m_xWidget->SetControlBackground(rColor);
298  m_xWidget->SetBackground(m_xWidget->GetControlBackground());
299  // turn off WB_CLIPCHILDREN otherwise the bg won't extend "under"
300  // transparent children of the widget
301  m_xWidget->SetStyle(m_xWidget->GetStyle() & ~WB_CLIPCHILDREN);
302  }
303 
304 public:
305  SalInstanceWidget(vcl::Window* pWidget, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
306  : m_xWidget(pWidget)
307  , m_pBuilder(pBuilder)
308  , m_bTakeOwnership(bTakeOwnership)
309  , m_bEventListener(false)
310  , m_bKeyEventListener(false)
311  , m_bMouseEventListener(false)
312  , m_nBlockNotify(0)
313  {
314  }
315 
316  virtual void set_sensitive(bool sensitive) override
317  {
318  m_xWidget->Enable(sensitive);
319  }
320 
321  virtual bool get_sensitive() const override
322  {
323  return m_xWidget->IsEnabled();
324  }
325 
326  virtual bool get_visible() const override
327  {
328  return m_xWidget->IsVisible();
329  }
330 
331  virtual bool is_visible() const override
332  {
333  return m_xWidget->IsReallyVisible();
334  }
335 
336  virtual void set_can_focus(bool bCanFocus) override
337  {
338  auto nStyle = m_xWidget->GetStyle() & ~(WB_TABSTOP | WB_NOTABSTOP);
339  if (bCanFocus)
340  nStyle |= WB_TABSTOP;
341  else
342  nStyle |= WB_NOTABSTOP;
343  m_xWidget->SetStyle(nStyle);
344  }
345 
346  virtual void grab_focus() override
347  {
348  m_xWidget->GrabFocus();
349  }
350 
351  virtual bool has_focus() const override
352  {
353  return m_xWidget->HasFocus();
354  }
355 
356  virtual bool is_active() const override
357  {
358  return m_xWidget->IsActive();
359  }
360 
361  virtual void set_has_default(bool has_default) override
362  {
363  m_xWidget->set_property("has-default", OUString::boolean(has_default));
364  }
365 
366  virtual bool get_has_default() const override
367  {
368  return m_xWidget->GetStyle() & WB_DEFBUTTON;
369  }
370 
371  virtual void show() override
372  {
373  m_xWidget->Show();
374  }
375 
376  virtual void hide() override
377  {
378  m_xWidget->Hide();
379  }
380 
381  virtual void set_size_request(int nWidth, int nHeight) override
382  {
383  m_xWidget->set_width_request(nWidth);
384  m_xWidget->set_height_request(nHeight);
385  }
386 
387  virtual Size get_size_request() const override
388  {
389  return Size(m_xWidget->get_width_request(),
390  m_xWidget->get_height_request());
391  }
392 
393  virtual Size get_preferred_size() const override
394  {
395  return m_xWidget->get_preferred_size();
396  }
397 
398  virtual float get_approximate_digit_width() const override
399  {
400  return m_xWidget->approximate_digit_width();
401  }
402 
403  virtual int get_text_height() const override
404  {
405  return m_xWidget->GetTextHeight();
406  }
407 
408  virtual Size get_pixel_size(const OUString& rText) const override
409  {
410  //TODO, or do I want GetTextBoundRect ?, just using width at the moment anyway
411  return Size(m_xWidget->GetTextWidth(rText), m_xWidget->GetTextHeight());
412  }
413 
414  virtual vcl::Font get_font() override
415  {
416  return m_xWidget->GetPointFont(*m_xWidget);
417  }
418 
419  virtual OString get_buildable_name() const override
420  {
421  return m_xWidget->get_id().toUtf8();
422  }
423 
424  virtual void set_help_id(const OString& rId) override
425  {
426  return m_xWidget->SetHelpId(rId);
427  }
428 
429  virtual OString get_help_id() const override
430  {
431  return m_xWidget->GetHelpId();
432  }
433 
434  virtual void set_grid_left_attach(int nAttach) override
435  {
436  m_xWidget->set_grid_left_attach(nAttach);
437  }
438 
439  virtual int get_grid_left_attach() const override
440  {
441  return m_xWidget->get_grid_left_attach();
442  }
443 
444  virtual void set_grid_width(int nCols) override
445  {
446  m_xWidget->set_grid_width(nCols);
447  }
448 
449  virtual void set_grid_top_attach(int nAttach) override
450  {
451  m_xWidget->set_grid_top_attach(nAttach);
452  }
453 
454  virtual int get_grid_top_attach() const override
455  {
456  return m_xWidget->get_grid_top_attach();
457  }
458 
459  virtual void set_hexpand(bool bExpand) override
460  {
461  m_xWidget->set_hexpand(bExpand);
462  }
463 
464  virtual bool get_hexpand() const override
465  {
466  return m_xWidget->get_hexpand();
467  }
468 
469  virtual void set_vexpand(bool bExpand) override
470  {
471  m_xWidget->set_vexpand(bExpand);
472  }
473 
474  virtual bool get_vexpand() const override
475  {
476  return m_xWidget->get_vexpand();
477  }
478 
479  virtual void set_secondary(bool bSecondary) override
480  {
481  m_xWidget->set_secondary(bSecondary);
482  }
483 
484  virtual void set_margin_top(int nMargin) override
485  {
486  m_xWidget->set_margin_top(nMargin);
487  }
488 
489  virtual void set_margin_bottom(int nMargin) override
490  {
491  m_xWidget->set_margin_bottom(nMargin);
492  }
493 
494  virtual void set_margin_left(int nMargin) override
495  {
496  m_xWidget->set_margin_left(nMargin);
497  }
498 
499  virtual void set_margin_right(int nMargin) override
500  {
501  m_xWidget->set_margin_bottom(nMargin);
502  }
503 
504  virtual int get_margin_top() const override
505  {
506  return m_xWidget->get_margin_top();
507  }
508 
509  virtual int get_margin_bottom() const override
510  {
511  return m_xWidget->get_margin_bottom();
512  }
513 
514  virtual int get_margin_left() const override
515  {
516  return m_xWidget->get_margin_left();
517  }
518 
519  virtual int get_margin_right() const override
520  {
521  return m_xWidget->get_margin_bottom();
522  }
523 
524  virtual void set_accessible_name(const OUString& rName) override
525  {
526  m_xWidget->SetAccessibleName(rName);
527  }
528 
529  virtual OUString get_accessible_name() const override
530  {
531  return m_xWidget->GetAccessibleName();
532  }
533 
534  virtual OUString get_accessible_description() const override
535  {
536  return m_xWidget->GetAccessibleDescription();
537  }
538 
539  virtual void set_accessible_relation_labeled_by(weld::Widget* pLabel) override
540  {
541  vcl::Window* pAtkLabel = pLabel ? dynamic_cast<SalInstanceWidget&>(*pLabel).getWidget() : nullptr;
542  m_xWidget->SetAccessibleRelationLabeledBy(pAtkLabel);
543  }
544 
545  virtual void set_accessible_relation_label_for(weld::Widget* pLabeled) override
546  {
547  vcl::Window* pAtkLabeled = pLabeled ? dynamic_cast<SalInstanceWidget&>(*pLabeled).getWidget() : nullptr;
548  m_xWidget->SetAccessibleRelationLabelFor(pAtkLabeled);
549  }
550 
551  virtual void add_extra_accessible_relation(const css::accessibility::AccessibleRelation &rRelation) override
552  {
553  m_xWidget->AddExtraAccessibleRelation(rRelation);
554  }
555 
556  virtual void clear_extra_accessible_relations() override
557  {
558  m_xWidget->ClearExtraAccessibleRelations();
559  }
560 
561  virtual void set_tooltip_text(const OUString& rTip) override
562  {
563  m_xWidget->SetQuickHelpText(rTip);
564  }
565 
566  virtual OUString get_tooltip_text() const override
567  {
568  return m_xWidget->GetQuickHelpText();
569  }
570 
571  virtual void connect_focus_in(const Link<Widget&, void>& rLink) override
572  {
573  ensure_event_listener();
575  }
576 
577  virtual void connect_mnemonic_activate(const Link<Widget&, bool>& rLink) override
578  {
579  m_xWidget->SetMnemonicActivateHdl(LINK(this, SalInstanceWidget, MnemonicActivateHdl));
581  }
582 
583  virtual void connect_focus_out(const Link<Widget&, void>& rLink) override
584  {
585  ensure_event_listener();
587  }
588 
589  virtual void connect_size_allocate(const Link<const Size&, void>& rLink) override
590  {
591  ensure_event_listener();
593  }
594 
595  virtual void connect_mouse_press(const Link<const MouseEvent&, bool>& rLink) override
596  {
597  ensure_mouse_listener();
599  }
600 
601  virtual void connect_mouse_move(const Link<const MouseEvent&, bool>& rLink) override
602  {
603  ensure_mouse_listener();
605  }
606 
607  virtual void connect_mouse_release(const Link<const MouseEvent&, bool>& rLink) override
608  {
609  ensure_mouse_listener();
611  }
612 
613  virtual void connect_key_press(const Link<const KeyEvent&, bool>& rLink) override
614  {
615  ensure_key_listener();
617  }
618 
619  virtual void connect_key_release(const Link<const KeyEvent&, bool>& rLink) override
620  {
621  ensure_key_listener();
623  }
624 
625  virtual bool get_extents_relative_to(Widget& rRelative, int& x, int &y, int& width, int &height) override
626  {
627  tools::Rectangle aRect(m_xWidget->GetWindowExtentsRelative(dynamic_cast<SalInstanceWidget&>(rRelative).getWidget()));
628  x = aRect.Left();
629  y = aRect.Top();
630  width = aRect.GetWidth();
631  height = aRect.GetHeight();
632  return true;
633  }
634 
635  virtual void grab_add() override
636  {
637  m_xWidget->CaptureMouse();
638  }
639 
640  virtual bool has_grab() const override
641  {
642  return m_xWidget->IsMouseCaptured();
643  }
644 
645  virtual void grab_remove() override
646  {
647  m_xWidget->ReleaseMouse();
648  }
649 
650  virtual bool get_direction() const override
651  {
652  return m_xWidget->IsRTLEnabled();
653  }
654 
655  virtual void set_direction(bool bRTL) override
656  {
657  m_xWidget->EnableRTL(bRTL);
658  }
659 
660  virtual void freeze() override
661  {
662  m_xWidget->SetUpdateMode(false);
663  }
664 
665  virtual void thaw() override
666  {
667  m_xWidget->SetUpdateMode(true);
668  }
669 
670  virtual std::unique_ptr<weld::Container> weld_parent() const override;
671 
672  virtual ~SalInstanceWidget() override
673  {
674  if (m_aMnemonicActivateHdl.IsSet())
676  if (m_bMouseEventListener)
677  Application::RemoveEventListener(LINK(this, SalInstanceWidget, MouseEventListener));
678  if (m_bKeyEventListener)
679  Application::RemoveKeyListener(LINK(this, SalInstanceWidget, KeyEventListener));
680  if (m_bEventListener)
681  m_xWidget->RemoveEventListener(LINK(this, SalInstanceWidget, EventListener));
682  if (m_bTakeOwnership)
683  m_xWidget.disposeAndClear();
684  }
685 
686  vcl::Window* getWidget()
687  {
688  return m_xWidget;
689  }
690 
691  void disable_notify_events()
692  {
693  ++m_nBlockNotify;
694  }
695 
696  bool notify_events_disabled()
697  {
698  return m_nBlockNotify != 0;
699  }
700 
701  void enable_notify_events()
702  {
703  --m_nBlockNotify;
704  }
705 
706  virtual void help_hierarchy_foreach(const std::function<bool(const OString&)>& func) override;
707 
708  virtual OUString strip_mnemonic(const OUString &rLabel) const override
709  {
710  return rLabel.replaceFirst("~", "");
711  }
712 
713  virtual VclPtr<VirtualDevice> create_virtual_device() const override
714  {
715  // create with (annoying) separate alpha layer that LibreOffice itself uses
717  }
718 
719  virtual css::uno::Reference<css::datatransfer::dnd::XDropTarget> get_drop_target() override
720  {
721  return m_xWidget->GetDropTarget();
722  }
723 
724  virtual void set_stack_background() override
725  {
726  set_background(m_xWidget->GetSettings().GetStyleSettings().GetWindowColor());
727  }
728 
729  virtual void set_highlight_background() override
730  {
731  set_background(m_xWidget->GetSettings().GetStyleSettings().GetHighlightColor());
732  }
733 
734  SystemWindow* getSystemWindow()
735  {
736  return m_xWidget->GetSystemWindow();
737  }
738 };
739 
740 }
741 
742 void SalInstanceWidget::HandleEventListener(VclWindowEvent& rEvent)
743 {
744  if (rEvent.GetId() == VclEventId::WindowGetFocus)
745  m_aFocusInHdl.Call(*this);
746  else if (rEvent.GetId() == VclEventId::WindowLoseFocus)
747  m_aFocusOutHdl.Call(*this);
748  else if (rEvent.GetId() == VclEventId::WindowResize)
749  m_aSizeAllocateHdl.Call(m_xWidget->GetSizePixel());
750 }
751 
752 void SalInstanceWidget::HandleMouseEventListener(VclSimpleEvent& rEvent)
753 {
755  {
756  auto& rWinEvent = static_cast<VclWindowEvent&>(rEvent);
757  if (m_xWidget->IsWindowOrChild(rWinEvent.GetWindow()))
758  {
759  const MouseEvent* pMouseEvent = static_cast<const MouseEvent*>(rWinEvent.GetData());
760  m_aMousePressHdl.Call(*pMouseEvent);
761  }
762  }
763  else if (rEvent.GetId() == VclEventId::WindowMouseButtonUp)
764  {
765  auto& rWinEvent = static_cast<VclWindowEvent&>(rEvent);
766  if (m_xWidget->IsWindowOrChild(rWinEvent.GetWindow()))
767  {
768  const MouseEvent* pMouseEvent = static_cast<const MouseEvent*>(rWinEvent.GetData());
769  m_aMouseReleaseHdl.Call(*pMouseEvent);
770  }
771  }
772  else if (rEvent.GetId() == VclEventId::WindowMouseMove)
773  {
774  auto& rWinEvent = static_cast<VclWindowEvent&>(rEvent);
775  if (m_xWidget->IsWindowOrChild(rWinEvent.GetWindow()))
776  {
777  const MouseEvent* pMouseEvent = static_cast<const MouseEvent*>(rWinEvent.GetData());
778  m_aMouseMotionHdl.Call(*pMouseEvent);
779  }
780  }
781 }
782 
783 bool SalInstanceWidget::HandleKeyEventListener(VclWindowEvent& rEvent)
784 {
785  // we get all key events here, ignore them unless we have focus
786  if (!has_focus())
787  return false;
788  if (rEvent.GetId() == VclEventId::WindowKeyInput)
789  {
790  const KeyEvent* pKeyEvent = static_cast<const KeyEvent*>(rEvent.GetData());
791  return m_aKeyPressHdl.Call(*pKeyEvent);
792  }
793  else if (rEvent.GetId() == VclEventId::WindowKeyUp)
794  {
795  const KeyEvent* pKeyEvent = static_cast<const KeyEvent*>(rEvent.GetData());
796  return m_aKeyReleaseHdl.Call(*pKeyEvent);
797  }
798  return false;
799 }
800 
801 IMPL_LINK(SalInstanceWidget, EventListener, VclWindowEvent&, rEvent, void)
802 {
803  HandleEventListener(rEvent);
804 }
805 
806 IMPL_LINK(SalInstanceWidget, KeyEventListener, VclWindowEvent&, rEvent, bool)
807 {
808  return HandleKeyEventListener(rEvent);
809 }
810 
811 IMPL_LINK(SalInstanceWidget, MouseEventListener, VclSimpleEvent&, rEvent, void)
812 {
813  HandleMouseEventListener(rEvent);
814 }
815 
816 IMPL_LINK_NOARG(SalInstanceWidget, MnemonicActivateHdl, vcl::Window&, bool)
817 {
818  return m_aMnemonicActivateHdl.Call(*this);
819 }
820 
821 namespace
822 {
823  Image createImage(const OUString& rImage)
824  {
825  if (rImage.isEmpty())
826  return Image();
827  if (rImage.lastIndexOf('.') != rImage.getLength() - 4)
828  {
829  assert((rImage == "dialog-warning" || rImage == "dialog-error" || rImage == "dialog-information") && "unknown stock image");
830  if (rImage == "dialog-warning")
831  return Image(StockImage::Yes, IMG_WARN);
832  else if (rImage == "dialog-error")
833  return Image(StockImage::Yes, IMG_ERROR);
834  else if (rImage == "dialog-information")
835  return Image(StockImage::Yes, IMG_INFO);
836  }
837  return Image(StockImage::Yes, rImage);
838  }
839 
840  Image createImage(const VirtualDevice& rDevice)
841  {
842  return Image(rDevice.GetBitmapEx(Point(), rDevice.GetOutputSizePixel()));
843  }
844 
845  sal_uInt16 insert_to_menu(sal_uInt16 nLastId, PopupMenu* pMenu, int pos, const OUString& rId, const OUString& rStr,
846  const OUString* pIconName, const VirtualDevice* pImageSurface, bool bCheck)
847  {
848  const sal_uInt16 nNewid = nLastId + 1;
849  pMenu->InsertItem(nNewid, rStr, bCheck ? MenuItemBits::CHECKABLE : MenuItemBits::NONE,
850  OUStringToOString(rId, RTL_TEXTENCODING_UTF8), pos == -1 ? MENU_APPEND : pos);
851  if (pIconName)
852  {
853  pMenu->SetItemImage(nNewid, createImage(*pIconName));
854  }
855  else if (pImageSurface)
856  {
857  pMenu->SetItemImage(nNewid, createImage(*pImageSurface));
858  }
859  return nNewid;
860  }
861 }
862 
863 namespace {
864 
865 class SalInstanceMenu : public weld::Menu
866 {
867 private:
868  VclPtr<PopupMenu> m_xMenu;
869 
870  bool const m_bTakeOwnership;
871  sal_uInt16 m_nLastId;
872 
873  DECL_LINK(SelectMenuHdl, ::Menu*, bool);
874 public:
875  SalInstanceMenu(PopupMenu* pMenu, bool bTakeOwnership)
876  : m_xMenu(pMenu)
877  , m_bTakeOwnership(bTakeOwnership)
878  {
879  const auto nCount = m_xMenu->GetItemCount();
880  m_nLastId = nCount ? pMenu->GetItemId(nCount-1) : 0;
881  m_xMenu->SetSelectHdl(LINK(this, SalInstanceMenu, SelectMenuHdl));
882  }
883  virtual OString popup_at_rect(weld::Widget* pParent, const tools::Rectangle &rRect) override
884  {
885  SalInstanceWidget* pVclWidget = dynamic_cast<SalInstanceWidget*>(pParent);
886  assert(pVclWidget);
887  m_xMenu->Execute(pVclWidget->getWidget(), rRect, PopupMenuFlags::ExecuteDown | PopupMenuFlags::NoMouseUpClose);
888  return m_xMenu->GetCurItemIdent();
889  }
890  virtual void set_sensitive(const OString& rIdent, bool bSensitive) override
891  {
892  m_xMenu->EnableItem(rIdent, bSensitive);
893  }
894  virtual void set_active(const OString& rIdent, bool bActive) override
895  {
896  m_xMenu->CheckItem(rIdent, bActive);
897  }
898  virtual bool get_active(const OString& rIdent) const override
899  {
900  return m_xMenu->IsItemChecked(m_xMenu->GetItemId(rIdent));
901  }
902  virtual void set_label(const OString& rIdent, const OUString& rLabel) override
903  {
904  m_xMenu->SetItemText(m_xMenu->GetItemId(rIdent), rLabel);
905  }
906  virtual void set_visible(const OString& rIdent, bool bShow) override
907  {
908  m_xMenu->ShowItem(m_xMenu->GetItemId(rIdent), bShow);
909  }
910  virtual void clear() override
911  {
912  m_xMenu->Clear();
913  }
914  virtual void insert(int pos, const OUString& rId, const OUString& rStr,
915  const OUString* pIconName, VirtualDevice* pImageSurface, bool bCheck) override
916  {
917  m_nLastId = insert_to_menu(m_nLastId, m_xMenu, pos, rId, rStr, pIconName, pImageSurface, bCheck);
918  }
919  virtual void insert_separator(int pos, const OUString& rId) override
920  {
921  auto nInsertPos = pos == -1 ? MENU_APPEND : pos;
922  m_xMenu->InsertSeparator(rId.toUtf8(), nInsertPos);
923  }
924  PopupMenu* getMenu() const
925  {
926  return m_xMenu.get();
927  }
928  virtual ~SalInstanceMenu() override
929  {
930  m_xMenu->SetSelectHdl(Link<::Menu*, bool>());
931  if (m_bTakeOwnership)
932  m_xMenu.disposeAndClear();
933  }
934 };
935 
936 }
937 
938 IMPL_LINK_NOARG(SalInstanceMenu, SelectMenuHdl, ::Menu*, bool)
939 {
940  signal_activate(m_xMenu->GetCurItemIdent());
941  return true;
942 }
943 
944 namespace {
945 
946 class SalInstanceToolbar : public SalInstanceWidget, public virtual weld::Toolbar
947 {
948 private:
949  VclPtr<ToolBox> m_xToolBox;
950  std::map<sal_uInt16, VclPtr<vcl::Window>> m_aFloats;
951  std::map<sal_uInt16, VclPtr<PopupMenu>> m_aMenus;
952 
953  OString m_sStartShowIdent;
954 
955  DECL_LINK(ClickHdl, ToolBox*, void);
956  DECL_LINK(DropdownClick, ToolBox*, void);
957  DECL_LINK(MenuToggleListener, VclWindowEvent&, void);
958 
959 public:
960  SalInstanceToolbar(ToolBox* pToolBox, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
961  : SalInstanceWidget(pToolBox, pBuilder, bTakeOwnership)
962  , m_xToolBox(pToolBox)
963  {
964  m_xToolBox->SetSelectHdl(LINK(this, SalInstanceToolbar, ClickHdl));
965  m_xToolBox->SetDropdownClickHdl(LINK(this, SalInstanceToolbar, DropdownClick));
966  }
967 
968  virtual void set_item_sensitive(const OString& rIdent, bool bSensitive) override
969  {
970  m_xToolBox->EnableItem(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), bSensitive);
971  }
972 
973  virtual bool get_item_sensitive(const OString& rIdent) const override
974  {
975  return m_xToolBox->IsItemEnabled(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)));
976  }
977 
978  virtual void set_item_visible(const OString& rIdent, bool bVisible) override
979  {
980  m_xToolBox->ShowItem(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), bVisible);
981  }
982 
983  virtual bool get_item_visible(const OString& rIdent) const override
984  {
985  return m_xToolBox->IsItemVisible(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)));
986  }
987 
988  virtual void set_item_active(const OString& rIdent, bool bActive) override
989  {
990  sal_uInt16 nItemId = m_xToolBox->GetItemId(OUString::fromUtf8(rIdent));
991  m_xToolBox->CheckItem(nItemId, bActive);
992  }
993 
994  virtual bool get_item_active(const OString& rIdent) const override
995  {
996  return m_xToolBox->IsItemChecked(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)));
997  }
998 
999  void set_menu_item_active(const OString& rIdent, bool bActive) override
1000  {
1001  sal_uInt16 nItemId = m_xToolBox->GetItemId(OUString::fromUtf8(rIdent));
1002  assert (m_xToolBox->GetItemBits(nItemId) & ToolBoxItemBits::DROPDOWN);
1003 
1004  if (bActive)
1005  {
1006  m_sStartShowIdent = m_xToolBox->GetItemCommand(nItemId).toUtf8();
1007  signal_toggle_menu(m_sStartShowIdent);
1008  }
1009 
1010  auto pFloat = m_aFloats[nItemId];
1011  if (pFloat)
1012  {
1013  if (bActive)
1015  else
1017  }
1018  auto pPopup = m_aMenus[nItemId];
1019  if (pPopup)
1020  {
1021  if (bActive)
1022  {
1023  tools::Rectangle aRect = m_xToolBox->GetItemRect(nItemId);
1024  pPopup->Execute(m_xToolBox, aRect, PopupMenuFlags::ExecuteDown);
1025  }
1026  else
1027  pPopup->EndExecute();
1028  }
1029 
1030  m_sStartShowIdent.clear();
1031  }
1032 
1033  bool get_menu_item_active(const OString& rIdent) const override
1034  {
1035  sal_uInt16 nItemId = m_xToolBox->GetItemId(OUString::fromUtf8(rIdent));
1036  assert (m_xToolBox->GetItemBits(nItemId) & ToolBoxItemBits::DROPDOWN);
1037 
1038  if (rIdent == m_sStartShowIdent)
1039  return true;
1040 
1041  auto aFloat = m_aFloats.find(nItemId);
1042  if (aFloat != m_aFloats.end())
1043  {
1044  return vcl::Window::GetDockingManager()->IsInPopupMode(aFloat->second);
1045  }
1046 
1047  auto aPopup = m_aMenus.find(nItemId);
1048  if (aPopup != m_aMenus.end())
1049  {
1050  return PopupMenu::GetActivePopupMenu() == aPopup->second;
1051  }
1052 
1053  return false;
1054  }
1055 
1056  virtual void set_item_popover(const OString& rIdent, weld::Widget* pPopover) override
1057  {
1058  SalInstanceWidget* pPopoverWidget = dynamic_cast<SalInstanceWidget*>(pPopover);
1059 
1060  vcl::Window* pFloat = pPopoverWidget ? pPopoverWidget->getWidget() : nullptr;
1061  if (pFloat)
1062  {
1063  pFloat->AddEventListener(LINK(this, SalInstanceToolbar, MenuToggleListener));
1064  pFloat->EnableDocking();
1065  }
1066 
1067  sal_uInt16 nId = m_xToolBox->GetItemId(OUString::fromUtf8(rIdent));
1068  auto xOldFloat = m_aFloats[nId];
1069  if (xOldFloat)
1070  {
1071  xOldFloat->RemoveEventListener(LINK(this, SalInstanceToolbar, MenuToggleListener));
1072  }
1073  m_aFloats[nId] = pFloat;
1074  m_aMenus[nId] = nullptr;
1075  }
1076 
1077  virtual void set_item_menu(const OString& rIdent, weld::Menu* pMenu) override
1078  {
1079  SalInstanceMenu* pInstanceMenu = dynamic_cast<SalInstanceMenu*>(pMenu);
1080 
1081  PopupMenu* pPopup = pInstanceMenu? pInstanceMenu->getMenu() : nullptr;
1082 
1083  sal_uInt16 nId = m_xToolBox->GetItemId(OUString::fromUtf8(rIdent));
1084  m_aMenus[nId] = pPopup;
1085  m_aFloats[nId] = nullptr;
1086  }
1087 
1088  virtual void insert_separator(int pos, const OUString& /*rId*/) override
1089  {
1090  auto nInsertPos = pos == -1 ? ToolBox::APPEND : pos;
1091  m_xToolBox->InsertSeparator(nInsertPos, 5);
1092  }
1093 
1094  virtual int get_n_items() const override
1095  {
1096  return m_xToolBox->GetItemCount();
1097  }
1098 
1099  virtual OString get_item_ident(int nIndex) const override
1100  {
1101  return m_xToolBox->GetItemCommand(m_xToolBox->GetItemId(nIndex)).toUtf8();
1102  }
1103 
1104  virtual void set_item_ident(int nIndex, const OString& rIdent) override
1105  {
1106  return m_xToolBox->SetItemCommand(m_xToolBox->GetItemId(nIndex), OUString::fromUtf8(rIdent));
1107  }
1108 
1109  virtual void set_item_label(int nIndex, const OUString& rLabel) override
1110  {
1111  m_xToolBox->SetItemText(m_xToolBox->GetItemId(nIndex), rLabel);
1112  }
1113 
1114  virtual OUString get_item_label(const OString& rIdent) const override
1115  {
1116  return m_xToolBox->GetItemText(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)));
1117  }
1118 
1119  virtual void set_item_label(const OString& rIdent, const OUString& rLabel) override
1120  {
1121  m_xToolBox->SetItemText(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), rLabel);
1122  }
1123 
1124  virtual void set_item_icon_name(const OString& rIdent, const OUString& rIconName) override
1125  {
1126  m_xToolBox->SetItemImage(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), Image(StockImage::Yes, rIconName));
1127  }
1128 
1129  virtual void set_item_image(const OString& rIdent, const css::uno::Reference<css::graphic::XGraphic>& rIcon) override
1130  {
1131  m_xToolBox->SetItemImage(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), Image(rIcon));
1132  }
1133 
1134  virtual void set_item_image(const OString& rIdent, VirtualDevice* pDevice) override
1135  {
1136  if (pDevice)
1137  m_xToolBox->SetItemImage(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), createImage(*pDevice));
1138  else
1139  m_xToolBox->SetItemImage(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), Image());
1140  }
1141 
1142  virtual void set_item_image(int nIndex, const css::uno::Reference<css::graphic::XGraphic>& rIcon) override
1143  {
1144  m_xToolBox->SetItemImage(m_xToolBox->GetItemId(nIndex), Image(rIcon));
1145  }
1146 
1147  virtual void set_item_tooltip_text(int nIndex, const OUString& rTip) override
1148  {
1149  m_xToolBox->SetQuickHelpText(m_xToolBox->GetItemId(nIndex), rTip);
1150  }
1151 
1152  virtual void set_item_tooltip_text(const OString& rIdent, const OUString& rTip) override
1153  {
1154  m_xToolBox->SetQuickHelpText(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), rTip);
1155  }
1156 
1157  virtual OUString get_item_tooltip_text(const OString& rIdent) const override
1158  {
1159  return m_xToolBox->GetQuickHelpText(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)));
1160  }
1161 
1162  virtual vcl::ImageType get_icon_size() const override
1163  {
1164  return m_xToolBox->GetImageSize();
1165  }
1166 
1167  virtual ~SalInstanceToolbar() override
1168  {
1170  m_xToolBox->SetSelectHdl(Link<ToolBox*, void>());
1171  }
1172 };
1173 
1174 }
1175 
1176 IMPL_LINK_NOARG(SalInstanceToolbar, ClickHdl, ToolBox*, void)
1177 {
1178  sal_uInt16 nItemId = m_xToolBox->GetCurItemId();
1179  signal_clicked(m_xToolBox->GetItemCommand(nItemId).toUtf8());
1180 }
1181 
1182 IMPL_LINK_NOARG(SalInstanceToolbar, DropdownClick, ToolBox*, void)
1183 {
1184  sal_uInt16 nItemId = m_xToolBox->GetCurItemId();
1185  set_menu_item_active(m_xToolBox->GetItemCommand(nItemId).toUtf8(), true);
1186 }
1187 
1188 IMPL_LINK(SalInstanceToolbar, MenuToggleListener, VclWindowEvent&, rEvent, void)
1189 {
1190  if (rEvent.GetId() == VclEventId::WindowEndPopupMode)
1191  {
1192  for (auto& rFloat : m_aFloats)
1193  {
1194  if (rEvent.GetWindow() == rFloat.second)
1195  {
1196  sal_uInt16 nItemId = rFloat.first;
1197  signal_toggle_menu(m_xToolBox->GetItemCommand(nItemId).toUtf8());
1198  break;
1199  }
1200  }
1201  }
1202 }
1203 
1204 namespace {
1205 
1206 class SalInstanceSizeGroup : public weld::SizeGroup
1207 {
1208 private:
1209  std::shared_ptr<VclSizeGroup> m_xGroup;
1210 public:
1211  SalInstanceSizeGroup()
1212  : m_xGroup(new VclSizeGroup)
1213  {
1214  }
1215  virtual void add_widget(weld::Widget* pWidget) override
1216  {
1217  SalInstanceWidget* pVclWidget = dynamic_cast<SalInstanceWidget*>(pWidget);
1218  assert(pVclWidget && pVclWidget->getWidget());
1219  pVclWidget->getWidget()->add_to_size_group(m_xGroup);
1220  }
1221  virtual void set_mode(VclSizeGroupMode eMode) override
1222  {
1223  m_xGroup->set_mode(eMode);
1224  }
1225 };
1226 
1227 class SalInstanceContainer : public SalInstanceWidget, public virtual weld::Container
1228 {
1229 protected:
1231 
1232 private:
1233  void implResetDefault(const vcl::Window* _pWindow)
1234  {
1235  vcl::Window* pChildLoop = _pWindow->GetWindow(GetWindowType::FirstChild);
1236  while (pChildLoop)
1237  {
1238  // does the window participate in the tabbing order?
1239  if (pChildLoop->GetStyle() & WB_DIALOGCONTROL)
1240  implResetDefault(pChildLoop);
1241 
1242  // is it a button?
1243  WindowType eType = pChildLoop->GetType();
1244  if ( (WindowType::PUSHBUTTON == eType)
1245  || (WindowType::OKBUTTON == eType)
1246  || (WindowType::CANCELBUTTON == eType)
1247  || (WindowType::HELPBUTTON == eType)
1248  || (WindowType::IMAGEBUTTON == eType)
1249  || (WindowType::MENUBUTTON == eType)
1250  || (WindowType::MOREBUTTON == eType)
1251  )
1252  {
1253  pChildLoop->SetStyle(pChildLoop->GetStyle() & ~WB_DEFBUTTON);
1254  }
1255 
1256  // the next one ...
1257  pChildLoop = pChildLoop->GetWindow(GetWindowType::Next);
1258  }
1259  }
1260 
1261 public:
1262  SalInstanceContainer(vcl::Window* pContainer, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
1263  : SalInstanceWidget(pContainer, pBuilder, bTakeOwnership)
1264  , m_xContainer(pContainer)
1265  {
1266  }
1267  virtual void move(weld::Widget* pWidget, weld::Container* pNewParent) override
1268  {
1269  SalInstanceWidget* pVclWidget = dynamic_cast<SalInstanceWidget*>(pWidget);
1270  assert(pVclWidget);
1271  SalInstanceContainer* pNewVclParent = dynamic_cast<SalInstanceContainer*>(pNewParent);
1272  assert(!pNewParent || pNewVclParent);
1273  pVclWidget->getWidget()->SetParent(pNewVclParent ? pNewVclParent->getWidget() : nullptr);
1274  }
1275  virtual void recursively_unset_default_buttons() override
1276  {
1277  implResetDefault(m_xContainer.get());
1278  }
1279  virtual css::uno::Reference<css::awt::XWindow> CreateChildFrame() override
1280  {
1281  auto xPage = VclPtr<VclBin>::Create(m_xContainer.get());
1282  xPage->set_expand(true);
1283  xPage->Show();
1284  return css::uno::Reference<css::awt::XWindow>(xPage->GetComponentInterface(), css::uno::UNO_QUERY);
1285  }
1286 };
1287 
1288 }
1289 
1290 std::unique_ptr<weld::Container> SalInstanceWidget::weld_parent() const
1291 {
1292  vcl::Window* pParent = m_xWidget->GetParent();
1293  if (!pParent)
1294  return nullptr;
1295  return std::make_unique<SalInstanceContainer>(pParent, m_pBuilder, false);
1296 }
1297 
1298 namespace {
1299 
1300 class SalInstanceBox : public SalInstanceContainer, public virtual weld::Box
1301 {
1302 public:
1303  SalInstanceBox(vcl::Window* pContainer, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
1304  : SalInstanceContainer(pContainer, pBuilder, bTakeOwnership)
1305  {
1306  }
1307  virtual void reorder_child(weld::Widget* pWidget, int nNewPosition) override
1308  {
1309  SalInstanceWidget* pVclWidget = dynamic_cast<SalInstanceWidget*>(pWidget);
1310  assert(pVclWidget);
1311  pVclWidget->getWidget()->reorderWithinParent(nNewPosition);
1312  }
1313 };
1314 
1315  void CollectChildren(const vcl::Window& rCurrent, const basegfx::B2IPoint& rTopLeft, weld::ScreenShotCollection& rControlDataCollection)
1316  {
1317  if (rCurrent.IsVisible())
1318  {
1319  const Point aCurrentPos(rCurrent.GetPosPixel());
1320  const Size aCurrentSize(rCurrent.GetSizePixel());
1321  const basegfx::B2IPoint aCurrentTopLeft(rTopLeft.getX() + aCurrentPos.X(), rTopLeft.getY() + aCurrentPos.Y());
1322  const basegfx::B2IRange aCurrentRange(aCurrentTopLeft, aCurrentTopLeft + basegfx::B2IPoint(aCurrentSize.Width(), aCurrentSize.Height()));
1323 
1324  if (!aCurrentRange.isEmpty())
1325  {
1326  rControlDataCollection.emplace_back(rCurrent.GetHelpId(), aCurrentRange);
1327  }
1328 
1329  for (sal_uInt16 a(0); a < rCurrent.GetChildCount(); a++)
1330  {
1331  vcl::Window* pChild = rCurrent.GetChild(a);
1332  if (nullptr != pChild)
1333  {
1334  CollectChildren(*pChild, aCurrentTopLeft, rControlDataCollection);
1335  }
1336  }
1337  }
1338  }
1339 
1340 class SalInstanceWindow : public SalInstanceContainer, public virtual weld::Window
1341 {
1342 private:
1343  VclPtr<vcl::Window> m_xWindow;
1344 
1345  DECL_LINK(HelpHdl, vcl::Window&, bool);
1346 
1347  void override_child_help(vcl::Window* pParent)
1348  {
1349  for (vcl::Window *pChild = pParent->GetWindow(GetWindowType::FirstChild); pChild; pChild = pChild->GetWindow(GetWindowType::Next))
1350  override_child_help(pChild);
1351  pParent->SetHelpHdl(LINK(this, SalInstanceWindow, HelpHdl));
1352  }
1353 
1354  void clear_child_help(vcl::Window* pParent)
1355  {
1356  for (vcl::Window *pChild = pParent->GetWindow(GetWindowType::FirstChild); pChild; pChild = pChild->GetWindow(GetWindowType::Next))
1357  clear_child_help(pChild);
1358  pParent->SetHelpHdl(Link<vcl::Window&,bool>());
1359  }
1360 
1361 public:
1362  SalInstanceWindow(vcl::Window* pWindow, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
1363  : SalInstanceContainer(pWindow, pBuilder, bTakeOwnership)
1364  , m_xWindow(pWindow)
1365  {
1366  override_child_help(m_xWindow);
1367  }
1368 
1369  virtual void set_title(const OUString& rTitle) override
1370  {
1371  m_xWindow->SetText(rTitle);
1372  }
1373 
1374  virtual OUString get_title() const override
1375  {
1376  return m_xWindow->GetText();
1377  }
1378 
1379  void help();
1380 
1381  virtual void set_busy_cursor(bool bBusy) override
1382  {
1383  if (bBusy)
1384  m_xWindow->EnterWait();
1385  else
1386  m_xWindow->LeaveWait();
1387  }
1388 
1389  virtual css::uno::Reference<css::awt::XWindow> GetXWindow() override
1390  {
1391  css::uno::Reference<css::awt::XWindow> xWindow(m_xWindow->GetComponentInterface(), css::uno::UNO_QUERY);
1392  return xWindow;
1393  }
1394 
1395  virtual void resize_to_request() override
1396  {
1397  if (SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(m_xWindow.get()))
1398  {
1399  pSysWin->setOptimalLayoutSize();
1400  return;
1401  }
1402  if (DockingWindow* pDockWin = dynamic_cast<DockingWindow*>(m_xWindow.get()))
1403  {
1404  pDockWin->setOptimalLayoutSize();
1405  return;
1406  }
1407  assert(false && "must be system or docking window");
1408  }
1409 
1410  virtual void set_modal(bool bModal) override
1411  {
1412  m_xWindow->ImplGetFrame()->SetModal(bModal);
1413  }
1414 
1415  virtual bool get_modal() const override
1416  {
1417  return m_xWindow->ImplGetFrame()->GetModal();
1418  }
1419 
1420  virtual void window_move(int x, int y) override
1421  {
1422  m_xWindow->SetPosPixel(Point(x, y));
1423  }
1424 
1425  virtual Size get_size() const override
1426  {
1427  return m_xWindow->GetSizePixel();
1428  }
1429 
1430  virtual Point get_position() const override
1431  {
1432  return m_xWindow->GetPosPixel();
1433  }
1434 
1435  virtual tools::Rectangle get_monitor_workarea() const override
1436  {
1437  return m_xWindow->GetDesktopRectPixel();
1438  }
1439 
1440  virtual void set_centered_on_parent(bool /*bTrackGeometryRequests*/) override
1441  {
1442  if (vcl::Window* pParent = m_xWidget->GetParent())
1443  {
1444  Size aParentGeometry(pParent->GetSizePixel());
1445  Size aGeometry(m_xWidget->get_preferred_size());
1446  auto nX = (aParentGeometry.Width() - aGeometry.Width()) / 2;
1447  auto nY = (aParentGeometry.Height() - aGeometry.Height()) / 2;
1448  m_xWidget->SetPosPixel(Point(nX, nY));
1449  }
1450  }
1451 
1452  virtual bool get_resizable() const override
1453  {
1454  return m_xWindow->GetStyle() & WB_SIZEABLE;
1455  }
1456 
1457  virtual bool has_toplevel_focus() const override
1458  {
1459  return m_xWindow->HasChildPathFocus();
1460  }
1461 
1462  virtual void present() override
1463  {
1465  }
1466 
1467  virtual void set_window_state(const OString& rStr) override
1468  {
1469  SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(m_xWindow.get());
1470  assert(pSysWin);
1471  pSysWin->SetWindowState(rStr);
1472  }
1473 
1474  virtual OString get_window_state(WindowStateMask nMask) const override
1475  {
1476  SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(m_xWindow.get());
1477  assert(pSysWin);
1478  return pSysWin->GetWindowState(nMask);
1479  }
1480 
1481  virtual SystemEnvData get_system_data() const override
1482  {
1483  return *m_xWindow->GetSystemData();
1484  }
1485 
1486  virtual void connect_toplevel_focus_changed(const Link<weld::Widget&, void>& rLink) override
1487  {
1488  ensure_event_listener();
1490  }
1491 
1492  virtual void HandleEventListener(VclWindowEvent& rEvent) override
1493  {
1494  if (rEvent.GetId() == VclEventId::WindowActivate || rEvent.GetId() == VclEventId::WindowDeactivate)
1495  {
1497  return;
1498  }
1499  SalInstanceContainer::HandleEventListener(rEvent);
1500  }
1501 
1502  virtual void draw(VirtualDevice& rOutput) override
1503  {
1504  SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(m_xWindow.get());
1505  assert(pSysWin);
1506  pSysWin->createScreenshot(rOutput);
1507  }
1508 
1510  {
1512 
1513  // collect all children. Choose start pos to be negative
1514  // of target dialog's position to get all positions relative to (0,0)
1515  const Point aParentPos(m_xWindow->GetPosPixel());
1516  const basegfx::B2IPoint aTopLeft(-aParentPos.X(), -aParentPos.Y());
1517  CollectChildren(*m_xWindow, aTopLeft, aRet);
1518 
1519  return aRet;
1520  }
1521 
1522  virtual ~SalInstanceWindow() override
1523  {
1524  clear_child_help(m_xWindow);
1525  }
1526 };
1527 
1528 }
1529 
1530 IMPL_LINK_NOARG(SalInstanceWindow, HelpHdl, vcl::Window&, bool)
1531 {
1532  help();
1533  return false;
1534 }
1535 
1536 typedef std::set<VclPtr<vcl::Window> > winset;
1537 
1538 namespace
1539 {
1540  void hideUnless(const vcl::Window *pTop, const winset& rVisibleWidgets,
1541  std::vector<VclPtr<vcl::Window> > &rWasVisibleWidgets)
1542  {
1543  for (vcl::Window* pChild = pTop->GetWindow(GetWindowType::FirstChild); pChild;
1544  pChild = pChild->GetWindow(GetWindowType::Next))
1545  {
1546  if (!pChild->IsVisible())
1547  continue;
1548  if (rVisibleWidgets.find(pChild) == rVisibleWidgets.end())
1549  {
1550  rWasVisibleWidgets.emplace_back(pChild);
1551  pChild->Hide();
1552  }
1553  else if (isContainerWindow(pChild))
1554  {
1555  hideUnless(pChild, rVisibleWidgets, rWasVisibleWidgets);
1556  }
1557  }
1558  }
1559 
1560 class SalInstanceDialog : public SalInstanceWindow, public virtual weld::Dialog
1561 {
1562 private:
1564 
1565  // for calc ref dialog that shrink to range selection widgets and resize back
1566  VclPtr<vcl::Window> m_xRefEdit;
1567  std::vector<VclPtr<vcl::Window> > m_aHiddenWidgets; // vector of hidden Controls
1568  long m_nOldEditWidthReq; // Original width request of the input field
1569  sal_Int32 m_nOldBorderWidth; // border width for expanded dialog
1570 
1571  DECL_LINK(PopupScreenShotMenuHdl, const CommandEvent&, bool);
1572 
1573 public:
1574  SalInstanceDialog(::Dialog* pDialog, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
1575  : SalInstanceWindow(pDialog, pBuilder, bTakeOwnership)
1576  , m_xDialog(pDialog)
1577  , m_nOldEditWidthReq(0)
1578  , m_nOldBorderWidth(0)
1579  {
1580  const bool bScreenshotMode(officecfg::Office::Common::Misc::ScreenshotMode::get());
1581  if (bScreenshotMode)
1582  {
1583  m_xDialog->SetPopupMenuHdl(LINK(this, SalInstanceDialog, PopupScreenShotMenuHdl));
1584  }
1585  }
1586 
1587  virtual bool runAsync(std::shared_ptr<weld::DialogController> aOwner, const std::function<void(sal_Int32)> &rEndDialogFn) override
1588  {
1590  aCtx.mxOwnerDialogController = aOwner;
1591  aCtx.maEndDialogFn = rEndDialogFn;
1592  VclButtonBox* pActionArea = m_xDialog->get_action_area();
1593  if (pActionArea)
1594  pActionArea->sort_native_button_order();
1595  return m_xDialog->StartExecuteAsync(aCtx);
1596  }
1597 
1598  virtual bool runAsync(std::shared_ptr<Dialog> const & rxSelf, const std::function<void(sal_Int32)> &rEndDialogFn) override
1599  {
1600  assert( rxSelf.get() == this );
1602  // In order to store a shared_ptr to ourself, we have to have been constructed by make_shared,
1603  // which is that rxSelf enforces.
1604  aCtx.mxOwnerSelf = rxSelf;
1605  aCtx.maEndDialogFn = rEndDialogFn;
1606  VclButtonBox* pActionArea = m_xDialog->get_action_area();
1607  if (pActionArea)
1608  pActionArea->sort_native_button_order();
1609  return m_xDialog->StartExecuteAsync(aCtx);
1610  }
1611 
1612  virtual void collapse(weld::Widget* pEdit, weld::Widget* pButton) override
1613  {
1614  SalInstanceWidget* pVclEdit = dynamic_cast<SalInstanceWidget*>(pEdit);
1615  assert(pVclEdit);
1616  SalInstanceWidget* pVclButton = dynamic_cast<SalInstanceWidget*>(pButton);
1617 
1618  vcl::Window* pRefEdit = pVclEdit->getWidget();
1619  vcl::Window* pRefBtn = pVclButton ? pVclButton->getWidget() : nullptr;
1620 
1621  auto nOldEditWidth = pRefEdit->GetSizePixel().Width();
1622  m_nOldEditWidthReq = pRefEdit->get_width_request();
1623 
1624  //We want just pRefBtn and pRefEdit to be shown
1625  //mark widgets we want to be visible, starting with pRefEdit
1626  //and all its direct parents.
1627  winset aVisibleWidgets;
1628  vcl::Window *pContentArea = m_xDialog->get_content_area();
1629  for (vcl::Window *pCandidate = pRefEdit;
1630  pCandidate && (pCandidate != pContentArea && pCandidate->IsVisible());
1631  pCandidate = pCandidate->GetWindow(GetWindowType::RealParent))
1632  {
1633  aVisibleWidgets.insert(pCandidate);
1634  }
1635  //same again with pRefBtn, except stop if there's a
1636  //shared parent in the existing widgets
1637  for (vcl::Window *pCandidate = pRefBtn;
1638  pCandidate && (pCandidate != pContentArea && pCandidate->IsVisible());
1639  pCandidate = pCandidate->GetWindow(GetWindowType::RealParent))
1640  {
1641  if (aVisibleWidgets.insert(pCandidate).second)
1642  break;
1643  }
1644 
1645  //hide everything except the aVisibleWidgets
1646  hideUnless(pContentArea, aVisibleWidgets, m_aHiddenWidgets);
1647 
1648  // the insert function case has an initially hidden edit widget, so it has
1649  // not start size, so take larger of actual size and size request
1650  pRefEdit->set_width_request(std::max(nOldEditWidth, m_nOldEditWidthReq));
1651  m_nOldBorderWidth = m_xDialog->get_border_width();
1652  m_xDialog->set_border_width(0);
1653  if (vcl::Window *pActionArea = m_xDialog->get_action_area())
1654  pActionArea->Hide();
1655  m_xDialog->setOptimalLayoutSize();
1656  m_xRefEdit = pRefEdit;
1657  }
1658 
1659  virtual void undo_collapse() override
1660  {
1661  // All others: Show();
1662  for (VclPtr<vcl::Window> const & pWindow : m_aHiddenWidgets)
1663  {
1664  pWindow->Show();
1665  }
1666  m_aHiddenWidgets.clear();
1667 
1668  m_xRefEdit->set_width_request(m_nOldEditWidthReq);
1669  m_xRefEdit.clear();
1670  m_xDialog->set_border_width(m_nOldBorderWidth);
1671  if (vcl::Window *pActionArea = m_xDialog->get_action_area())
1672  pActionArea->Show();
1673  m_xDialog->setOptimalLayoutSize();
1674  }
1675 
1676  virtual void SetInstallLOKNotifierHdl(const Link<void*, vcl::ILibreOfficeKitNotifier*>& rLink) override
1677  {
1678  m_xDialog->SetInstallLOKNotifierHdl(rLink);
1679  }
1680 
1681  virtual int run() override
1682  {
1683  VclButtonBox* pActionArea = m_xDialog->get_action_area();
1684  if (pActionArea)
1685  pActionArea->sort_native_button_order();
1686  return m_xDialog->Execute();
1687  }
1688 
1689  virtual void response(int nResponse) override
1690  {
1691  m_xDialog->EndDialog(nResponse);
1692  }
1693 
1694  virtual void add_button(const OUString& rText, int nResponse, const OString& rHelpId) override
1695  {
1696  VclButtonBox* pBox = m_xDialog->get_action_area();
1698  xButton->SetText(rText);
1699  xButton->SetHelpId(rHelpId);
1700 
1701  switch (nResponse)
1702  {
1703  case RET_OK:
1704  xButton->set_id("ok");
1705  break;
1706  case RET_CLOSE:
1707  xButton->set_id("close");
1708  break;
1709  case RET_CANCEL:
1710  xButton->set_id("cancel");
1711  break;
1712  case RET_YES:
1713  xButton->set_id("yes");
1714  break;
1715  case RET_NO:
1716  xButton->set_id("no");
1717  break;
1718  }
1719 
1720  xButton->Show();
1721  m_xDialog->add_button(xButton, nResponse, true);
1722  }
1723 
1724  virtual void set_modal(bool bModal) override
1725  {
1726  if (get_modal() == bModal)
1727  return;
1728  m_xDialog->SetModalInputMode(bModal);
1729  }
1730 
1731  virtual bool get_modal() const override
1732  {
1733  return m_xDialog->IsModalInputMode();
1734  }
1735 
1736  virtual weld::Button* weld_widget_for_response(int nResponse) override;
1737 
1738  virtual void set_default_response(int nResponse) override
1739  {
1740  m_xDialog->set_default_response(nResponse);
1741  }
1742 
1743  virtual Container* weld_content_area() override
1744  {
1745  return new SalInstanceContainer(m_xDialog->get_content_area(), m_pBuilder, false);
1746  }
1747 
1748 };
1749 
1750 }
1751 
1752 IMPL_LINK(SalInstanceDialog, PopupScreenShotMenuHdl, const CommandEvent&, rCEvt, bool)
1753 {
1754  if (CommandEventId::ContextMenu == rCEvt.GetCommand())
1755  {
1756  const Point aMenuPos(rCEvt.GetMousePosPixel());
1758  sal_uInt16 nLocalID(1);
1759 
1760  aMenu->InsertItem(nLocalID, VclResId(SV_BUTTONTEXT_SCREENSHOT));
1761  aMenu->SetHelpText(nLocalID, VclResId(SV_HELPTEXT_SCREENSHOT));
1762  aMenu->SetHelpId(nLocalID, "InteractiveScreenshotMode");
1763  aMenu->EnableItem(nLocalID);
1764 
1765  const sal_uInt16 nId(aMenu->Execute(m_xDialog, aMenuPos));
1766 
1767  // 0 == no selection (so not usable as ID)
1768  if (0 != nId)
1769  {
1770  // open screenshot annotation dialog
1774 
1775  if (pDialog)
1776  {
1777  // currently just execute the dialog, no need to do
1778  // different things for ok/cancel. This may change later,
1779  // for that case use 'if (pDlg->Execute() == RET_OK)'
1780  pDialog->Execute();
1781  }
1782  }
1783 
1784  // consume event when:
1785  // - CommandEventId::ContextMenu
1786  // - bScreenshotMode
1787  return true;
1788  }
1789 
1790  return false;
1791 }
1792 
1793 namespace {
1794 
1795 class SalInstanceMessageDialog : public SalInstanceDialog, public virtual weld::MessageDialog
1796 {
1797 private:
1798  VclPtr<::MessageDialog> m_xMessageDialog;
1799 public:
1800  SalInstanceMessageDialog(::MessageDialog* pDialog, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
1801  : SalInstanceDialog(pDialog, pBuilder, bTakeOwnership)
1802  , m_xMessageDialog(pDialog)
1803  {
1804  }
1805 
1806  virtual void set_primary_text(const OUString& rText) override
1807  {
1808  m_xMessageDialog->set_primary_text(rText);
1809  }
1810 
1811  virtual OUString get_primary_text() const override
1812  {
1813  return m_xMessageDialog->get_primary_text();
1814  }
1815 
1816  virtual void set_secondary_text(const OUString& rText) override
1817  {
1818  m_xMessageDialog->set_secondary_text(rText);
1819  }
1820 
1821  virtual OUString get_secondary_text() const override
1822  {
1823  return m_xMessageDialog->get_secondary_text();
1824  }
1825 
1826  virtual Container* weld_message_area() override
1827  {
1828  return new SalInstanceContainer(m_xMessageDialog->get_message_area(), m_pBuilder, false);
1829  }
1830 };
1831 
1832 class SalInstanceAboutDialog : public SalInstanceDialog, public virtual weld::AboutDialog
1833 {
1834 private:
1835  VclPtr<vcl::AboutDialog> m_xAboutDialog;
1836 public:
1837  SalInstanceAboutDialog(vcl::AboutDialog* pDialog, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
1838  : SalInstanceDialog(pDialog, pBuilder, bTakeOwnership)
1839  , m_xAboutDialog(pDialog)
1840  {
1841  }
1842  virtual void set_version(const OUString& rVersion) override
1843  {
1844  m_xAboutDialog->SetVersion(rVersion);
1845  }
1846  virtual void set_copyright(const OUString& rCopyright) override
1847  {
1848  m_xAboutDialog->SetCopyright(rCopyright);
1849  }
1850  virtual void set_website(const OUString& rURL) override
1851  {
1852  m_xAboutDialog->SetWebsiteLink(rURL);
1853  }
1854  virtual void set_website_label(const OUString& rLabel) override
1855  {
1856  m_xAboutDialog->SetWebsiteLabel(rLabel);
1857  }
1858  virtual OUString get_website_label() const override
1859  {
1860  return m_xAboutDialog->GetWebsiteLabel();
1861  }
1862  virtual void set_logo(const css::uno::Reference<css::graphic::XGraphic>& rImage) override
1863  {
1864  m_xAboutDialog->SetLogo(Image(rImage));
1865  }
1866  virtual void set_background(const css::uno::Reference<css::graphic::XGraphic>& rImage) override
1867  {
1868  m_xAboutDialog->SetBackground(Image(rImage));
1869  }
1870 };
1871 
1872 class SalInstanceAssistant : public SalInstanceDialog, public virtual weld::Assistant
1873 {
1874 private:
1875  VclPtr<vcl::RoadmapWizard> m_xWizard;
1876  std::vector<std::unique_ptr<SalInstanceContainer>> m_aPages;
1877  std::vector<VclPtr<TabPage>> m_aAddedPages;
1878  std::vector<int> m_aIds;
1879  std::vector<VclPtr<VclGrid>> m_aAddedGrids;
1880  Idle m_aUpdateRoadmapIdle;
1881 
1882  int find_page(const OString& rIdent) const
1883  {
1884  for (size_t i = 0; i < m_aAddedPages.size(); ++i)
1885  {
1886  if (m_aAddedPages[i]->get_id().toUtf8() == rIdent)
1887  return i;
1888  }
1889  return -1;
1890  }
1891 
1892  int find_id(int nId) const
1893  {
1894  for (size_t i = 0; i < m_aIds.size(); ++i)
1895  {
1896  if (nId == m_aIds[i])
1897  return i;
1898  }
1899  return -1;
1900  }
1901 
1902  DECL_LINK(OnRoadmapItemSelected, LinkParamNone*, void);
1903  DECL_LINK(UpdateRoadmap_Hdl, Timer*, void);
1904 
1905 public:
1906  SalInstanceAssistant(vcl::RoadmapWizard* pDialog, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
1907  : SalInstanceDialog(pDialog, pBuilder, bTakeOwnership)
1908  , m_xWizard(pDialog)
1909  {
1910  m_xWizard->SetItemSelectHdl(LINK(this, SalInstanceAssistant, OnRoadmapItemSelected));
1911 
1912  m_aUpdateRoadmapIdle.SetInvokeHandler(LINK(this, SalInstanceAssistant, UpdateRoadmap_Hdl));
1913  m_aUpdateRoadmapIdle.SetPriority(TaskPriority::HIGHEST);
1914  }
1915 
1916  virtual int get_current_page() const override
1917  {
1918  return find_id(m_xWizard->GetCurLevel());
1919  }
1920 
1921  virtual int get_n_pages() const override
1922  {
1923  return m_aAddedPages.size();
1924  }
1925 
1926  virtual OString get_page_ident(int nPage) const override
1927  {
1928  return m_aAddedPages[nPage]->get_id().toUtf8();
1929  }
1930 
1931  virtual OString get_current_page_ident() const override
1932  {
1933  return get_page_ident(get_current_page());
1934  }
1935 
1936  virtual void set_current_page(int nPage) override
1937  {
1938  disable_notify_events();
1939 
1940  // take the first shown page as the size for all pages
1941  if (m_xWizard->GetPageSizePixel().Width() == 0)
1942  {
1943  Size aFinalSize;
1944  for (int i = 0, nPages = get_n_pages(); i < nPages; ++i)
1945  {
1946  TabPage* pPage = m_xWizard->GetPage(m_aIds[i]);
1947  assert(pPage);
1948  Size aPageSize(pPage->get_preferred_size());
1949  if (aPageSize.Width() > aFinalSize.Width())
1950  aFinalSize.setWidth(aPageSize.Width());
1951  if (aPageSize.Height() > aFinalSize.Height())
1952  aFinalSize.setHeight(aPageSize.Height());
1953  }
1954  m_xWizard->SetPageSizePixel(aFinalSize);
1955  }
1956 
1957  (void)m_xWizard->ShowPage(m_aIds[nPage]);
1958  enable_notify_events();
1959  }
1960 
1961  virtual void set_current_page(const OString& rIdent) override
1962  {
1963  int nIndex = find_page(rIdent);
1964  if (nIndex == -1)
1965  return;
1966  set_current_page(nIndex);
1967  }
1968 
1969  virtual void set_page_index(const OString& rIdent, int nNewIndex) override
1970  {
1971  int nOldIndex = find_page(rIdent);
1972 
1973  if (nOldIndex == -1)
1974  return;
1975 
1976  if (nOldIndex == nNewIndex)
1977  return;
1978 
1979  disable_notify_events();
1980 
1981  auto entry = std::move(m_aAddedPages[nOldIndex]);
1982  m_aAddedPages.erase(m_aAddedPages.begin() + nOldIndex);
1983  m_aAddedPages.insert(m_aAddedPages.begin() + nNewIndex, std::move(entry));
1984 
1985  int nId = m_aIds[nOldIndex];
1986  m_aIds.erase(m_aIds.begin() + nOldIndex);
1987  m_aIds.insert(m_aIds.begin() + nNewIndex, nId);
1988 
1989  m_aUpdateRoadmapIdle.Start();
1990 
1991  enable_notify_events();
1992  }
1993 
1994  virtual weld::Container* append_page(const OString& rIdent) override
1995  {
1996  VclPtrInstance<TabPage> xPage(m_xWizard);
1997  VclPtrInstance<VclGrid> xGrid(xPage);
1998  xPage->set_id(OUString::fromUtf8(rIdent));
1999  xPage->Show();
2000  xGrid->set_hexpand(true);
2001  xGrid->set_vexpand(true);
2002  xGrid->Show();
2003  m_xWizard->AddPage(xPage);
2004  m_aIds.push_back(m_aAddedPages.size());
2005  m_xWizard->SetPage(m_aIds.back(), xPage);
2006  m_aAddedPages.push_back(xPage);
2007  m_aAddedGrids.push_back(xGrid);
2008 
2009  m_aUpdateRoadmapIdle.Start();
2010 
2011  m_aPages.emplace_back(new SalInstanceContainer(xGrid, m_pBuilder, false));
2012  return m_aPages.back().get();
2013  }
2014 
2015  virtual OUString get_page_title(const OString& rIdent) const override
2016  {
2017  int nIndex = find_page(rIdent);
2018  if (nIndex == -1)
2019  return OUString();
2020  return m_aAddedPages[nIndex]->GetText();
2021  }
2022 
2023  virtual void set_page_title(const OString& rIdent, const OUString& rTitle) override
2024  {
2025  int nIndex = find_page(rIdent);
2026  if (nIndex == -1)
2027  return;
2028  if (m_aAddedPages[nIndex]->GetText() != rTitle)
2029  {
2030  disable_notify_events();
2031  m_aAddedPages[nIndex]->SetText(rTitle);
2032  m_aUpdateRoadmapIdle.Start();
2033  enable_notify_events();
2034  }
2035  }
2036 
2037  virtual void set_page_sensitive(const OString& rIdent, bool bSensitive) override
2038  {
2039  int nIndex = find_page(rIdent);
2040  if (nIndex == -1)
2041  return;
2042  if (m_aAddedPages[nIndex]->IsEnabled() != bSensitive)
2043  {
2044  disable_notify_events();
2045  m_aAddedPages[nIndex]->Enable(bSensitive);
2046  m_aUpdateRoadmapIdle.Start();
2047  enable_notify_events();
2048  }
2049  }
2050 
2051  virtual void set_page_side_help_id(const OString& rHelpId) override
2052  {
2053  m_xWizard->SetRoadmapHelpId(rHelpId);
2054  }
2055 
2056  weld::Button* weld_widget_for_response(int nResponse) override;
2057 
2058  virtual ~SalInstanceAssistant() override
2059  {
2060  for (auto &rGrid : m_aAddedGrids)
2061  rGrid.disposeAndClear();
2062  for (auto &rPage : m_aAddedPages)
2063  rPage.disposeAndClear();
2064  }
2065 };
2066 
2067 }
2068 
2069 IMPL_LINK_NOARG(SalInstanceAssistant, OnRoadmapItemSelected, LinkParamNone*, void)
2070 {
2071  if (notify_events_disabled())
2072  return;
2073  int nPageIndex(find_id(m_xWizard->GetCurrentRoadmapItemID()));
2074  if (!signal_jump_page(get_page_ident(nPageIndex)))
2075  m_xWizard->SelectRoadmapItemByID(m_xWizard->GetCurLevel());
2076 }
2077 
2078 IMPL_LINK_NOARG(SalInstanceAssistant, UpdateRoadmap_Hdl, Timer*, void)
2079 {
2080  disable_notify_events();
2081 
2082  m_xWizard->DeleteRoadmapItems();
2083 
2084  int nPos = 0;
2085  for (size_t i = 0; i < m_aAddedPages.size(); ++i)
2086  {
2087  const OUString& rLabel = m_aAddedPages[i]->GetText();
2088  bool bSensitive = m_aAddedPages[i]->IsEnabled();
2089  if (rLabel.isEmpty())
2090  continue;
2091  m_xWizard->InsertRoadmapItem(nPos++, rLabel, m_aIds[i], bSensitive);
2092  }
2093 
2094  m_xWizard->SelectRoadmapItemByID(m_aIds[get_current_page()]);
2095 
2096  m_xWizard->ShowRoadmap(nPos != 0);
2097 
2098  enable_notify_events();
2099 }
2100 
2101 namespace {
2102 
2103 class SalInstanceFrame : public SalInstanceContainer, public virtual weld::Frame
2104 {
2105 private:
2107 public:
2108  SalInstanceFrame(VclFrame* pFrame, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2109  : SalInstanceContainer(pFrame, pBuilder, bTakeOwnership)
2110  , m_xFrame(pFrame)
2111  {
2112  }
2113 
2114  virtual void set_label(const OUString& rText) override
2115  {
2116  m_xFrame->set_label(rText);
2117  }
2118 
2119  virtual OUString get_label() const override
2120  {
2121  return m_xFrame->get_label();
2122  }
2123 
2124  virtual std::unique_ptr<weld::Label> weld_label_widget() const override;
2125 };
2126 
2127 class SalInstanceScrolledWindow : public SalInstanceContainer, public virtual weld::ScrolledWindow
2128 {
2129 private:
2130  VclPtr<VclScrolledWindow> m_xScrolledWindow;
2131  Link<ScrollBar*,void> m_aOrigVScrollHdl;
2132  Link<ScrollBar*,void> m_aOrigHScrollHdl;
2133  bool m_bUserManagedScrolling;
2134 
2135  DECL_LINK(VscrollHdl, ScrollBar*, void);
2136  DECL_LINK(HscrollHdl, ScrollBar*, void);
2137 
2138 public:
2139  SalInstanceScrolledWindow(VclScrolledWindow* pScrolledWindow, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2140  : SalInstanceContainer(pScrolledWindow, pBuilder, bTakeOwnership)
2141  , m_xScrolledWindow(pScrolledWindow)
2142  , m_bUserManagedScrolling(false)
2143  {
2144  ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2145  m_aOrigVScrollHdl = rVertScrollBar.GetScrollHdl();
2146  rVertScrollBar.SetScrollHdl(LINK(this, SalInstanceScrolledWindow, VscrollHdl));
2147  ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2148  m_aOrigHScrollHdl = rHorzScrollBar.GetScrollHdl();
2149  rHorzScrollBar.SetScrollHdl(LINK(this, SalInstanceScrolledWindow, HscrollHdl));
2150  }
2151 
2152  virtual void hadjustment_configure(int value, int lower, int upper,
2153  int step_increment, int page_increment,
2154  int page_size) override
2155  {
2156  ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2157  rHorzScrollBar.SetRangeMin(lower);
2158  rHorzScrollBar.SetRangeMax(upper);
2159  rHorzScrollBar.SetLineSize(step_increment);
2160  rHorzScrollBar.SetPageSize(page_increment);
2161  rHorzScrollBar.SetThumbPos(value);
2162  rHorzScrollBar.SetVisibleSize(page_size);
2163  }
2164 
2165  virtual int hadjustment_get_value() const override
2166  {
2167  ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2168  return rHorzScrollBar.GetThumbPos();
2169  }
2170 
2171  virtual void hadjustment_set_value(int value) override
2172  {
2173  ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2174  rHorzScrollBar.SetThumbPos(value);
2175  if (!m_bUserManagedScrolling)
2176  m_aOrigHScrollHdl.Call(&rHorzScrollBar);
2177  }
2178 
2179  virtual int hadjustment_get_upper() const override
2180  {
2181  ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2182  return rHorzScrollBar.GetRangeMax();
2183  }
2184 
2185  virtual void hadjustment_set_upper(int upper) override
2186  {
2187  ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2188  rHorzScrollBar.SetRangeMax(upper);
2189  }
2190 
2191  virtual int hadjustment_get_page_size() const override
2192  {
2193  ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2194  return rHorzScrollBar.GetVisibleSize();
2195  }
2196 
2197  virtual void hadjustment_set_page_size(int size) override
2198  {
2199  ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2200  return rHorzScrollBar.SetVisibleSize(size);
2201  }
2202 
2203  virtual void hadjustment_set_page_increment(int size) override
2204  {
2205  ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2206  return rHorzScrollBar.SetPageSize(size);
2207  }
2208 
2209  virtual void hadjustment_set_step_increment(int size) override
2210  {
2211  ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2212  return rHorzScrollBar.SetLineSize(size);
2213  }
2214 
2215  virtual void set_hpolicy(VclPolicyType eHPolicy) override
2216  {
2217  WinBits nWinBits = m_xScrolledWindow->GetStyle() & ~(WB_AUTOHSCROLL|WB_HSCROLL);
2218  if (eHPolicy == VclPolicyType::ALWAYS)
2219  nWinBits |= WB_HSCROLL;
2220  else if (eHPolicy == VclPolicyType::AUTOMATIC)
2221  nWinBits |= WB_AUTOHSCROLL;
2222  m_xScrolledWindow->SetStyle(nWinBits);
2223  m_xScrolledWindow->queue_resize();
2224  }
2225 
2226  virtual VclPolicyType get_hpolicy() const override
2227  {
2228  WinBits nWinBits = m_xScrolledWindow->GetStyle();
2229  if (nWinBits & WB_AUTOHSCROLL)
2230  return VclPolicyType::AUTOMATIC;
2231  else if (nWinBits & WB_HSCROLL)
2232  return VclPolicyType::ALWAYS;
2233  return VclPolicyType::NEVER;
2234  }
2235 
2236  virtual int get_hscroll_height() const override
2237  {
2238  return m_xScrolledWindow->getHorzScrollBar().get_preferred_size().Height();
2239  }
2240 
2241  virtual void vadjustment_configure(int value, int lower, int upper,
2242  int step_increment, int page_increment,
2243  int page_size) override
2244  {
2245  ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2246  rVertScrollBar.SetRangeMin(lower);
2247  rVertScrollBar.SetRangeMax(upper);
2248  rVertScrollBar.SetLineSize(step_increment);
2249  rVertScrollBar.SetPageSize(page_increment);
2250  rVertScrollBar.SetThumbPos(value);
2251  rVertScrollBar.SetVisibleSize(page_size);
2252  }
2253 
2254  virtual int vadjustment_get_value() const override
2255  {
2256  ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2257  return rVertScrollBar.GetThumbPos();
2258  }
2259 
2260  virtual void vadjustment_set_value(int value) override
2261  {
2262  ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2263  rVertScrollBar.SetThumbPos(value);
2264  if (!m_bUserManagedScrolling)
2265  m_aOrigVScrollHdl.Call(&rVertScrollBar);
2266  }
2267 
2268  virtual int vadjustment_get_upper() const override
2269  {
2270  ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2271  return rVertScrollBar.GetRangeMax();
2272  }
2273 
2274  virtual void vadjustment_set_upper(int upper) override
2275  {
2276  ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2277  rVertScrollBar.SetRangeMax(upper);
2278  }
2279 
2280  virtual int vadjustment_get_lower() const override
2281  {
2282  ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2283  return rVertScrollBar.GetRangeMin();
2284  }
2285 
2286  virtual void vadjustment_set_lower(int lower) override
2287  {
2288  ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2289  rVertScrollBar.SetRangeMin(lower);
2290  }
2291 
2292  virtual int vadjustment_get_page_size() const override
2293  {
2294  ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2295  return rVertScrollBar.GetVisibleSize();
2296  }
2297 
2298  virtual void vadjustment_set_page_size(int size) override
2299  {
2300  ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2301  return rVertScrollBar.SetVisibleSize(size);
2302  }
2303 
2304  virtual void vadjustment_set_page_increment(int size) override
2305  {
2306  ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2307  return rVertScrollBar.SetPageSize(size);
2308  }
2309 
2310  virtual void vadjustment_set_step_increment(int size) override
2311  {
2312  ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2313  return rVertScrollBar.SetLineSize(size);
2314  }
2315 
2316  virtual void set_vpolicy(VclPolicyType eVPolicy) override
2317  {
2318  WinBits nWinBits = m_xScrolledWindow->GetStyle() & ~(WB_AUTOVSCROLL|WB_VSCROLL);
2319  if (eVPolicy == VclPolicyType::ALWAYS)
2320  nWinBits |= WB_VSCROLL;
2321  else if (eVPolicy == VclPolicyType::AUTOMATIC)
2322  nWinBits |= WB_AUTOVSCROLL;
2323  m_xScrolledWindow->SetStyle(nWinBits);
2324  m_xScrolledWindow->queue_resize();
2325  }
2326 
2327  virtual VclPolicyType get_vpolicy() const override
2328  {
2329  WinBits nWinBits = m_xScrolledWindow->GetStyle();
2330  if (nWinBits & WB_AUTOVSCROLL)
2331  return VclPolicyType::AUTOMATIC;
2332  else if (nWinBits & WB_VSCROLL)
2333  return VclPolicyType::ALWAYS;
2334  return VclPolicyType::NEVER;
2335  }
2336 
2337  virtual int get_vscroll_width() const override
2338  {
2339  return m_xScrolledWindow->getVertScrollBar().get_preferred_size().Width();
2340  }
2341 
2342  virtual void set_user_managed_scrolling() override
2343  {
2344  m_bUserManagedScrolling = true;
2345  m_xScrolledWindow->setUserManagedScrolling(true);
2346  }
2347 
2348  virtual ~SalInstanceScrolledWindow() override
2349  {
2350  ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2351  rVertScrollBar.SetScrollHdl(m_aOrigVScrollHdl);
2352  }
2353 };
2354 
2355 }
2356 
2357 IMPL_LINK(SalInstanceScrolledWindow, VscrollHdl, ScrollBar*, pScrollBar, void)
2358 {
2359  signal_vadjustment_changed();
2360  if (!m_bUserManagedScrolling)
2361  m_aOrigVScrollHdl.Call(pScrollBar);
2362 }
2363 
2364 IMPL_LINK_NOARG(SalInstanceScrolledWindow, HscrollHdl, ScrollBar*, void)
2365 {
2366  signal_hadjustment_changed();
2367  if (!m_bUserManagedScrolling)
2368  m_aOrigHScrollHdl.Call(&m_xScrolledWindow->getHorzScrollBar());
2369 }
2370 
2371 namespace {
2372 
2373 class SalInstanceNotebook : public SalInstanceContainer, public virtual weld::Notebook
2374 {
2375 private:
2376  VclPtr<TabControl> m_xNotebook;
2377  mutable std::vector<std::unique_ptr<SalInstanceContainer>> m_aPages;
2378  std::map<OString, std::pair<VclPtr<TabPage>, VclPtr<VclGrid>>> m_aAddedPages;
2379 
2380  DECL_LINK(DeactivatePageHdl, TabControl*, bool);
2381  DECL_LINK(ActivatePageHdl, TabControl*, void);
2382 
2383 public:
2384  SalInstanceNotebook(TabControl* pNotebook, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2385  : SalInstanceContainer(pNotebook, pBuilder, bTakeOwnership)
2386  , m_xNotebook(pNotebook)
2387  {
2388  m_xNotebook->SetActivatePageHdl(LINK(this, SalInstanceNotebook, ActivatePageHdl));
2389  m_xNotebook->SetDeactivatePageHdl(LINK(this, SalInstanceNotebook, DeactivatePageHdl));
2390  }
2391 
2392  virtual int get_current_page() const override
2393  {
2394  return m_xNotebook->GetPagePos(m_xNotebook->GetCurPageId());
2395  }
2396 
2397  virtual OString get_page_ident(int nPage) const override
2398  {
2399  return m_xNotebook->GetPageName(m_xNotebook->GetPageId(nPage));
2400  }
2401 
2402  virtual OString get_current_page_ident() const override
2403  {
2404  return m_xNotebook->GetPageName(m_xNotebook->GetCurPageId());
2405  }
2406 
2407  virtual weld::Container* get_page(const OString& rIdent) const override
2408  {
2409  sal_uInt16 nPageId = m_xNotebook->GetPageId(rIdent);
2410  sal_uInt16 nPageIndex = m_xNotebook->GetPagePos(nPageId);
2411  if (nPageIndex == TAB_PAGE_NOTFOUND)
2412  return nullptr;
2413  TabPage* pPage = m_xNotebook->GetTabPage(nPageId);
2414  vcl::Window* pChild = pPage->GetChild(0);
2415  if (m_aPages.size() < nPageIndex + 1U)
2416  m_aPages.resize(nPageIndex + 1U);
2417  if (!m_aPages[nPageIndex])
2418  m_aPages[nPageIndex].reset(new SalInstanceContainer(pChild, m_pBuilder, false));
2419  return m_aPages[nPageIndex].get();
2420  }
2421 
2422  virtual void set_current_page(int nPage) override
2423  {
2424  m_xNotebook->SetCurPageId(m_xNotebook->GetPageId(nPage));
2425  }
2426 
2427  virtual void set_current_page(const OString& rIdent) override
2428  {
2429  m_xNotebook->SetCurPageId(m_xNotebook->GetPageId(rIdent));
2430  }
2431 
2432  virtual void remove_page(const OString& rIdent) override
2433  {
2434  sal_uInt16 nPageId = m_xNotebook->GetPageId(rIdent);
2435  sal_uInt16 nPageIndex = m_xNotebook->GetPagePos(nPageId);
2436  if (nPageIndex == TAB_PAGE_NOTFOUND)
2437  return;
2438 
2439  m_xNotebook->RemovePage(nPageId);
2440  if (nPageIndex < m_aPages.size())
2441  m_aPages.erase(m_aPages.begin() + nPageIndex);
2442 
2443  auto iter = m_aAddedPages.find(rIdent);
2444  if (iter != m_aAddedPages.end())
2445  {
2446  iter->second.second.disposeAndClear();
2447  iter->second.first.disposeAndClear();
2448  m_aAddedPages.erase(iter);
2449  }
2450  }
2451 
2452  virtual void insert_page(const OString& rIdent, const OUString& rLabel, int nPos) override
2453  {
2454  sal_uInt16 nPageCount = m_xNotebook->GetPageCount();
2455  sal_uInt16 nLastPageId = nPageCount ? m_xNotebook->GetPageId(nPageCount - 1) : 0;
2456  sal_uInt16 nNewPageId = nLastPageId + 1;
2457  m_xNotebook->InsertPage(nNewPageId, rLabel, nPos == -1 ? TAB_APPEND : nPos);
2458  VclPtrInstance<TabPage> xPage(m_xNotebook);
2459  VclPtrInstance<VclGrid> xGrid(xPage);
2460  xPage->Show();
2461  xGrid->set_hexpand(true);
2462  xGrid->set_vexpand(true);
2463  xGrid->Show();
2464  m_xNotebook->SetTabPage(nNewPageId, xPage);
2465  m_xNotebook->SetPageName(nNewPageId, rIdent);
2466  m_aAddedPages.try_emplace(rIdent, xPage, xGrid);
2467  }
2468 
2469  virtual int get_n_pages() const override
2470  {
2471  return m_xNotebook->GetPageCount();
2472  }
2473 
2474  virtual OUString get_tab_label_text(const OString& rIdent) const override
2475  {
2476  return m_xNotebook->GetPageText(m_xNotebook->GetPageId(rIdent));
2477  }
2478 
2479  virtual void set_tab_label_text(const OString& rIdent, const OUString& rText) override
2480  {
2481  return m_xNotebook->SetPageText(m_xNotebook->GetPageId(rIdent), rText);
2482  }
2483 
2484  virtual ~SalInstanceNotebook() override
2485  {
2486  for (auto &rItem : m_aAddedPages)
2487  {
2488  rItem.second.second.disposeAndClear();
2489  rItem.second.first.disposeAndClear();
2490  }
2493  }
2494 };
2495 
2496 }
2497 
2498 IMPL_LINK_NOARG(SalInstanceNotebook, DeactivatePageHdl, TabControl*, bool)
2499 {
2500  return !m_aLeavePageHdl.IsSet() || m_aLeavePageHdl.Call(get_current_page_ident());
2501 }
2502 
2503 IMPL_LINK_NOARG(SalInstanceNotebook, ActivatePageHdl, TabControl*, void)
2504 {
2505  m_aEnterPageHdl.Call(get_current_page_ident());
2506 }
2507 
2508 namespace {
2509 
2510 class SalInstanceVerticalNotebook : public SalInstanceContainer, public virtual weld::Notebook
2511 {
2512 private:
2513  VclPtr<VerticalTabControl> m_xNotebook;
2514  mutable std::vector<std::unique_ptr<SalInstanceContainer>> m_aPages;
2515 
2516  DECL_LINK(DeactivatePageHdl, VerticalTabControl*, bool);
2517  DECL_LINK(ActivatePageHdl, VerticalTabControl*, void);
2518 
2519 public:
2520  SalInstanceVerticalNotebook(VerticalTabControl* pNotebook, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2521  : SalInstanceContainer(pNotebook, pBuilder, bTakeOwnership)
2522  , m_xNotebook(pNotebook)
2523  {
2524  m_xNotebook->SetActivatePageHdl(LINK(this, SalInstanceVerticalNotebook, ActivatePageHdl));
2525  m_xNotebook->SetDeactivatePageHdl(LINK(this, SalInstanceVerticalNotebook, DeactivatePageHdl));
2526  }
2527 
2528  virtual int get_current_page() const override
2529  {
2530  return m_xNotebook->GetPagePos(m_xNotebook->GetCurPageId());
2531  }
2532 
2533  virtual OString get_page_ident(int nPage) const override
2534  {
2535  return m_xNotebook->GetPageId(nPage);
2536  }
2537 
2538  virtual OString get_current_page_ident() const override
2539  {
2540  return m_xNotebook->GetCurPageId();
2541  }
2542 
2543  virtual weld::Container* get_page(const OString& rIdent) const override
2544  {
2545  sal_uInt16 nPageIndex = m_xNotebook->GetPagePos(rIdent);
2546  if (nPageIndex == TAB_PAGE_NOTFOUND)
2547  return nullptr;
2548  auto pChild = m_xNotebook->GetPage(rIdent);
2549  if (m_aPages.size() < nPageIndex + 1U)
2550  m_aPages.resize(nPageIndex + 1U);
2551  if (!m_aPages[nPageIndex])
2552  m_aPages[nPageIndex].reset(new SalInstanceContainer(pChild, m_pBuilder, false));
2553  return m_aPages[nPageIndex].get();
2554  }
2555 
2556  virtual void set_current_page(int nPage) override
2557  {
2558  m_xNotebook->SetCurPageId(m_xNotebook->GetPageId(nPage));
2559  }
2560 
2561  virtual void set_current_page(const OString& rIdent) override
2562  {
2563  m_xNotebook->SetCurPageId(rIdent);
2564  }
2565 
2566  virtual void remove_page(const OString& rIdent) override
2567  {
2568  sal_uInt16 nPageIndex = m_xNotebook->GetPagePos(rIdent);
2569  if (nPageIndex == TAB_PAGE_NOTFOUND)
2570  return;
2571  m_xNotebook->RemovePage(rIdent);
2572  if (nPageIndex < m_aPages.size())
2573  m_aPages.erase(m_aPages.begin() + nPageIndex);
2574  }
2575 
2576  virtual void insert_page(const OString& rIdent, const OUString& rLabel, int nPos) override
2577  {
2578  VclPtrInstance<VclGrid> xGrid(m_xNotebook->GetPageParent());
2579  xGrid->set_hexpand(true);
2580  xGrid->set_vexpand(true);
2581  m_xNotebook->InsertPage(rIdent, rLabel, Image(), "", xGrid, nPos);
2582  }
2583 
2584  virtual int get_n_pages() const override
2585  {
2586  return m_xNotebook->GetPageCount();
2587  }
2588 
2589  virtual void set_tab_label_text(const OString& rIdent, const OUString& rText) override
2590  {
2591  return m_xNotebook->SetPageText(rIdent, rText);
2592  }
2593 
2594  virtual OUString get_tab_label_text(const OString& rIdent) const override
2595  {
2596  return m_xNotebook->GetPageText(rIdent);
2597  }
2598 
2599  virtual ~SalInstanceVerticalNotebook() override
2600  {
2603  }
2604 };
2605 
2606 }
2607 
2608 IMPL_LINK_NOARG(SalInstanceVerticalNotebook, DeactivatePageHdl, VerticalTabControl*, bool)
2609 {
2610  return !m_aLeavePageHdl.IsSet() || m_aLeavePageHdl.Call(get_current_page_ident());
2611 }
2612 
2613 IMPL_LINK_NOARG(SalInstanceVerticalNotebook, ActivatePageHdl, VerticalTabControl*, void)
2614 {
2615  m_aEnterPageHdl.Call(get_current_page_ident());
2616 }
2617 
2618 namespace {
2619 
2620 class SalInstanceButton : public SalInstanceContainer, public virtual weld::Button
2621 {
2622 private:
2623  VclPtr<::Button> m_xButton;
2624  Link<::Button*,void> const m_aOldClickHdl;
2625 
2626  DECL_LINK(ClickHdl, ::Button*, void);
2627 public:
2628  SalInstanceButton(::Button* pButton, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2629  : SalInstanceContainer(pButton, pBuilder, bTakeOwnership)
2630  , m_xButton(pButton)
2631  , m_aOldClickHdl(pButton->GetClickHdl())
2632  {
2633  m_xButton->SetClickHdl(LINK(this, SalInstanceButton, ClickHdl));
2634  }
2635 
2636  virtual void set_label(const OUString& rText) override
2637  {
2638  m_xButton->SetText(rText);
2639  }
2640 
2641  virtual void set_image(VirtualDevice* pDevice) override
2642  {
2643  m_xButton->SetImageAlign(ImageAlign::Left);
2644  if (pDevice)
2645  m_xButton->SetModeImage(createImage(*pDevice));
2646  else
2647  m_xButton->SetModeImage(Image());
2648  }
2649 
2650  virtual void set_image(const css::uno::Reference<css::graphic::XGraphic>& rImage) override
2651  {
2652  m_xButton->SetImageAlign(ImageAlign::Left);
2653  m_xButton->SetModeImage(Image(rImage));
2654  }
2655 
2656  virtual void set_from_icon_name(const OUString& rIconName) override
2657  {
2658  m_xButton->SetModeImage(Image(StockImage::Yes, rIconName));
2659  }
2660 
2661  virtual void set_label_line_wrap(bool wrap) override
2662  {
2663  WinBits nBits = m_xButton->GetStyle();
2664  nBits &= ~WB_WORDBREAK;
2665  if (wrap)
2666  nBits |= WB_WORDBREAK;
2667  m_xButton->SetStyle(nBits);
2668  m_xButton->queue_resize();
2669  }
2670 
2671  virtual OUString get_label() const override
2672  {
2673  return m_xButton->GetText();
2674  }
2675 
2676  virtual ~SalInstanceButton() override
2677  {
2678  m_xButton->SetClickHdl(Link<::Button*,void>());
2679  }
2680 };
2681 
2682 }
2683 
2684 IMPL_LINK(SalInstanceButton, ClickHdl, ::Button*, pButton, void)
2685 {
2686  //if there's no handler set, disengage our intercept and
2687  //run the click again to get default behaviour for cancel/ok
2688  //etc buttons.
2689  if (!m_aClickHdl.IsSet())
2690  {
2691  pButton->SetClickHdl(m_aOldClickHdl);
2692  pButton->Click();
2693  pButton->SetClickHdl(LINK(this, SalInstanceButton, ClickHdl));
2694  return;
2695  }
2696  signal_clicked();
2697 }
2698 
2699 weld::Button* SalInstanceDialog::weld_widget_for_response(int nResponse)
2700 {
2701  PushButton* pButton = dynamic_cast<PushButton*>(m_xDialog->get_widget_for_response(nResponse));
2702  return pButton ? new SalInstanceButton(pButton, nullptr, false) : nullptr;
2703 }
2704 
2705 weld::Button* SalInstanceAssistant::weld_widget_for_response(int nResponse)
2706 {
2707  PushButton* pButton = nullptr;
2708  if (nResponse == RET_YES)
2709  pButton = m_xWizard->m_pNextPage;
2710  else if (nResponse == RET_NO)
2711  pButton = m_xWizard->m_pPrevPage;
2712  else if (nResponse == RET_OK)
2713  pButton = m_xWizard->m_pFinish;
2714  else if (nResponse == RET_CANCEL)
2715  pButton = m_xWizard->m_pCancel;
2716  else if (nResponse == RET_HELP)
2717  pButton = m_xWizard->m_pHelp;
2718  if (pButton)
2719  return new SalInstanceButton(pButton, nullptr, false);
2720  return nullptr;
2721 }
2722 
2723 namespace {
2724 
2725 class SalInstanceMenuButton : public SalInstanceButton, public virtual weld::MenuButton
2726 {
2727 private:
2728  VclPtr<::MenuButton> m_xMenuButton;
2729  sal_uInt16 m_nLastId;
2730 
2731  DECL_LINK(MenuSelectHdl, ::MenuButton*, void);
2732  DECL_LINK(ActivateHdl, ::MenuButton*, void);
2733 
2734 public:
2735  SalInstanceMenuButton(::MenuButton* pButton, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2736  : SalInstanceButton(pButton, pBuilder, bTakeOwnership)
2737  , m_xMenuButton(pButton)
2738  , m_nLastId(0)
2739  {
2740  m_xMenuButton->SetActivateHdl(LINK(this, SalInstanceMenuButton, ActivateHdl));
2741  m_xMenuButton->SetSelectHdl(LINK(this, SalInstanceMenuButton, MenuSelectHdl));
2742  if (PopupMenu* pMenu = m_xMenuButton->GetPopupMenu())
2743  {
2744  pMenu->SetMenuFlags(MenuFlags::NoAutoMnemonics);
2745  const auto nCount = pMenu->GetItemCount();
2746  m_nLastId = nCount ? pMenu->GetItemId(nCount-1) : 0;
2747  }
2748  }
2749 
2750  virtual void set_active(bool active) override
2751  {
2752  if (active == get_active())
2753  return;
2754  if (active)
2755  m_xMenuButton->ExecuteMenu();
2756  else
2757  m_xMenuButton->CancelMenu();
2758  }
2759 
2760  virtual bool get_active() const override
2761  {
2762  return m_xMenuButton->InPopupMode();
2763  }
2764 
2765  virtual void set_inconsistent(bool /*inconsistent*/) override
2766  {
2767  //not available
2768  }
2769 
2770  virtual bool get_inconsistent() const override
2771  {
2772  return false;
2773  }
2774 
2775  virtual void insert_item(int pos, const OUString& rId, const OUString& rStr,
2776  const OUString* pIconName, VirtualDevice* pImageSurface, bool bCheck) override
2777  {
2778  m_nLastId = insert_to_menu(m_nLastId, m_xMenuButton->GetPopupMenu(), pos, rId, rStr, pIconName, pImageSurface, bCheck);
2779  }
2780 
2781  virtual void insert_separator(int pos, const OUString& rId) override
2782  {
2783  auto nInsertPos = pos == -1 ? MENU_APPEND : pos;
2784  m_xMenuButton->GetPopupMenu()->InsertSeparator(rId.toUtf8(), nInsertPos);
2785  }
2786 
2787  virtual void set_item_sensitive(const OString& rIdent, bool bSensitive) override
2788  {
2789  PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2790  pMenu->EnableItem(rIdent, bSensitive);
2791  }
2792 
2793  virtual void remove_item(const OString& rId) override
2794  {
2795  PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2796  pMenu->RemoveItem(pMenu->GetItemPos(pMenu->GetItemId(rId)));
2797  }
2798 
2799  virtual void clear() override
2800  {
2801  PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2802  pMenu->Clear();
2803  }
2804 
2805  virtual void set_item_active(const OString& rIdent, bool bActive) override
2806  {
2807  PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2808  pMenu->CheckItem(rIdent, bActive);
2809  }
2810 
2811  virtual void set_item_label(const OString& rIdent, const OUString& rText) override
2812  {
2813  PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2814  pMenu->SetItemText(pMenu->GetItemId(rIdent), rText);
2815  }
2816 
2817  virtual OUString get_item_label(const OString& rIdent) const override
2818  {
2819  PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2820  return pMenu->GetItemText(pMenu->GetItemId(rIdent));
2821  }
2822 
2823  virtual void set_item_visible(const OString& rIdent, bool bShow) override
2824  {
2825  PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2826  pMenu->ShowItem(pMenu->GetItemId(rIdent), bShow);
2827  }
2828 
2829  virtual void set_item_help_id(const OString& rIdent, const OString& rHelpId) override
2830  {
2831  PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2832  pMenu->SetHelpId(pMenu->GetItemId(rIdent), rHelpId);
2833  }
2834 
2835  virtual OString get_item_help_id(const OString& rIdent) const override
2836  {
2837  PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2838  return pMenu->GetHelpId(pMenu->GetItemId(rIdent));
2839  }
2840 
2841  virtual void set_popover(weld::Widget* pPopover) override
2842  {
2843  SalInstanceWidget* pPopoverWidget = dynamic_cast<SalInstanceWidget*>(pPopover);
2844  m_xMenuButton->SetPopover(pPopoverWidget ? pPopoverWidget->getWidget() : nullptr);
2845  }
2846 
2847  virtual ~SalInstanceMenuButton() override
2848  {
2849  m_xMenuButton->SetSelectHdl(Link<::MenuButton*, void>());
2850  m_xMenuButton->SetActivateHdl(Link<::MenuButton*, void>());
2851  }
2852 };
2853 
2854 }
2855 
2856 IMPL_LINK_NOARG(SalInstanceMenuButton, MenuSelectHdl, ::MenuButton*, void)
2857 {
2858  signal_selected(m_xMenuButton->GetCurItemIdent());
2859 }
2860 
2861 IMPL_LINK_NOARG(SalInstanceMenuButton, ActivateHdl, ::MenuButton*, void)
2862 {
2863  if (notify_events_disabled())
2864  return;
2865  signal_toggled();
2866 }
2867 
2868 namespace {
2869 
2870 class SalInstanceLinkButton : public SalInstanceContainer, public virtual weld::LinkButton
2871 {
2872 private:
2873  VclPtr<FixedHyperlink> m_xButton;
2874  Link<FixedHyperlink&,void> m_aOrigClickHdl;
2875 
2876  DECL_LINK(ClickHdl, FixedHyperlink&, void);
2877 public:
2878  SalInstanceLinkButton(FixedHyperlink* pButton, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2879  : SalInstanceContainer(pButton, pBuilder, bTakeOwnership)
2880  , m_xButton(pButton)
2881  {
2882  m_aOrigClickHdl = m_xButton->GetClickHdl();
2883  m_xButton->SetClickHdl(LINK(this, SalInstanceLinkButton, ClickHdl));
2884  }
2885 
2886  virtual void set_label(const OUString& rText) override
2887  {
2888  m_xButton->SetText(rText);
2889  }
2890 
2891  virtual OUString get_label() const override
2892  {
2893  return m_xButton->GetText();
2894  }
2895 
2896  virtual void set_uri(const OUString& rUri) override
2897  {
2898  m_xButton->SetURL(rUri);
2899  }
2900 
2901  virtual OUString get_uri() const override
2902  {
2903  return m_xButton->GetURL();
2904  }
2905 
2906  virtual ~SalInstanceLinkButton() override
2907  {
2908  m_xButton->SetClickHdl(m_aOrigClickHdl);
2909  }
2910 };
2911 
2912 }
2913 
2914 IMPL_LINK(SalInstanceLinkButton, ClickHdl, FixedHyperlink&, rButton, void)
2915 {
2916  bool bConsumed = signal_activate_link();
2917  if (!bConsumed)
2918  m_aOrigClickHdl.Call(rButton);
2919 }
2920 
2921 namespace {
2922 
2923 class SalInstanceRadioButton : public SalInstanceButton, public virtual weld::RadioButton
2924 {
2925 private:
2926  VclPtr<::RadioButton> m_xRadioButton;
2927 
2928  DECL_LINK(ToggleHdl, ::RadioButton&, void);
2929 
2930 public:
2931  SalInstanceRadioButton(::RadioButton* pButton, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2932  : SalInstanceButton(pButton, pBuilder, bTakeOwnership)
2933  , m_xRadioButton(pButton)
2934  {
2935  m_xRadioButton->SetToggleHdl(LINK(this, SalInstanceRadioButton, ToggleHdl));
2936  }
2937 
2938  virtual void set_active(bool active) override
2939  {
2940  disable_notify_events();
2941  m_xRadioButton->Check(active);
2942  enable_notify_events();
2943  }
2944 
2945  virtual bool get_active() const override
2946  {
2947  return m_xRadioButton->IsChecked();
2948  }
2949 
2950  virtual void set_image(VirtualDevice* pDevice) override
2951  {
2952  m_xRadioButton->SetImageAlign(ImageAlign::Center);
2953  if (pDevice)
2954  m_xRadioButton->SetModeImage(createImage(*pDevice));
2955  else
2956  m_xRadioButton->SetModeImage(Image());
2957  }
2958 
2959  virtual void set_image(const css::uno::Reference<css::graphic::XGraphic>& rImage) override
2960  {
2961  m_xRadioButton->SetImageAlign(ImageAlign::Center);
2962  m_xRadioButton->SetModeImage(Image(rImage));
2963  }
2964 
2965  virtual void set_from_icon_name(const OUString& rIconName) override
2966  {
2967  m_xRadioButton->SetModeRadioImage(Image(StockImage::Yes, rIconName));
2968  }
2969 
2970  virtual void set_inconsistent(bool /*inconsistent*/) override
2971  {
2972  //not available
2973  }
2974 
2975  virtual bool get_inconsistent() const override
2976  {
2977  return false;
2978  }
2979 
2980  virtual ~SalInstanceRadioButton() override
2981  {
2982  m_xRadioButton->SetToggleHdl(Link<::RadioButton&, void>());
2983  }
2984 };
2985 
2986 }
2987 
2988 IMPL_LINK_NOARG(SalInstanceRadioButton, ToggleHdl, ::RadioButton&, void)
2989 {
2990  if (notify_events_disabled())
2991  return;
2992  signal_toggled();
2993 }
2994 
2995 namespace {
2996 
2997 class SalInstanceToggleButton : public SalInstanceButton, public virtual weld::ToggleButton
2998 {
2999 private:
3000  VclPtr<PushButton> m_xToggleButton;
3001 
3002  DECL_LINK(ToggleListener, VclWindowEvent&, void);
3003 
3004 public:
3005  SalInstanceToggleButton(PushButton* pButton, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3006  : SalInstanceButton(pButton, pBuilder, bTakeOwnership)
3007  , m_xToggleButton(pButton)
3008  {
3009  }
3010 
3011  virtual void connect_toggled(const Link<ToggleButton&, void>& rLink) override
3012  {
3013  assert(!m_aToggleHdl.IsSet());
3014  m_xToggleButton->AddEventListener(LINK(this, SalInstanceToggleButton, ToggleListener));
3016  }
3017 
3018  virtual void set_active(bool active) override
3019  {
3020  disable_notify_events();
3021  m_xToggleButton->Check(active);
3022  enable_notify_events();
3023  }
3024 
3025  virtual bool get_active() const override
3026  {
3027  return m_xToggleButton->IsChecked();
3028  }
3029 
3030  virtual void set_inconsistent(bool inconsistent) override
3031  {
3032  disable_notify_events();
3033  m_xToggleButton->SetState(inconsistent ? TRISTATE_INDET : TRISTATE_FALSE);
3034  enable_notify_events();
3035  }
3036 
3037  virtual bool get_inconsistent() const override
3038  {
3039  return m_xToggleButton->GetState() == TRISTATE_INDET;
3040  }
3041 
3042  virtual ~SalInstanceToggleButton() override
3043  {
3044  if (m_aToggleHdl.IsSet())
3045  m_xToggleButton->RemoveEventListener(LINK(this, SalInstanceToggleButton, ToggleListener));
3046  }
3047 };
3048 
3049 }
3050 
3051 IMPL_LINK(SalInstanceToggleButton, ToggleListener, VclWindowEvent&, rEvent, void)
3052 {
3053  if (notify_events_disabled())
3054  return;
3055  if (rEvent.GetId() == VclEventId::PushbuttonToggle)
3056  signal_toggled();
3057 }
3058 
3059 namespace {
3060 
3061 class SalInstanceCheckButton : public SalInstanceButton, public virtual weld::CheckButton
3062 {
3063 private:
3064  VclPtr<CheckBox> m_xCheckButton;
3065 
3066  DECL_LINK(ToggleHdl, CheckBox&, void);
3067 public:
3068  SalInstanceCheckButton(CheckBox* pButton, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3069  : SalInstanceButton(pButton, pBuilder, bTakeOwnership)
3070  , m_xCheckButton(pButton)
3071  {
3072  m_xCheckButton->SetToggleHdl(LINK(this, SalInstanceCheckButton, ToggleHdl));
3073  }
3074 
3075  virtual void set_active(bool active) override
3076  {
3077  disable_notify_events();
3078  m_xCheckButton->EnableTriState(false);
3079  m_xCheckButton->Check(active);
3080  enable_notify_events();
3081  }
3082 
3083  virtual bool get_active() const override
3084  {
3085  return m_xCheckButton->IsChecked();
3086  }
3087 
3088  virtual void set_inconsistent(bool inconsistent) override
3089  {
3090  disable_notify_events();
3091  m_xCheckButton->EnableTriState(true);
3092  m_xCheckButton->SetState(inconsistent ? TRISTATE_INDET : TRISTATE_FALSE);
3093  enable_notify_events();
3094  }
3095 
3096  virtual bool get_inconsistent() const override
3097  {
3098  return m_xCheckButton->GetState() == TRISTATE_INDET;
3099  }
3100 
3101  virtual ~SalInstanceCheckButton() override
3102  {
3103  m_xCheckButton->SetToggleHdl(Link<CheckBox&, void>());
3104  }
3105 };
3106 
3107 }
3108 
3109 IMPL_LINK_NOARG(SalInstanceCheckButton, ToggleHdl, CheckBox&, void)
3110 {
3111  if (notify_events_disabled())
3112  return;
3113  m_xCheckButton->EnableTriState(false);
3114  signal_toggled();
3115 }
3116 
3117 namespace {
3118 
3119 class SalInstanceScale : public SalInstanceWidget, public virtual weld::Scale
3120 {
3121 private:
3122  VclPtr<Slider> m_xScale;
3123 
3124  DECL_LINK(SlideHdl, Slider*, void);
3125 public:
3126  SalInstanceScale(Slider* pScale, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3127  : SalInstanceWidget(pScale, pBuilder, bTakeOwnership)
3128  , m_xScale(pScale)
3129  {
3130  m_xScale->SetSlideHdl(LINK(this, SalInstanceScale, SlideHdl));
3131  }
3132 
3133  virtual void set_value(int value) override
3134  {
3135  m_xScale->SetThumbPos(value);
3136  }
3137 
3138  virtual void set_range(int min, int max) override
3139  {
3140  m_xScale->SetRangeMin(min);
3141  m_xScale->SetRangeMax(max);
3142  }
3143 
3144  virtual int get_value() const override
3145  {
3146  return m_xScale->GetThumbPos();
3147  }
3148 
3149  virtual ~SalInstanceScale() override
3150  {
3151  m_xScale->SetSlideHdl(Link<Slider*, void>());
3152  }
3153 };
3154 
3155 }
3156 
3157 IMPL_LINK_NOARG(SalInstanceScale, SlideHdl, Slider*, void)
3158 {
3159  signal_value_changed();
3160 }
3161 
3162 namespace {
3163 
3164 class SalInstanceSpinner : public SalInstanceWidget, public virtual weld::Spinner
3165 {
3166 private:
3167  VclPtr<Throbber> m_xThrobber;
3168 
3169 public:
3170  SalInstanceSpinner(Throbber* pThrobber, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3171  : SalInstanceWidget(pThrobber, pBuilder, bTakeOwnership)
3172  , m_xThrobber(pThrobber)
3173  {
3174  }
3175 
3176  virtual void start() override
3177  {
3178  m_xThrobber->start();
3179  }
3180 
3181  virtual void stop() override
3182  {
3183  m_xThrobber->stop();
3184  }
3185 };
3186 
3187 class SalInstanceProgressBar : public SalInstanceWidget, public virtual weld::ProgressBar
3188 {
3189 private:
3190  VclPtr<::ProgressBar> m_xProgressBar;
3191 
3192 public:
3193  SalInstanceProgressBar(::ProgressBar* pProgressBar, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3194  : SalInstanceWidget(pProgressBar, pBuilder, bTakeOwnership)
3195  , m_xProgressBar(pProgressBar)
3196  {
3197  }
3198 
3199  virtual void set_percentage(int value) override
3200  {
3201  m_xProgressBar->SetValue(value);
3202  }
3203 
3204  virtual OUString get_text() const override
3205  {
3206  return m_xProgressBar->GetText();
3207  }
3208 
3209  virtual void set_text(const OUString& rText) override
3210  {
3211  m_xProgressBar->SetText(rText);
3212  }
3213 };
3214 
3215 class SalInstanceImage : public SalInstanceWidget, public virtual weld::Image
3216 {
3217 private:
3218  VclPtr<FixedImage> m_xImage;
3219 
3220 public:
3221  SalInstanceImage(FixedImage* pImage, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3222  : SalInstanceWidget(pImage, pBuilder, bTakeOwnership)
3223  , m_xImage(pImage)
3224  {
3225  }
3226 
3227  virtual void set_from_icon_name(const OUString& rIconName) override
3228  {
3229  m_xImage->SetImage(::Image(StockImage::Yes, rIconName));
3230  }
3231 
3232  virtual void set_image(VirtualDevice* pDevice) override
3233  {
3234  if (pDevice)
3235  m_xImage->SetImage(createImage(*pDevice));
3236  else
3237  m_xImage->SetImage(::Image());
3238  }
3239 
3240  virtual void set_image(const css::uno::Reference<css::graphic::XGraphic>& rImage) override
3241  {
3242  m_xImage->SetImage(::Image(rImage));
3243  }
3244 };
3245 
3246 class SalInstanceCalendar : public SalInstanceWidget, public virtual weld::Calendar
3247 {
3248 private:
3249  VclPtr<::Calendar> m_xCalendar;
3250 
3251  DECL_LINK(SelectHdl, ::Calendar*, void);
3252  DECL_LINK(ActivateHdl, ::Calendar*, void);
3253 
3254 public:
3255  SalInstanceCalendar(::Calendar* pCalendar, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3256  : SalInstanceWidget(pCalendar, pBuilder, bTakeOwnership)
3257  , m_xCalendar(pCalendar)
3258  {
3259  m_xCalendar->SetSelectHdl(LINK(this, SalInstanceCalendar, SelectHdl));
3260  m_xCalendar->SetActivateHdl(LINK(this, SalInstanceCalendar, ActivateHdl));
3261  }
3262 
3263  virtual void set_date(const Date& rDate) override
3264  {
3265  m_xCalendar->SetCurDate(rDate);
3266  }
3267 
3268  virtual Date get_date() const override
3269  {
3270  return m_xCalendar->GetFirstSelectedDate();
3271  }
3272 
3273  virtual ~SalInstanceCalendar() override
3274  {
3275  m_xCalendar->SetSelectHdl(Link<::Calendar*, void>());
3276  m_xCalendar->SetActivateHdl(Link<::Calendar*, void>());
3277  }
3278 };
3279 
3280 }
3281 
3282 IMPL_LINK_NOARG(SalInstanceCalendar, SelectHdl, ::Calendar*, void)
3283 {
3284  if (notify_events_disabled())
3285  return;
3286  signal_selected();
3287 }
3288 
3289 IMPL_LINK_NOARG(SalInstanceCalendar, ActivateHdl, ::Calendar*, void)
3290 {
3291  if (notify_events_disabled())
3292  return;
3293  signal_activated();
3294 }
3295 
3296 namespace
3297 {
3298  class WeldTextFilter : public TextFilter
3299  {
3300  private:
3301  Link<OUString&, bool>& m_rInsertTextHdl;
3302  public:
3303  WeldTextFilter(Link<OUString&, bool>& rInsertTextHdl)
3304  : TextFilter(OUString())
3305  , m_rInsertTextHdl(rInsertTextHdl)
3306  {
3307  }
3308 
3309  virtual OUString filter(const OUString &rText) override
3310  {
3311  if (!m_rInsertTextHdl.IsSet())
3312  return rText;
3313  OUString sText(rText);
3314  const bool bContinue = m_rInsertTextHdl.Call(sText);
3315  if (!bContinue)
3316  return OUString();
3317  return sText;
3318  }
3319  };
3320 
3321 class SalInstanceEntry : public SalInstanceWidget, public virtual weld::Entry
3322 {
3323 private:
3324  VclPtr<Edit> m_xEntry;
3325 
3326  DECL_LINK(ChangeHdl, Edit&, void);
3327  DECL_LINK(CursorListener, VclWindowEvent&, void);
3328  DECL_LINK(ActivateHdl, Edit&, bool);
3329 
3330  WeldTextFilter m_aTextFilter;
3331 public:
3332  SalInstanceEntry(Edit* pEntry, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3333  : SalInstanceWidget(pEntry, pBuilder, bTakeOwnership)
3334  , m_xEntry(pEntry)
3335  , m_aTextFilter(m_aInsertTextHdl)
3336  {
3337  m_xEntry->SetModifyHdl(LINK(this, SalInstanceEntry, ChangeHdl));
3338  m_xEntry->SetActivateHdl(LINK(this, SalInstanceEntry, ActivateHdl));
3339  m_xEntry->SetTextFilter(&m_aTextFilter);
3340  }
3341 
3342  virtual void set_text(const OUString& rText) override
3343  {
3344  disable_notify_events();
3345  m_xEntry->SetText(rText);
3346  enable_notify_events();
3347  }
3348 
3349  virtual OUString get_text() const override
3350  {
3351  return m_xEntry->GetText();
3352  }
3353 
3354  virtual void set_width_chars(int nChars) override
3355  {
3356  m_xEntry->SetWidthInChars(nChars);
3357  }
3358 
3359  virtual int get_width_chars() const override
3360  {
3361  return m_xEntry->GetWidthInChars();
3362  }
3363 
3364  virtual void set_max_length(int nChars) override
3365  {
3366  m_xEntry->SetMaxTextLen(nChars);
3367  }
3368 
3369  virtual void select_region(int nStartPos, int nEndPos) override
3370  {
3371  disable_notify_events();
3372  m_xEntry->SetSelection(Selection(nStartPos, nEndPos < 0 ? SELECTION_MAX : nEndPos));
3373  enable_notify_events();
3374  }
3375 
3376  bool get_selection_bounds(int& rStartPos, int &rEndPos) override
3377  {
3378  const Selection& rSelection = m_xEntry->GetSelection();
3379  rStartPos = rSelection.Min();
3380  rEndPos = rSelection.Max();
3381  return rSelection.Len();
3382  }
3383 
3384  virtual void replace_selection(const OUString& rText) override
3385  {
3386  m_xEntry->ReplaceSelected(rText);
3387  }
3388 
3389  virtual void set_position(int nCursorPos) override
3390  {
3391  disable_notify_events();
3392  if (nCursorPos < 0)
3393  m_xEntry->SetCursorAtLast();
3394  else
3395  m_xEntry->SetSelection(Selection(nCursorPos, nCursorPos));
3396  enable_notify_events();
3397  }
3398 
3399  virtual int get_position() const override
3400  {
3401  return m_xEntry->GetSelection().Max();
3402  }
3403 
3404  virtual void set_editable(bool bEditable) override
3405  {
3406  m_xEntry->SetReadOnly(!bEditable);
3407  }
3408 
3409  virtual bool get_editable() const override
3410  {
3411  return !m_xEntry->IsReadOnly();
3412  }
3413 
3414  virtual void set_message_type(weld::EntryMessageType eType) override
3415  {
3416  if (eType == weld::EntryMessageType::Error)
3417  {
3418  // tdf#114603: enable setting the background to a different color;
3419  // relevant for GTK; see also #i75179#
3420  m_xEntry->SetForceControlBackground(true);
3421  m_xEntry->SetControlForeground(COL_WHITE);
3422  m_xEntry->SetControlBackground(0xff6563);
3423  }
3424  else if (eType == weld::EntryMessageType::Warning)
3425  {
3426  // tdf#114603: enable setting the background to a different color;
3427  // relevant for GTK; see also #i75179#
3428  m_xEntry->SetForceControlBackground(true);
3429  m_xEntry->SetControlForeground();
3430  m_xEntry->SetControlBackground(COL_YELLOW);
3431  }
3432  else
3433  {
3434  m_xEntry->SetForceControlBackground(false);
3435  m_xEntry->SetControlForeground();
3436  m_xEntry->SetControlBackground();
3437  }
3438  }
3439 
3440  virtual void set_font(const vcl::Font& rFont) override
3441  {
3442  m_xEntry->SetPointFont(*m_xEntry, rFont);
3443  m_xEntry->Invalidate();
3444  }
3445 
3446  virtual void connect_cursor_position(const Link<Entry&, void>& rLink) override
3447  {
3448  assert(!m_aCursorPositionHdl.IsSet());
3449  m_xEntry->AddEventListener(LINK(this, SalInstanceEntry, CursorListener));
3451  }
3452 
3453  Edit& getEntry()
3454  {
3455  return *m_xEntry;
3456  }
3457 
3458  void fire_signal_changed()
3459  {
3460  signal_changed();
3461  }
3462 
3463  virtual void cut_clipboard() override
3464  {
3465  m_xEntry->Cut();
3466  }
3467 
3468  virtual void copy_clipboard() override
3469  {
3470  m_xEntry->Copy();
3471  }
3472 
3473  virtual void paste_clipboard() override
3474  {
3475  m_xEntry->Paste();
3476  }
3477 
3478  virtual ~SalInstanceEntry() override
3479  {
3480  if (m_aCursorPositionHdl.IsSet())
3481  m_xEntry->RemoveEventListener(LINK(this, SalInstanceEntry, CursorListener));
3482  m_xEntry->SetTextFilter(nullptr);
3483  m_xEntry->SetActivateHdl(Link<Edit&, bool>());
3484  m_xEntry->SetModifyHdl(Link<Edit&, void>());
3485  }
3486 };
3487 
3488 }
3489 
3490 IMPL_LINK_NOARG(SalInstanceEntry, ChangeHdl, Edit&, void)
3491 {
3492  signal_changed();
3493 }
3494 
3495 IMPL_LINK(SalInstanceEntry, CursorListener, VclWindowEvent&, rEvent, void)
3496 {
3497  if (notify_events_disabled())
3498  return;
3500  signal_cursor_position();
3501 }
3502 
3503 IMPL_LINK_NOARG(SalInstanceEntry, ActivateHdl, Edit&, bool)
3504 {
3505  return m_aActivateHdl.Call(*this);
3506 }
3507 
3508 namespace {
3509 
3510 struct SalInstanceTreeIter : public weld::TreeIter
3511 {
3512  SalInstanceTreeIter(const SalInstanceTreeIter* pOrig)
3513  : iter(pOrig ? pOrig->iter : nullptr)
3514  {
3515  }
3516  SalInstanceTreeIter(SvTreeListEntry* pIter)
3517  : iter(pIter)
3518  {
3519  }
3520  virtual bool equal(const TreeIter& rOther) const override
3521  {
3522  return iter == static_cast<const SalInstanceTreeIter&>(rOther).iter;
3523  }
3524  SvTreeListEntry* iter;
3525 };
3526 
3527  TriState get_toggle(SvTreeListEntry* pEntry, int col)
3528  {
3529  ++col; //skip dummy/expander column
3530 
3531  if (static_cast<size_t>(col) == pEntry->ItemCount())
3532  return TRISTATE_FALSE;
3533 
3534  assert(col >= 0 && static_cast<size_t>(col) < pEntry->ItemCount());
3535  SvLBoxItem& rItem = pEntry->GetItem(col);
3536  assert(dynamic_cast<SvLBoxButton*>(&rItem));
3537  SvLBoxButton& rToggle = static_cast<SvLBoxButton&>(rItem);
3538  if (rToggle.IsStateTristate())
3539  return TRISTATE_INDET;
3540  else if (rToggle.IsStateChecked())
3541  return TRISTATE_TRUE;
3542  return TRISTATE_FALSE;
3543  }
3544 
3545  bool get_text_emphasis(SvTreeListEntry* pEntry, int col)
3546  {
3547  ++col; //skip dummy/expander column
3548 
3549  assert(col >= 0 && static_cast<size_t>(col) < pEntry->ItemCount());
3550  SvLBoxItem& rItem = pEntry->GetItem(col);
3551  assert(dynamic_cast<SvLBoxString*>(&rItem));
3552  return static_cast<SvLBoxString&>(rItem).IsEmphasized();
3553  }
3554 }
3555 
3557 
3559 
3560 class SalInstanceTreeView : public SalInstanceContainer, public virtual weld::TreeView
3561 {
3562 private:
3563  // owner for UserData
3564  std::vector<std::unique_ptr<OUString>> m_aUserData;
3570 
3571  DECL_LINK(SelectHdl, SvTreeListBox*, void);
3572  DECL_LINK(DeSelectHdl, SvTreeListBox*, void);
3573  DECL_LINK(DoubleClickHdl, SvTreeListBox*, bool);
3574  DECL_LINK(ExpandingHdl, SvTreeListBox*, bool);
3575  DECL_LINK(EndDragHdl, HeaderBar*, void);
3576  DECL_LINK(HeaderBarClickedHdl, HeaderBar*, void);
3577  DECL_LINK(ToggleHdl, SvLBoxButtonData*, void);
3578  DECL_LINK(ModelChangedHdl, SvTreeListBox*, void);
3579  DECL_LINK(StartDragHdl, SvTreeListBox*, bool);
3580  DECL_STATIC_LINK(SalInstanceTreeView, FinishDragHdl, SvTreeListBox*, void);
3581  DECL_LINK(EditingEntryHdl, SvTreeListEntry*, bool);
3582  typedef std::pair<SvTreeListEntry*, OUString> IterString;
3583  DECL_LINK(EditedEntryHdl, IterString, bool);
3584  DECL_LINK(VisibleRangeChangedHdl, SvTreeListBox*, void);
3585  DECL_LINK(CompareHdl, const SvSortData&, sal_Int32);
3586  DECL_LINK(PopupMenuHdl, const CommandEvent&, bool);
3587  DECL_LINK(TooltipHdl, const HelpEvent&, bool);
3588 
3589  bool IsDummyEntry(SvTreeListEntry* pEntry) const
3590  {
3591  return m_xTreeView->GetEntryText(pEntry).trim() == "<dummy>";
3592  }
3593 
3594 public:
3595  SalInstanceTreeView(SvTabListBox* pTreeView, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3596  : SalInstanceContainer(pTreeView, pBuilder, bTakeOwnership)
3597  , m_xTreeView(pTreeView)
3598  , m_aCheckButtonData(pTreeView, false)
3599  , m_aRadioButtonData(pTreeView, true)
3600  , m_bDisableCheckBoxAutoWidth(false)
3601  , m_nSortColumn(-1)
3602  {
3603  m_xTreeView->SetNodeDefaultImages();
3604  m_xTreeView->SetSelectHdl(LINK(this, SalInstanceTreeView, SelectHdl));
3605  m_xTreeView->SetDeselectHdl(LINK(this, SalInstanceTreeView, DeSelectHdl));
3606  m_xTreeView->SetDoubleClickHdl(LINK(this, SalInstanceTreeView, DoubleClickHdl));
3607  m_xTreeView->SetExpandingHdl(LINK(this, SalInstanceTreeView, ExpandingHdl));
3608  m_xTreeView->SetPopupMenuHdl(LINK(this, SalInstanceTreeView, PopupMenuHdl));
3609  const long aTabPositions[] = { 0 };
3610  m_xTreeView->SetTabs(SAL_N_ELEMENTS(aTabPositions), aTabPositions);
3611  LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
3612 
3613  if (pHeaderBox)
3614  {
3615  if (HeaderBar* pHeaderBar = pHeaderBox->GetHeaderBar())
3616  {
3617  //make the last entry fill available space
3618  pHeaderBar->SetItemSize(pHeaderBar->GetItemId(pHeaderBar->GetItemCount() - 1 ), HEADERBAR_FULLSIZE);
3619  pHeaderBar->SetEndDragHdl(LINK(this, SalInstanceTreeView, EndDragHdl));
3620  pHeaderBar->SetSelectHdl(LINK(this, SalInstanceTreeView, HeaderBarClickedHdl));
3621  }
3622  pHeaderBox->SetEditingEntryHdl(LINK(this, SalInstanceTreeView, EditingEntryHdl));
3623  pHeaderBox->SetEditedEntryHdl(LINK(this, SalInstanceTreeView, EditedEntryHdl));
3624  }
3625  else
3626  {
3627  static_cast<LclTabListBox&>(*m_xTreeView).SetModelChangedHdl(LINK(this, SalInstanceTreeView, ModelChangedHdl));
3628  static_cast<LclTabListBox&>(*m_xTreeView).SetStartDragHdl(LINK(this, SalInstanceTreeView, StartDragHdl));
3629  static_cast<LclTabListBox&>(*m_xTreeView).SetEndDragHdl(LINK(this, SalInstanceTreeView, FinishDragHdl));
3630  static_cast<LclTabListBox&>(*m_xTreeView).SetEditingEntryHdl(LINK(this, SalInstanceTreeView, EditingEntryHdl));
3631  static_cast<LclTabListBox&>(*m_xTreeView).SetEditedEntryHdl(LINK(this, SalInstanceTreeView, EditedEntryHdl));
3632  }
3633  m_aCheckButtonData.SetLink(LINK(this, SalInstanceTreeView, ToggleHdl));
3634  m_aRadioButtonData.SetLink(LINK(this, SalInstanceTreeView, ToggleHdl));
3635  }
3636 
3638  {
3640  m_xTreeView->SetTooltipHdl(LINK(this, SalInstanceTreeView, TooltipHdl));
3641  }
3642 
3643  virtual void columns_autosize() override
3644  {
3645  std::vector<long> aWidths;
3646  m_xTreeView->getPreferredDimensions(aWidths);
3647  if (aWidths.size() > 2)
3648  {
3649  std::vector<int> aColWidths;
3650  for (size_t i = 1; i < aWidths.size() - 1; ++i)
3651  aColWidths.push_back(aWidths[i] - aWidths[i - 1]);
3652  set_column_fixed_widths(aColWidths);
3653  }
3654  }
3655 
3656  virtual void freeze() override
3657  {
3658  SalInstanceWidget::freeze();
3659  m_xTreeView->SetUpdateMode(false);
3660  }
3661 
3662  virtual void thaw() override
3663  {
3664  m_xTreeView->SetUpdateMode(true);
3665  SalInstanceWidget::thaw();
3666  }
3667 
3668  virtual void set_column_fixed_widths(const std::vector<int>& rWidths) override
3669  {
3670  m_bDisableCheckBoxAutoWidth = true;
3671  std::vector<long> aTabPositions;
3672  aTabPositions.push_back(0);
3673  for (size_t i = 0; i < rWidths.size(); ++i)
3674  aTabPositions.push_back(aTabPositions[i] + rWidths[i]);
3675  m_xTreeView->SetTabs(aTabPositions.size(), aTabPositions.data(), MapUnit::MapPixel);
3676  LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
3677  if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
3678  {
3679  for (size_t i = 0; i < rWidths.size(); ++i)
3680  pHeaderBar->SetItemSize(pHeaderBar->GetItemId(i), rWidths[i]);
3681  }
3682  // call Resize to recalculate based on the new tabs
3683  m_xTreeView->Resize();
3684  }
3685 
3686  virtual void set_centered_column(int nCol) override
3687  {
3688  m_xTreeView->SetTabJustify(nCol, SvTabJustify::AdjustCenter);
3689  }
3690 
3691  virtual int get_column_width(int nColumn) const override
3692  {
3693  LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
3694  if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
3695  return pHeaderBar->GetItemSize(pHeaderBar->GetItemId(nColumn));
3696  // GetTab(0) gives the position of the bitmap which is automatically inserted by the TabListBox.
3697  // So the first text column's width is Tab(2)-Tab(1).
3698  auto nWidthPixel = m_xTreeView->GetLogicTab(nColumn + 2) - m_xTreeView->GetLogicTab(nColumn + 1);
3699  nWidthPixel -= SV_TAB_BORDER;
3700  return nWidthPixel;
3701  }
3702 
3703  virtual OUString get_column_title(int nColumn) const override
3704  {
3705  LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
3706  if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
3707  {
3708  return pHeaderBar->GetItemText(pHeaderBar->GetItemId(nColumn));
3709  }
3710  return OUString();
3711  }
3712 
3713  virtual void set_column_title(int nColumn, const OUString& rTitle) override
3714  {
3715  LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
3716  if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
3717  {
3718  return pHeaderBar->SetItemText(pHeaderBar->GetItemId(nColumn), rTitle);
3719  }
3720  }
3721 
3722  virtual void show() override
3723  {
3724  if (LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get()))
3725  pHeaderBox->GetParent()->Show();
3726  SalInstanceContainer::show();
3727  }
3728 
3729  virtual void hide() override
3730  {
3731  if (LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get()))
3732  pHeaderBox->GetParent()->Hide();
3733  SalInstanceContainer::hide();
3734  }
3735 
3736  virtual void insert(const weld::TreeIter* pParent, int pos, const OUString* pStr, const OUString* pId,
3737  const OUString* pIconName, VirtualDevice* pImageSurface,
3738  const OUString* pExpanderName, bool bChildrenOnDemand, weld::TreeIter* pRet) override
3739  {
3740  disable_notify_events();
3741  const SalInstanceTreeIter* pVclIter = static_cast<const SalInstanceTreeIter*>(pParent);
3742  SvTreeListEntry* iter = pVclIter ? pVclIter->iter : nullptr;
3743  auto nInsertPos = pos == -1 ? TREELIST_APPEND : pos;
3744  void* pUserData;
3745  if (pId)
3746  {
3747  m_aUserData.emplace_back(std::make_unique<OUString>(*pId));
3748  pUserData = m_aUserData.back().get();
3749  }
3750  else
3751  pUserData = nullptr;
3752 
3753  SvTreeListEntry* pEntry = new SvTreeListEntry;
3754  if (pIconName || pImageSurface)
3755  {
3756  Image aImage(pIconName ? createImage(*pIconName) : createImage(*pImageSurface));
3757  pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(aImage, aImage, false));
3758  }
3759  else
3760  {
3761  Image aDummy;
3762  pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(aDummy, aDummy, false));
3763  }
3764  if (pStr)
3765  pEntry->AddItem(std::make_unique<SvLBoxString>(*pStr));
3766  pEntry->SetUserData(pUserData);
3767  m_xTreeView->Insert(pEntry, iter, nInsertPos);
3768 
3769  if (pExpanderName)
3770  {
3771  Image aImage(createImage(*pExpanderName));
3772  m_xTreeView->SetExpandedEntryBmp(pEntry, aImage);
3773  m_xTreeView->SetCollapsedEntryBmp(pEntry, aImage);
3774  }
3775 
3776  if (pRet)
3777  {
3778  SalInstanceTreeIter* pVclRetIter = static_cast<SalInstanceTreeIter*>(pRet);
3779  pVclRetIter->iter = pEntry;
3780  }
3781 
3782  if (bChildrenOnDemand)
3783  {
3784  m_xTreeView->InsertEntry("<dummy>", pEntry, false, 0, nullptr);
3785  }
3786  enable_notify_events();
3787  }
3788 
3789  virtual void bulk_insert_for_each(int nSourceCount,
3790  const std::function<void(weld::TreeIter&, int nSourceIndex)>& func,
3791  const std::vector<int>* pFixedWidths) override
3792  {
3793  freeze();
3794  clear();
3795  SalInstanceTreeIter aVclIter(static_cast<SvTreeListEntry*>(nullptr));
3796 
3797  m_xTreeView->nTreeFlags |= SvTreeFlags::MANINS;
3798 
3799  if (pFixedWidths)
3800  set_column_fixed_widths(*pFixedWidths);
3801 
3802  for (int i = 0; i < nSourceCount; ++i)
3803  {
3804  aVclIter.iter = new SvTreeListEntry;
3805  m_xTreeView->Insert(aVclIter.iter, nullptr, TREELIST_APPEND);
3806  func(aVclIter, i);
3807 
3808  if (!pFixedWidths)
3809  continue;
3810 
3811  size_t nFixedWidths = std::min(pFixedWidths->size(), aVclIter.iter->ItemCount());
3812  for (size_t j = 0; j < nFixedWidths; ++j)
3813  {
3814  SvLBoxItem& rItem = aVclIter.iter->GetItem(j);
3815  SvViewDataItem* pViewDataItem = m_xTreeView->GetViewDataItem(aVclIter.iter, &rItem);
3816  pViewDataItem->mnWidth = (*pFixedWidths)[j];
3817  }
3818  }
3819 
3820  m_xTreeView->nTreeFlags &= ~SvTreeFlags::MANINS;
3821 
3822  thaw();
3823  }
3824 
3825  virtual void set_font_color(int pos, const Color& rColor) const override
3826  {
3827  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
3828  pEntry->SetTextColor(rColor);
3829  }
3830 
3831  virtual void set_font_color(const weld::TreeIter& rIter, const Color& rColor) const override
3832  {
3833  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
3834  rVclIter.iter->SetTextColor(rColor);
3835  }
3836 
3837  virtual void remove(int pos) override
3838  {
3839  disable_notify_events();
3840  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
3841  m_xTreeView->RemoveEntry(pEntry);
3842  enable_notify_events();
3843  }
3844 
3845  virtual int find_text(const OUString& rText) const override
3846  {
3847  for (SvTreeListEntry* pEntry = m_xTreeView->First(); pEntry; pEntry = m_xTreeView->Next(pEntry))
3848  {
3849  if (SvTabListBox::GetEntryText(pEntry, 0) == rText)
3850  return SvTreeList::GetRelPos(pEntry);
3851  }
3852  return -1;
3853  }
3854 
3855  virtual int find_id(const OUString& rId) const override
3856  {
3857  for (SvTreeListEntry* pEntry = m_xTreeView->First(); pEntry; pEntry = m_xTreeView->Next(pEntry))
3858  {
3859  const OUString* pId = static_cast<const OUString*>(pEntry->GetUserData());
3860  if (!pId)
3861  continue;
3862  if (rId == *pId)
3863  return SvTreeList::GetRelPos(pEntry);
3864  }
3865  return -1;
3866  }
3867 
3868  virtual void swap(int pos1, int pos2) override
3869  {
3870  SvTreeList* pModel = m_xTreeView->GetModel();
3871  SvTreeListEntry* pEntry1 = pModel->GetEntry(nullptr, pos1);
3872  SvTreeListEntry* pEntry2 = pModel->GetEntry(nullptr, pos2);
3873  pModel->Move(pEntry1, pEntry2);
3874  }
3875 
3876  virtual void clear() override
3877  {
3878  disable_notify_events();
3879  m_xTreeView->Clear();
3880  m_aUserData.clear();
3881  enable_notify_events();
3882  }
3883 
3884  virtual int n_children() const override
3885  {
3886  return m_xTreeView->GetModel()->GetChildList(nullptr).size();
3887  }
3888 
3889  virtual int iter_n_children(const weld::TreeIter& rIter) const override
3890  {
3891  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
3892  return m_xTreeView->GetModel()->GetChildList(rVclIter.iter).size();
3893  }
3894 
3895  virtual void select(int pos) override
3896  {
3897  assert(m_xTreeView->IsUpdateMode() && "don't select when frozen");
3898  disable_notify_events();
3899  if (pos == -1 || (pos == 0 && n_children() == 0))
3900  m_xTreeView->SelectAll(false);
3901  else
3902  {
3903  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
3904  m_xTreeView->Select(pEntry, true);
3905  m_xTreeView->MakeVisible(pEntry);
3906  }
3907  enable_notify_events();
3908  }
3909 
3910  virtual int get_cursor_index() const override
3911  {
3912  SvTreeListEntry* pEntry = m_xTreeView->GetCurEntry();
3913  if (!pEntry)
3914  return -1;
3915  return SvTreeList::GetRelPos(pEntry);
3916  }
3917 
3918  virtual void set_cursor(int pos) override
3919  {
3920  disable_notify_events();
3921  if (pos == -1)
3922  m_xTreeView->SetCurEntry(nullptr);
3923  else
3924  {
3925  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
3926  m_xTreeView->SetCurEntry(pEntry);
3927  }
3928  enable_notify_events();
3929  }
3930 
3931  virtual void scroll_to_row(int pos) override
3932  {
3933  assert(m_xTreeView->IsUpdateMode() && "don't select when frozen");
3934  disable_notify_events();
3935  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
3936  m_xTreeView->MakeVisible(pEntry);
3937  enable_notify_events();
3938  }
3939 
3940  virtual bool is_selected(int pos) const override
3941  {
3942  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
3943  return m_xTreeView->IsSelected(pEntry);
3944  }
3945 
3946  virtual void unselect(int pos) override
3947  {
3948  assert(m_xTreeView->IsUpdateMode() && "don't select when frozen");
3949  disable_notify_events();
3950  if (pos == -1)
3951  m_xTreeView->SelectAll(true);
3952  else
3953  {
3954  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
3955  m_xTreeView->Select(pEntry, false);
3956  }
3957  enable_notify_events();
3958  }
3959 
3960  virtual std::vector<int> get_selected_rows() const override
3961  {
3962  std::vector<int> aRows;
3963 
3964  aRows.reserve(m_xTreeView->GetSelectionCount());
3965  for (SvTreeListEntry* pEntry = m_xTreeView->FirstSelected(); pEntry; pEntry = m_xTreeView->NextSelected(pEntry))
3966  aRows.push_back(SvTreeList::GetRelPos(pEntry));
3967 
3968  return aRows;
3969  }
3970 
3971  static OUString get_text(SvTreeListEntry* pEntry, int col)
3972  {
3973  if (col == -1)
3974  return SvTabListBox::GetEntryText(pEntry, 0);
3975 
3976  ++col; //skip dummy/expander column
3977 
3978  if (static_cast<size_t>(col) == pEntry->ItemCount())
3979  return OUString();
3980 
3981  assert(col >= 0 && static_cast<size_t>(col) < pEntry->ItemCount());
3982  SvLBoxItem& rItem = pEntry->GetItem(col);
3983  assert(dynamic_cast<SvLBoxString*>(&rItem));
3984  return static_cast<SvLBoxString&>(rItem).GetText();
3985  }
3986 
3987  virtual OUString get_text(int pos, int col) const override
3988  {
3989  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
3990  return get_text(pEntry, col);
3991  }
3992 
3993  void set_text(SvTreeListEntry* pEntry, const OUString& rText, int col)
3994  {
3995  if (col == -1)
3996  {
3997  m_xTreeView->SetEntryText(pEntry, rText);
3998  return;
3999  }
4000 
4001  ++col; //skip dummy/expander column
4002 
4003  // blank out missing entries
4004  for (int i = pEntry->ItemCount(); i < col ; ++i)
4005  pEntry->AddItem(std::make_unique<SvLBoxString>(""));
4006 
4007  if (static_cast<size_t>(col) == pEntry->ItemCount())
4008  {
4009  pEntry->AddItem(std::make_unique<SvLBoxString>(rText));
4010  SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry);
4011  m_xTreeView->InitViewData(pViewData, pEntry);
4012  }
4013  else
4014  {
4015  assert(col >= 0 && static_cast<size_t>(col) < pEntry->ItemCount());
4016  SvLBoxItem& rItem = pEntry->GetItem(col);
4017  assert(dynamic_cast<SvLBoxString*>(&rItem));
4018  static_cast<SvLBoxString&>(rItem).SetText(rText);
4019  }
4020  m_xTreeView->ModelHasEntryInvalidated(pEntry);
4021  }
4022 
4023  virtual void set_text(int pos, const OUString& rText, int col) override
4024  {
4025  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4026  set_text(pEntry, rText, col);
4027  }
4028 
4029  void set_sensitive(SvTreeListEntry* pEntry, bool bSensitive, int col)
4030  {
4031  if (col == -1)
4032  {
4033  const sal_uInt16 nCount = pEntry->ItemCount();
4034  for (sal_uInt16 nCur = 0; nCur < nCount; ++nCur)
4035  {
4036  SvLBoxItem& rItem = pEntry->GetItem(nCur);
4037  if (rItem.GetType() == SvLBoxItemType::String)
4038  {
4039  rItem.Enable(bSensitive);
4040  m_xTreeView->ModelHasEntryInvalidated(pEntry);
4041  break;
4042  }
4043  }
4044  return;
4045  }
4046 
4047  ++col; //skip dummy/expander column
4048 
4049  assert(col >= 0 && static_cast<size_t>(col) < pEntry->ItemCount());
4050  SvLBoxItem& rItem = pEntry->GetItem(col);
4051  rItem.Enable(bSensitive);
4052 
4053  m_xTreeView->ModelHasEntryInvalidated(pEntry);
4054  }
4055 
4056  using SalInstanceWidget::set_sensitive;
4057 
4058  virtual void set_sensitive(int pos, bool bSensitive, int col) override
4059  {
4060  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4061  set_sensitive(pEntry, bSensitive, col);
4062  }
4063 
4064  virtual void set_sensitive(const weld::TreeIter& rIter, bool bSensitive, int col) override
4065  {
4066  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4067  set_sensitive(rVclIter.iter, bSensitive, col);
4068  }
4069 
4070  virtual TriState get_toggle(int pos, int col) const override
4071  {
4072  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4073  return ::get_toggle(pEntry, col);
4074  }
4075 
4076  virtual TriState get_toggle(const weld::TreeIter& rIter, int col) const override
4077  {
4078  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4079  return ::get_toggle(rVclIter.iter, col);
4080  }
4081 
4082  void set_toggle(SvTreeListEntry* pEntry, TriState eState, int col)
4083  {
4084  bool bRadio = std::find(m_aRadioIndexes.begin(), m_aRadioIndexes.end(), col) != m_aRadioIndexes.end();
4085  ++col; //skip dummy/expander column
4086 
4087  // blank out missing entries
4088  for (int i = pEntry->ItemCount(); i < col ; ++i)
4089  pEntry->AddItem(std::make_unique<SvLBoxString>(""));
4090 
4091  if (static_cast<size_t>(col) == pEntry->ItemCount())
4092  {
4093  SvLBoxButtonData* pData = bRadio ? &m_aRadioButtonData : &m_aCheckButtonData;
4094 
4095  // if we want to have the implicit auto-sizing of the checkbox
4096  // column we need to call EnableCheckButton and CheckBoxInserted to
4097  // let it figure out that width. But we don't want to override any
4098  // explicitly set column width, so disable this if we've set
4099  // explicit column widths
4100  if (!m_bDisableCheckBoxAutoWidth)
4101  {
4102  if (!(m_xTreeView->GetTreeFlags() & SvTreeFlags::CHKBTN))
4103  {
4104  m_xTreeView->EnableCheckButton(pData);
4105  // EnableCheckButton clobbered this, restore it
4106  pData->SetLink(LINK(this, SalInstanceTreeView, ToggleHdl));
4107  }
4108  }
4109 
4110  pEntry->AddItem(std::make_unique<SvLBoxButton>(pData));
4111  SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry);
4112  m_xTreeView->InitViewData(pViewData, pEntry);
4113 
4114  if (!m_bDisableCheckBoxAutoWidth)
4115  m_xTreeView->CheckBoxInserted(pEntry);
4116  }
4117 
4118  assert(col >= 0 && static_cast<size_t>(col) < pEntry->ItemCount());
4119  SvLBoxItem& rItem = pEntry->GetItem(col);
4120  assert(dynamic_cast<SvLBoxButton*>(&rItem));
4121  switch (eState)
4122  {
4123  case TRISTATE_TRUE:
4124  static_cast<SvLBoxButton&>(rItem).SetStateChecked();
4125  break;
4126  case TRISTATE_FALSE:
4127  static_cast<SvLBoxButton&>(rItem).SetStateUnchecked();
4128  break;
4129  case TRISTATE_INDET:
4130  static_cast<SvLBoxButton&>(rItem).SetStateTristate();
4131  break;
4132  }
4133 
4134  m_xTreeView->ModelHasEntryInvalidated(pEntry);
4135  }
4136 
4137  virtual void set_toggle(int pos, TriState eState, int col) override
4138  {
4139  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4140  set_toggle(pEntry, eState, col);
4141  }
4142 
4143  virtual void set_toggle(const weld::TreeIter& rIter, TriState eState, int col) override
4144  {
4145  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4146  set_toggle(rVclIter.iter, eState, col);
4147  }
4148 
4149  void set_text_emphasis(SvTreeListEntry* pEntry, bool bOn, int col)
4150  {
4151  ++col; //skip dummy/expander column
4152 
4153  assert(col >= 0 && static_cast<size_t>(col) < pEntry->ItemCount());
4154  SvLBoxItem& rItem = pEntry->GetItem(col);
4155  assert(dynamic_cast<SvLBoxString*>(&rItem));
4156  static_cast<SvLBoxString&>(rItem).Emphasize(bOn);
4157 
4158  m_xTreeView->ModelHasEntryInvalidated(pEntry);
4159  }
4160 
4161  virtual void set_text_emphasis(const weld::TreeIter& rIter, bool bOn, int col) override
4162  {
4163  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4164  set_text_emphasis(rVclIter.iter, bOn, col);
4165  }
4166 
4167  virtual void set_text_emphasis(int pos, bool bOn, int col) override
4168  {
4169  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4170  set_text_emphasis(pEntry, bOn, col);
4171  }
4172 
4173  virtual bool get_text_emphasis(const weld::TreeIter& rIter, int col) const override
4174  {
4175  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4176  return ::get_text_emphasis(rVclIter.iter, col);
4177  }
4178 
4179  virtual bool get_text_emphasis(int pos, int col) const override
4180  {
4181  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4182  return ::get_text_emphasis(pEntry, col);
4183  }
4184 
4185  virtual void connect_editing(const Link<const weld::TreeIter&, bool>& rStartLink,
4186  const Link<const std::pair<const weld::TreeIter&, OUString>&, bool>& rEndLink) override
4187  {
4188  m_xTreeView->EnableInplaceEditing(rStartLink.IsSet() || rEndLink.IsSet());
4189  weld::TreeView::connect_editing(rStartLink, rEndLink);
4190  }
4191 
4192  virtual void start_editing(const weld::TreeIter& rIter) override
4193  {
4194  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4195  m_xTreeView->EditEntry(rVclIter.iter);
4196  }
4197 
4198  virtual void end_editing() override
4199  {
4200  m_xTreeView->EndEditing();
4201  }
4202 
4203  void set_image(SvTreeListEntry* pEntry, const Image& rImage, int col)
4204  {
4205  if (col == -1)
4206  {
4207  m_xTreeView->SetExpandedEntryBmp(pEntry, rImage);
4208  m_xTreeView->SetCollapsedEntryBmp(pEntry, rImage);
4209  return;
4210  }
4211 
4212  ++col; //skip dummy/expander column
4213 
4214  // blank out missing entries
4215  for (int i = pEntry->ItemCount(); i < col ; ++i)
4216  pEntry->AddItem(std::make_unique<SvLBoxString>(""));
4217 
4218  if (static_cast<size_t>(col) == pEntry->ItemCount())
4219  {
4220  pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(rImage, rImage, false));
4221  SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry);
4222  m_xTreeView->InitViewData(pViewData, pEntry);
4223  }
4224  else
4225  {
4226  assert(col >= 0 && static_cast<size_t>(col) < pEntry->ItemCount());
4227  SvLBoxItem& rItem = pEntry->GetItem(col);
4228  assert(dynamic_cast<SvLBoxContextBmp*>(&rItem));
4229  static_cast<SvLBoxContextBmp&>(rItem).SetBitmap1(rImage);
4230  static_cast<SvLBoxContextBmp&>(rItem).SetBitmap2(rImage);
4231  }
4232 
4233  m_xTreeView->SetEntryHeight(pEntry);
4234  m_xTreeView->ModelHasEntryInvalidated(pEntry);
4235  }
4236 
4237  virtual void set_image(int pos, const OUString& rImage, int col) override
4238  {
4239  set_image(m_xTreeView->GetEntry(nullptr, pos), createImage(rImage), col);
4240  }
4241 
4242  virtual void set_image(int pos, const css::uno::Reference<css::graphic::XGraphic>& rImage, int col) override
4243  {
4244  set_image(m_xTreeView->GetEntry(nullptr, pos), Image(rImage), col);
4245  }
4246 
4247  virtual void set_image(int pos, VirtualDevice& rImage, int col) override
4248  {
4249  set_image(m_xTreeView->GetEntry(nullptr, pos), createImage(rImage), col);
4250  }
4251 
4252  virtual void set_image(const weld::TreeIter& rIter, const OUString& rImage, int col) override
4253  {
4254  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4255  set_image(rVclIter.iter, createImage(rImage), col);
4256  }
4257 
4258  virtual void set_image(const weld::TreeIter& rIter, const css::uno::Reference<css::graphic::XGraphic>& rImage, int col) override
4259  {
4260  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4261  set_image(rVclIter.iter, Image(rImage), col);
4262  }
4263 
4264  virtual void set_image(const weld::TreeIter& rIter, VirtualDevice& rImage, int col) override
4265  {
4266  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4267  set_image(rVclIter.iter, createImage(rImage), col);
4268  }
4269 
4270  const OUString* getEntryData(int index) const
4271  {
4272  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, index);
4273  return pEntry ? static_cast<const OUString*>(pEntry->GetUserData()) : nullptr;
4274  }
4275 
4276  virtual OUString get_id(int pos) const override
4277  {
4278  const OUString* pRet = getEntryData(pos);
4279  if (!pRet)
4280  return OUString();
4281  return *pRet;
4282  }
4283 
4284  void set_id(SvTreeListEntry* pEntry, const OUString& rId)
4285  {
4286  m_aUserData.emplace_back(std::make_unique<OUString>(rId));
4287  pEntry->SetUserData(m_aUserData.back().get());
4288  }
4289 
4290  virtual void set_id(int pos, const OUString& rId) override
4291  {
4292  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4293  set_id(pEntry, rId);
4294  }
4295 
4296  virtual int get_selected_index() const override
4297  {
4298  assert(m_xTreeView->IsUpdateMode() && "don't request selection when frozen");
4299  SvTreeListEntry* pEntry = m_xTreeView->FirstSelected();
4300  if (!pEntry)
4301  return -1;
4302  return SvTreeList::GetRelPos(pEntry);
4303  }
4304 
4305  virtual OUString get_selected_text() const override
4306  {
4307  assert(m_xTreeView->IsUpdateMode() && "don't request selection when frozen");
4308  if (SvTreeListEntry* pEntry = m_xTreeView->FirstSelected())
4309  return m_xTreeView->GetEntryText(pEntry);
4310  return OUString();
4311  }
4312 
4313  virtual OUString get_selected_id() const override
4314  {
4315  assert(m_xTreeView->IsUpdateMode() && "don't request selection when frozen");
4316  if (SvTreeListEntry* pEntry = m_xTreeView->FirstSelected())
4317  {
4318  if (const OUString* pStr = static_cast<const OUString*>(pEntry->GetUserData()))
4319  return *pStr;
4320  }
4321  return OUString();
4322  }
4323 
4324  virtual std::unique_ptr<weld::TreeIter> make_iterator(const weld::TreeIter* pOrig) const override
4325  {
4326  return std::unique_ptr<weld::TreeIter>(new SalInstanceTreeIter(static_cast<const SalInstanceTreeIter*>(pOrig)));
4327  }
4328 
4329  virtual void copy_iterator(const weld::TreeIter& rSource, weld::TreeIter& rDest) const override
4330  {
4331  const SalInstanceTreeIter& rVclSource(static_cast<const SalInstanceTreeIter&>(rSource));
4332  SalInstanceTreeIter& rVclDest(static_cast<SalInstanceTreeIter&>(rDest));
4333  rVclDest.iter = rVclSource.iter;
4334  }
4335 
4336  virtual bool get_selected(weld::TreeIter* pIter) const override
4337  {
4338  SvTreeListEntry* pEntry = m_xTreeView->FirstSelected();
4339  auto pVclIter = static_cast<SalInstanceTreeIter*>(pIter);
4340  if (pVclIter)
4341  pVclIter->iter = pEntry;
4342  return pEntry != nullptr;
4343  }
4344 
4345  virtual bool get_cursor(weld::TreeIter* pIter) const override
4346  {
4347  SvTreeListEntry* pEntry = m_xTreeView->GetCurEntry();
4348  auto pVclIter = static_cast<SalInstanceTreeIter*>(pIter);
4349  if (pVclIter)
4350  pVclIter->iter = pEntry;
4351  return pEntry != nullptr;
4352  }
4353 
4354  virtual void set_cursor(const weld::TreeIter& rIter) override
4355  {
4356  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4357  disable_notify_events();
4358  m_xTreeView->SetCurEntry(rVclIter.iter);
4359  enable_notify_events();
4360  }
4361 
4362  virtual bool get_iter_first(weld::TreeIter& rIter) const override
4363  {
4364  SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
4365  rVclIter.iter = m_xTreeView->GetEntry(0);
4366  return rVclIter.iter != nullptr;
4367  }
4368 
4369  virtual bool iter_next_sibling(weld::TreeIter& rIter) const override
4370  {
4371  SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
4372  rVclIter.iter = rVclIter.iter->NextSibling();
4373  return rVclIter.iter != nullptr;
4374  }
4375 
4376  virtual bool iter_next(weld::TreeIter& rIter) const override
4377  {
4378  SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
4379  rVclIter.iter = m_xTreeView->Next(rVclIter.iter);
4380  if (rVclIter.iter && IsDummyEntry(rVclIter.iter))
4381  return iter_next(rVclIter);
4382  return rVclIter.iter != nullptr;
4383  }
4384 
4385  virtual bool iter_children(weld::TreeIter& rIter) const override
4386  {
4387  SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
4388  rVclIter.iter = m_xTreeView->FirstChild(rVclIter.iter);
4389  bool bRet = rVclIter.iter != nullptr;
4390  if (bRet)
4391  {
4392  //on-demand dummy entry doesn't count
4393  return !IsDummyEntry(rVclIter.iter);
4394  }
4395  return bRet;
4396  }
4397 
4398  virtual bool iter_parent(weld::TreeIter& rIter) const override
4399  {
4400  SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
4401  rVclIter.iter = m_xTreeView->GetParent(rVclIter.iter);
4402  return rVclIter.iter != nullptr;
4403  }
4404 
4405  virtual void remove(const weld::TreeIter& rIter) override
4406  {
4407  disable_notify_events();
4408  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4409  m_xTreeView->RemoveEntry(rVclIter.iter);
4410  enable_notify_events();
4411  }
4412 
4413  virtual void select(const weld::TreeIter& rIter) override
4414  {
4415  assert(m_xTreeView->IsUpdateMode() && "don't select when frozen");
4416  disable_notify_events();
4417  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4418  m_xTreeView->Select(rVclIter.iter, true);
4419  enable_notify_events();
4420  }
4421 
4422  virtual void scroll_to_row(const weld::TreeIter& rIter) override
4423  {
4424  assert(m_xTreeView->IsUpdateMode() && "don't select when frozen");
4425  disable_notify_events();
4426  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4427  m_xTreeView->MakeVisible(rVclIter.iter);
4428  enable_notify_events();
4429  }
4430 
4431  virtual void unselect(const weld::TreeIter& rIter) override
4432  {
4433  assert(m_xTreeView->IsUpdateMode() && "don't unselect when frozen");
4434  disable_notify_events();
4435  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4436  m_xTreeView->Select(rVclIter.iter, false);
4437  enable_notify_events();
4438  }
4439 
4440  virtual int get_iter_depth(const weld::TreeIter& rIter) const override
4441  {
4442  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4443  return m_xTreeView->GetModel()->GetDepth(rVclIter.iter);
4444  }
4445 
4446  virtual bool iter_has_child(const weld::TreeIter& rIter) const override
4447  {
4448  weld::TreeIter& rNonConstIter = const_cast<weld::TreeIter&>(rIter);
4449  SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rNonConstIter);
4450  SvTreeListEntry* restore(rVclIter.iter);
4451  bool ret = iter_children(rNonConstIter);
4452  rVclIter.iter = restore;
4453  return ret;
4454  }
4455 
4456  virtual bool get_row_expanded(const weld::TreeIter& rIter) const override
4457  {
4458  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4459  return m_xTreeView->IsExpanded(rVclIter.iter);
4460  }
4461 
4462  virtual void expand_row(const weld::TreeIter& rIter) override
4463  {
4464  assert(m_xTreeView->IsUpdateMode() && "don't expand when frozen");
4465  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4466  if (!m_xTreeView->IsExpanded(rVclIter.iter) && signal_expanding(rIter))
4467  m_xTreeView->Expand(rVclIter.iter);
4468  }
4469 
4470  virtual void collapse_row(const weld::TreeIter& rIter) override
4471  {
4472  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4473  if (m_xTreeView->IsExpanded(rVclIter.iter))
4474  m_xTreeView->Collapse(rVclIter.iter);
4475  }
4476 
4477  virtual OUString get_text(const weld::TreeIter& rIter, int col) const override
4478  {
4479  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4480  return get_text(rVclIter.iter, col);
4481  }
4482 
4483  virtual void set_text(const weld::TreeIter& rIter, const OUString& rText, int col) override
4484  {
4485  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4486  set_text(rVclIter.iter, rText, col);
4487  }
4488 
4489  virtual OUString get_id(const weld::TreeIter& rIter) const override
4490  {
4491  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4492  const OUString* pStr = static_cast<const OUString*>(rVclIter.iter->GetUserData());
4493  if (pStr)
4494  return *pStr;
4495  return OUString();
4496  }
4497 
4498  virtual void set_id(const weld::TreeIter& rIter, const OUString& rId) override
4499  {
4500  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4501  set_id(rVclIter.iter, rId);
4502  }
4503 
4504  virtual void enable_drag_source(rtl::Reference<TransferDataContainer>& rHelper, sal_uInt8 eDNDConstants) override
4505  {
4506  m_xTreeView->SetDragHelper(rHelper, eDNDConstants);
4507  }
4508 
4509  virtual void set_selection_mode(SelectionMode eMode) override
4510  {
4511  m_xTreeView->SetSelectionMode(eMode);
4512  }
4513 
4514  virtual void all_foreach(const std::function<bool(weld::TreeIter&)>& func) override
4515  {
4516  SalInstanceTreeIter aVclIter(m_xTreeView->First());
4517  while (aVclIter.iter)
4518  {
4519  if (func(aVclIter))
4520  return;
4521  aVclIter.iter = m_xTreeView->Next(aVclIter.iter);
4522  }
4523  }
4524 
4525  virtual void selected_foreach(const std::function<bool(weld::TreeIter&)>& func) override
4526  {
4527  SalInstanceTreeIter aVclIter(m_xTreeView->FirstSelected());
4528  while (aVclIter.iter)
4529  {
4530  if (func(aVclIter))
4531  return;
4532  aVclIter.iter = m_xTreeView->NextSelected(aVclIter.iter);
4533  }
4534  }
4535 
4536  virtual void visible_foreach(const std::function<bool(weld::TreeIter&)>& func) override
4537  {
4538  SalInstanceTreeIter aVclIter(m_xTreeView->GetFirstEntryInView());
4539  while (aVclIter.iter)
4540  {
4541  if (func(aVclIter))
4542  return;
4543  aVclIter.iter = m_xTreeView->GetNextEntryInView(aVclIter.iter);
4544  }
4545  }
4546 
4548  {
4550  m_xTreeView->SetScrolledHdl(LINK(this, SalInstanceTreeView, VisibleRangeChangedHdl));
4551  }
4552 
4553  virtual void remove_selection() override
4554  {
4555  disable_notify_events();
4556  SvTreeListEntry* pSelected = m_xTreeView->FirstSelected();
4557  while (pSelected)
4558  {
4559  SvTreeListEntry* pNextSelected = m_xTreeView->NextSelected(pSelected);
4560  m_xTreeView->RemoveEntry(pSelected);
4561  pSelected = pNextSelected;
4562  }
4563  enable_notify_events();
4564  }
4565 
4566  virtual bool is_selected(const weld::TreeIter& rIter) const override
4567  {
4568  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4569  return m_xTreeView->IsSelected(rVclIter.iter);
4570  }
4571 
4572  virtual int get_iter_index_in_parent(const weld::TreeIter& rIter) const override
4573  {
4574  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4575  return SvTreeList::GetRelPos(rVclIter.iter);
4576  }
4577 
4578  virtual int iter_compare(const weld::TreeIter& a, const weld::TreeIter& b) const override
4579  {
4580  const SalInstanceTreeIter& rVclIterA = static_cast<const SalInstanceTreeIter&>(a);
4581  const SalInstanceTreeIter& rVclIterB = static_cast<const SalInstanceTreeIter&>(b);
4582  const SvTreeList* pModel = m_xTreeView->GetModel();
4583  auto nAbsPosA = pModel->GetAbsPos(rVclIterA.iter);
4584  auto nAbsPosB = pModel->GetAbsPos(rVclIterB.iter);
4585  if (nAbsPosA < nAbsPosB)
4586  return -1;
4587  if (nAbsPosA > nAbsPosB)
4588  return 1;
4589  return 0;
4590  }
4591 
4592  virtual void move_subtree(weld::TreeIter& rNode, const weld::TreeIter* pNewParent, int nIndexInNewParent) override
4593  {
4594  SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rNode);
4595  const SalInstanceTreeIter* pVclParentIter = static_cast<const SalInstanceTreeIter*>(pNewParent);
4596  m_xTreeView->GetModel()->Move(rVclIter.iter, pVclParentIter ? pVclParentIter->iter : nullptr, nIndexInNewParent);
4597  }
4598 
4599  virtual int count_selected_rows() const override
4600  {
4601  return m_xTreeView->GetSelectionCount();
4602  }
4603 
4604  virtual int get_height_rows(int nRows) const override
4605  {
4606  return m_xTreeView->GetEntryHeight() * nRows;
4607  }
4608 
4609  virtual void make_sorted() override
4610  {
4611  assert(m_xTreeView->IsUpdateMode() && "don't sort when frozen");
4612  m_xTreeView->SetStyle(m_xTreeView->GetStyle() | WB_SORT);
4613  m_xTreeView->GetModel()->SetCompareHdl(LINK(this, SalInstanceTreeView, CompareHdl));
4614  set_sort_order(true);
4615  }
4616 
4617  virtual void set_sort_func(const std::function<int(const weld::TreeIter&, const weld::TreeIter&)>& func) override
4618  {
4620  SvTreeList* pListModel = m_xTreeView->GetModel();
4621  pListModel->Resort();
4622  }
4623 
4624  virtual void make_unsorted() override
4625  {
4626  m_xTreeView->SetStyle(m_xTreeView->GetStyle() & ~WB_SORT);
4627  }
4628 
4629  virtual void set_sort_order(bool bAscending) override
4630  {
4631  SvTreeList* pListModel = m_xTreeView->GetModel();
4632  pListModel->SetSortMode(bAscending ? SortAscending : SortDescending);
4633  pListModel->Resort();
4634  }
4635 
4636  virtual bool get_sort_order() const override
4637  {
4638  return m_xTreeView->GetModel()->GetSortMode() == SortAscending;
4639  }
4640 
4641  virtual void set_sort_indicator(TriState eState, int col) override
4642  {
4643  if (col == -1)
4644  col = 0;
4645 
4646  LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
4647  if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
4648  {
4649  sal_uInt16 nTextId = pHeaderBar->GetItemId(col);
4650  HeaderBarItemBits nBits = pHeaderBar->GetItemBits(nTextId);
4651  nBits &= ~HeaderBarItemBits::UPARROW;
4652  nBits &= ~HeaderBarItemBits::DOWNARROW;
4653  if (eState != TRISTATE_INDET)
4654  {
4655  if (eState == TRISTATE_TRUE)
4657  else
4658  nBits |= HeaderBarItemBits::UPARROW;
4659  }
4660  pHeaderBar->SetItemBits(nTextId, nBits);
4661  }
4662  }
4663 
4664  virtual TriState get_sort_indicator(int col) const override
4665  {
4666  if (col == -1)
4667  col = 0;
4668 
4669  LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
4670  if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
4671  {
4672  sal_uInt16 nTextId = pHeaderBar->GetItemId(col);
4673  HeaderBarItemBits nBits = pHeaderBar->GetItemBits(nTextId);
4674  if (nBits & HeaderBarItemBits::DOWNARROW)
4675  return TRISTATE_TRUE;
4676  if (nBits & HeaderBarItemBits::UPARROW)
4677  return TRISTATE_FALSE;
4678  }
4679 
4680  return TRISTATE_INDET;
4681  }
4682 
4683  virtual int get_sort_column() const override
4684  {
4685  return m_nSortColumn;
4686  }
4687 
4688  virtual void set_sort_column(int nColumn) override
4689  {
4690  if (nColumn == -1)
4691  {
4692  make_unsorted();
4693  m_nSortColumn = -1;
4694  return;
4695  }
4696 
4697  if (nColumn != m_nSortColumn)
4698  {
4699  m_nSortColumn = nColumn;
4700  m_xTreeView->GetModel()->Resort();
4701  }
4702  }
4703 
4705  {
4706  return *m_xTreeView;
4707  }
4708 
4709  virtual bool get_dest_row_at_pos(const Point &rPos, weld::TreeIter* pResult) override
4710  {
4711  SvTreeListEntry* pTarget = m_xTreeView->GetDropTarget(rPos);
4712 
4713  if (pTarget && pResult)
4714  {
4715  SalInstanceTreeIter& rSalIter = static_cast<SalInstanceTreeIter&>(*pResult);
4716  rSalIter.iter = pTarget;
4717  }
4718 
4719  return pTarget != nullptr;
4720  }
4721 
4722  virtual TreeView* get_drag_source() const override
4723  {
4724  return g_DragSource;
4725  }
4726 
4727  virtual ~SalInstanceTreeView() override
4728  {
4729  LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
4730  if (pHeaderBox)
4731  {
4732  if (HeaderBar* pHeaderBar = pHeaderBox->GetHeaderBar())
4733  {
4734  pHeaderBar->SetSelectHdl(Link<HeaderBar*, void>());
4735  pHeaderBar->SetEndDragHdl(Link<HeaderBar*, void>());
4736  }
4737  }
4738  else
4739  {
4740  static_cast<LclTabListBox&>(*m_xTreeView).SetEndDragHdl(Link<SvTreeListBox*, void>());
4741  static_cast<LclTabListBox&>(*m_xTreeView).SetStartDragHdl(Link<SvTreeListBox*, bool>());
4742  static_cast<LclTabListBox&>(*m_xTreeView).SetModelChangedHdl(Link<SvTreeListBox*, void>());
4743  }
4747  m_xTreeView->SetSelectHdl(Link<SvTreeListBox*, void>());
4751  }
4752 };
4753 
4754 IMPL_LINK(SalInstanceTreeView, TooltipHdl, const HelpEvent&, rHEvt, bool)
4755 {
4756  if (notify_events_disabled())
4757  return false;
4758  Point aPos(m_xTreeView->ScreenToOutputPixel(rHEvt.GetMousePosPixel()));
4759  SvTreeListEntry* pEntry = m_xTreeView->GetEntry(aPos);
4760  if (pEntry)
4761  {
4762  SalInstanceTreeIter aIter(pEntry);
4763  OUString aTooltip = signal_query_tooltip(aIter);
4764  if (aTooltip.isEmpty())
4765  return false;
4766  Size aSize(m_xTreeView->GetOutputSizePixel().Width(), m_xTreeView->GetEntryHeight());
4767  tools::Rectangle aScreenRect(m_xTreeView->OutputToScreenPixel(m_xTreeView->GetEntryPosition(pEntry)), aSize);
4768  Help::ShowQuickHelp(m_xTreeView, aScreenRect, aTooltip);
4769  }
4770  return true;
4771 }
4772 
4773 IMPL_LINK(SalInstanceTreeView, CompareHdl, const SvSortData&, rSortData, sal_Int32)
4774 {
4775  const SvTreeListEntry* pLHS = rSortData.pLeft;
4776  const SvTreeListEntry* pRHS = rSortData.pRight;
4777  assert(pLHS && pRHS);
4778 
4779  if (m_aCustomSort)
4780  return m_aCustomSort(SalInstanceTreeIter(const_cast<SvTreeListEntry*>(pLHS)),
4781  SalInstanceTreeIter(const_cast<SvTreeListEntry*>(pRHS)));
4782 
4783  const SvLBoxString* pLeftTextItem;
4784  const SvLBoxString* pRightTextItem;
4785 
4786  if (m_nSortColumn != -1)
4787  {
4788  size_t col = m_nSortColumn;
4789 
4790  ++col; //skip dummy/expander column
4791 
4792  if (col < pLHS->ItemCount())
4793  {
4794  const SvLBoxString& rLeftTextItem = static_cast<const SvLBoxString&>(pLHS->GetItem(col));
4795  pLeftTextItem = &rLeftTextItem;
4796  }
4797  else
4798  pLeftTextItem = nullptr;
4799  if (col < pRHS->ItemCount())
4800  {
4801  const SvLBoxString& rRightTextItem = static_cast<const SvLBoxString&>(pRHS->GetItem(col));
4802  pRightTextItem = &rRightTextItem;
4803  }
4804  else
4805  pRightTextItem = nullptr;
4806  }
4807  else
4808  {
4809  pLeftTextItem = static_cast<const SvLBoxString*>(pLHS->GetFirstItem(SvLBoxItemType::String));
4810  pRightTextItem = static_cast<const SvLBoxString*>(pRHS->GetFirstItem(SvLBoxItemType::String));
4811  }
4812 
4813  return m_xTreeView->DefaultCompare(pLeftTextItem, pRightTextItem);
4814 }
4815 
4816 IMPL_LINK_NOARG(SalInstanceTreeView, VisibleRangeChangedHdl, SvTreeListBox*, void)
4817 {
4818  if (notify_events_disabled())
4819  return;
4820  signal_visible_range_changed();
4821 }
4822 
4824 {
4825  if (notify_events_disabled())
4826  return;
4827  signal_model_changed();
4828 }
4829 
4831 {
4832  if (m_aDragBeginHdl.Call(*this))
4833  return true;
4834  g_DragSource = this;
4835  return false;
4836 }
4837 
4839 {
4840  g_DragSource = nullptr;
4841 }
4842 
4844 {
4845  SvTreeListEntry* pEntry = pData->GetActEntry();
4846  SvLBoxButton* pBox = pData->GetActBox();
4847 
4848  // tdf#122874 Select the row, calling SelectHdl, before handling
4849  // the toggle
4850  if (!m_xTreeView->IsSelected(pEntry))
4851  {
4852  m_xTreeView->SelectAll(false);
4853  m_xTreeView->Select(pEntry, true);
4854  }
4855 
4856  // toggled signal handlers can query get_cursor to get which
4857  // node was clicked
4858  m_xTreeView->pImpl->m_pCursor = pEntry;
4859 
4860  for (int i = 1, nCount = pEntry->ItemCount(); i < nCount; ++i)
4861  {
4862  SvLBoxItem& rItem = pEntry->GetItem(i);
4863  if (&rItem == pBox)
4864  {
4865  int nRow = SvTreeList::GetRelPos(pEntry);
4866  int nCol = i - 1; // less dummy/expander column
4867  signal_toggled(std::make_pair(nRow, nCol));
4868  break;
4869  }
4870  }
4871 }
4872 
4874 {
4875  if (notify_events_disabled())
4876  return;
4877  signal_changed();
4878 }
4879 
4881 {
4882  if (notify_events_disabled())
4883  return;
4884  if (m_xTreeView->GetSelectionMode() == SelectionMode::Single)
4885  return;
4886  signal_changed();
4887 }
4888 
4890 {
4891  if (notify_events_disabled())
4892  return false;
4893  return !signal_row_activated();
4894 }
4895 
4896 IMPL_LINK(SalInstanceTreeView, EndDragHdl, HeaderBar*, pHeaderBar, void)
4897 {
4898  std::vector<long> aTabPositions;
4899  aTabPositions.push_back(0);
4900  for (int i = 0; i < pHeaderBar->GetItemCount() - 1; ++i)
4901  aTabPositions.push_back(aTabPositions[i] + pHeaderBar->GetItemSize(pHeaderBar->GetItemId(i)));
4902  m_xTreeView->SetTabs(aTabPositions.size(), aTabPositions.data(), MapUnit::MapPixel);
4903 }
4904 
4905 IMPL_LINK(SalInstanceTreeView, HeaderBarClickedHdl, HeaderBar*, pHeaderBar, void)
4906 {
4907  sal_uInt16 nId = pHeaderBar->GetCurItemId();
4908  if (!(pHeaderBar->GetItemBits(nId) & HeaderBarItemBits::CLICKABLE))
4909  return;
4910  signal_column_clicked(pHeaderBar->GetItemPos(nId));
4911 }
4912 
4914 {
4915  SvTreeListEntry* pEntry = m_xTreeView->GetHdlEntry();
4916  if (m_xTreeView->IsExpanded(pEntry))
4917  {
4918  //collapsing;
4919  return true;
4920  }
4921 
4922  // if there's a preexisting placeholder child, required to make this
4923  // potentially expandable in the first place, now we remove it
4924  bool bPlaceHolder = false;
4925  if (pEntry->HasChildren())
4926  {
4927  auto pChild = m_xTreeView->FirstChild(pEntry);
4928  assert(pChild);
4929  if (IsDummyEntry(pChild))
4930  {
4931  m_xTreeView->RemoveEntry(pChild);
4932  bPlaceHolder = true;
4933  }
4934  }
4935 
4936  SalInstanceTreeIter aIter(pEntry);
4937  bool bRet = signal_expanding(aIter);
4938 
4939  //expand disallowed, restore placeholder
4940  if (!bRet && bPlaceHolder)
4941  {
4942  m_xTreeView->InsertEntry("<dummy>", pEntry, false, 0, nullptr);
4943  }
4944 
4945  return bRet;
4946 }
4947 
4948 IMPL_LINK(SalInstanceTreeView, PopupMenuHdl, const CommandEvent&, rEvent, bool)
4949 {
4950  return m_aPopupMenuHdl.Call(rEvent);
4951 }
4952 
4953 IMPL_LINK(SalInstanceTreeView, EditingEntryHdl, SvTreeListEntry*, pEntry, bool)
4954 {
4955  return signal_editing_started(SalInstanceTreeIter(pEntry));
4956 }
4957 
4958 IMPL_LINK(SalInstanceTreeView, EditedEntryHdl, IterString, rIterString, bool)
4959 {
4960  return signal_editing_done(std::pair<const weld::TreeIter&, OUString>(SalInstanceTreeIter(rIterString.first), rIterString.second));
4961 }
4962 
4963 class SalInstanceIconView : public SalInstanceContainer, public virtual weld::IconView
4964 {
4965 private:
4966  // owner for UserData
4967  std::vector<std::unique_ptr<OUString>> m_aUserData;
4969 
4970  DECL_LINK(SelectHdl, SvTreeListBox*, void);
4971  DECL_LINK(DeSelectHdl, SvTreeListBox*, void);
4972  DECL_LINK(DoubleClickHdl, SvTreeListBox*, bool);
4973 
4974 public:
4975  SalInstanceIconView(::IconView* pIconView, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
4976  : SalInstanceContainer(pIconView, pBuilder, bTakeOwnership)
4977  , m_xIconView(pIconView)
4978  {
4979  m_xIconView->SetSelectHdl(LINK(this, SalInstanceIconView, SelectHdl));
4980  m_xIconView->SetDeselectHdl(LINK(this, SalInstanceIconView, DeSelectHdl));
4981  m_xIconView->SetDoubleClickHdl(LINK(this, SalInstanceIconView, DoubleClickHdl));
4982  }
4983 
4984  virtual void freeze() override
4985  {
4986  SalInstanceWidget::freeze();
4987  m_xIconView->SetUpdateMode(false);
4988  }
4989 
4990  virtual void thaw() override
4991  {
4992  m_xIconView->SetUpdateMode(true);
4993  SalInstanceWidget::thaw();
4994  }
4995 
4996  virtual void insert(int pos, const OUString* pStr, const OUString* pId,
4997  const OUString* pIconName, weld::TreeIter* pRet) override
4998  {
4999  disable_notify_events();
5000  auto nInsertPos = pos == -1 ? TREELIST_APPEND : pos;
5001  void* pUserData;
5002  if (pId)
5003  {
5004  m_aUserData.emplace_back(std::make_unique<OUString>(*pId));
5005  pUserData = m_aUserData.back().get();
5006  }
5007  else
5008  pUserData = nullptr;
5009 
5010  SvTreeListEntry* pEntry = new SvTreeListEntry;
5011  if (pIconName)
5012  {
5013  Image aImage(createImage(*pIconName));
5014  pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(aImage, aImage, false));
5015  }
5016  else
5017  {
5018  Image aDummy;
5019  pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(aDummy, aDummy, false));
5020  }
5021  if (pStr)
5022  pEntry->AddItem(std::make_unique<SvLBoxString>(*pStr));
5023  pEntry->SetUserData(pUserData);
5024  m_xIconView->Insert(pEntry, nullptr, nInsertPos);
5025 
5026  if (pRet)
5027  {
5028  SalInstanceTreeIter* pVclRetIter = static_cast<SalInstanceTreeIter*>(pRet);
5029  pVclRetIter->iter = pEntry;
5030  }
5031 
5032  enable_notify_events();
5033  }
5034 
5035  virtual OUString get_selected_id() const override
5036  {
5037  assert(m_xIconView->IsUpdateMode() && "don't request selection when frozen");
5038  if (SvTreeListEntry* pEntry = m_xIconView->FirstSelected())
5039  {
5040  if (const OUString* pStr = static_cast<const OUString*>(pEntry->GetUserData()))
5041  return *pStr;
5042  }
5043  return OUString();
5044  }
5045 
5046  virtual OUString get_selected_text() const override
5047  {
5048  assert(m_xIconView->IsUpdateMode() && "don't request selection when frozen");
5049  if (SvTreeListEntry* pEntry = m_xIconView->FirstSelected())
5050  return m_xIconView->GetEntryText(pEntry);
5051  return OUString();
5052  }
5053 
5054  virtual int count_selected_items() const override
5055  {
5056  return m_xIconView->GetSelectionCount();
5057  }
5058 
5059  virtual void select(int pos) override
5060  {
5061  assert(m_xIconView->IsUpdateMode() && "don't select when frozen");
5062  disable_notify_events();
5063  if (pos == -1 || (pos == 0 && n_children() == 0))
5064  m_xIconView->SelectAll(false);
5065  else
5066  {
5067  SvTreeListEntry* pEntry = m_xIconView->GetEntry(nullptr, pos);
5068  m_xIconView->Select(pEntry, true);
5069  m_xIconView->MakeVisible(pEntry);
5070  }
5071  enable_notify_events();
5072  }
5073 
5074  virtual void unselect(int pos) override
5075  {
5076  assert(m_xIconView->IsUpdateMode() && "don't select when frozen");
5077  disable_notify_events();
5078  if (pos == -1)
5079  m_xIconView->SelectAll(true);
5080  else
5081  {
5082  SvTreeListEntry* pEntry = m_xIconView->GetEntry(nullptr, pos);
5083  m_xIconView->Select(pEntry, false);
5084  }
5085  enable_notify_events();
5086  }
5087 
5088  virtual int n_children() const override
5089  {
5090  return m_xIconView->GetModel()->GetChildList(nullptr).size();
5091  }
5092 
5093  virtual std::unique_ptr<weld::TreeIter> make_iterator(const weld::TreeIter* pOrig) const override
5094  {
5095  return std::unique_ptr<weld::TreeIter>(new SalInstanceTreeIter(static_cast<const SalInstanceTreeIter*>(pOrig)));
5096  }
5097 
5098  virtual bool get_selected(weld::TreeIter* pIter) const override
5099  {
5100  SvTreeListEntry* pEntry = m_xIconView->FirstSelected();
5101  auto pVclIter = static_cast<SalInstanceTreeIter*>(pIter);
5102  if (pVclIter)
5103  pVclIter->iter = pEntry;
5104  return pEntry != nullptr;
5105  }
5106 
5107  virtual bool get_cursor(weld::TreeIter* pIter) const override
5108  {
5109  SvTreeListEntry* pEntry = m_xIconView->GetCurEntry();
5110  auto pVclIter = static_cast<SalInstanceTreeIter*>(pIter);
5111  if (pVclIter)
5112  pVclIter->iter = pEntry;
5113  return pEntry != nullptr;
5114  }
5115 
5116  virtual void set_cursor(const weld::TreeIter& rIter) override
5117  {
5118  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
5119  disable_notify_events();
5120  m_xIconView->SetCurEntry(rVclIter.iter);
5121  enable_notify_events();
5122  }
5123 
5124  virtual bool get_iter_first(weld::TreeIter& rIter) const override
5125  {
5126  SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
5127  rVclIter.iter = m_xIconView->GetEntry(0);
5128  return rVclIter.iter != nullptr;
5129  }
5130 
5131  virtual void scroll_to_item(const weld::TreeIter& rIter) override
5132  {
5133  assert(m_xIconView->IsUpdateMode() && "don't select when frozen");
5134  disable_notify_events();
5135  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
5136  m_xIconView->MakeVisible(rVclIter.iter);
5137  enable_notify_events();
5138  }
5139 
5140  virtual void selected_foreach(const std::function<bool(weld::TreeIter&)>& func) override
5141  {
5142  SalInstanceTreeIter aVclIter(m_xIconView->FirstSelected());
5143  while (aVclIter.iter)
5144  {
5145  if (func(aVclIter))
5146  return;
5147  aVclIter.iter = m_xIconView->NextSelected(aVclIter.iter);
5148  }
5149  }
5150 
5151  virtual OUString get_id(const weld::TreeIter& rIter) const override
5152  {
5153  const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
5154  const OUString* pStr = static_cast<const OUString*>(rVclIter.iter->GetUserData());
5155  if (pStr)
5156  return *pStr;
5157  return OUString();
5158  }
5159 
5160  virtual void clear() override
5161  {
5162  disable_notify_events();
5163  m_xIconView->Clear();
5164  m_aUserData.clear();
5165  enable_notify_events();
5166  }
5167 
5168  virtual ~SalInstanceIconView() override
5169  {
5171  m_xIconView->SetSelectHdl(Link<SvTreeListBox*, void>());
5173  }
5174 };
5175 
5177 {
5178  if (notify_events_disabled())
5179  return;
5180  signal_selection_changed();
5181 }
5182 
5184 {
5185  if (notify_events_disabled())
5186  return;
5187  if (m_xIconView->GetSelectionMode() == SelectionMode::Single)
5188  return;
5189  signal_selection_changed();
5190 }
5191 
5193 {
5194  if (notify_events_disabled())
5195  return false;
5196  return !signal_item_activated();
5197 }
5198 
5199 namespace {
5200 
5201 class SalInstanceSpinButton : public SalInstanceEntry, public virtual weld::SpinButton
5202 {
5203 private:
5204  VclPtr<FormattedField> m_xButton;
5205 
5206  DECL_LINK(UpDownHdl, SpinField&, void);
5207  DECL_LINK(LoseFocusHdl, Control&, void);
5208  DECL_LINK(OutputHdl, Edit&, bool);
5209  DECL_LINK(InputHdl, sal_Int64*, TriState);
5210  DECL_LINK(ActivateHdl, Edit&, bool);
5211 
5212  double toField(int nValue) const
5213  {
5214  return static_cast<double>(nValue) / Power10(get_digits());
5215  }
5216 
5217  int fromField(double fValue) const
5218  {
5219  return FRound(fValue * Power10(get_digits()));
5220  }
5221 
5222 public:
5223  SalInstanceSpinButton(FormattedField* pButton, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
5224  : SalInstanceEntry(pButton, pBuilder, bTakeOwnership)
5225  , m_xButton(pButton)
5226  {
5227  m_xButton->SetThousandsSep(false); //off by default, MetricSpinButton enables it
5228  m_xButton->SetUpHdl(LINK(this, SalInstanceSpinButton, UpDownHdl));
5229  m_xButton->SetDownHdl(LINK(this, SalInstanceSpinButton, UpDownHdl));
5230  m_xButton->SetLoseFocusHdl(LINK(this, SalInstanceSpinButton, LoseFocusHdl));
5231  m_xButton->SetOutputHdl(LINK(this, SalInstanceSpinButton, OutputHdl));
5232  m_xButton->SetInputHdl(LINK(this, SalInstanceSpinButton, InputHdl));
5233  if (Edit* pEdit = m_xButton->GetSubEdit())
5234  pEdit->SetActivateHdl(LINK(this, SalInstanceSpinButton, ActivateHdl));
5235  else
5236  m_xButton->SetActivateHdl(LINK(this, SalInstanceSpinButton, ActivateHdl));
5237  }
5238 
5239  virtual int get_value() const override
5240  {
5241  return fromField(m_xButton->GetValue());
5242  }
5243 
5244  virtual void set_value(int value) override
5245  {
5246  m_xButton->SetValue(toField(value));
5247  }
5248 
5249  virtual void set_range(int min, int max) override
5250  {
5251  m_xButton->SetMinValue(toField(min));
5252  m_xButton->SetMaxValue(toField(max));
5253  }
5254 
5255  virtual void get_range(int& min, int& max) const override
5256  {
5257  min = fromField(m_xButton->GetMinValue());
5258  max = fromField(m_xButton->GetMaxValue());
5259  }
5260 
5261  virtual void set_increments(int step, int /*page*/) override
5262  {
5263  m_xButton->SetSpinSize(toField(step));
5264  }
5265 
5266  virtual void get_increments(int& step, int& page) const override
5267  {
5268  step = fromField(m_xButton->GetSpinSize());
5269  page = fromField(m_xButton->GetSpinSize());
5270  }
5271 
5272  virtual void set_digits(unsigned int digits) override
5273  {
5274  m_xButton->SetDecimalDigits(digits);
5275  }
5276 
5277  // SpinButton may be comprised of multiple subwidgets, consider the lot as
5278  // one thing for focus
5279  virtual bool has_focus() const override
5280  {
5281  return m_xWidget->HasChildPathFocus();
5282  }
5283 
5284  //so with hh::mm::ss, incrementing mm will not reset ss
5285  void DisableRemainderFactor()
5286  {
5287  m_xButton->DisableRemainderFactor();
5288  }
5289 
5290  //off by default for direct SpinButtons, MetricSpinButton enables it
5291  void SetUseThousandSep()
5292  {
5293  m_xButton->SetThousandsSep(true);
5294  }
5295 
5296  virtual unsigned int get_digits() const override
5297  {
5298  return m_xButton->GetDecimalDigits();
5299  }
5300 
5301  virtual ~SalInstanceSpinButton() override
5302  {
5303  if (Edit* pEdit = m_xButton->GetSubEdit())
5304  pEdit->SetActivateHdl(Link<Edit&, bool>());
5305  else
5306  m_xButton->SetActivateHdl(Link<Edit&, bool>());
5308  m_xButton->SetOutputHdl(Link<Edit&, bool>());
5309  m_xButton->SetLoseFocusHdl(Link<Control&, void>());
5310  m_xButton->SetDownHdl(Link<SpinField&, void>());
5311  m_xButton->SetUpHdl(Link<SpinField&, void>());
5312  }
5313 };
5314 
5315 }
5316 
5317 IMPL_LINK_NOARG(SalInstanceSpinButton, ActivateHdl, Edit&, bool)
5318 {
5319  // tdf#122348 return pressed to end dialog
5320  signal_value_changed();
5321  return false;
5322 }
5323 
5324 IMPL_LINK_NOARG(SalInstanceSpinButton, UpDownHdl, SpinField&, void)
5325 {
5326  signal_value_changed();
5327 }
5328 
5329 IMPL_LINK_NOARG(SalInstanceSpinButton, LoseFocusHdl, Control&, void)
5330 {
5331  signal_value_changed();
5332 }
5333 
5334 IMPL_LINK_NOARG(SalInstanceSpinButton, OutputHdl, Edit&, bool)
5335 {
5336  return signal_output();
5337 }
5338 
5339 IMPL_LINK(SalInstanceSpinButton, InputHdl, sal_Int64*, pResult, TriState)
5340 {
5341  int nResult;
5342  TriState eRet = signal_input(&nResult);
5343  if (eRet == TRISTATE_TRUE)
5344  *pResult = nResult;
5345  return eRet;
5346 }
5347 
5348 namespace {
5349 
5350 class SalInstanceFormattedSpinButton : public SalInstanceEntry, public virtual weld::FormattedSpinButton
5351 {
5352 private:
5353  VclPtr<FormattedField> m_xButton;
5354 
5355 public:
5356  SalInstanceFormattedSpinButton(FormattedField* pButton, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
5357  : SalInstanceEntry(pButton, pBuilder, bTakeOwnership)
5358  , m_xButton(pButton)
5359  {
5360  // #i6278# allow more decimal places than the output format. As
5361  // the numbers shown in the edit fields are used for input, it makes more
5362  // sense to display the values in the input format rather than the output
5363  // format.
5364  m_xButton->UseInputStringForFormatting();
5365  }
5366 
5367  virtual double get_value() const override
5368  {
5369  return m_xButton->GetValue();
5370  }
5371 
5372  virtual void set_value(double value) override
5373  {
5374  m_xButton->SetValue(value);
5375  }
5376 
5377  virtual void set_range(double min, double max) override
5378  {
5379  m_xButton->SetMinValue(min);
5380  m_xButton->SetMaxValue(max);
5381  }
5382 
5383  virtual void get_range(double& min, double& max) const override
5384  {
5385  min = m_xButton->GetMinValue();
5386  max = m_xButton->GetMaxValue();
5387  }
5388 
5389  virtual void set_formatter(SvNumberFormatter* pFormatter) override
5390  {
5391  m_xButton->SetFormatter(pFormatter);
5392  }
5393 
5394  virtual SvNumberFormatter* get_formatter() override
5395  {
5396  return m_xButton->GetFormatter();
5397  }
5398 
5399  virtual sal_Int32 get_format_key() const override
5400  {
5401  return m_xButton->GetFormatKey();
5402  }
5403 
5404  virtual void set_format_key(sal_Int32 nFormatKey) override
5405  {
5406  m_xButton->SetFormatKey(nFormatKey);
5407  }
5408 
5409  virtual void treat_as_number(bool bSet) override
5410  {
5411  m_xButton->TreatAsNumber(bSet);
5412  }
5413 
5414  virtual void set_digits(unsigned int digits) override
5415  {
5416  m_xButton->SetDecimalDigits(digits);
5417  }
5418 };
5419 
5420 class SalInstanceLabel : public SalInstanceWidget, public virtual weld::Label
5421 {
5422 private:
5423  // Control instead of FixedText so we can also use this for
5424  // SelectableFixedText which is derived from Edit. We just typically need
5425  // [G|S]etText which exists in their shared baseclass
5426  VclPtr<Control> m_xLabel;
5427 public:
5428  SalInstanceLabel(Control* pLabel, SalInstanceBuilder *pBuilder, bool bTakeOwnership)
5429  : SalInstanceWidget(pLabel, pBuilder, bTakeOwnership)
5430  , m_xLabel(pLabel)
5431  {
5432  }
5433 
5434  virtual void set_label(const OUString& rText) override
5435  {
5436  m_xLabel->SetText(rText);
5437  }
5438 
5439  virtual OUString get_label() const override
5440  {
5441  return m_xLabel->GetText();
5442  }
5443 
5444  virtual void set_mnemonic_widget(Widget* pTarget) override
5445  {
5446  FixedText* pLabel = dynamic_cast<FixedText*>(m_xLabel.get());
5447  assert(pLabel && "can't use set_mnemonic_widget on SelectableFixedText");
5448  SalInstanceWidget* pTargetWidget = dynamic_cast<SalInstanceWidget*>(pTarget);
5449  pLabel->set_mnemonic_widget(pTargetWidget ? pTargetWidget->getWidget() : nullptr);
5450  }
5451 
5452  virtual void set_message_type(weld::EntryMessageType eType) override
5453  {
5454  if (eType == weld::EntryMessageType::Error)
5456  else if (eType == weld::EntryMessageType::Warning)
5457  m_xLabel->SetControlBackground(COL_YELLOW);
5458  else
5459  m_xLabel->SetControlBackground();
5460  }
5461 
5462  virtual void set_font(const vcl::Font& rFont) override
5463  {
5464  m_xLabel->SetPointFont(*m_xLabel, rFont);
5465  m_xLabel->Invalidate();
5466  }
5467 };
5468 
5469 }
5470 
5471 std::unique_ptr<weld::Label> SalInstanceFrame::weld_label_widget() const
5472 {
5473  FixedText* pLabel = dynamic_cast<FixedText*>(m_xFrame->get_label_widget());
5474  if (!pLabel)
5475  return nullptr;
5476  return std::make_unique<SalInstanceLabel>(pLabel, m_pBuilder, false);
5477 }
5478 
5479 namespace {
5480 
5481 class SalInstanceTextView : public SalInstanceContainer, public virtual weld::TextView
5482 {
5483 private:
5484  VclPtr<VclMultiLineEdit> m_xTextView;
5485  Link<ScrollBar*,void> m_aOrigVScrollHdl;
5486 
5487  DECL_LINK(ChangeHdl, Edit&, void);
5488  DECL_LINK(VscrollHdl, ScrollBar*, void);
5489  DECL_LINK(CursorListener, VclWindowEvent&, void);
5490 public:
5491  SalInstanceTextView(VclMultiLineEdit* pTextView, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
5492  : SalInstanceContainer(pTextView, pBuilder, bTakeOwnership)
5493  , m_xTextView(pTextView)
5494  {
5495  m_xTextView->SetModifyHdl(LINK(this, SalInstanceTextView, ChangeHdl));
5496  ScrollBar& rVertScrollBar = m_xTextView->GetVScrollBar();
5497  m_aOrigVScrollHdl = rVertScrollBar.GetScrollHdl();
5498  rVertScrollBar.SetScrollHdl(LINK(this, SalInstanceTextView, VscrollHdl));
5499  }
5500 
5501  virtual void set_text(const OUString& rText) override
5502  {
5503  disable_notify_events();
5504  m_xTextView->SetText(rText);
5505  enable_notify_events();
5506  }
5507 
5508  virtual void replace_selection(const OUString& rText) override
5509  {
5510  disable_notify_events();
5511  m_xTextView->ReplaceSelected(rText);
5512  enable_notify_events();
5513  }
5514 
5515  virtual OUString get_text() const override
5516  {
5517  return m_xTextView->GetText();
5518  }
5519 
5520  bool get_selection_bounds(int& rStartPos, int &rEndPos) override
5521  {
5522  const Selection& rSelection = m_xTextView->GetSelection();
5523  rStartPos = rSelection.Min();
5524  rEndPos = rSelection.Max();
5525  return rSelection.Len();
5526  }
5527 
5528  virtual void select_region(int nStartPos, int nEndPos) override
5529  {