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