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