1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <sal/config.h>
21 
22 #include <string_view>
23 
24 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
25 #include <com/sun/star/awt/XWindow.hpp>
26 #include <com/sun/star/awt/XWindowPeer.hpp>
27 #include <o3tl/safeint.hxx>
28 #include <o3tl/sorted_vector.hxx>
29 #include <officecfg/Office/Common.hxx>
30 #include <salframe.hxx>
31 #include <salinst.hxx>
32 #include <salvd.hxx>
33 #include <salprn.hxx>
34 #include <saltimer.hxx>
35 #include <salsession.hxx>
36 #include <salsys.hxx>
37 #include <salbmp.hxx>
38 #include <salobj.hxx>
39 #include <salmenu.hxx>
40 #include <strings.hrc>
41 #include <svdata.hxx>
42 #include <svimpbox.hxx>
43 #include <messagedialog.hxx>
44 #include <treeglue.hxx>
45 #include <unotools/accessiblerelationsethelper.hxx>
46 #include <unotools/configmgr.hxx>
47 #include <utility>
48 #include <tools/helpers.hxx>
49 #include <vcl/abstdlg.hxx>
50 #include <vcl/builder.hxx>
51 #include <vcl/toolkit/combobox.hxx>
52 #include <vcl/toolkit/dialog.hxx>
53 #include <vcl/toolkit/fixed.hxx>
54 #include <vcl/toolkit/fixedhyper.hxx>
55 #include <vcl/toolkit/fmtfield.hxx>
56 #include <vcl/headbar.hxx>
57 #include <vcl/toolkit/ivctrl.hxx>
58 #include <vcl/layout.hxx>
59 #include <vcl/toolkit/menubtn.hxx>
60 #include <vcl/toolkit/prgsbar.hxx>
61 #include <vcl/ptrstyle.hxx>
62 #include <slider.hxx>
63 #include <vcl/sysdata.hxx>
64 #include <vcl/toolkit/svlbitm.hxx>
65 #include <vcl/toolkit/svtabbx.hxx>
66 #include <vcl/tabctrl.hxx>
67 #include <vcl/tabpage.hxx>
68 #include <vcl/toolkit/treelistentry.hxx>
69 #include <vcl/toolkit/throbber.hxx>
70 #include <vcl/toolkit/unowrap.hxx>
71 #include <vcl/weld.hxx>
72 #include <vcl/weldutils.hxx>
73 #include <vcl/toolkit/vclmedit.hxx>
74 #include <vcl/toolkit/viewdataentry.hxx>
75 #include <vcl/virdev.hxx>
76 #include <bitmaps.hlst>
77 #include <calendar.hxx>
78 #include <menutogglebutton.hxx>
79 #include <verticaltabctrl.hxx>
80 #include <window.h>
81 #include <wizdlg.hxx>
82 #include <salvtables.hxx>
83 #include <comphelper/lok.hxx>
84 
SalFrame()85 SalFrame::SalFrame()
86     : m_pWindow(nullptr)
87     , m_pProc(nullptr)
88 {
89 }
90 
91 // this file contains the virtual destructors of the sal interface
92 // compilers usually put their vtables where the destructor is
93 
~SalFrame()94 SalFrame::~SalFrame() {}
95 
SetCallback(vcl::Window * pWindow,SALFRAMEPROC pProc)96 void SalFrame::SetCallback(vcl::Window* pWindow, SALFRAMEPROC pProc)
97 {
98     m_pWindow = pWindow;
99     m_pProc = pProc;
100 }
101 
102 // default to full-frame flushes
103 // on ports where partial-flushes are much cheaper this method should be overridden
Flush(const tools::Rectangle &)104 void SalFrame::Flush(const tools::Rectangle&) { Flush(); }
105 
SetRepresentedURL(const OUString &)106 void SalFrame::SetRepresentedURL(const OUString&)
107 {
108     // currently this is Mac only functionality
109 }
110 
SalInstance(std::unique_ptr<comphelper::SolarMutex> pMutex)111 SalInstance::SalInstance(std::unique_ptr<comphelper::SolarMutex> pMutex)
112     : m_pYieldMutex(std::move(pMutex))
113 {
114 }
115 
~SalInstance()116 SalInstance::~SalInstance() {}
117 
GetYieldMutex()118 comphelper::SolarMutex* SalInstance::GetYieldMutex() { return m_pYieldMutex.get(); }
119 
ReleaseYieldMutexAll()120 sal_uInt32 SalInstance::ReleaseYieldMutexAll() { return m_pYieldMutex->release(true); }
121 
AcquireYieldMutex(sal_uInt32 nCount)122 void SalInstance::AcquireYieldMutex(sal_uInt32 nCount) { m_pYieldMutex->acquire(nCount); }
123 
CreateSalSession()124 std::unique_ptr<SalSession> SalInstance::CreateSalSession() { return nullptr; }
125 
CreateOpenGLContext()126 OpenGLContext* SalInstance::CreateOpenGLContext()
127 {
128     assert(!m_bSupportsOpenGL);
129     std::abort();
130 }
131 
CreateMenu(bool,Menu *)132 std::unique_ptr<SalMenu> SalInstance::CreateMenu(bool, Menu*)
133 {
134     // default: no native menus
135     return nullptr;
136 }
137 
CreateMenuItem(const SalItemParams &)138 std::unique_ptr<SalMenuItem> SalInstance::CreateMenuItem(const SalItemParams&) { return nullptr; }
139 
CallEventCallback(void const * pEvent,int nBytes)140 bool SalInstance::CallEventCallback(void const* pEvent, int nBytes)
141 {
142     return m_pEventInst.is() && m_pEventInst->dispatchEvent(pEvent, nBytes);
143 }
144 
~SalTimer()145 SalTimer::~SalTimer() COVERITY_NOEXCEPT_FALSE {}
146 
DropScaledCache()147 void SalBitmap::DropScaledCache()
148 {
149     if (ImplSVData* pSVData = ImplGetSVData())
150     {
151         auto& rCache = pSVData->maGDIData.maScaleCache;
152 
153         rCache.remove_if([this](const lru_scale_cache::key_value_pair_t& rKeyValuePair) {
154             return rKeyValuePair.first.mpBitmap == this;
155         });
156     }
157 }
158 
~SalBitmap()159 SalBitmap::~SalBitmap() { DropScaledCache(); }
160 
~SalSystem()161 SalSystem::~SalSystem() {}
162 
~SalPrinter()163 SalPrinter::~SalPrinter() {}
164 
StartJob(const OUString *,const OUString &,const OUString &,ImplJobSetup *,vcl::PrinterController &)165 bool SalPrinter::StartJob(const OUString*, const OUString&, const OUString&, ImplJobSetup*,
166                           vcl::PrinterController&)
167 {
168     return false;
169 }
170 
~SalInfoPrinter()171 SalInfoPrinter::~SalInfoPrinter() {}
172 
~SalVirtualDevice()173 SalVirtualDevice::~SalVirtualDevice() {}
174 
~SalObject()175 SalObject::~SalObject() {}
176 
~SalMenu()177 SalMenu::~SalMenu() {}
178 
ShowNativePopupMenu(FloatingWindow *,const tools::Rectangle &,FloatWinPopupFlags)179 bool SalMenu::ShowNativePopupMenu(FloatingWindow*, const tools::Rectangle&, FloatWinPopupFlags)
180 {
181     return false;
182 }
183 
ShowCloseButton(bool)184 void SalMenu::ShowCloseButton(bool) {}
185 
AddMenuBarButton(const SalMenuButtonItem &)186 bool SalMenu::AddMenuBarButton(const SalMenuButtonItem&) { return false; }
187 
RemoveMenuBarButton(sal_uInt16)188 void SalMenu::RemoveMenuBarButton(sal_uInt16) {}
189 
GetMenuBarButtonRectPixel(sal_uInt16,SalFrame *)190 tools::Rectangle SalMenu::GetMenuBarButtonRectPixel(sal_uInt16, SalFrame*)
191 {
192     return tools::Rectangle();
193 }
194 
GetMenuBarHeight() const195 int SalMenu::GetMenuBarHeight() const { return 0; }
196 
ApplyPersona()197 void SalMenu::ApplyPersona() {}
198 
~SalMenuItem()199 SalMenuItem::~SalMenuItem() {}
200 
ensure_event_listener()201 void SalInstanceWidget::ensure_event_listener()
202 {
203     if (!m_bEventListener)
204     {
205         m_xWidget->AddEventListener(LINK(this, SalInstanceWidget, EventListener));
206         m_bEventListener = true;
207     }
208 }
209 
210 // we want the ability to mark key events as handled, so use this variant
211 // for those, we get all keystrokes in this case, so we will need to filter
212 // them later
ensure_key_listener()213 void SalInstanceWidget::ensure_key_listener()
214 {
215     if (!m_bKeyEventListener)
216     {
217         Application::AddKeyListener(LINK(this, SalInstanceWidget, KeyEventListener));
218         m_bKeyEventListener = true;
219     }
220 }
221 
222 // we want the ability to know about mouse events that happen in our children
223 // so use this variant, we will need to filter them later
ensure_mouse_listener()224 void SalInstanceWidget::ensure_mouse_listener()
225 {
226     if (!m_bMouseEventListener)
227     {
228         m_xWidget->AddChildEventListener(LINK(this, SalInstanceWidget, MouseEventListener));
229         m_bMouseEventListener = true;
230     }
231 }
232 
set_background(const Color & rColor)233 void SalInstanceWidget::set_background(const Color& rColor)
234 {
235     m_xWidget->SetControlBackground(rColor);
236     m_xWidget->SetBackground(m_xWidget->GetControlBackground());
237     if (m_xWidget->GetStyle() & WB_CLIPCHILDREN)
238     {
239         // turn off WB_CLIPCHILDREN otherwise the bg won't extend "under"
240         // transparent children of the widget e.g. expander in sidebar panel header
241         m_xWidget->SetStyle(m_xWidget->GetStyle() & ~WB_CLIPCHILDREN);
242         // and toggle mbClipChildren on instead otherwise the bg won't fill e.g.
243         // deck titlebar header when its width is stretched
244         WindowImpl* pImpl = m_xWidget->ImplGetWindowImpl();
245         pImpl->mbClipChildren = true;
246     }
247 }
248 
SalInstanceWidget(vcl::Window * pWidget,SalInstanceBuilder * pBuilder,bool bTakeOwnership)249 SalInstanceWidget::SalInstanceWidget(vcl::Window* pWidget, SalInstanceBuilder* pBuilder,
250                                      bool bTakeOwnership)
251     : m_xWidget(pWidget)
252     , m_pBuilder(pBuilder)
253     , m_bTakeOwnership(bTakeOwnership)
254     , m_bEventListener(false)
255     , m_bKeyEventListener(false)
256     , m_bMouseEventListener(false)
257     , m_nBlockNotify(0)
258     , m_nFreezeCount(0)
259 {
260 }
261 
set_sensitive(bool sensitive)262 void SalInstanceWidget::set_sensitive(bool sensitive) { m_xWidget->Enable(sensitive); }
263 
get_sensitive() const264 bool SalInstanceWidget::get_sensitive() const { return m_xWidget->IsEnabled(); }
265 
get_visible() const266 bool SalInstanceWidget::get_visible() const { return m_xWidget->IsVisible(); }
267 
is_visible() const268 bool SalInstanceWidget::is_visible() const { return m_xWidget->IsReallyVisible(); }
269 
set_can_focus(bool bCanFocus)270 void SalInstanceWidget::set_can_focus(bool bCanFocus)
271 {
272     auto nStyle = m_xWidget->GetStyle() & ~(WB_TABSTOP | WB_NOTABSTOP);
273     if (bCanFocus)
274         nStyle |= WB_TABSTOP;
275     else
276         nStyle |= WB_NOTABSTOP;
277     m_xWidget->SetStyle(nStyle);
278 }
279 
grab_focus()280 void SalInstanceWidget::grab_focus()
281 {
282     if (has_focus())
283         return;
284     m_xWidget->GrabFocus();
285 }
286 
has_focus() const287 bool SalInstanceWidget::has_focus() const { return m_xWidget->HasFocus(); }
288 
is_active() const289 bool SalInstanceWidget::is_active() const { return m_xWidget->IsActive(); }
290 
has_child_focus() const291 bool SalInstanceWidget::has_child_focus() const { return m_xWidget->HasChildPathFocus(true); }
292 
set_has_default(bool has_default)293 void SalInstanceWidget::set_has_default(bool has_default)
294 {
295     m_xWidget->set_property("has-default", OUString::boolean(has_default));
296 }
297 
get_has_default() const298 bool SalInstanceWidget::get_has_default() const { return m_xWidget->GetStyle() & WB_DEFBUTTON; }
299 
show()300 void SalInstanceWidget::show() { m_xWidget->Show(); }
301 
hide()302 void SalInstanceWidget::hide() { m_xWidget->Hide(); }
303 
set_size_request(int nWidth,int nHeight)304 void SalInstanceWidget::set_size_request(int nWidth, int nHeight)
305 {
306     m_xWidget->set_width_request(nWidth);
307     m_xWidget->set_height_request(nHeight);
308 }
309 
get_size_request() const310 Size SalInstanceWidget::get_size_request() const
311 {
312     return Size(m_xWidget->get_width_request(), m_xWidget->get_height_request());
313 }
314 
get_preferred_size() const315 Size SalInstanceWidget::get_preferred_size() const { return m_xWidget->get_preferred_size(); }
316 
get_approximate_digit_width() const317 float SalInstanceWidget::get_approximate_digit_width() const
318 {
319     return m_xWidget->approximate_digit_width();
320 }
321 
get_text_height() const322 int SalInstanceWidget::get_text_height() const { return m_xWidget->GetTextHeight(); }
323 
get_pixel_size(const OUString & rText) const324 Size SalInstanceWidget::get_pixel_size(const OUString& rText) const
325 {
326     //TODO, or do I want GetTextBoundRect ?, just using width at the moment anyway
327     return Size(m_xWidget->GetTextWidth(rText), m_xWidget->GetTextHeight());
328 }
329 
get_font()330 vcl::Font SalInstanceWidget::get_font() { return m_xWidget->GetPointFont(*m_xWidget->GetOutDev()); }
331 
get_buildable_name() const332 OString SalInstanceWidget::get_buildable_name() const { return m_xWidget->get_id().toUtf8(); }
333 
set_buildable_name(const OString & rId)334 void SalInstanceWidget::set_buildable_name(const OString& rId)
335 {
336     return m_xWidget->set_id(OUString::fromUtf8(rId));
337 }
338 
set_help_id(const OString & rId)339 void SalInstanceWidget::set_help_id(const OString& rId) { return m_xWidget->SetHelpId(rId); }
340 
get_help_id() const341 OString SalInstanceWidget::get_help_id() const { return m_xWidget->GetHelpId(); }
342 
set_grid_left_attach(int nAttach)343 void SalInstanceWidget::set_grid_left_attach(int nAttach)
344 {
345     m_xWidget->set_grid_left_attach(nAttach);
346 }
347 
get_grid_left_attach() const348 int SalInstanceWidget::get_grid_left_attach() const { return m_xWidget->get_grid_left_attach(); }
349 
set_grid_width(int nCols)350 void SalInstanceWidget::set_grid_width(int nCols) { m_xWidget->set_grid_width(nCols); }
351 
set_grid_top_attach(int nAttach)352 void SalInstanceWidget::set_grid_top_attach(int nAttach)
353 {
354     m_xWidget->set_grid_top_attach(nAttach);
355 }
356 
get_grid_top_attach() const357 int SalInstanceWidget::get_grid_top_attach() const { return m_xWidget->get_grid_top_attach(); }
358 
set_hexpand(bool bExpand)359 void SalInstanceWidget::set_hexpand(bool bExpand) { m_xWidget->set_hexpand(bExpand); }
360 
get_hexpand() const361 bool SalInstanceWidget::get_hexpand() const { return m_xWidget->get_hexpand(); }
362 
set_vexpand(bool bExpand)363 void SalInstanceWidget::set_vexpand(bool bExpand) { m_xWidget->set_vexpand(bExpand); }
364 
get_vexpand() const365 bool SalInstanceWidget::get_vexpand() const { return m_xWidget->get_vexpand(); }
366 
set_margin_top(int nMargin)367 void SalInstanceWidget::set_margin_top(int nMargin) { m_xWidget->set_margin_top(nMargin); }
368 
set_margin_bottom(int nMargin)369 void SalInstanceWidget::set_margin_bottom(int nMargin) { m_xWidget->set_margin_bottom(nMargin); }
370 
set_margin_start(int nMargin)371 void SalInstanceWidget::set_margin_start(int nMargin) { m_xWidget->set_margin_start(nMargin); }
372 
set_margin_end(int nMargin)373 void SalInstanceWidget::set_margin_end(int nMargin) { m_xWidget->set_margin_bottom(nMargin); }
374 
get_margin_top() const375 int SalInstanceWidget::get_margin_top() const { return m_xWidget->get_margin_top(); }
376 
get_margin_bottom() const377 int SalInstanceWidget::get_margin_bottom() const { return m_xWidget->get_margin_bottom(); }
378 
get_margin_start() const379 int SalInstanceWidget::get_margin_start() const { return m_xWidget->get_margin_start(); }
380 
get_margin_end() const381 int SalInstanceWidget::get_margin_end() const { return m_xWidget->get_margin_bottom(); }
382 
set_accessible_name(const OUString & rName)383 void SalInstanceWidget::set_accessible_name(const OUString& rName)
384 {
385     m_xWidget->SetAccessibleName(rName);
386 }
387 
set_accessible_description(const OUString & rDescription)388 void SalInstanceWidget::set_accessible_description(const OUString& rDescription)
389 {
390     m_xWidget->SetAccessibleDescription(rDescription);
391 }
392 
get_accessible_name() const393 OUString SalInstanceWidget::get_accessible_name() const { return m_xWidget->GetAccessibleName(); }
394 
get_accessible_description() const395 OUString SalInstanceWidget::get_accessible_description() const
396 {
397     return m_xWidget->GetAccessibleDescription();
398 }
399 
set_accessible_relation_labeled_by(weld::Widget * pLabel)400 void SalInstanceWidget::set_accessible_relation_labeled_by(weld::Widget* pLabel)
401 {
402     vcl::Window* pAtkLabel
403         = pLabel ? dynamic_cast<SalInstanceWidget&>(*pLabel).getWidget() : nullptr;
404     m_xWidget->SetAccessibleRelationLabeledBy(pAtkLabel);
405 }
406 
set_accessible_relation_label_for(weld::Widget * pLabeled)407 void SalInstanceWidget::set_accessible_relation_label_for(weld::Widget* pLabeled)
408 {
409     vcl::Window* pAtkLabeled
410         = pLabeled ? dynamic_cast<SalInstanceWidget&>(*pLabeled).getWidget() : nullptr;
411     m_xWidget->SetAccessibleRelationLabelFor(pAtkLabeled);
412 }
413 
set_tooltip_text(const OUString & rTip)414 void SalInstanceWidget::set_tooltip_text(const OUString& rTip)
415 {
416     m_xWidget->SetQuickHelpText(rTip);
417 }
418 
get_tooltip_text() const419 OUString SalInstanceWidget::get_tooltip_text() const { return m_xWidget->GetQuickHelpText(); }
420 
connect_focus_in(const Link<Widget &,void> & rLink)421 void SalInstanceWidget::connect_focus_in(const Link<Widget&, void>& rLink)
422 {
423     ensure_event_listener();
424     weld::Widget::connect_focus_in(rLink);
425 }
426 
connect_mnemonic_activate(const Link<Widget &,bool> & rLink)427 void SalInstanceWidget::connect_mnemonic_activate(const Link<Widget&, bool>& rLink)
428 {
429     m_xWidget->SetMnemonicActivateHdl(LINK(this, SalInstanceWidget, MnemonicActivateHdl));
430     weld::Widget::connect_mnemonic_activate(rLink);
431 }
432 
connect_focus_out(const Link<Widget &,void> & rLink)433 void SalInstanceWidget::connect_focus_out(const Link<Widget&, void>& rLink)
434 {
435     ensure_event_listener();
436     weld::Widget::connect_focus_out(rLink);
437 }
438 
connect_size_allocate(const Link<const Size &,void> & rLink)439 void SalInstanceWidget::connect_size_allocate(const Link<const Size&, void>& rLink)
440 {
441     ensure_event_listener();
442     weld::Widget::connect_size_allocate(rLink);
443 }
444 
connect_mouse_press(const Link<const MouseEvent &,bool> & rLink)445 void SalInstanceWidget::connect_mouse_press(const Link<const MouseEvent&, bool>& rLink)
446 {
447     ensure_mouse_listener();
448     weld::Widget::connect_mouse_press(rLink);
449 }
450 
connect_mouse_move(const Link<const MouseEvent &,bool> & rLink)451 void SalInstanceWidget::connect_mouse_move(const Link<const MouseEvent&, bool>& rLink)
452 {
453     ensure_mouse_listener();
454     weld::Widget::connect_mouse_move(rLink);
455 }
456 
connect_mouse_release(const Link<const MouseEvent &,bool> & rLink)457 void SalInstanceWidget::connect_mouse_release(const Link<const MouseEvent&, bool>& rLink)
458 {
459     ensure_mouse_listener();
460     weld::Widget::connect_mouse_release(rLink);
461 }
462 
connect_key_press(const Link<const KeyEvent &,bool> & rLink)463 void SalInstanceWidget::connect_key_press(const Link<const KeyEvent&, bool>& rLink)
464 {
465     ensure_key_listener();
466     weld::Widget::connect_key_press(rLink);
467 }
468 
connect_key_release(const Link<const KeyEvent &,bool> & rLink)469 void SalInstanceWidget::connect_key_release(const Link<const KeyEvent&, bool>& rLink)
470 {
471     ensure_key_listener();
472     weld::Widget::connect_key_release(rLink);
473 }
474 
get_extents_relative_to(const Widget & rRelative,int & x,int & y,int & width,int & height) const475 bool SalInstanceWidget::get_extents_relative_to(const Widget& rRelative, int& x, int& y, int& width,
476                                                 int& height) const
477 {
478     tools::Rectangle aRect(m_xWidget->GetWindowExtentsRelative(
479         dynamic_cast<const SalInstanceWidget&>(rRelative).getWidget()));
480     x = aRect.Left();
481     y = aRect.Top();
482     width = aRect.GetWidth();
483     height = aRect.GetHeight();
484     return true;
485 }
486 
grab_add()487 void SalInstanceWidget::grab_add() { m_xWidget->CaptureMouse(); }
488 
has_grab() const489 bool SalInstanceWidget::has_grab() const { return m_xWidget->IsMouseCaptured(); }
490 
grab_remove()491 void SalInstanceWidget::grab_remove() { m_xWidget->ReleaseMouse(); }
492 
get_direction() const493 bool SalInstanceWidget::get_direction() const { return m_xWidget->IsRTLEnabled(); }
494 
set_direction(bool bRTL)495 void SalInstanceWidget::set_direction(bool bRTL) { m_xWidget->EnableRTL(bRTL); }
496 
freeze()497 void SalInstanceWidget::freeze()
498 {
499     if (m_nFreezeCount == 0)
500         m_xWidget->SetUpdateMode(false);
501     ++m_nFreezeCount;
502 }
503 
thaw()504 void SalInstanceWidget::thaw()
505 {
506     --m_nFreezeCount;
507     if (m_nFreezeCount == 0)
508         m_xWidget->SetUpdateMode(true);
509 }
510 
set_busy_cursor(bool bBusy)511 void SalInstanceWidget::set_busy_cursor(bool bBusy)
512 {
513     if (bBusy)
514         m_xWidget->EnterWait();
515     else
516         m_xWidget->LeaveWait();
517 }
518 
queue_resize()519 void SalInstanceWidget::queue_resize() { m_xWidget->queue_resize(); }
520 
~SalInstanceWidget()521 SalInstanceWidget::~SalInstanceWidget()
522 {
523     if (m_aMnemonicActivateHdl.IsSet())
524         m_xWidget->SetMnemonicActivateHdl(Link<vcl::Window&, bool>());
525     if (m_bMouseEventListener)
526         m_xWidget->RemoveChildEventListener(LINK(this, SalInstanceWidget, MouseEventListener));
527     if (m_bKeyEventListener)
528         Application::RemoveKeyListener(LINK(this, SalInstanceWidget, KeyEventListener));
529     if (m_bEventListener)
530         m_xWidget->RemoveEventListener(LINK(this, SalInstanceWidget, EventListener));
531     if (m_bTakeOwnership)
532         m_xWidget.disposeAndClear();
533 }
534 
getWidget() const535 vcl::Window* SalInstanceWidget::getWidget() const { return m_xWidget; }
536 
disable_notify_events()537 void SalInstanceWidget::disable_notify_events() { ++m_nBlockNotify; }
538 
notify_events_disabled()539 bool SalInstanceWidget::notify_events_disabled() { return m_nBlockNotify != 0; }
540 
enable_notify_events()541 void SalInstanceWidget::enable_notify_events() { --m_nBlockNotify; }
542 
strip_mnemonic(const OUString & rLabel) const543 OUString SalInstanceWidget::strip_mnemonic(const OUString& rLabel) const
544 {
545     return rLabel.replaceFirst("~", "");
546 }
547 
create_virtual_device() const548 VclPtr<VirtualDevice> SalInstanceWidget::create_virtual_device() const
549 {
550     // create with (annoying) separate alpha layer that LibreOffice itself uses
551     return VclPtr<VirtualDevice>::Create(*Application::GetDefaultDevice(), DeviceFormat::DEFAULT,
552                                          DeviceFormat::DEFAULT);
553 }
554 
get_drop_target()555 css::uno::Reference<css::datatransfer::dnd::XDropTarget> SalInstanceWidget::get_drop_target()
556 {
557     return m_xWidget->GetDropTarget();
558 }
559 
560 css::uno::Reference<css::datatransfer::clipboard::XClipboard>
get_clipboard() const561 SalInstanceWidget::get_clipboard() const
562 {
563     return m_xWidget->GetClipboard();
564 }
565 
connect_get_property_tree(const Link<tools::JsonWriter &,void> & rLink)566 void SalInstanceWidget::connect_get_property_tree(const Link<tools::JsonWriter&, void>& rLink)
567 {
568     m_xWidget->SetDumpAsPropertyTreeHdl(rLink);
569 }
570 
get_property_tree(tools::JsonWriter & rJsonWriter)571 void SalInstanceWidget::get_property_tree(tools::JsonWriter& rJsonWriter)
572 {
573     m_xWidget->DumpAsPropertyTree(rJsonWriter);
574 }
575 
set_stack_background()576 void SalInstanceWidget::set_stack_background()
577 {
578     set_background(m_xWidget->GetSettings().GetStyleSettings().GetWindowColor());
579 }
580 
set_title_background()581 void SalInstanceWidget::set_title_background()
582 {
583     set_background(m_xWidget->GetSettings().GetStyleSettings().GetShadowColor());
584 }
585 
set_toolbar_background()586 void SalInstanceWidget::set_toolbar_background()
587 {
588     m_xWidget->SetBackground();
589     m_xWidget->SetPaintTransparent(true);
590 }
591 
set_highlight_background()592 void SalInstanceWidget::set_highlight_background()
593 {
594     set_background(m_xWidget->GetSettings().GetStyleSettings().GetHighlightColor());
595 }
596 
getSystemWindow()597 SystemWindow* SalInstanceWidget::getSystemWindow() { return m_xWidget->GetSystemWindow(); }
598 
HandleEventListener(VclWindowEvent & rEvent)599 void SalInstanceWidget::HandleEventListener(VclWindowEvent& rEvent)
600 {
601     if (rEvent.GetId() == VclEventId::WindowGetFocus)
602         m_aFocusInHdl.Call(*this);
603     else if (rEvent.GetId() == VclEventId::WindowLoseFocus)
604         m_aFocusOutHdl.Call(*this);
605     else if (rEvent.GetId() == VclEventId::WindowResize)
606         m_aSizeAllocateHdl.Call(m_xWidget->GetSizePixel());
607 }
608 
609 namespace
610 {
TransformEvent(const MouseEvent & rEvent,const vcl::Window * pParent,const vcl::Window * pChild)611 MouseEvent TransformEvent(const MouseEvent& rEvent, const vcl::Window* pParent,
612                           const vcl::Window* pChild)
613 {
614     return MouseEvent(
615         pParent->ScreenToOutputPixel(pChild->OutputToScreenPixel(rEvent.GetPosPixel())),
616         rEvent.GetClicks(), rEvent.GetMode(), rEvent.GetButtons(), rEvent.GetModifier());
617 }
618 }
619 
HandleMouseEventListener(VclWindowEvent & rWinEvent)620 void SalInstanceWidget::HandleMouseEventListener(VclWindowEvent& rWinEvent)
621 {
622     if (rWinEvent.GetId() == VclEventId::WindowMouseButtonDown)
623     {
624         if (m_xWidget == rWinEvent.GetWindow())
625         {
626             const MouseEvent* pMouseEvent = static_cast<const MouseEvent*>(rWinEvent.GetData());
627             m_aMousePressHdl.Call(*pMouseEvent);
628         }
629         else if (m_xWidget->ImplIsChild(rWinEvent.GetWindow()))
630         {
631             const MouseEvent* pMouseEvent = static_cast<const MouseEvent*>(rWinEvent.GetData());
632             const MouseEvent aTransformedEvent(
633                 TransformEvent(*pMouseEvent, m_xWidget, rWinEvent.GetWindow()));
634             m_aMousePressHdl.Call(aTransformedEvent);
635         }
636     }
637     else if (rWinEvent.GetId() == VclEventId::WindowMouseButtonUp)
638     {
639         if (m_xWidget == rWinEvent.GetWindow())
640         {
641             const MouseEvent* pMouseEvent = static_cast<const MouseEvent*>(rWinEvent.GetData());
642             m_aMouseReleaseHdl.Call(*pMouseEvent);
643         }
644         else if (m_xWidget->ImplIsChild(rWinEvent.GetWindow()))
645         {
646             const MouseEvent* pMouseEvent = static_cast<const MouseEvent*>(rWinEvent.GetData());
647             const MouseEvent aTransformedEvent(
648                 TransformEvent(*pMouseEvent, m_xWidget, rWinEvent.GetWindow()));
649             m_aMouseReleaseHdl.Call(aTransformedEvent);
650         }
651     }
652     else if (rWinEvent.GetId() == VclEventId::WindowMouseMove)
653     {
654         if (m_xWidget == rWinEvent.GetWindow())
655         {
656             const MouseEvent* pMouseEvent = static_cast<const MouseEvent*>(rWinEvent.GetData());
657             m_aMouseMotionHdl.Call(*pMouseEvent);
658         }
659         else if (m_xWidget->ImplIsChild(rWinEvent.GetWindow()))
660         {
661             const MouseEvent* pMouseEvent = static_cast<const MouseEvent*>(rWinEvent.GetData());
662             const MouseEvent aTransformedEvent(
663                 TransformEvent(*pMouseEvent, m_xWidget, rWinEvent.GetWindow()));
664             m_aMouseMotionHdl.Call(aTransformedEvent);
665         }
666     }
667 }
668 
HandleKeyEventListener(VclWindowEvent & rEvent)669 bool SalInstanceWidget::HandleKeyEventListener(VclWindowEvent& rEvent)
670 {
671     // we get all key events here, ignore them unless we have focus
672     if (!m_xWidget->HasChildPathFocus())
673         return false;
674     if (rEvent.GetId() == VclEventId::WindowKeyInput)
675     {
676         const KeyEvent* pKeyEvent = static_cast<const KeyEvent*>(rEvent.GetData());
677         return m_aKeyPressHdl.Call(*pKeyEvent);
678     }
679     else if (rEvent.GetId() == VclEventId::WindowKeyUp)
680     {
681         const KeyEvent* pKeyEvent = static_cast<const KeyEvent*>(rEvent.GetData());
682         return m_aKeyReleaseHdl.Call(*pKeyEvent);
683     }
684     return false;
685 }
686 
IMPL_LINK(SalInstanceWidget,EventListener,VclWindowEvent &,rEvent,void)687 IMPL_LINK(SalInstanceWidget, EventListener, VclWindowEvent&, rEvent, void)
688 {
689     HandleEventListener(rEvent);
690 }
691 
IMPL_LINK(SalInstanceWidget,KeyEventListener,VclWindowEvent &,rEvent,bool)692 IMPL_LINK(SalInstanceWidget, KeyEventListener, VclWindowEvent&, rEvent, bool)
693 {
694     return HandleKeyEventListener(rEvent);
695 }
696 
IMPL_LINK(SalInstanceWidget,MouseEventListener,VclWindowEvent &,rEvent,void)697 IMPL_LINK(SalInstanceWidget, MouseEventListener, VclWindowEvent&, rEvent, void)
698 {
699     HandleMouseEventListener(rEvent);
700 }
701 
IMPL_LINK_NOARG(SalInstanceWidget,MnemonicActivateHdl,vcl::Window &,bool)702 IMPL_LINK_NOARG(SalInstanceWidget, MnemonicActivateHdl, vcl::Window&, bool)
703 {
704     return m_aMnemonicActivateHdl.Call(*this);
705 }
706 
707 namespace
708 {
createImage(const OUString & rImage)709 Image createImage(const OUString& rImage)
710 {
711     if (rImage.isEmpty())
712         return Image();
713     if (rImage.lastIndexOf('.') != rImage.getLength() - 4)
714     {
715         assert((rImage == "dialog-warning" || rImage == "dialog-error"
716                 || rImage == "dialog-information")
717                && "unknown stock image");
718         if (rImage == "dialog-warning")
719             return Image(StockImage::Yes, IMG_WARN);
720         else if (rImage == "dialog-error")
721             return Image(StockImage::Yes, IMG_ERROR);
722         else if (rImage == "dialog-information")
723             return Image(StockImage::Yes, IMG_INFO);
724     }
725     return Image(StockImage::Yes, rImage);
726 }
727 
createImage(const VirtualDevice & rDevice)728 Image createImage(const VirtualDevice& rDevice)
729 {
730     return Image(rDevice.GetBitmapEx(Point(), rDevice.GetOutputSizePixel()));
731 }
732 
insert_to_menu(sal_uInt16 nLastId,PopupMenu * pMenu,int pos,std::u16string_view rId,const OUString & rStr,const OUString * pIconName,const VirtualDevice * pImageSurface,const css::uno::Reference<css::graphic::XGraphic> & rImage,TriState eCheckRadioFalse)733 sal_uInt16 insert_to_menu(sal_uInt16 nLastId, PopupMenu* pMenu, int pos, std::u16string_view rId,
734                           const OUString& rStr, const OUString* pIconName,
735                           const VirtualDevice* pImageSurface,
736                           const css::uno::Reference<css::graphic::XGraphic>& rImage,
737                           TriState eCheckRadioFalse)
738 {
739     const sal_uInt16 nNewid = nLastId + 1;
740 
741     MenuItemBits nBits;
742     if (eCheckRadioFalse == TRISTATE_TRUE)
743         nBits = MenuItemBits::CHECKABLE;
744     else if (eCheckRadioFalse == TRISTATE_FALSE)
745         nBits = MenuItemBits::CHECKABLE | MenuItemBits::RADIOCHECK;
746     else
747         nBits = MenuItemBits::NONE;
748 
749     pMenu->InsertItem(nNewid, rStr, nBits, OUStringToOString(rId, RTL_TEXTENCODING_UTF8),
750                       pos == -1 ? MENU_APPEND : pos);
751     if (pIconName)
752     {
753         pMenu->SetItemImage(nNewid, createImage(*pIconName));
754     }
755     else if (pImageSurface)
756     {
757         pMenu->SetItemImage(nNewid, createImage(*pImageSurface));
758     }
759     else if (rImage)
760     {
761         pMenu->SetItemImage(nNewid, Image(rImage));
762     }
763     return nNewid;
764 }
765 }
766 
SalInstanceMenu(PopupMenu * pMenu,bool bTakeOwnership)767 SalInstanceMenu::SalInstanceMenu(PopupMenu* pMenu, bool bTakeOwnership)
768     : m_xMenu(pMenu)
769     , m_bTakeOwnership(bTakeOwnership)
770 {
771     const auto nCount = m_xMenu->GetItemCount();
772     m_nLastId = nCount ? pMenu->GetItemId(nCount - 1) : 0;
773     m_xMenu->SetSelectHdl(LINK(this, SalInstanceMenu, SelectMenuHdl));
774 }
popup_at_rect(weld::Widget * pParent,const tools::Rectangle & rRect)775 OString SalInstanceMenu::popup_at_rect(weld::Widget* pParent, const tools::Rectangle& rRect)
776 {
777     SalInstanceWidget* pVclWidget = dynamic_cast<SalInstanceWidget*>(pParent);
778     assert(pVclWidget);
779     m_xMenu->Execute(pVclWidget->getWidget(), rRect,
780                      PopupMenuFlags::ExecuteDown | PopupMenuFlags::NoMouseUpClose);
781     return m_xMenu->GetCurItemIdent();
782 }
set_sensitive(const OString & rIdent,bool bSensitive)783 void SalInstanceMenu::set_sensitive(const OString& rIdent, bool bSensitive)
784 {
785     m_xMenu->EnableItem(rIdent, bSensitive);
786 }
get_sensitive(const OString & rIdent) const787 bool SalInstanceMenu::get_sensitive(const OString& rIdent) const
788 {
789     return m_xMenu->IsItemEnabled(m_xMenu->GetItemId(rIdent));
790 }
set_active(const OString & rIdent,bool bActive)791 void SalInstanceMenu::set_active(const OString& rIdent, bool bActive)
792 {
793     m_xMenu->CheckItem(rIdent, bActive);
794 }
get_active(const OString & rIdent) const795 bool SalInstanceMenu::get_active(const OString& rIdent) const
796 {
797     return m_xMenu->IsItemChecked(m_xMenu->GetItemId(rIdent));
798 }
set_label(const OString & rIdent,const OUString & rLabel)799 void SalInstanceMenu::set_label(const OString& rIdent, const OUString& rLabel)
800 {
801     m_xMenu->SetItemText(m_xMenu->GetItemId(rIdent), rLabel);
802 }
get_label(const OString & rIdent) const803 OUString SalInstanceMenu::get_label(const OString& rIdent) const
804 {
805     return m_xMenu->GetItemText(m_xMenu->GetItemId(rIdent));
806 }
set_visible(const OString & rIdent,bool bShow)807 void SalInstanceMenu::set_visible(const OString& rIdent, bool bShow)
808 {
809     m_xMenu->ShowItem(m_xMenu->GetItemId(rIdent), bShow);
810 }
clear()811 void SalInstanceMenu::clear() { m_xMenu->Clear(); }
insert(int pos,const OUString & rId,const OUString & rStr,const OUString * pIconName,VirtualDevice * pImageSurface,const css::uno::Reference<css::graphic::XGraphic> & rImage,TriState eCheckRadioFalse)812 void SalInstanceMenu::insert(int pos, const OUString& rId, const OUString& rStr,
813                              const OUString* pIconName, VirtualDevice* pImageSurface,
814                              const css::uno::Reference<css::graphic::XGraphic>& rImage,
815                              TriState eCheckRadioFalse)
816 {
817     m_nLastId = insert_to_menu(m_nLastId, m_xMenu, pos, rId, rStr, pIconName, pImageSurface, rImage,
818                                eCheckRadioFalse);
819 }
insert_separator(int pos,const OUString & rId)820 void SalInstanceMenu::insert_separator(int pos, const OUString& rId)
821 {
822     auto nInsertPos = pos == -1 ? MENU_APPEND : pos;
823     m_xMenu->InsertSeparator(rId.toUtf8(), nInsertPos);
824 }
remove(const OString & rId)825 void SalInstanceMenu::remove(const OString& rId)
826 {
827     m_xMenu->RemoveItem(m_xMenu->GetItemPos(m_xMenu->GetItemId(rId)));
828 }
n_children() const829 int SalInstanceMenu::n_children() const { return m_xMenu->GetItemCount(); }
get_id(int pos) const830 OString SalInstanceMenu::get_id(int pos) const
831 {
832     return m_xMenu->GetItemIdent(m_xMenu->GetItemId(pos));
833 }
getMenu() const834 PopupMenu* SalInstanceMenu::getMenu() const { return m_xMenu.get(); }
~SalInstanceMenu()835 SalInstanceMenu::~SalInstanceMenu()
836 {
837     m_xMenu->SetSelectHdl(Link<::Menu*, bool>());
838     if (m_bTakeOwnership)
839         m_xMenu.disposeAndClear();
840 }
841 
IMPL_LINK_NOARG(SalInstanceMenu,SelectMenuHdl,::Menu *,bool)842 IMPL_LINK_NOARG(SalInstanceMenu, SelectMenuHdl, ::Menu*, bool)
843 {
844     signal_activate(m_xMenu->GetCurItemIdent());
845     /* tdf#131333 Menu::Select depends on a false here to allow
846        propagating a submens's selected id to its parent menu to become its
847        selected id.
848 
849        without this, while gen menus already have propagated this to its parent
850        in MenuFloatingWindow::EndExecute, SalMenus as used under kf5/macOS
851        won't propagate the selected id
852     */
853     return false;
854 }
855 
SalInstanceToolbar(ToolBox * pToolBox,SalInstanceBuilder * pBuilder,bool bTakeOwnership)856 SalInstanceToolbar::SalInstanceToolbar(ToolBox* pToolBox, SalInstanceBuilder* pBuilder,
857                                        bool bTakeOwnership)
858     : SalInstanceWidget(pToolBox, pBuilder, bTakeOwnership)
859     , m_xToolBox(pToolBox)
860 {
861     m_xToolBox->SetSelectHdl(LINK(this, SalInstanceToolbar, ClickHdl));
862     m_xToolBox->SetDropdownClickHdl(LINK(this, SalInstanceToolbar, DropdownClick));
863 }
864 
set_item_sensitive(const OString & rIdent,bool bSensitive)865 void SalInstanceToolbar::set_item_sensitive(const OString& rIdent, bool bSensitive)
866 {
867     m_xToolBox->EnableItem(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), bSensitive);
868 }
869 
get_item_sensitive(const OString & rIdent) const870 bool SalInstanceToolbar::get_item_sensitive(const OString& rIdent) const
871 {
872     return m_xToolBox->IsItemEnabled(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)));
873 }
874 
set_item_visible(const OString & rIdent,bool bVisible)875 void SalInstanceToolbar::set_item_visible(const OString& rIdent, bool bVisible)
876 {
877     m_xToolBox->ShowItem(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), bVisible);
878 }
879 
set_item_help_id(const OString & rIdent,const OString & rHelpId)880 void SalInstanceToolbar::set_item_help_id(const OString& rIdent, const OString& rHelpId)
881 {
882     m_xToolBox->SetHelpId(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), rHelpId);
883 }
884 
get_item_visible(const OString & rIdent) const885 bool SalInstanceToolbar::get_item_visible(const OString& rIdent) const
886 {
887     return m_xToolBox->IsItemVisible(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)));
888 }
889 
set_item_active(const OString & rIdent,bool bActive)890 void SalInstanceToolbar::set_item_active(const OString& rIdent, bool bActive)
891 {
892     ToolBoxItemId nItemId = m_xToolBox->GetItemId(OUString::fromUtf8(rIdent));
893     m_xToolBox->CheckItem(nItemId, bActive);
894 }
895 
get_item_active(const OString & rIdent) const896 bool SalInstanceToolbar::get_item_active(const OString& rIdent) const
897 {
898     return m_xToolBox->IsItemChecked(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)));
899 }
900 
set_menu_item_active(const OString & rIdent,bool bActive)901 void SalInstanceToolbar::set_menu_item_active(const OString& rIdent, bool bActive)
902 {
903     ToolBoxItemId nItemId = m_xToolBox->GetItemId(OUString::fromUtf8(rIdent));
904     assert(m_xToolBox->GetItemBits(nItemId) & ToolBoxItemBits::DROPDOWN);
905 
906     if (bActive)
907     {
908         m_sStartShowIdent = m_xToolBox->GetItemCommand(nItemId).toUtf8();
909         signal_toggle_menu(m_sStartShowIdent);
910     }
911 
912     auto pFloat = m_aFloats[nItemId];
913     if (pFloat)
914     {
915         if (bActive)
916             vcl::Window::GetDockingManager()->StartPopupMode(m_xToolBox, pFloat,
917                                                              FloatWinPopupFlags::GrabFocus);
918         else
919             vcl::Window::GetDockingManager()->EndPopupMode(pFloat);
920     }
921     auto pPopup = m_aMenus[nItemId];
922     if (pPopup)
923     {
924         if (bActive)
925         {
926             tools::Rectangle aRect = m_xToolBox->GetItemRect(nItemId);
927             pPopup->Execute(m_xToolBox, aRect, PopupMenuFlags::ExecuteDown);
928         }
929         else
930             pPopup->EndExecute();
931     }
932 
933     m_sStartShowIdent.clear();
934 }
935 
get_menu_item_active(const OString & rIdent) const936 bool SalInstanceToolbar::get_menu_item_active(const OString& rIdent) const
937 {
938     ToolBoxItemId nItemId = m_xToolBox->GetItemId(OUString::fromUtf8(rIdent));
939     assert(m_xToolBox->GetItemBits(nItemId) & ToolBoxItemBits::DROPDOWN);
940 
941     if (rIdent == m_sStartShowIdent)
942         return true;
943 
944     auto aFloat = m_aFloats.find(nItemId);
945     if (aFloat != m_aFloats.end())
946     {
947         return vcl::Window::GetDockingManager()->IsInPopupMode(aFloat->second);
948     }
949 
950     auto aPopup = m_aMenus.find(nItemId);
951     if (aPopup != m_aMenus.end())
952     {
953         return PopupMenu::GetActivePopupMenu() == aPopup->second;
954     }
955 
956     return false;
957 }
958 
set_item_popover(const OString & rIdent,weld::Widget * pPopover)959 void SalInstanceToolbar::set_item_popover(const OString& rIdent, weld::Widget* pPopover)
960 {
961     SalInstanceWidget* pPopoverWidget = dynamic_cast<SalInstanceWidget*>(pPopover);
962 
963     vcl::Window* pFloat = pPopoverWidget ? pPopoverWidget->getWidget() : nullptr;
964     if (pFloat)
965     {
966         pFloat->AddEventListener(LINK(this, SalInstanceToolbar, MenuToggleListener));
967         pFloat->EnableDocking();
968     }
969 
970     ToolBoxItemId nId = m_xToolBox->GetItemId(OUString::fromUtf8(rIdent));
971     auto xOldFloat = m_aFloats[nId];
972     if (xOldFloat)
973     {
974         xOldFloat->RemoveEventListener(LINK(this, SalInstanceToolbar, MenuToggleListener));
975     }
976     m_aFloats[nId] = pFloat;
977     m_aMenus[nId] = nullptr;
978 }
979 
set_item_menu(const OString & rIdent,weld::Menu * pMenu)980 void SalInstanceToolbar::set_item_menu(const OString& rIdent, weld::Menu* pMenu)
981 {
982     SalInstanceMenu* pInstanceMenu = dynamic_cast<SalInstanceMenu*>(pMenu);
983 
984     PopupMenu* pPopup = pInstanceMenu ? pInstanceMenu->getMenu() : nullptr;
985 
986     ToolBoxItemId nId = m_xToolBox->GetItemId(OUString::fromUtf8(rIdent));
987     m_aMenus[nId] = pPopup;
988     m_aFloats[nId] = nullptr;
989 }
990 
insert_item(int pos,const OUString & rId)991 void SalInstanceToolbar::insert_item(int pos, const OUString& rId)
992 {
993     ToolBoxItemId nId(pos);
994     m_xToolBox->InsertItem(nId, rId, ToolBoxItemBits::ICON_ONLY);
995     m_xToolBox->SetItemCommand(nId, rId);
996 }
997 
insert_separator(int pos,const OUString &)998 void SalInstanceToolbar::insert_separator(int pos, const OUString& /*rId*/)
999 {
1000     auto nInsertPos = pos == -1 ? ToolBox::APPEND : pos;
1001     m_xToolBox->InsertSeparator(nInsertPos, 5);
1002 }
1003 
get_n_items() const1004 int SalInstanceToolbar::get_n_items() const { return m_xToolBox->GetItemCount(); }
1005 
get_item_ident(int nIndex) const1006 OString SalInstanceToolbar::get_item_ident(int nIndex) const
1007 {
1008     return m_xToolBox->GetItemCommand(m_xToolBox->GetItemId(nIndex)).toUtf8();
1009 }
1010 
set_item_ident(int nIndex,const OString & rIdent)1011 void SalInstanceToolbar::set_item_ident(int nIndex, const OString& rIdent)
1012 {
1013     return m_xToolBox->SetItemCommand(m_xToolBox->GetItemId(nIndex), OUString::fromUtf8(rIdent));
1014 }
1015 
set_item_label(int nIndex,const OUString & rLabel)1016 void SalInstanceToolbar::set_item_label(int nIndex, const OUString& rLabel)
1017 {
1018     m_xToolBox->SetItemText(m_xToolBox->GetItemId(nIndex), rLabel);
1019 }
1020 
get_item_label(const OString & rIdent) const1021 OUString SalInstanceToolbar::get_item_label(const OString& rIdent) const
1022 {
1023     return m_xToolBox->GetItemText(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)));
1024 }
1025 
set_item_label(const OString & rIdent,const OUString & rLabel)1026 void SalInstanceToolbar::set_item_label(const OString& rIdent, const OUString& rLabel)
1027 {
1028     m_xToolBox->SetItemText(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), rLabel);
1029 }
1030 
set_item_icon_name(const OString & rIdent,const OUString & rIconName)1031 void SalInstanceToolbar::set_item_icon_name(const OString& rIdent, const OUString& rIconName)
1032 {
1033     m_xToolBox->SetItemImage(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)),
1034                              Image(StockImage::Yes, rIconName));
1035 }
1036 
set_item_image(const OString & rIdent,const css::uno::Reference<css::graphic::XGraphic> & rIcon)1037 void SalInstanceToolbar::set_item_image(const OString& rIdent,
1038                                         const css::uno::Reference<css::graphic::XGraphic>& rIcon)
1039 {
1040     m_xToolBox->SetItemImage(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), Image(rIcon));
1041 }
1042 
set_item_image(const OString & rIdent,VirtualDevice * pDevice)1043 void SalInstanceToolbar::set_item_image(const OString& rIdent, VirtualDevice* pDevice)
1044 {
1045     if (pDevice)
1046         m_xToolBox->SetItemImage(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)),
1047                                  createImage(*pDevice));
1048     else
1049         m_xToolBox->SetItemImage(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), Image());
1050 }
1051 
set_item_image(int nIndex,const css::uno::Reference<css::graphic::XGraphic> & rIcon)1052 void SalInstanceToolbar::set_item_image(int nIndex,
1053                                         const css::uno::Reference<css::graphic::XGraphic>& rIcon)
1054 {
1055     m_xToolBox->SetItemImage(m_xToolBox->GetItemId(nIndex), Image(rIcon));
1056 }
1057 
set_item_tooltip_text(int nIndex,const OUString & rTip)1058 void SalInstanceToolbar::set_item_tooltip_text(int nIndex, const OUString& rTip)
1059 {
1060     m_xToolBox->SetQuickHelpText(m_xToolBox->GetItemId(nIndex), rTip);
1061 }
1062 
set_item_tooltip_text(const OString & rIdent,const OUString & rTip)1063 void SalInstanceToolbar::set_item_tooltip_text(const OString& rIdent, const OUString& rTip)
1064 {
1065     m_xToolBox->SetQuickHelpText(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), rTip);
1066 }
1067 
get_item_tooltip_text(const OString & rIdent) const1068 OUString SalInstanceToolbar::get_item_tooltip_text(const OString& rIdent) const
1069 {
1070     return m_xToolBox->GetQuickHelpText(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)));
1071 }
1072 
get_icon_size() const1073 vcl::ImageType SalInstanceToolbar::get_icon_size() const { return m_xToolBox->GetImageSize(); }
1074 
set_icon_size(vcl::ImageType eType)1075 void SalInstanceToolbar::set_icon_size(vcl::ImageType eType)
1076 {
1077     ToolBoxButtonSize eButtonSize = ToolBoxButtonSize::DontCare;
1078     switch (eType)
1079     {
1080         case vcl::ImageType::Size16:
1081             eButtonSize = ToolBoxButtonSize::Small;
1082             break;
1083         case vcl::ImageType::Size26:
1084             eButtonSize = ToolBoxButtonSize::Large;
1085             break;
1086         case vcl::ImageType::Size32:
1087             eButtonSize = ToolBoxButtonSize::Size32;
1088             break;
1089     }
1090     if (m_xToolBox->GetToolboxButtonSize() != eButtonSize)
1091     {
1092         m_xToolBox->SetToolboxButtonSize(eButtonSize);
1093         m_xToolBox->queue_resize();
1094     }
1095 }
1096 
get_modifier_state() const1097 sal_uInt16 SalInstanceToolbar::get_modifier_state() const { return m_xToolBox->GetModifier(); }
1098 
get_drop_index(const Point & rPoint) const1099 int SalInstanceToolbar::get_drop_index(const Point& rPoint) const
1100 {
1101     auto nRet = m_xToolBox->GetItemPos(rPoint);
1102     if (nRet == ToolBox::ITEM_NOTFOUND)
1103         return 0;
1104     return nRet;
1105 }
1106 
~SalInstanceToolbar()1107 SalInstanceToolbar::~SalInstanceToolbar()
1108 {
1109     m_xToolBox->SetDropdownClickHdl(Link<ToolBox*, void>());
1110     m_xToolBox->SetSelectHdl(Link<ToolBox*, void>());
1111 }
1112 
IMPL_LINK_NOARG(SalInstanceToolbar,ClickHdl,ToolBox *,void)1113 IMPL_LINK_NOARG(SalInstanceToolbar, ClickHdl, ToolBox*, void)
1114 {
1115     ToolBoxItemId nItemId = m_xToolBox->GetCurItemId();
1116     signal_clicked(m_xToolBox->GetItemCommand(nItemId).toUtf8());
1117 }
1118 
IMPL_LINK_NOARG(SalInstanceToolbar,DropdownClick,ToolBox *,void)1119 IMPL_LINK_NOARG(SalInstanceToolbar, DropdownClick, ToolBox*, void)
1120 {
1121     ToolBoxItemId nItemId = m_xToolBox->GetCurItemId();
1122     set_menu_item_active(m_xToolBox->GetItemCommand(nItemId).toUtf8(), true);
1123 }
1124 
IMPL_LINK(SalInstanceToolbar,MenuToggleListener,VclWindowEvent &,rEvent,void)1125 IMPL_LINK(SalInstanceToolbar, MenuToggleListener, VclWindowEvent&, rEvent, void)
1126 {
1127     if (rEvent.GetId() == VclEventId::WindowEndPopupMode)
1128     {
1129         for (auto& rFloat : m_aFloats)
1130         {
1131             if (rEvent.GetWindow() == rFloat.second)
1132             {
1133                 ToolBoxItemId nItemId = rFloat.first;
1134                 signal_toggle_menu(m_xToolBox->GetItemCommand(nItemId).toUtf8());
1135                 break;
1136             }
1137         }
1138     }
1139 }
1140 
1141 namespace
1142 {
1143 class SalInstanceSizeGroup : public weld::SizeGroup
1144 {
1145 private:
1146     std::shared_ptr<VclSizeGroup> m_xGroup;
1147 
1148 public:
SalInstanceSizeGroup()1149     SalInstanceSizeGroup()
1150         : m_xGroup(std::make_shared<VclSizeGroup>())
1151     {
1152     }
add_widget(weld::Widget * pWidget)1153     virtual void add_widget(weld::Widget* pWidget) override
1154     {
1155         SalInstanceWidget* pVclWidget = dynamic_cast<SalInstanceWidget*>(pWidget);
1156         assert(pVclWidget && pVclWidget->getWidget());
1157         pVclWidget->getWidget()->add_to_size_group(m_xGroup);
1158     }
set_mode(VclSizeGroupMode eMode)1159     virtual void set_mode(VclSizeGroupMode eMode) override { m_xGroup->set_mode(eMode); }
1160 };
1161 }
1162 
implResetDefault(const vcl::Window * _pWindow)1163 void SalInstanceContainer::implResetDefault(const vcl::Window* _pWindow)
1164 {
1165     vcl::Window* pChildLoop = _pWindow->GetWindow(GetWindowType::FirstChild);
1166     while (pChildLoop)
1167     {
1168         // does the window participate in the tabbing order?
1169         if (pChildLoop->GetStyle() & WB_DIALOGCONTROL)
1170             implResetDefault(pChildLoop);
1171 
1172         // is it a button?
1173         WindowType eType = pChildLoop->GetType();
1174         if ((WindowType::PUSHBUTTON == eType) || (WindowType::OKBUTTON == eType)
1175             || (WindowType::CANCELBUTTON == eType) || (WindowType::HELPBUTTON == eType)
1176             || (WindowType::IMAGEBUTTON == eType) || (WindowType::MENUBUTTON == eType)
1177             || (WindowType::MOREBUTTON == eType))
1178         {
1179             pChildLoop->SetStyle(pChildLoop->GetStyle() & ~WB_DEFBUTTON);
1180         }
1181 
1182         // the next one ...
1183         pChildLoop = pChildLoop->GetWindow(GetWindowType::Next);
1184     }
1185 }
1186 
connect_container_focus_changed(const Link<Container &,void> & rLink)1187 void SalInstanceContainer::connect_container_focus_changed(const Link<Container&, void>& rLink)
1188 {
1189     ensure_event_listener();
1190     weld::Container::connect_container_focus_changed(rLink);
1191 }
1192 
HandleEventListener(VclWindowEvent & rEvent)1193 void SalInstanceContainer::HandleEventListener(VclWindowEvent& rEvent)
1194 {
1195     if (rEvent.GetId() == VclEventId::WindowActivate
1196         || rEvent.GetId() == VclEventId::WindowDeactivate)
1197     {
1198         signal_container_focus_changed();
1199         return;
1200     }
1201     SalInstanceWidget::HandleEventListener(rEvent);
1202 }
1203 
SalInstanceContainer(vcl::Window * pContainer,SalInstanceBuilder * pBuilder,bool bTakeOwnership)1204 SalInstanceContainer::SalInstanceContainer(vcl::Window* pContainer, SalInstanceBuilder* pBuilder,
1205                                            bool bTakeOwnership)
1206     : SalInstanceWidget(pContainer, pBuilder, bTakeOwnership)
1207     , m_xContainer(pContainer)
1208 {
1209 }
1210 
move(weld::Widget * pWidget,weld::Container * pNewParent)1211 void SalInstanceContainer::move(weld::Widget* pWidget, weld::Container* pNewParent)
1212 {
1213     SalInstanceWidget* pVclWidget = dynamic_cast<SalInstanceWidget*>(pWidget);
1214     assert(pVclWidget);
1215     SalInstanceContainer* pNewVclParent = dynamic_cast<SalInstanceContainer*>(pNewParent);
1216     assert(!pNewParent || pNewVclParent);
1217     vcl::Window* pVclWindow = pVclWidget->getWidget();
1218     if (pNewVclParent)
1219         pVclWindow->SetParent(pNewVclParent->getWidget());
1220     else
1221     {
1222         pVclWindow->Hide();
1223         pVclWindow->SetParent(ImplGetDefaultWindow());
1224     }
1225 }
1226 
child_grab_focus()1227 void SalInstanceContainer::child_grab_focus()
1228 {
1229     m_xContainer->GrabFocus();
1230     if (vcl::Window* pFirstChild = m_xContainer->ImplGetDlgWindow(0, GetDlgWindowType::First))
1231         pFirstChild->ImplControlFocus();
1232 }
1233 
recursively_unset_default_buttons()1234 void SalInstanceContainer::recursively_unset_default_buttons()
1235 {
1236     implResetDefault(m_xContainer.get());
1237 }
1238 
CreateChildFrame()1239 css::uno::Reference<css::awt::XWindow> SalInstanceContainer::CreateChildFrame()
1240 {
1241     auto xPage = VclPtr<VclBin>::Create(m_xContainer.get());
1242     xPage->set_expand(true);
1243     xPage->Show();
1244     return css::uno::Reference<css::awt::XWindow>(xPage->GetComponentInterface(),
1245                                                   css::uno::UNO_QUERY);
1246 }
1247 
weld_parent() const1248 std::unique_ptr<weld::Container> SalInstanceWidget::weld_parent() const
1249 {
1250     vcl::Window* pParent = m_xWidget->GetParent();
1251     if (!pParent)
1252         return nullptr;
1253     return std::make_unique<SalInstanceContainer>(pParent, m_pBuilder, false);
1254 }
1255 
DoRecursivePaint(vcl::Window * pWindow,const Point & rRenderLogicPos,OutputDevice & rOutput)1256 void SalInstanceWidget::DoRecursivePaint(vcl::Window* pWindow, const Point& rRenderLogicPos,
1257                                          OutputDevice& rOutput)
1258 {
1259     rOutput.Push();
1260     bool bOldMapModeEnabled = pWindow->IsMapModeEnabled();
1261 
1262     if (pWindow->GetMapMode().GetMapUnit() != rOutput.GetMapMode().GetMapUnit())
1263     {
1264         // This is needed for e.g. the scrollbar in writer comments in margins that has its map unit in pixels
1265         // as seen with bin/run gtktiledviewer --enable-tiled-annotations on a document containing a comment
1266         // long enough to need a scrollbar
1267         pWindow->EnableMapMode();
1268         MapMode aMapMode = pWindow->GetMapMode();
1269         aMapMode.SetMapUnit(rOutput.GetMapMode().GetMapUnit());
1270         aMapMode.SetScaleX(rOutput.GetMapMode().GetScaleX());
1271         aMapMode.SetScaleY(rOutput.GetMapMode().GetScaleY());
1272         pWindow->SetMapMode(aMapMode);
1273     }
1274 
1275     VclPtr<VirtualDevice> xOutput(VclPtr<VirtualDevice>::Create(DeviceFormat::DEFAULT));
1276     Size aChildSizePixel(pWindow->GetSizePixel());
1277     xOutput->SetOutputSizePixel(aChildSizePixel);
1278 
1279     MapMode aMapMode(xOutput->GetMapMode());
1280     aMapMode.SetMapUnit(rOutput.GetMapMode().GetMapUnit());
1281     aMapMode.SetScaleX(rOutput.GetMapMode().GetScaleX());
1282     aMapMode.SetScaleY(rOutput.GetMapMode().GetScaleY());
1283     xOutput->SetMapMode(aMapMode);
1284 
1285     Size aTempLogicSize(xOutput->PixelToLogic(aChildSizePixel));
1286     Size aRenderLogicSize(rOutput.PixelToLogic(aChildSizePixel));
1287 
1288     switch (rOutput.GetOutDevType())
1289     {
1290         case OUTDEV_WINDOW:
1291         case OUTDEV_VIRDEV:
1292             xOutput->DrawOutDev(Point(), aTempLogicSize, rRenderLogicPos, aRenderLogicSize,
1293                                 rOutput);
1294             break;
1295         case OUTDEV_PRINTER:
1296         case OUTDEV_PDF:
1297             xOutput->SetBackground(rOutput.GetBackground());
1298             xOutput->Erase();
1299             break;
1300     }
1301 
1302     //set ReallyVisible to match Visible, we restore the original state after Paint
1303     WindowImpl* pImpl = pWindow->ImplGetWindowImpl();
1304     bool bRVisible = pImpl->mbReallyVisible;
1305     pImpl->mbReallyVisible = pWindow->IsVisible();
1306 
1307     pWindow->ApplySettings(*xOutput);
1308     pWindow->Paint(*xOutput, tools::Rectangle(Point(), pWindow->PixelToLogic(aChildSizePixel)));
1309 
1310     pImpl->mbReallyVisible = bRVisible;
1311 
1312     switch (rOutput.GetOutDevType())
1313     {
1314         case OUTDEV_WINDOW:
1315         case OUTDEV_VIRDEV:
1316             rOutput.DrawOutDev(rRenderLogicPos, aRenderLogicSize, Point(), aTempLogicSize,
1317                                *xOutput);
1318             break;
1319         case OUTDEV_PRINTER:
1320         case OUTDEV_PDF:
1321             rOutput.DrawBitmapEx(rRenderLogicPos, aRenderLogicSize,
1322                                  xOutput->GetBitmapEx(Point(), aTempLogicSize));
1323             break;
1324     }
1325 
1326     xOutput.disposeAndClear();
1327 
1328     pWindow->EnableMapMode(bOldMapModeEnabled);
1329     rOutput.Pop();
1330 
1331     for (vcl::Window* pChild = pWindow->GetWindow(GetWindowType::FirstChild); pChild;
1332          pChild = pChild->GetWindow(GetWindowType::Next))
1333     {
1334         if (!pChild->IsVisible())
1335             continue;
1336         Point aRelPos(pChild->GetPosPixel());
1337         Size aRelLogicOffset(rOutput.PixelToLogic(Size(aRelPos.X(), aRelPos.Y())));
1338         DoRecursivePaint(pChild,
1339                          rRenderLogicPos + Point(aRelLogicOffset.Width(), aRelLogicOffset.Height()),
1340                          rOutput);
1341     }
1342 }
1343 
draw(OutputDevice & rOutput,const Point & rPos,const Size & rSizePixel)1344 void SalInstanceWidget::draw(OutputDevice& rOutput, const Point& rPos, const Size& rSizePixel)
1345 {
1346     Size aOrigSize(m_xWidget->GetSizePixel());
1347     bool bChangeSize = aOrigSize != rSizePixel;
1348     if (bChangeSize)
1349         m_xWidget->SetSizePixel(rSizePixel);
1350 
1351     DoRecursivePaint(m_xWidget, rPos, rOutput);
1352 
1353     if (bChangeSize)
1354         m_xWidget->SetSizePixel(aOrigSize);
1355 }
1356 
1357 namespace
1358 {
1359 class SalInstanceBox : public SalInstanceContainer, public virtual weld::Box
1360 {
1361 private:
1362     VclPtr<VclBox> m_xBox;
1363 
1364 public:
SalInstanceBox(VclBox * pContainer,SalInstanceBuilder * pBuilder,bool bTakeOwnership)1365     SalInstanceBox(VclBox* pContainer, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
1366         : SalInstanceContainer(pContainer, pBuilder, bTakeOwnership)
1367         , m_xBox(pContainer)
1368     {
1369     }
reorder_child(weld::Widget * pWidget,int nNewPosition)1370     virtual void reorder_child(weld::Widget* pWidget, int nNewPosition) override
1371     {
1372         SalInstanceWidget* pVclWidget = dynamic_cast<SalInstanceWidget*>(pWidget);
1373         assert(pVclWidget);
1374         pVclWidget->getWidget()->reorderWithinParent(nNewPosition);
1375     }
sort_native_button_order()1376     virtual void sort_native_button_order() override { ::sort_native_button_order(*m_xBox); }
1377 };
1378 
CollectChildren(const vcl::Window & rCurrent,const basegfx::B2IPoint & rTopLeft,weld::ScreenShotCollection & rControlDataCollection)1379 void CollectChildren(const vcl::Window& rCurrent, const basegfx::B2IPoint& rTopLeft,
1380                      weld::ScreenShotCollection& rControlDataCollection)
1381 {
1382     if (!rCurrent.IsVisible())
1383         return;
1384 
1385     const Point aCurrentPos(rCurrent.GetPosPixel());
1386     const Size aCurrentSize(rCurrent.GetSizePixel());
1387     const basegfx::B2IPoint aCurrentTopLeft(rTopLeft.getX() + aCurrentPos.X(),
1388                                             rTopLeft.getY() + aCurrentPos.Y());
1389     const basegfx::B2IRange aCurrentRange(
1390         aCurrentTopLeft,
1391         aCurrentTopLeft + basegfx::B2IPoint(aCurrentSize.Width(), aCurrentSize.Height()));
1392 
1393     if (!aCurrentRange.isEmpty())
1394     {
1395         rControlDataCollection.emplace_back(rCurrent.GetHelpId(), aCurrentRange);
1396     }
1397 
1398     for (sal_uInt16 a(0); a < rCurrent.GetChildCount(); a++)
1399     {
1400         vcl::Window* pChild = rCurrent.GetChild(a);
1401         if (nullptr != pChild)
1402         {
1403             CollectChildren(*pChild, aCurrentTopLeft, rControlDataCollection);
1404         }
1405     }
1406 }
1407 }
1408 
override_child_help(vcl::Window * pParent)1409 void SalInstanceWindow::override_child_help(vcl::Window* pParent)
1410 {
1411     for (vcl::Window* pChild = pParent->GetWindow(GetWindowType::FirstChild); pChild;
1412          pChild = pChild->GetWindow(GetWindowType::Next))
1413         override_child_help(pChild);
1414     pParent->SetHelpHdl(LINK(this, SalInstanceWindow, HelpHdl));
1415 }
1416 
clear_child_help(vcl::Window * pParent)1417 void SalInstanceWindow::clear_child_help(vcl::Window* pParent)
1418 {
1419     for (vcl::Window* pChild = pParent->GetWindow(GetWindowType::FirstChild); pChild;
1420          pChild = pChild->GetWindow(GetWindowType::Next))
1421         clear_child_help(pChild);
1422     pParent->SetHelpHdl(Link<vcl::Window&, bool>());
1423 }
1424 
SalInstanceWindow(vcl::Window * pWindow,SalInstanceBuilder * pBuilder,bool bTakeOwnership)1425 SalInstanceWindow::SalInstanceWindow(vcl::Window* pWindow, SalInstanceBuilder* pBuilder,
1426                                      bool bTakeOwnership)
1427     : SalInstanceContainer(pWindow, pBuilder, bTakeOwnership)
1428     , m_xWindow(pWindow)
1429 {
1430     // tdf#129745 only override child help for the normal case, not for
1431     // m_pBuilder of null which is the toplevel application frame case.
1432     if (m_pBuilder)
1433         override_child_help(m_xWindow);
1434 }
1435 
set_title(const OUString & rTitle)1436 void SalInstanceWindow::set_title(const OUString& rTitle) { m_xWindow->SetText(rTitle); }
1437 
get_title() const1438 OUString SalInstanceWindow::get_title() const { return m_xWindow->GetText(); }
1439 
GetXWindow()1440 css::uno::Reference<css::awt::XWindow> SalInstanceWindow::GetXWindow()
1441 {
1442     css::uno::Reference<css::awt::XWindow> xWindow(m_xWindow->GetComponentInterface(),
1443                                                    css::uno::UNO_QUERY);
1444     return xWindow;
1445 }
1446 
resize_to_request()1447 void SalInstanceWindow::resize_to_request()
1448 {
1449     if (SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(m_xWindow.get()))
1450     {
1451         pSysWin->setOptimalLayoutSize();
1452         return;
1453     }
1454     if (DockingWindow* pDockWin = dynamic_cast<DockingWindow*>(m_xWindow.get()))
1455     {
1456         pDockWin->setOptimalLayoutSize();
1457         return;
1458     }
1459     assert(false && "must be system or docking window");
1460 }
1461 
set_modal(bool bModal)1462 void SalInstanceWindow::set_modal(bool bModal) { m_xWindow->ImplGetFrame()->SetModal(bModal); }
1463 
get_modal() const1464 bool SalInstanceWindow::get_modal() const { return m_xWindow->ImplGetFrame()->GetModal(); }
1465 
window_move(int x,int y)1466 void SalInstanceWindow::window_move(int x, int y) { m_xWindow->SetPosPixel(Point(x, y)); }
1467 
get_size() const1468 Size SalInstanceWindow::get_size() const { return m_xWindow->GetSizePixel(); }
1469 
get_position() const1470 Point SalInstanceWindow::get_position() const { return m_xWindow->GetPosPixel(); }
1471 
get_monitor_workarea() const1472 tools::Rectangle SalInstanceWindow::get_monitor_workarea() const
1473 {
1474     return m_xWindow->GetDesktopRectPixel();
1475 }
1476 
set_centered_on_parent(bool)1477 void SalInstanceWindow::set_centered_on_parent(bool /*bTrackGeometryRequests*/)
1478 {
1479     if (vcl::Window* pParent = m_xWidget->GetParent())
1480     {
1481         Size aParentGeometry(pParent->GetSizePixel());
1482         Size aGeometry(m_xWidget->get_preferred_size());
1483         auto nX = (aParentGeometry.Width() - aGeometry.Width()) / 2;
1484         auto nY = (aParentGeometry.Height() - aGeometry.Height()) / 2;
1485         m_xWidget->SetPosPixel(Point(nX, nY));
1486     }
1487 }
1488 
get_resizable() const1489 bool SalInstanceWindow::get_resizable() const { return m_xWindow->GetStyle() & WB_SIZEABLE; }
1490 
has_toplevel_focus() const1491 bool SalInstanceWindow::has_toplevel_focus() const { return m_xWindow->HasChildPathFocus(); }
1492 
present()1493 void SalInstanceWindow::present()
1494 {
1495     m_xWindow->ToTop(ToTopFlags::RestoreWhenMin | ToTopFlags::ForegroundTask);
1496 }
1497 
set_window_state(const OString & rStr)1498 void SalInstanceWindow::set_window_state(const OString& rStr)
1499 {
1500     SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(m_xWindow.get());
1501     assert(pSysWin);
1502     pSysWin->SetWindowState(rStr);
1503 }
1504 
get_window_state(WindowStateMask nMask) const1505 OString SalInstanceWindow::get_window_state(WindowStateMask nMask) const
1506 {
1507     SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(m_xWindow.get());
1508     assert(pSysWin);
1509     return pSysWin->GetWindowState(nMask);
1510 }
1511 
get_system_data() const1512 SystemEnvData SalInstanceWindow::get_system_data() const { return *m_xWindow->GetSystemData(); }
1513 
screenshot()1514 VclPtr<VirtualDevice> SalInstanceWindow::screenshot()
1515 {
1516     SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(m_xWindow.get());
1517     assert(pSysWin);
1518     return pSysWin->createScreenshot();
1519 }
1520 
collect_screenshot_data()1521 weld::ScreenShotCollection SalInstanceWindow::collect_screenshot_data()
1522 {
1523     weld::ScreenShotCollection aRet;
1524 
1525     // collect all children. Choose start pos to be negative
1526     // of target dialog's position to get all positions relative to (0,0)
1527     const Point aParentPos(m_xWindow->GetPosPixel());
1528     const basegfx::B2IPoint aTopLeft(-aParentPos.X(), -aParentPos.Y());
1529     CollectChildren(*m_xWindow, aTopLeft, aRet);
1530 
1531     return aRet;
1532 }
1533 
~SalInstanceWindow()1534 SalInstanceWindow::~SalInstanceWindow()
1535 {
1536     // tdf#129745 only undo overriding child help for the normal case, not for
1537     // m_pBuilder of null which is the toplevel application frame case.
1538     if (m_pBuilder)
1539         clear_child_help(m_xWindow);
1540 }
1541 
IMPL_LINK_NOARG(SalInstanceWindow,HelpHdl,vcl::Window &,bool)1542 IMPL_LINK_NOARG(SalInstanceWindow, HelpHdl, vcl::Window&, bool)
1543 {
1544     help();
1545     return false;
1546 }
1547 
1548 typedef std::set<VclPtr<vcl::Window>> winset;
1549 
1550 namespace
1551 {
hideUnless(const vcl::Window * pTop,const winset & rVisibleWidgets,std::vector<VclPtr<vcl::Window>> & rWasVisibleWidgets)1552 void hideUnless(const vcl::Window* pTop, const winset& rVisibleWidgets,
1553                 std::vector<VclPtr<vcl::Window>>& rWasVisibleWidgets)
1554 {
1555     for (vcl::Window* pChild = pTop->GetWindow(GetWindowType::FirstChild); pChild;
1556          pChild = pChild->GetWindow(GetWindowType::Next))
1557     {
1558         if (!pChild->IsVisible())
1559             continue;
1560         if (rVisibleWidgets.find(pChild) == rVisibleWidgets.end())
1561         {
1562             rWasVisibleWidgets.emplace_back(pChild);
1563             pChild->Hide();
1564         }
1565         else if (isContainerWindow(pChild))
1566         {
1567             hideUnless(pChild, rVisibleWidgets, rWasVisibleWidgets);
1568         }
1569     }
1570 }
1571 }
1572 
SalInstanceDialog(::Dialog * pDialog,SalInstanceBuilder * pBuilder,bool bTakeOwnership)1573 SalInstanceDialog::SalInstanceDialog(::Dialog* pDialog, SalInstanceBuilder* pBuilder,
1574                                      bool bTakeOwnership)
1575     : SalInstanceWindow(pDialog, pBuilder, bTakeOwnership)
1576     , m_xDialog(pDialog)
1577     , m_nOldEditWidthReq(0)
1578     , m_nOldBorderWidth(0)
1579 {
1580     const bool bScreenshotMode(officecfg::Office::Common::Misc::ScreenshotMode::get());
1581     if (bScreenshotMode)
1582     {
1583         m_xDialog->SetPopupMenuHdl(LINK(this, SalInstanceDialog, PopupScreenShotMenuHdl));
1584     }
1585 }
1586 
runAsync(std::shared_ptr<weld::DialogController> aOwner,const std::function<void (sal_Int32)> & rEndDialogFn)1587 bool SalInstanceDialog::runAsync(std::shared_ptr<weld::DialogController> aOwner,
1588                                  const std::function<void(sal_Int32)>& rEndDialogFn)
1589 {
1590     VclAbstractDialog::AsyncContext aCtx;
1591     aCtx.mxOwnerDialogController = aOwner;
1592     aCtx.maEndDialogFn = rEndDialogFn;
1593     VclButtonBox* pActionArea = m_xDialog->get_action_area();
1594     if (pActionArea)
1595         sort_native_button_order(*pActionArea);
1596     return m_xDialog->StartExecuteAsync(aCtx);
1597 }
1598 
runAsync(std::shared_ptr<Dialog> const & rxSelf,const std::function<void (sal_Int32)> & rEndDialogFn)1599 bool SalInstanceDialog::runAsync(std::shared_ptr<Dialog> const& rxSelf,
1600                                  const std::function<void(sal_Int32)>& rEndDialogFn)
1601 {
1602     assert(rxSelf.get() == this);
1603     VclAbstractDialog::AsyncContext aCtx;
1604     // In order to store a shared_ptr to ourself, we have to have been constructed by make_shared,
1605     // which is that rxSelf enforces.
1606     aCtx.mxOwnerSelf = rxSelf;
1607     aCtx.maEndDialogFn = rEndDialogFn;
1608     VclButtonBox* pActionArea = m_xDialog->get_action_area();
1609     if (pActionArea)
1610         sort_native_button_order(*pActionArea);
1611     return m_xDialog->StartExecuteAsync(aCtx);
1612 }
1613 
collapse(weld::Widget * pEdit,weld::Widget * pButton)1614 void SalInstanceDialog::collapse(weld::Widget* pEdit, weld::Widget* pButton)
1615 {
1616     SalInstanceWidget* pVclEdit = dynamic_cast<SalInstanceWidget*>(pEdit);
1617     assert(pVclEdit);
1618     SalInstanceWidget* pVclButton = dynamic_cast<SalInstanceWidget*>(pButton);
1619 
1620     vcl::Window* pRefEdit = pVclEdit->getWidget();
1621     vcl::Window* pRefBtn = pVclButton ? pVclButton->getWidget() : nullptr;
1622 
1623     auto nOldEditWidth = pRefEdit->GetSizePixel().Width();
1624     m_nOldEditWidthReq = pRefEdit->get_width_request();
1625 
1626     //We want just pRefBtn and pRefEdit to be shown
1627     //mark widgets we want to be visible, starting with pRefEdit
1628     //and all its direct parents.
1629     winset aVisibleWidgets;
1630     vcl::Window* pContentArea = m_xDialog->get_content_area();
1631     for (vcl::Window* pCandidate = pRefEdit;
1632          pCandidate && (pCandidate != pContentArea && pCandidate->IsVisible());
1633          pCandidate = pCandidate->GetWindow(GetWindowType::RealParent))
1634     {
1635         aVisibleWidgets.insert(pCandidate);
1636     }
1637     //same again with pRefBtn, except stop if there's a
1638     //shared parent in the existing widgets
1639     for (vcl::Window* pCandidate = pRefBtn;
1640          pCandidate && (pCandidate != pContentArea && pCandidate->IsVisible());
1641          pCandidate = pCandidate->GetWindow(GetWindowType::RealParent))
1642     {
1643         if (aVisibleWidgets.insert(pCandidate).second)
1644             break;
1645     }
1646 
1647     //hide everything except the aVisibleWidgets
1648     hideUnless(pContentArea, aVisibleWidgets, m_aHiddenWidgets);
1649 
1650     // the insert function case has an initially hidden edit widget, so it has
1651     // not start size, so take larger of actual size and size request
1652     pRefEdit->set_width_request(std::max(nOldEditWidth, m_nOldEditWidthReq));
1653     m_nOldBorderWidth = m_xDialog->get_border_width();
1654     m_xDialog->set_border_width(0);
1655     if (vcl::Window* pActionArea = m_xDialog->get_action_area())
1656         pActionArea->Hide();
1657     m_xDialog->setOptimalLayoutSize();
1658     m_xRefEdit = pRefEdit;
1659 }
1660 
undo_collapse()1661 void SalInstanceDialog::undo_collapse()
1662 {
1663     // All others: Show();
1664     for (VclPtr<vcl::Window> const& pWindow : m_aHiddenWidgets)
1665     {
1666         pWindow->Show();
1667     }
1668     m_aHiddenWidgets.clear();
1669 
1670     m_xRefEdit->set_width_request(m_nOldEditWidthReq);
1671     m_xRefEdit.clear();
1672     m_xDialog->set_border_width(m_nOldBorderWidth);
1673     if (vcl::Window* pActionArea = m_xDialog->get_action_area())
1674         pActionArea->Show();
1675     m_xDialog->setOptimalLayoutSize();
1676 }
1677 
SetInstallLOKNotifierHdl(const Link<void *,vcl::ILibreOfficeKitNotifier * > & rLink)1678 void SalInstanceDialog::SetInstallLOKNotifierHdl(
1679     const Link<void*, vcl::ILibreOfficeKitNotifier*>& rLink)
1680 {
1681     m_xDialog->SetInstallLOKNotifierHdl(rLink);
1682 }
1683 
run()1684 int SalInstanceDialog::run()
1685 {
1686     VclButtonBox* pActionArea = m_xDialog->get_action_area();
1687     if (pActionArea)
1688         sort_native_button_order(*pActionArea);
1689     return m_xDialog->Execute();
1690 }
1691 
response(int nResponse)1692 void SalInstanceDialog::response(int nResponse) { m_xDialog->EndDialog(nResponse); }
1693 
add_button(const OUString & rText,int nResponse,const OString & rHelpId)1694 void SalInstanceDialog::add_button(const OUString& rText, int nResponse, const OString& rHelpId)
1695 {
1696     VclButtonBox* pBox = m_xDialog->get_action_area();
1697     VclPtr<PushButton> xButton(
1698         VclPtr<PushButton>::Create(pBox, WB_CLIPCHILDREN | WB_CENTER | WB_VCENTER));
1699     xButton->SetText(rText);
1700     xButton->SetHelpId(rHelpId);
1701 
1702     switch (nResponse)
1703     {
1704         case RET_OK:
1705             xButton->set_id("ok");
1706             break;
1707         case RET_CLOSE:
1708             xButton->set_id("close");
1709             break;
1710         case RET_CANCEL:
1711             xButton->set_id("cancel");
1712             break;
1713         case RET_YES:
1714             xButton->set_id("yes");
1715             break;
1716         case RET_NO:
1717             xButton->set_id("no");
1718             break;
1719     }
1720 
1721     xButton->Show();
1722     m_xDialog->add_button(xButton, nResponse, true);
1723 }
1724 
set_modal(bool bModal)1725 void SalInstanceDialog::set_modal(bool bModal)
1726 {
1727     if (get_modal() == bModal)
1728         return;
1729     m_xDialog->SetModalInputMode(bModal);
1730 }
1731 
get_modal() const1732 bool SalInstanceDialog::get_modal() const { return m_xDialog->IsModalInputMode(); }
1733 
set_default_response(int nResponse)1734 void SalInstanceDialog::set_default_response(int nResponse)
1735 {
1736     m_xDialog->set_default_response(nResponse);
1737 }
1738 
weld_content_area()1739 weld::Container* SalInstanceDialog::weld_content_area()
1740 {
1741     return new SalInstanceContainer(m_xDialog->get_content_area(), m_pBuilder, false);
1742 }
1743 
IMPL_LINK(SalInstanceDialog,PopupScreenShotMenuHdl,const CommandEvent &,rCEvt,bool)1744 IMPL_LINK(SalInstanceDialog, PopupScreenShotMenuHdl, const CommandEvent&, rCEvt, bool)
1745 {
1746     if (CommandEventId::ContextMenu == rCEvt.GetCommand())
1747     {
1748         const Point aMenuPos(rCEvt.GetMousePosPixel());
1749         ScopedVclPtrInstance<PopupMenu> aMenu;
1750         sal_uInt16 nLocalID(1);
1751 
1752         aMenu->InsertItem(nLocalID, VclResId(SV_BUTTONTEXT_SCREENSHOT));
1753         aMenu->SetHelpText(nLocalID, VclResId(SV_HELPTEXT_SCREENSHOT));
1754         aMenu->SetHelpId(nLocalID, "InteractiveScreenshotMode");
1755         aMenu->EnableItem(nLocalID);
1756 
1757         const sal_uInt16 nId(aMenu->Execute(m_xDialog, aMenuPos));
1758 
1759         // 0 == no selection (so not usable as ID)
1760         if (0 != nId)
1761         {
1762             // open screenshot annotation dialog
1763             VclAbstractDialogFactory* pFact = VclAbstractDialogFactory::Create();
1764             VclPtr<AbstractScreenshotAnnotationDlg> pTmp
1765                 = pFact->CreateScreenshotAnnotationDlg(*this);
1766             ScopedVclPtr<AbstractScreenshotAnnotationDlg> pDialog(pTmp);
1767 
1768             if (pDialog)
1769             {
1770                 // currently just execute the dialog, no need to do
1771                 // different things for ok/cancel. This may change later,
1772                 // for that case use 'if (pDlg->Execute() == RET_OK)'
1773                 pDialog->Execute();
1774             }
1775         }
1776 
1777         // consume event when:
1778         // - CommandEventId::ContextMenu
1779         // - bScreenshotMode
1780         return true;
1781     }
1782 
1783     return false;
1784 }
1785 
SalInstanceMessageDialog(::MessageDialog * pDialog,SalInstanceBuilder * pBuilder,bool bTakeOwnership)1786 SalInstanceMessageDialog::SalInstanceMessageDialog(::MessageDialog* pDialog,
1787                                                    SalInstanceBuilder* pBuilder,
1788                                                    bool bTakeOwnership)
1789     : SalInstanceDialog(pDialog, pBuilder, bTakeOwnership)
1790     , m_xMessageDialog(pDialog)
1791 {
1792 }
1793 
set_primary_text(const OUString & rText)1794 void SalInstanceMessageDialog::set_primary_text(const OUString& rText)
1795 {
1796     m_xMessageDialog->set_primary_text(rText);
1797 }
1798 
get_primary_text() const1799 OUString SalInstanceMessageDialog::get_primary_text() const
1800 {
1801     return m_xMessageDialog->get_primary_text();
1802 }
1803 
set_secondary_text(const OUString & rText)1804 void SalInstanceMessageDialog::set_secondary_text(const OUString& rText)
1805 {
1806     m_xMessageDialog->set_secondary_text(rText);
1807 }
1808 
get_secondary_text() const1809 OUString SalInstanceMessageDialog::get_secondary_text() const
1810 {
1811     return m_xMessageDialog->get_secondary_text();
1812 }
1813 
weld_message_area()1814 weld::Container* SalInstanceMessageDialog::weld_message_area()
1815 {
1816     return new SalInstanceContainer(m_xMessageDialog->get_message_area(), m_pBuilder, false);
1817 }
1818 
1819 namespace
1820 {
1821 class SalInstanceAssistant : public SalInstanceDialog, public virtual weld::Assistant
1822 {
1823 private:
1824     VclPtr<vcl::RoadmapWizard> m_xWizard;
1825     std::vector<std::unique_ptr<SalInstanceContainer>> m_aPages;
1826     std::vector<VclPtr<TabPage>> m_aAddedPages;
1827     std::vector<int> m_aIds;
1828     std::vector<VclPtr<VclGrid>> m_aAddedGrids;
1829     Idle m_aUpdateRoadmapIdle;
1830 
find_page(std::string_view rIdent) const1831     int find_page(std::string_view rIdent) const
1832     {
1833         for (size_t i = 0; i < m_aAddedPages.size(); ++i)
1834         {
1835             if (m_aAddedPages[i]->get_id().toUtf8() == rIdent)
1836                 return i;
1837         }
1838         return -1;
1839     }
1840 
find_id(int nId) const1841     int find_id(int nId) const
1842     {
1843         for (size_t i = 0; i < m_aIds.size(); ++i)
1844         {
1845             if (nId == m_aIds[i])
1846                 return i;
1847         }
1848         return -1;
1849     }
1850 
1851     DECL_LINK(OnRoadmapItemSelected, LinkParamNone*, void);
1852     DECL_LINK(UpdateRoadmap_Hdl, Timer*, void);
1853 
1854 public:
SalInstanceAssistant(vcl::RoadmapWizard * pDialog,SalInstanceBuilder * pBuilder,bool bTakeOwnership)1855     SalInstanceAssistant(vcl::RoadmapWizard* pDialog, SalInstanceBuilder* pBuilder,
1856                          bool bTakeOwnership)
1857         : SalInstanceDialog(pDialog, pBuilder, bTakeOwnership)
1858         , m_xWizard(pDialog)
1859     {
1860         m_xWizard->SetItemSelectHdl(LINK(this, SalInstanceAssistant, OnRoadmapItemSelected));
1861 
1862         m_aUpdateRoadmapIdle.SetInvokeHandler(LINK(this, SalInstanceAssistant, UpdateRoadmap_Hdl));
1863         m_aUpdateRoadmapIdle.SetPriority(TaskPriority::HIGHEST);
1864     }
1865 
get_current_page() const1866     virtual int get_current_page() const override { return find_id(m_xWizard->GetCurLevel()); }
1867 
get_n_pages() const1868     virtual int get_n_pages() const override { return m_aAddedPages.size(); }
1869 
get_page_ident(int nPage) const1870     virtual OString get_page_ident(int nPage) const override
1871     {
1872         return m_aAddedPages[nPage]->get_id().toUtf8();
1873     }
1874 
get_current_page_ident() const1875     virtual OString get_current_page_ident() const override
1876     {
1877         return get_page_ident(get_current_page());
1878     }
1879 
set_current_page(int nPage)1880     virtual void set_current_page(int nPage) override
1881     {
1882         disable_notify_events();
1883 
1884         // take the first shown page as the size for all pages
1885         if (m_xWizard->GetPageSizePixel().Width() == 0)
1886         {
1887             Size aFinalSize;
1888             for (int i = 0, nPages = get_n_pages(); i < nPages; ++i)
1889             {
1890                 TabPage* pPage = m_xWizard->GetPage(m_aIds[i]);
1891                 assert(pPage);
1892                 Size aPageSize(pPage->get_preferred_size());
1893                 if (aPageSize.Width() > aFinalSize.Width())
1894                     aFinalSize.setWidth(aPageSize.Width());
1895                 if (aPageSize.Height() > aFinalSize.Height())
1896                     aFinalSize.setHeight(aPageSize.Height());
1897             }
1898             m_xWizard->SetPageSizePixel(aFinalSize);
1899         }
1900 
1901         (void)m_xWizard->ShowPage(m_aIds[nPage]);
1902         enable_notify_events();
1903     }
1904 
set_current_page(const OString & rIdent)1905     virtual void set_current_page(const OString& rIdent) override
1906     {
1907         int nIndex = find_page(rIdent);
1908         if (nIndex == -1)
1909             return;
1910         set_current_page(nIndex);
1911     }
1912 
set_page_index(const OString & rIdent,int nNewIndex)1913     virtual void set_page_index(const OString& rIdent, int nNewIndex) override
1914     {
1915         int nOldIndex = find_page(rIdent);
1916 
1917         if (nOldIndex == -1)
1918             return;
1919 
1920         if (nOldIndex == nNewIndex)
1921             return;
1922 
1923         disable_notify_events();
1924 
1925         auto entry = std::move(m_aAddedPages[nOldIndex]);
1926         m_aAddedPages.erase(m_aAddedPages.begin() + nOldIndex);
1927         m_aAddedPages.insert(m_aAddedPages.begin() + nNewIndex, std::move(entry));
1928 
1929         int nId = m_aIds[nOldIndex];
1930         m_aIds.erase(m_aIds.begin() + nOldIndex);
1931         m_aIds.insert(m_aIds.begin() + nNewIndex, nId);
1932 
1933         m_aUpdateRoadmapIdle.Start();
1934 
1935         enable_notify_events();
1936     }
1937 
append_page(const OString & rIdent)1938     virtual weld::Container* append_page(const OString& rIdent) override
1939     {
1940         VclPtrInstance<TabPage> xPage(m_xWizard);
1941         VclPtrInstance<VclGrid> xGrid(xPage);
1942         xPage->set_id(OUString::fromUtf8(rIdent));
1943         xPage->Show();
1944         xGrid->set_hexpand(true);
1945         xGrid->set_vexpand(true);
1946         xGrid->Show();
1947         m_xWizard->AddPage(xPage);
1948         m_aIds.push_back(m_aAddedPages.size());
1949         m_xWizard->SetPage(m_aIds.back(), xPage);
1950         m_aAddedPages.push_back(xPage);
1951         m_aAddedGrids.push_back(xGrid);
1952 
1953         m_aUpdateRoadmapIdle.Start();
1954 
1955         m_aPages.emplace_back(new SalInstanceContainer(xGrid, m_pBuilder, false));
1956         return m_aPages.back().get();
1957     }
1958 
get_page_title(const OString & rIdent) const1959     virtual OUString get_page_title(const OString& rIdent) const override
1960     {
1961         int nIndex = find_page(rIdent);
1962         if (nIndex == -1)
1963             return OUString();
1964         return m_aAddedPages[nIndex]->GetText();
1965     }
1966 
set_page_title(const OString & rIdent,const OUString & rTitle)1967     virtual void set_page_title(const OString& rIdent, const OUString& rTitle) override
1968     {
1969         int nIndex = find_page(rIdent);
1970         if (nIndex == -1)
1971             return;
1972         if (m_aAddedPages[nIndex]->GetText() != rTitle)
1973         {
1974             disable_notify_events();
1975             m_aAddedPages[nIndex]->SetText(rTitle);
1976             m_aUpdateRoadmapIdle.Start();
1977             enable_notify_events();
1978         }
1979     }
1980 
set_page_sensitive(const OString & rIdent,bool bSensitive)1981     virtual void set_page_sensitive(const OString& rIdent, bool bSensitive) override
1982     {
1983         int nIndex = find_page(rIdent);
1984         if (nIndex == -1)
1985             return;
1986         if (m_aAddedPages[nIndex]->IsEnabled() != bSensitive)
1987         {
1988             disable_notify_events();
1989             m_aAddedPages[nIndex]->Enable(bSensitive);
1990             m_aUpdateRoadmapIdle.Start();
1991             enable_notify_events();
1992         }
1993     }
1994 
set_page_side_help_id(const OString & rHelpId)1995     virtual void set_page_side_help_id(const OString& rHelpId) override
1996     {
1997         m_xWizard->SetRoadmapHelpId(rHelpId);
1998     }
1999 
2000     weld::Button* weld_widget_for_response(int nResponse) override;
2001 
~SalInstanceAssistant()2002     virtual ~SalInstanceAssistant() override
2003     {
2004         for (auto& rGrid : m_aAddedGrids)
2005             rGrid.disposeAndClear();
2006         for (auto& rPage : m_aAddedPages)
2007             rPage.disposeAndClear();
2008     }
2009 };
2010 }
2011 
IMPL_LINK_NOARG(SalInstanceAssistant,OnRoadmapItemSelected,LinkParamNone *,void)2012 IMPL_LINK_NOARG(SalInstanceAssistant, OnRoadmapItemSelected, LinkParamNone*, void)
2013 {
2014     if (notify_events_disabled())
2015         return;
2016     auto nCurItemId = m_xWizard->GetCurrentRoadmapItemID();
2017     int nPageIndex(find_id(nCurItemId));
2018     if (!signal_jump_page(get_page_ident(nPageIndex)) && nCurItemId != m_xWizard->GetCurLevel())
2019         m_xWizard->SelectRoadmapItemByID(m_xWizard->GetCurLevel());
2020 }
2021 
IMPL_LINK_NOARG(SalInstanceAssistant,UpdateRoadmap_Hdl,Timer *,void)2022 IMPL_LINK_NOARG(SalInstanceAssistant, UpdateRoadmap_Hdl, Timer*, void)
2023 {
2024     disable_notify_events();
2025 
2026     m_xWizard->DeleteRoadmapItems();
2027 
2028     int nPos = 0;
2029     for (size_t i = 0; i < m_aAddedPages.size(); ++i)
2030     {
2031         const OUString& rLabel = m_aAddedPages[i]->GetText();
2032         bool bSensitive = m_aAddedPages[i]->IsEnabled();
2033         if (rLabel.isEmpty())
2034             continue;
2035         m_xWizard->InsertRoadmapItem(nPos++, rLabel, m_aIds[i], bSensitive);
2036     }
2037 
2038     m_xWizard->SelectRoadmapItemByID(m_aIds[get_current_page()], false);
2039 
2040     m_xWizard->ShowRoadmap(nPos != 0);
2041 
2042     enable_notify_events();
2043 }
2044 
2045 namespace
2046 {
2047 class SalInstanceFrame : public SalInstanceContainer, public virtual weld::Frame
2048 {
2049 private:
2050     VclPtr<VclFrame> m_xFrame;
2051 
2052 public:
SalInstanceFrame(VclFrame * pFrame,SalInstanceBuilder * pBuilder,bool bTakeOwnership)2053     SalInstanceFrame(VclFrame* pFrame, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2054         : SalInstanceContainer(pFrame, pBuilder, bTakeOwnership)
2055         , m_xFrame(pFrame)
2056     {
2057     }
2058 
set_label(const OUString & rText)2059     virtual void set_label(const OUString& rText) override { m_xFrame->set_label(rText); }
2060 
get_label() const2061     virtual OUString get_label() const override { return m_xFrame->get_label(); }
2062 
2063     virtual std::unique_ptr<weld::Label> weld_label_widget() const override;
2064 };
2065 
2066 class SalInstancePaned : public SalInstanceContainer, public virtual weld::Paned
2067 {
2068 private:
2069     VclPtr<VclPaned> m_xPaned;
2070 
2071 public:
SalInstancePaned(VclPaned * pPaned,SalInstanceBuilder * pBuilder,bool bTakeOwnership)2072     SalInstancePaned(VclPaned* pPaned, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2073         : SalInstanceContainer(pPaned, pBuilder, bTakeOwnership)
2074         , m_xPaned(pPaned)
2075     {
2076     }
2077 
set_position(int nPos)2078     virtual void set_position(int nPos) override { m_xPaned->set_position(nPos); }
2079 
get_position() const2080     virtual int get_position() const override { return m_xPaned->get_position(); }
2081 };
2082 
2083 class SalInstanceScrolledWindow : public SalInstanceContainer, public virtual weld::ScrolledWindow
2084 {
2085 private:
2086     VclPtr<VclScrolledWindow> m_xScrolledWindow;
2087     Link<ScrollBar*, void> m_aOrigVScrollHdl;
2088     Link<ScrollBar*, void> m_aOrigHScrollHdl;
2089     bool m_bUserManagedScrolling;
2090 
2091     DECL_LINK(VscrollHdl, ScrollBar*, void);
2092     DECL_LINK(HscrollHdl, ScrollBar*, void);
2093 
customize_scrollbars(ScrollBar & rScrollBar,const Color & rButtonTextColor,const Color & rBackgroundColor,const Color & rShadowColor,const Color & rFaceColor)2094     static void customize_scrollbars(ScrollBar& rScrollBar, const Color& rButtonTextColor,
2095                                      const Color& rBackgroundColor, const Color& rShadowColor,
2096                                      const Color& rFaceColor)
2097     {
2098         rScrollBar.EnableNativeWidget(false);
2099         AllSettings aSettings = rScrollBar.GetSettings();
2100         StyleSettings aStyleSettings = aSettings.GetStyleSettings();
2101         aStyleSettings.SetButtonTextColor(rButtonTextColor);
2102         aStyleSettings.SetCheckedColor(rBackgroundColor); // background
2103         aStyleSettings.SetShadowColor(rShadowColor);
2104         aStyleSettings.SetFaceColor(rFaceColor);
2105         aSettings.SetStyleSettings(aStyleSettings);
2106         rScrollBar.SetSettings(aSettings);
2107     }
2108 
2109 public:
SalInstanceScrolledWindow(VclScrolledWindow * pScrolledWindow,SalInstanceBuilder * pBuilder,bool bTakeOwnership,bool bUserManagedScrolling)2110     SalInstanceScrolledWindow(VclScrolledWindow* pScrolledWindow, SalInstanceBuilder* pBuilder,
2111                               bool bTakeOwnership, bool bUserManagedScrolling)
2112         : SalInstanceContainer(pScrolledWindow, pBuilder, bTakeOwnership)
2113         , m_xScrolledWindow(pScrolledWindow)
2114         , m_bUserManagedScrolling(bUserManagedScrolling)
2115     {
2116         ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2117         m_aOrigVScrollHdl = rVertScrollBar.GetScrollHdl();
2118         rVertScrollBar.SetScrollHdl(LINK(this, SalInstanceScrolledWindow, VscrollHdl));
2119         ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2120         m_aOrigHScrollHdl = rHorzScrollBar.GetScrollHdl();
2121         rHorzScrollBar.SetScrollHdl(LINK(this, SalInstanceScrolledWindow, HscrollHdl));
2122         m_xScrolledWindow->setUserManagedScrolling(m_bUserManagedScrolling);
2123     }
2124 
hadjustment_configure(int value,int lower,int upper,int step_increment,int page_increment,int page_size)2125     virtual void hadjustment_configure(int value, int lower, int upper, int step_increment,
2126                                        int page_increment, int page_size) override
2127     {
2128         ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2129         rHorzScrollBar.SetRangeMin(lower);
2130         rHorzScrollBar.SetRangeMax(upper);
2131         rHorzScrollBar.SetLineSize(step_increment);
2132         rHorzScrollBar.SetPageSize(page_increment);
2133         rHorzScrollBar.SetThumbPos(value);
2134         rHorzScrollBar.SetVisibleSize(page_size);
2135     }
2136 
hadjustment_get_value() const2137     virtual int hadjustment_get_value() const override
2138     {
2139         ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2140         return rHorzScrollBar.GetThumbPos();
2141     }
2142 
hadjustment_set_value(int value)2143     virtual void hadjustment_set_value(int value) override
2144     {
2145         ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2146         rHorzScrollBar.SetThumbPos(value);
2147         if (!m_bUserManagedScrolling)
2148             m_aOrigHScrollHdl.Call(&rHorzScrollBar);
2149     }
2150 
hadjustment_get_upper() const2151     virtual int hadjustment_get_upper() const override
2152     {
2153         ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2154         return rHorzScrollBar.GetRangeMax();
2155     }
2156 
hadjustment_set_upper(int upper)2157     virtual void hadjustment_set_upper(int upper) override
2158     {
2159         ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2160         rHorzScrollBar.SetRangeMax(upper);
2161     }
2162 
hadjustment_get_page_size() const2163     virtual int hadjustment_get_page_size() const override
2164     {
2165         ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2166         return rHorzScrollBar.GetVisibleSize();
2167     }
2168 
hadjustment_set_page_size(int size)2169     virtual void hadjustment_set_page_size(int size) override
2170     {
2171         ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2172         return rHorzScrollBar.SetVisibleSize(size);
2173     }
2174 
hadjustment_set_page_increment(int size)2175     virtual void hadjustment_set_page_increment(int size) override
2176     {
2177         ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2178         return rHorzScrollBar.SetPageSize(size);
2179     }
2180 
hadjustment_set_step_increment(int size)2181     virtual void hadjustment_set_step_increment(int size) override
2182     {
2183         ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2184         return rHorzScrollBar.SetLineSize(size);
2185     }
2186 
set_hpolicy(VclPolicyType eHPolicy)2187     virtual void set_hpolicy(VclPolicyType eHPolicy) override
2188     {
2189         WinBits nWinBits = m_xScrolledWindow->GetStyle() & ~(WB_AUTOHSCROLL | WB_HSCROLL);
2190         if (eHPolicy == VclPolicyType::ALWAYS)
2191             nWinBits |= WB_HSCROLL;
2192         else if (eHPolicy == VclPolicyType::AUTOMATIC)
2193             nWinBits |= WB_AUTOHSCROLL;
2194         m_xScrolledWindow->SetStyle(nWinBits);
2195         m_xScrolledWindow->queue_resize();
2196     }
2197 
get_hpolicy() const2198     virtual VclPolicyType get_hpolicy() const override
2199     {
2200         WinBits nWinBits = m_xScrolledWindow->GetStyle();
2201         if (nWinBits & WB_AUTOHSCROLL)
2202             return VclPolicyType::AUTOMATIC;
2203         else if (nWinBits & WB_HSCROLL)
2204             return VclPolicyType::ALWAYS;
2205         return VclPolicyType::NEVER;
2206     }
2207 
vadjustment_configure(int value,int lower,int upper,int step_increment,int page_increment,int page_size)2208     virtual void vadjustment_configure(int value, int lower, int upper, int step_increment,
2209                                        int page_increment, int page_size) override
2210     {
2211         ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2212         rVertScrollBar.SetRangeMin(lower);
2213         rVertScrollBar.SetRangeMax(upper);
2214         rVertScrollBar.SetLineSize(step_increment);
2215         rVertScrollBar.SetPageSize(page_increment);
2216         rVertScrollBar.SetThumbPos(value);
2217         rVertScrollBar.SetVisibleSize(page_size);
2218     }
2219 
vadjustment_get_value() const2220     virtual int vadjustment_get_value() const override
2221     {
2222         ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2223         return rVertScrollBar.GetThumbPos();
2224     }
2225 
vadjustment_set_value(int value)2226     virtual void vadjustment_set_value(int value) override
2227     {
2228         ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2229         rVertScrollBar.SetThumbPos(value);
2230         if (!m_bUserManagedScrolling)
2231             m_aOrigVScrollHdl.Call(&rVertScrollBar);
2232     }
2233 
vadjustment_get_upper() const2234     virtual int vadjustment_get_upper() const override
2235     {
2236         ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2237         return rVertScrollBar.GetRangeMax();
2238     }
2239 
vadjustment_set_upper(int upper)2240     virtual void vadjustment_set_upper(int upper) override
2241     {
2242         ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2243         rVertScrollBar.SetRangeMax(upper);
2244     }
2245 
vadjustment_get_lower() const2246     virtual int vadjustment_get_lower() const override
2247     {
2248         ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2249         return rVertScrollBar.GetRangeMin();
2250     }
2251 
vadjustment_set_lower(int lower)2252     virtual void vadjustment_set_lower(int lower) override
2253     {
2254         ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2255         rVertScrollBar.SetRangeMin(lower);
2256     }
2257 
vadjustment_get_page_size() const2258     virtual int vadjustment_get_page_size() const override
2259     {
2260         ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2261         return rVertScrollBar.GetVisibleSize();
2262     }
2263 
vadjustment_set_page_size(int size)2264     virtual void vadjustment_set_page_size(int size) override
2265     {
2266         ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2267         return rVertScrollBar.SetVisibleSize(size);
2268     }
2269 
vadjustment_set_page_increment(int size)2270     virtual void vadjustment_set_page_increment(int size) override
2271     {
2272         ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2273         return rVertScrollBar.SetPageSize(size);
2274     }
2275 
vadjustment_set_step_increment(int size)2276     virtual void vadjustment_set_step_increment(int size) override
2277     {
2278         ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2279         return rVertScrollBar.SetLineSize(size);
2280     }
2281 
set_vpolicy(VclPolicyType eVPolicy)2282     virtual void set_vpolicy(VclPolicyType eVPolicy) override
2283     {
2284         WinBits nWinBits = m_xScrolledWindow->GetStyle() & ~(WB_AUTOVSCROLL | WB_VSCROLL);
2285         if (eVPolicy == VclPolicyType::ALWAYS)
2286             nWinBits |= WB_VSCROLL;
2287         else if (eVPolicy == VclPolicyType::AUTOMATIC)
2288             nWinBits |= WB_AUTOVSCROLL;
2289         m_xScrolledWindow->SetStyle(nWinBits);
2290         m_xScrolledWindow->queue_resize();
2291     }
2292 
get_vpolicy() const2293     virtual VclPolicyType get_vpolicy() const override
2294     {
2295         WinBits nWinBits = m_xScrolledWindow->GetStyle();
2296         if (nWinBits & WB_AUTOVSCROLL)
2297             return VclPolicyType::AUTOMATIC;
2298         else if (nWinBits & WB_VSCROLL)
2299             return VclPolicyType::ALWAYS;
2300         return VclPolicyType::NEVER;
2301     }
2302 
get_scroll_thickness() const2303     virtual int get_scroll_thickness() const override
2304     {
2305         return m_xScrolledWindow->getVertScrollBar().get_preferred_size().Width();
2306     }
2307 
set_scroll_thickness(int nThickness)2308     virtual void set_scroll_thickness(int nThickness) override
2309     {
2310         ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2311         ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2312         rHorzScrollBar.set_height_request(nThickness);
2313         rVertScrollBar.set_width_request(nThickness);
2314     }
2315 
customize_scrollbars(const Color & rBackgroundColor,const Color & rShadowColor,const Color & rFaceColor)2316     virtual void customize_scrollbars(const Color& rBackgroundColor, const Color& rShadowColor,
2317                                       const Color& rFaceColor) override
2318     {
2319         ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2320         ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2321         customize_scrollbars(rHorzScrollBar, Color(0, 0, 0), rBackgroundColor, rShadowColor,
2322                              rFaceColor);
2323         customize_scrollbars(rVertScrollBar, Color(0, 0, 0), rBackgroundColor, rShadowColor,
2324                              rFaceColor);
2325     }
2326 
~SalInstanceScrolledWindow()2327     virtual ~SalInstanceScrolledWindow() override
2328     {
2329         ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2330         rVertScrollBar.SetScrollHdl(m_aOrigVScrollHdl);
2331     }
2332 };
2333 }
2334 
IMPL_LINK(SalInstanceScrolledWindow,VscrollHdl,ScrollBar *,pScrollBar,void)2335 IMPL_LINK(SalInstanceScrolledWindow, VscrollHdl, ScrollBar*, pScrollBar, void)
2336 {
2337     signal_vadjustment_changed();
2338     if (!m_bUserManagedScrolling)
2339         m_aOrigVScrollHdl.Call(pScrollBar);
2340 }
2341 
IMPL_LINK_NOARG(SalInstanceScrolledWindow,HscrollHdl,ScrollBar *,void)2342 IMPL_LINK_NOARG(SalInstanceScrolledWindow, HscrollHdl, ScrollBar*, void)
2343 {
2344     signal_hadjustment_changed();
2345     if (!m_bUserManagedScrolling)
2346         m_aOrigHScrollHdl.Call(&m_xScrolledWindow->getHorzScrollBar());
2347 }
2348 
SalInstanceNotebook(TabControl * pNotebook,SalInstanceBuilder * pBuilder,bool bTakeOwnership)2349 SalInstanceNotebook::SalInstanceNotebook(TabControl* pNotebook, SalInstanceBuilder* pBuilder,
2350                                          bool bTakeOwnership)
2351     : SalInstanceWidget(pNotebook, pBuilder, bTakeOwnership)
2352     , m_xNotebook(pNotebook)
2353 {
2354     m_xNotebook->SetActivatePageHdl(LINK(this, SalInstanceNotebook, ActivatePageHdl));
2355     m_xNotebook->SetDeactivatePageHdl(LINK(this, SalInstanceNotebook, DeactivatePageHdl));
2356 }
2357 
get_current_page() const2358 int SalInstanceNotebook::get_current_page() const
2359 {
2360     return m_xNotebook->GetPagePos(m_xNotebook->GetCurPageId());
2361 }
2362 
get_page_ident(int nPage) const2363 OString SalInstanceNotebook::get_page_ident(int nPage) const
2364 {
2365     return m_xNotebook->GetPageName(m_xNotebook->GetPageId(nPage));
2366 }
2367 
get_current_page_ident() const2368 OString SalInstanceNotebook::get_current_page_ident() const
2369 {
2370     return m_xNotebook->GetPageName(m_xNotebook->GetCurPageId());
2371 }
2372 
get_page_index(const OString & rIdent) const2373 int SalInstanceNotebook::get_page_index(const OString& rIdent) const
2374 {
2375     sal_uInt16 nPageId = m_xNotebook->GetPageId(rIdent);
2376     sal_uInt16 nPageIndex = m_xNotebook->GetPagePos(nPageId);
2377     if (nPageIndex == TAB_PAGE_NOTFOUND)
2378         return -1;
2379     return nPageIndex;
2380 }
2381 
get_page(const OString & rIdent) const2382 weld::Container* SalInstanceNotebook::get_page(const OString& rIdent) const
2383 {
2384     int nPageIndex = get_page_index(rIdent);
2385     if (nPageIndex == -1)
2386         return nullptr;
2387     sal_uInt16 nPageId = m_xNotebook->GetPageId(rIdent);
2388     TabPage* pPage = m_xNotebook->GetTabPage(nPageId);
2389     vcl::Window* pChild = pPage->GetChild(0);
2390     if (m_aPages.size() < nPageIndex + 1U)
2391         m_aPages.resize(nPageIndex + 1U);
2392     if (!m_aPages[nPageIndex])
2393         m_aPages[nPageIndex] = std::make_shared<SalInstanceContainer>(pChild, m_pBuilder, false);
2394     return m_aPages[nPageIndex].get();
2395 }
2396 
set_current_page(int nPage)2397 void SalInstanceNotebook::set_current_page(int nPage)
2398 {
2399     m_xNotebook->SetCurPageId(m_xNotebook->GetPageId(nPage));
2400 }
2401 
set_current_page(const OString & rIdent)2402 void SalInstanceNotebook::set_current_page(const OString& rIdent)
2403 {
2404     m_xNotebook->SetCurPageId(m_xNotebook->GetPageId(rIdent));
2405 }
2406 
remove_page(const OString & rIdent)2407 void SalInstanceNotebook::remove_page(const OString& rIdent)
2408 {
2409     sal_uInt16 nPageId = m_xNotebook->GetPageId(rIdent);
2410     sal_uInt16 nPageIndex = m_xNotebook->GetPagePos(nPageId);
2411     if (nPageIndex == TAB_PAGE_NOTFOUND)
2412         return;
2413 
2414     m_xNotebook->RemovePage(nPageId);
2415     if (nPageIndex < m_aPages.size())
2416         m_aPages.erase(m_aPages.begin() + nPageIndex);
2417 
2418     auto iter = m_aAddedPages.find(rIdent);
2419     if (iter != m_aAddedPages.end())
2420     {
2421         iter->second.second.disposeAndClear();
2422         iter->second.first.disposeAndClear();
2423         m_aAddedPages.erase(iter);
2424     }
2425 }
2426 
insert_page(const OString & rIdent,const OUString & rLabel,int nPos)2427 void SalInstanceNotebook::insert_page(const OString& rIdent, const OUString& rLabel, int nPos)
2428 {
2429     sal_uInt16 nPageCount = m_xNotebook->GetPageCount();
2430     sal_uInt16 nLastPageId = nPageCount ? m_xNotebook->GetPageId(nPageCount - 1) : 0;
2431     sal_uInt16 nNewPageId = nLastPageId + 1;
2432     while (m_xNotebook->GetPagePos(nNewPageId) != TAB_PAGE_NOTFOUND)
2433         ++nNewPageId;
2434     m_xNotebook->InsertPage(nNewPageId, rLabel, nPos == -1 ? TAB_APPEND : nPos);
2435     VclPtrInstance<TabPage> xPage(m_xNotebook);
2436     VclPtrInstance<VclGrid> xGrid(xPage);
2437     xPage->Show();
2438     xGrid->set_hexpand(true);
2439     xGrid->set_vexpand(true);
2440     xGrid->Show();
2441     m_xNotebook->SetTabPage(nNewPageId, xPage);
2442     m_xNotebook->SetPageName(nNewPageId, rIdent);
2443     m_aAddedPages.try_emplace(rIdent, xPage, xGrid);
2444 
2445     if (nPos != -1)
2446     {
2447         unsigned int nPageIndex = static_cast<unsigned int>(nPos);
2448         if (nPageIndex < m_aPages.size())
2449             m_aPages.insert(m_aPages.begin() + nPageIndex, nullptr);
2450     }
2451 }
2452 
get_n_pages() const2453 int SalInstanceNotebook::get_n_pages() const { return m_xNotebook->GetPageCount(); }
2454 
get_tab_label_text(const OString & rIdent) const2455 OUString SalInstanceNotebook::get_tab_label_text(const OString& rIdent) const
2456 {
2457     return m_xNotebook->GetPageText(m_xNotebook->GetPageId(rIdent));
2458 }
2459 
set_tab_label_text(const OString & rIdent,const OUString & rText)2460 void SalInstanceNotebook::set_tab_label_text(const OString& rIdent, const OUString& rText)
2461 {
2462     return m_xNotebook->SetPageText(m_xNotebook->GetPageId(rIdent), rText);
2463 }
2464 
~SalInstanceNotebook()2465 SalInstanceNotebook::~SalInstanceNotebook()
2466 {
2467     for (auto& rItem : m_aAddedPages)
2468     {
2469         rItem.second.second.disposeAndClear();
2470         rItem.second.first.disposeAndClear();
2471     }
2472     m_xNotebook->SetActivatePageHdl(Link<TabControl*, void>());
2473     m_xNotebook->SetDeactivatePageHdl(Link<TabControl*, bool>());
2474 }
2475 
IMPL_LINK_NOARG(SalInstanceNotebook,DeactivatePageHdl,TabControl *,bool)2476 IMPL_LINK_NOARG(SalInstanceNotebook, DeactivatePageHdl, TabControl*, bool)
2477 {
2478     return !m_aLeavePageHdl.IsSet() || m_aLeavePageHdl.Call(get_current_page_ident());
2479 }
2480 
IMPL_LINK_NOARG(SalInstanceNotebook,ActivatePageHdl,TabControl *,void)2481 IMPL_LINK_NOARG(SalInstanceNotebook, ActivatePageHdl, TabControl*, void)
2482 {
2483     m_aEnterPageHdl.Call(get_current_page_ident());
2484 }
2485 
2486 namespace
2487 {
2488 class SalInstanceVerticalNotebook : public SalInstanceWidget, public virtual weld::Notebook
2489 {
2490 private:
2491     VclPtr<VerticalTabControl> m_xNotebook;
2492     mutable std::vector<std::unique_ptr<SalInstanceContainer>> m_aPages;
2493 
2494     DECL_LINK(DeactivatePageHdl, VerticalTabControl*, bool);
2495     DECL_LINK(ActivatePageHdl, VerticalTabControl*, void);
2496 
2497 public:
SalInstanceVerticalNotebook(VerticalTabControl * pNotebook,SalInstanceBuilder * pBuilder,bool bTakeOwnership)2498     SalInstanceVerticalNotebook(VerticalTabControl* pNotebook, SalInstanceBuilder* pBuilder,
2499                                 bool bTakeOwnership)
2500         : SalInstanceWidget(pNotebook, pBuilder, bTakeOwnership)
2501         , m_xNotebook(pNotebook)
2502     {
2503         m_xNotebook->SetActivatePageHdl(LINK(this, SalInstanceVerticalNotebook, ActivatePageHdl));
2504         m_xNotebook->SetDeactivatePageHdl(
2505             LINK(this, SalInstanceVerticalNotebook, DeactivatePageHdl));
2506     }
2507 
get_current_page() const2508     virtual int get_current_page() const override
2509     {
2510         return m_xNotebook->GetPagePos(m_xNotebook->GetCurPageId());
2511     }
2512 
get_page_ident(int nPage) const2513     virtual OString get_page_ident(int nPage) const override
2514     {
2515         return m_xNotebook->GetPageId(nPage);
2516     }
2517 
get_current_page_ident() const2518     virtual OString get_current_page_ident() const override { return m_xNotebook->GetCurPageId(); }
2519 
get_page_index(const OString & rIdent) const2520     virtual int get_page_index(const OString& rIdent) const override
2521     {
2522         sal_uInt16 nPageIndex = m_xNotebook->GetPagePos(rIdent);
2523         if (nPageIndex == TAB_PAGE_NOTFOUND)
2524             return -1;
2525         return nPageIndex;
2526     }
2527 
get_page(const OString & rIdent) const2528     virtual weld::Container* get_page(const OString& rIdent) const override
2529     {
2530         int nPageIndex = get_page_index(rIdent);
2531         if (nPageIndex == -1)
2532             return nullptr;
2533         auto pChild = m_xNotebook->GetPage(rIdent);
2534         if (m_aPages.size() < nPageIndex + 1U)
2535             m_aPages.resize(nPageIndex + 1U);
2536         if (!m_aPages[nPageIndex])
2537             m_aPages[nPageIndex].reset(new SalInstanceContainer(pChild, m_pBuilder, false));
2538         return m_aPages[nPageIndex].get();
2539     }
2540 
set_current_page(int nPage)2541     virtual void set_current_page(int nPage) override
2542     {
2543         m_xNotebook->SetCurPageId(m_xNotebook->GetPageId(nPage));
2544     }
2545 
set_current_page(const OString & rIdent)2546     virtual void set_current_page(const OString& rIdent) override
2547     {
2548         m_xNotebook->SetCurPageId(rIdent);
2549     }
2550 
remove_page(const OString & rIdent)2551     virtual void remove_page(const OString& rIdent) override
2552     {
2553         sal_uInt16 nPageIndex = m_xNotebook->GetPagePos(rIdent);
2554         if (nPageIndex == TAB_PAGE_NOTFOUND)
2555             return;
2556         m_xNotebook->RemovePage(rIdent);
2557         if (nPageIndex < m_aPages.size())
2558             m_aPages.erase(m_aPages.begin() + nPageIndex);
2559     }
2560 
insert_page(const OString & rIdent,const OUString & rLabel,int nPos)2561     virtual void insert_page(const OString& rIdent, const OUString& rLabel, int nPos) override
2562     {
2563         VclPtrInstance<VclGrid> xGrid(m_xNotebook->GetPageParent());
2564         xGrid->set_hexpand(true);
2565         xGrid->set_vexpand(true);
2566         m_xNotebook->InsertPage(rIdent, rLabel, Image(), "", xGrid, nPos);
2567 
2568         if (nPos != -1)
2569         {
2570             unsigned int nPageIndex = static_cast<unsigned int>(nPos);
2571             if (nPageIndex < m_aPages.size())
2572                 m_aPages.insert(m_aPages.begin() + nPageIndex, nullptr);
2573         }
2574     }
2575 
get_n_pages() const2576     virtual int get_n_pages() const override { return m_xNotebook->GetPageCount(); }
2577 
set_tab_label_text(const OString & rIdent,const OUString & rText)2578     virtual void set_tab_label_text(const OString& rIdent, const OUString& rText) override
2579     {
2580         return m_xNotebook->SetPageText(rIdent, rText);
2581     }
2582 
get_tab_label_text(const OString & rIdent) const2583     virtual OUString get_tab_label_text(const OString& rIdent) const override
2584     {
2585         return m_xNotebook->GetPageText(rIdent);
2586     }
2587 
~SalInstanceVerticalNotebook()2588     virtual ~SalInstanceVerticalNotebook() override
2589     {
2590         m_xNotebook->SetActivatePageHdl(Link<VerticalTabControl*, void>());
2591         m_xNotebook->SetDeactivatePageHdl(Link<VerticalTabControl*, bool>());
2592     }
2593 };
2594 }
2595 
IMPL_LINK_NOARG(SalInstanceVerticalNotebook,DeactivatePageHdl,VerticalTabControl *,bool)2596 IMPL_LINK_NOARG(SalInstanceVerticalNotebook, DeactivatePageHdl, VerticalTabControl*, bool)
2597 {
2598     return !m_aLeavePageHdl.IsSet() || m_aLeavePageHdl.Call(get_current_page_ident());
2599 }
2600 
IMPL_LINK_NOARG(SalInstanceVerticalNotebook,ActivatePageHdl,VerticalTabControl *,void)2601 IMPL_LINK_NOARG(SalInstanceVerticalNotebook, ActivatePageHdl, VerticalTabControl*, void)
2602 {
2603     m_aEnterPageHdl.Call(get_current_page_ident());
2604 }
2605 
SalInstanceButton(::Button * pButton,SalInstanceBuilder * pBuilder,bool bTakeOwnership)2606 SalInstanceButton::SalInstanceButton(::Button* pButton, SalInstanceBuilder* pBuilder,
2607                                      bool bTakeOwnership)
2608     : SalInstanceWidget(pButton, pBuilder, bTakeOwnership)
2609     , m_xButton(pButton)
2610     , m_aOldClickHdl(pButton->GetClickHdl())
2611 {
2612     m_xButton->SetClickHdl(LINK(this, SalInstanceButton, ClickHdl));
2613 }
2614 
set_label(const OUString & rText)2615 void SalInstanceButton::set_label(const OUString& rText) { m_xButton->SetText(rText); }
2616 
set_image(VirtualDevice * pDevice)2617 void SalInstanceButton::set_image(VirtualDevice* pDevice)
2618 {
2619     m_xButton->SetImageAlign(ImageAlign::Left);
2620     if (pDevice)
2621         m_xButton->SetModeImage(createImage(*pDevice));
2622     else
2623         m_xButton->SetModeImage(Image());
2624 }
2625 
set_image(const css::uno::Reference<css::graphic::XGraphic> & rImage)2626 void SalInstanceButton::set_image(const css::uno::Reference<css::graphic::XGraphic>& rImage)
2627 {
2628     m_xButton->SetImageAlign(ImageAlign::Left);
2629     m_xButton->SetModeImage(Image(rImage));
2630 }
2631 
set_from_icon_name(const OUString & rIconName)2632 void SalInstanceButton::set_from_icon_name(const OUString& rIconName)
2633 {
2634     m_xButton->SetModeImage(Image(StockImage::Yes, rIconName));
2635 }
2636 
set_label_wrap(bool wrap)2637 void SalInstanceButton::set_label_wrap(bool wrap)
2638 {
2639     WinBits nBits = m_xButton->GetStyle();
2640     nBits &= ~WB_WORDBREAK;
2641     if (wrap)
2642         nBits |= WB_WORDBREAK;
2643     m_xButton->SetStyle(nBits);
2644     m_xButton->queue_resize();
2645 }
2646 
set_font(const vcl::Font & rFont)2647 void SalInstanceButton::set_font(const vcl::Font& rFont)
2648 {
2649     m_xButton->SetControlFont(rFont);
2650     m_xButton->Invalidate();
2651 }
2652 
set_custom_button(VirtualDevice * pDevice)2653 void SalInstanceButton::set_custom_button(VirtualDevice* pDevice)
2654 {
2655     if (pDevice)
2656         m_xButton->SetCustomButtonImage(createImage(*pDevice));
2657     else
2658         m_xButton->SetCustomButtonImage(Image());
2659     m_xButton->Invalidate();
2660 }
2661 
get_label() const2662 OUString SalInstanceButton::get_label() const { return m_xButton->GetText(); }
2663 
~SalInstanceButton()2664 SalInstanceButton::~SalInstanceButton() { m_xButton->SetClickHdl(Link<::Button*, void>()); }
2665 
IMPL_LINK(SalInstanceButton,ClickHdl,::Button *,pButton,void)2666 IMPL_LINK(SalInstanceButton, ClickHdl, ::Button*, pButton, void)
2667 {
2668     //if there's no handler set, disengage our intercept and
2669     //run the click again to get default behaviour for cancel/ok
2670     //etc buttons.
2671     if (!m_aClickHdl.IsSet())
2672     {
2673         pButton->SetClickHdl(m_aOldClickHdl);
2674         pButton->Click();
2675         pButton->SetClickHdl(LINK(this, SalInstanceButton, ClickHdl));
2676         return;
2677     }
2678     signal_clicked();
2679 }
2680 
weld_widget_for_response(int nResponse)2681 weld::Button* SalInstanceDialog::weld_widget_for_response(int nResponse)
2682 {
2683     PushButton* pButton = dynamic_cast<PushButton*>(m_xDialog->get_widget_for_response(nResponse));
2684     return pButton ? new SalInstanceButton(pButton, nullptr, false) : nullptr;
2685 }
2686 
weld_widget_for_response(int nResponse)2687 weld::Button* SalInstanceAssistant::weld_widget_for_response(int nResponse)
2688 {
2689     PushButton* pButton = nullptr;
2690     if (nResponse == RET_YES)
2691         pButton = m_xWizard->m_pNextPage;
2692     else if (nResponse == RET_NO)
2693         pButton = m_xWizard->m_pPrevPage;
2694     else if (nResponse == RET_OK)
2695         pButton = m_xWizard->m_pFinish;
2696     else if (nResponse == RET_CANCEL)
2697         pButton = m_xWizard->m_pCancel;
2698     else if (nResponse == RET_HELP)
2699         pButton = m_xWizard->m_pHelp;
2700     if (pButton)
2701         return new SalInstanceButton(pButton, nullptr, false);
2702     return nullptr;
2703 }
2704 
2705 namespace
2706 {
2707 class SalInstanceMenuButton : public SalInstanceButton, public virtual weld::MenuButton
2708 {
2709 private:
2710     VclPtr<::MenuButton> m_xMenuButton;
2711     sal_uInt16 m_nLastId;
2712 
2713     DECL_LINK(MenuSelectHdl, ::MenuButton*, void);
2714     DECL_LINK(ActivateHdl, ::MenuButton*, void);
2715 
2716 public:
SalInstanceMenuButton(::MenuButton * pButton,SalInstanceBuilder * pBuilder,bool bTakeOwnership)2717     SalInstanceMenuButton(::MenuButton* pButton, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2718         : SalInstanceButton(pButton, pBuilder, bTakeOwnership)
2719         , m_xMenuButton(pButton)
2720         , m_nLastId(0)
2721     {
2722         m_xMenuButton->SetActivateHdl(LINK(this, SalInstanceMenuButton, ActivateHdl));
2723         m_xMenuButton->SetSelectHdl(LINK(this, SalInstanceMenuButton, MenuSelectHdl));
2724         if (PopupMenu* pMenu = m_xMenuButton->GetPopupMenu())
2725         {
2726             pMenu->SetMenuFlags(MenuFlags::NoAutoMnemonics);
2727             const auto nCount = pMenu->GetItemCount();
2728             m_nLastId = nCount ? pMenu->GetItemId(nCount - 1) : 0;
2729         }
2730     }
2731 
set_active(bool active)2732     virtual void set_active(bool active) override
2733     {
2734         if (active == get_active())
2735             return;
2736         if (active)
2737             m_xMenuButton->ExecuteMenu();
2738         else
2739             m_xMenuButton->CancelMenu();
2740     }
2741 
get_active() const2742     virtual bool get_active() const override { return m_xMenuButton->InPopupMode(); }
2743 
set_inconsistent(bool)2744     virtual void set_inconsistent(bool /*inconsistent*/) override
2745     {
2746         //not available
2747     }
2748 
get_inconsistent() const2749     virtual bool get_inconsistent() const override { return false; }
2750 
insert_item(int pos,const OUString & rId,const OUString & rStr,const OUString * pIconName,VirtualDevice * pImageSurface,TriState eCheckRadioFalse)2751     virtual void insert_item(int pos, const OUString& rId, const OUString& rStr,
2752                              const OUString* pIconName, VirtualDevice* pImageSurface,
2753                              TriState eCheckRadioFalse) override
2754     {
2755         m_nLastId = insert_to_menu(m_nLastId, m_xMenuButton->GetPopupMenu(), pos, rId, rStr,
2756                                    pIconName, pImageSurface, nullptr, eCheckRadioFalse);
2757     }
2758 
insert_separator(int pos,const OUString & rId)2759     virtual void insert_separator(int pos, const OUString& rId) override
2760     {
2761         auto nInsertPos = pos == -1 ? MENU_APPEND : pos;
2762         m_xMenuButton->GetPopupMenu()->InsertSeparator(rId.toUtf8(), nInsertPos);
2763     }
2764 
set_item_sensitive(const OString & rIdent,bool bSensitive)2765     virtual void set_item_sensitive(const OString& rIdent, bool bSensitive) override
2766     {
2767         PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2768         pMenu->EnableItem(rIdent, bSensitive);
2769     }
2770 
remove_item(const OString & rId)2771     virtual void remove_item(const OString& rId) override
2772     {
2773         PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2774         pMenu->RemoveItem(pMenu->GetItemPos(pMenu->GetItemId(rId)));
2775     }
2776 
clear()2777     virtual void clear() override
2778     {
2779         PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2780         pMenu->Clear();
2781     }
2782 
set_item_active(const OString & rIdent,bool bActive)2783     virtual void set_item_active(const OString& rIdent, bool bActive) override
2784     {
2785         PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2786         pMenu->CheckItem(rIdent, bActive);
2787     }
2788 
set_item_label(const OString & rIdent,const OUString & rText)2789     virtual void set_item_label(const OString& rIdent, const OUString& rText) override
2790     {
2791         PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2792         pMenu->SetItemText(pMenu->GetItemId(rIdent), rText);
2793     }
2794 
get_item_label(const OString & rIdent) const2795     virtual OUString get_item_label(const OString& rIdent) const override
2796     {
2797         PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2798         return pMenu->GetItemText(pMenu->GetItemId(rIdent));
2799     }
2800 
set_item_visible(const OString & rIdent,bool bShow)2801     virtual void set_item_visible(const OString& rIdent, bool bShow) override
2802     {
2803         PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2804         pMenu->ShowItem(pMenu->GetItemId(rIdent), bShow);
2805     }
2806 
set_item_help_id(const OString & rIdent,const OString & rHelpId)2807     virtual void set_item_help_id(const OString& rIdent, const OString& rHelpId) override
2808     {
2809         PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2810         pMenu->SetHelpId(pMenu->GetItemId(rIdent), rHelpId);
2811     }
2812 
get_item_help_id(const OString & rIdent) const2813     virtual OString get_item_help_id(const OString& rIdent) const override
2814     {
2815         PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2816         return pMenu->GetHelpId(pMenu->GetItemId(rIdent));
2817     }
2818 
set_popover(weld::Widget * pPopover)2819     virtual void set_popover(weld::Widget* pPopover) override
2820     {
2821         SalInstanceWidget* pPopoverWidget = dynamic_cast<SalInstanceWidget*>(pPopover);
2822         m_xMenuButton->SetPopover(pPopoverWidget ? pPopoverWidget->getWidget() : nullptr);
2823     }
2824 
~SalInstanceMenuButton()2825     virtual ~SalInstanceMenuButton() override
2826     {
2827         m_xMenuButton->SetSelectHdl(Link<::MenuButton*, void>());
2828         m_xMenuButton->SetActivateHdl(Link<::MenuButton*, void>());
2829     }
2830 };
2831 }
2832 
IMPL_LINK_NOARG(SalInstanceMenuButton,MenuSelectHdl,::MenuButton *,void)2833 IMPL_LINK_NOARG(SalInstanceMenuButton, MenuSelectHdl, ::MenuButton*, void)
2834 {
2835     signal_selected(m_xMenuButton->GetCurItemIdent());
2836 }
2837 
IMPL_LINK_NOARG(SalInstanceMenuButton,ActivateHdl,::MenuButton *,void)2838 IMPL_LINK_NOARG(SalInstanceMenuButton, ActivateHdl, ::MenuButton*, void)
2839 {
2840     if (notify_events_disabled())
2841         return;
2842     signal_toggled();
2843 }
2844 
2845 namespace
2846 {
2847 class SalInstanceMenuToggleButton : public SalInstanceMenuButton,
2848                                     public virtual weld::MenuToggleButton
2849 {
2850 private:
2851     VclPtr<::MenuToggleButton> m_xMenuToggleButton;
2852 
2853 public:
SalInstanceMenuToggleButton(::MenuToggleButton * pButton,SalInstanceBuilder * pBuilder,bool bTakeOwnership)2854     SalInstanceMenuToggleButton(::MenuToggleButton* pButton, SalInstanceBuilder* pBuilder,
2855                                 bool bTakeOwnership)
2856         : SalInstanceMenuButton(pButton, pBuilder, bTakeOwnership)
2857         , m_xMenuToggleButton(pButton)
2858     {
2859         m_xMenuToggleButton->SetDelayMenu(true);
2860         m_xMenuToggleButton->SetDropDown(PushButtonDropdownStyle::SplitMenuButton);
2861     }
2862 
set_active(bool active)2863     virtual void set_active(bool active) override
2864     {
2865         disable_notify_events();
2866         m_xMenuToggleButton->SetActive(active);
2867         enable_notify_events();
2868     }
2869 
get_active() const2870     virtual bool get_active() const override { return m_xMenuToggleButton->GetActive(); }
2871 };
2872 }
2873 
2874 namespace
2875 {
2876 class SalInstanceLinkButton : public SalInstanceWidget, public virtual weld::LinkButton
2877 {
2878 private:
2879     VclPtr<FixedHyperlink> m_xButton;
2880     Link<FixedHyperlink&, void> m_aOrigClickHdl;
2881 
2882     DECL_LINK(ClickHdl, FixedHyperlink&, void);
2883 
2884 public:
SalInstanceLinkButton(FixedHyperlink * pButton,SalInstanceBuilder * pBuilder,bool bTakeOwnership)2885     SalInstanceLinkButton(FixedHyperlink* pButton, SalInstanceBuilder* pBuilder,
2886                           bool bTakeOwnership)
2887         : SalInstanceWidget(pButton, pBuilder, bTakeOwnership)
2888         , m_xButton(pButton)
2889     {
2890         m_aOrigClickHdl = m_xButton->GetClickHdl();
2891         m_xButton->SetClickHdl(LINK(this, SalInstanceLinkButton, ClickHdl));
2892     }
2893 
set_label(const OUString & rText)2894     virtual void set_label(const OUString& rText) override { m_xButton->SetText(rText); }
2895 
get_label() const2896     virtual OUString get_label() const override { return m_xButton->GetText(); }
2897 
set_uri(const OUString & rUri)2898     virtual void set_uri(const OUString& rUri) override { m_xButton->SetURL(rUri); }
2899 
get_uri() const2900     virtual OUString get_uri() const override { return m_xButton->GetURL(); }
2901 
~SalInstanceLinkButton()2902     virtual ~SalInstanceLinkButton() override { m_xButton->SetClickHdl(m_aOrigClickHdl); }
2903 };
2904 }
2905 
IMPL_LINK(SalInstanceLinkButton,ClickHdl,FixedHyperlink &,rButton,void)2906 IMPL_LINK(SalInstanceLinkButton, ClickHdl, FixedHyperlink&, rButton, void)
2907 {
2908     bool bConsumed = signal_activate_link();
2909     if (!bConsumed)
2910         m_aOrigClickHdl.Call(rButton);
2911 }
2912 
SalInstanceRadioButton(::RadioButton * pButton,SalInstanceBuilder * pBuilder,bool bTakeOwnership)2913 SalInstanceRadioButton::SalInstanceRadioButton(::RadioButton* pButton, SalInstanceBuilder* pBuilder,
2914                                                bool bTakeOwnership)
2915     : SalInstanceButton(pButton, pBuilder, bTakeOwnership)
2916     , m_xRadioButton(pButton)
2917 {
2918     m_xRadioButton->SetToggleHdl(LINK(this, SalInstanceRadioButton, ToggleHdl));
2919 }
2920 
set_active(bool active)2921 void SalInstanceRadioButton::set_active(bool active)
2922 {
2923     disable_notify_events();
2924     m_xRadioButton->Check(active);
2925     enable_notify_events();
2926 }
2927 
get_active() const2928 bool SalInstanceRadioButton::get_active() const { return m_xRadioButton->IsChecked(); }
2929 
set_image(VirtualDevice * pDevice)2930 void SalInstanceRadioButton::set_image(VirtualDevice* pDevice)
2931 {
2932     m_xRadioButton->SetImageAlign(ImageAlign::Center);
2933     if (pDevice)
2934         m_xRadioButton->SetModeImage(createImage(*pDevice));
2935     else
2936         m_xRadioButton->SetModeImage(Image());
2937 }
2938 
set_image(const css::uno::Reference<css::graphic::XGraphic> & rImage)2939 void SalInstanceRadioButton::set_image(const css::uno::Reference<css::graphic::XGraphic>& rImage)
2940 {
2941     m_xRadioButton->SetImageAlign(ImageAlign::Center);
2942     m_xRadioButton->SetModeImage(Image(rImage));
2943 }
2944 
set_from_icon_name(const OUString & rIconName)2945 void SalInstanceRadioButton::set_from_icon_name(const OUString& rIconName)
2946 {
2947     m_xRadioButton->SetModeRadioImage(Image(StockImage::Yes, rIconName));
2948 }
2949 
set_inconsistent(bool)2950 void SalInstanceRadioButton::set_inconsistent(bool /*inconsistent*/)
2951 {
2952     //not available
2953 }
2954 
get_inconsistent() const2955 bool SalInstanceRadioButton::get_inconsistent() const { return false; }
2956 
~SalInstanceRadioButton()2957 SalInstanceRadioButton::~SalInstanceRadioButton()
2958 {
2959     m_xRadioButton->SetToggleHdl(Link<::RadioButton&, void>());
2960 }
2961 
IMPL_LINK_NOARG(SalInstanceRadioButton,ToggleHdl,::RadioButton &,void)2962 IMPL_LINK_NOARG(SalInstanceRadioButton, ToggleHdl, ::RadioButton&, void)
2963 {
2964     if (notify_events_disabled())
2965         return;
2966     signal_toggled();
2967 }
2968 
2969 namespace
2970 {
2971 class SalInstanceToggleButton : public SalInstanceButton, public virtual weld::ToggleButton
2972 {
2973 private:
2974     VclPtr<PushButton> m_xToggleButton;
2975 
2976     DECL_LINK(ToggleListener, VclWindowEvent&, void);
2977 
2978 public:
SalInstanceToggleButton(PushButton * pButton,SalInstanceBuilder * pBuilder,bool bTakeOwnership)2979     SalInstanceToggleButton(PushButton* pButton, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2980         : SalInstanceButton(pButton, pBuilder, bTakeOwnership)
2981         , m_xToggleButton(pButton)
2982     {
2983     }
2984 
connect_toggled(const Link<Toggleable &,void> & rLink)2985     virtual void connect_toggled(const Link<Toggleable&, void>& rLink) override
2986     {
2987         assert(!m_aToggleHdl.IsSet());
2988         m_xToggleButton->AddEventListener(LINK(this, SalInstanceToggleButton, ToggleListener));
2989         weld::ToggleButton::connect_toggled(rLink);
2990     }
2991 
set_active(bool active)2992     virtual void set_active(bool active) override
2993     {
2994         disable_notify_events();
2995         m_xToggleButton->Check(active);
2996         enable_notify_events();
2997     }
2998 
get_active() const2999     virtual bool get_active() const override { return m_xToggleButton->IsChecked(); }
3000 
set_inconsistent(bool inconsistent)3001     virtual void set_inconsistent(bool inconsistent) override
3002     {
3003         disable_notify_events();
3004         m_xToggleButton->SetState(inconsistent ? TRISTATE_INDET : TRISTATE_FALSE);
3005         enable_notify_events();
3006     }
3007 
get_inconsistent() const3008     virtual bool get_inconsistent() const override
3009     {
3010         return m_xToggleButton->GetState() == TRISTATE_INDET;
3011     }
3012 
~SalInstanceToggleButton()3013     virtual ~SalInstanceToggleButton() override
3014     {
3015         if (m_aToggleHdl.IsSet())
3016             m_xToggleButton->RemoveEventListener(
3017                 LINK(this, SalInstanceToggleButton, ToggleListener));
3018     }
3019 };
3020 }
3021 
IMPL_LINK(SalInstanceToggleButton,ToggleListener,VclWindowEvent &,rEvent,void)3022 IMPL_LINK(SalInstanceToggleButton, ToggleListener, VclWindowEvent&, rEvent, void)
3023 {
3024     if (notify_events_disabled())
3025         return;
3026     if (rEvent.GetId() == VclEventId::PushbuttonToggle)
3027         signal_toggled();
3028 }
3029 
SalInstanceCheckButton(CheckBox * pButton,SalInstanceBuilder * pBuilder,bool bTakeOwnership)3030 SalInstanceCheckButton::SalInstanceCheckButton(CheckBox* pButton, SalInstanceBuilder* pBuilder,
3031                                                bool bTakeOwnership)
3032     : SalInstanceButton(pButton, pBuilder, bTakeOwnership)
3033     , m_xCheckButton(pButton)
3034 {
3035     m_xCheckButton->SetToggleHdl(LINK(this, SalInstanceCheckButton, ToggleHdl));
3036 }
3037 
set_active(bool active)3038 void SalInstanceCheckButton::set_active(bool active)
3039 {
3040     disable_notify_events();
3041     m_xCheckButton->EnableTriState(false);
3042     m_xCheckButton->Check(active);
3043     enable_notify_events();
3044 }
3045 
get_active() const3046 bool SalInstanceCheckButton::get_active() const { return m_xCheckButton->IsChecked(); }
3047 
set_inconsistent(bool inconsistent)3048 void SalInstanceCheckButton::set_inconsistent(bool inconsistent)
3049 {
3050     disable_notify_events();
3051     m_xCheckButton->EnableTriState(true);
3052     m_xCheckButton->SetState(inconsistent ? TRISTATE_INDET : TRISTATE_FALSE);
3053     enable_notify_events();
3054 }
3055 
get_inconsistent() const3056 bool SalInstanceCheckButton::get_inconsistent() const
3057 {
3058     return m_xCheckButton->GetState() == TRISTATE_INDET;
3059 }
3060 
~SalInstanceCheckButton()3061 SalInstanceCheckButton::~SalInstanceCheckButton()
3062 {
3063     m_xCheckButton->SetToggleHdl(Link<CheckBox&, void>());
3064 }
3065 
IMPL_LINK_NOARG(SalInstanceCheckButton,ToggleHdl,CheckBox &,void)3066 IMPL_LINK_NOARG(SalInstanceCheckButton, ToggleHdl, CheckBox&, void)
3067 {
3068     if (notify_events_disabled())
3069         return;
3070     m_xCheckButton->EnableTriState(false);
3071     signal_toggled();
3072 }
3073 
3074 namespace
3075 {
3076 class SalInstanceScale : public SalInstanceWidget, public virtual weld::Scale
3077 {
3078 private:
3079     VclPtr<Slider> m_xScale;
3080 
3081     DECL_LINK(SlideHdl, Slider*, void);
3082 
3083 public:
SalInstanceScale(Slider * pScale,SalInstanceBuilder * pBuilder,bool bTakeOwnership)3084     SalInstanceScale(Slider* pScale, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3085         : SalInstanceWidget(pScale, pBuilder, bTakeOwnership)
3086         , m_xScale(pScale)
3087     {
3088         m_xScale->SetSlideHdl(LINK(this, SalInstanceScale, SlideHdl));
3089     }
3090 
set_value(int value)3091     virtual void set_value(int value) override { m_xScale->SetThumbPos(value); }
3092 
set_range(int min,int max)3093     virtual void set_range(int min, int max) override
3094     {
3095         m_xScale->SetRangeMin(min);
3096         m_xScale->SetRangeMax(max);
3097     }
3098 
get_value() const3099     virtual int get_value() const override { return m_xScale->GetThumbPos(); }
3100 
set_increments(int step,int page)3101     virtual void set_increments(int step, int page) override
3102     {
3103         m_xScale->SetLineSize(step);
3104         m_xScale->SetPageSize(page);
3105     }
3106 
get_increments(int & step,int & page) const3107     virtual void get_increments(int& step, int& page) const override
3108     {
3109         step = m_xScale->GetLineSize();
3110         page = m_xScale->GetPageSize();
3111     }
3112 
~SalInstanceScale()3113     virtual ~SalInstanceScale() override { m_xScale->SetSlideHdl(Link<Slider*, void>()); }
3114 };
3115 }
3116 
IMPL_LINK_NOARG(SalInstanceScale,SlideHdl,Slider *,void)3117 IMPL_LINK_NOARG(SalInstanceScale, SlideHdl, Slider*, void) { signal_value_changed(); }
3118 
3119 namespace
3120 {
3121 class SalInstanceSpinner : public SalInstanceWidget, public virtual weld::Spinner
3122 {
3123 private:
3124     VclPtr<Throbber> m_xThrobber;
3125 
3126 public:
SalInstanceSpinner(Throbber * pThrobber,SalInstanceBuilder * pBuilder,bool bTakeOwnership)3127     SalInstanceSpinner(Throbber* pThrobber, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3128         : SalInstanceWidget(pThrobber, pBuilder, bTakeOwnership)
3129         , m_xThrobber(pThrobber)
3130     {
3131     }
3132 
start()3133     virtual void start() override { m_xThrobber->start(); }
3134 
stop()3135     virtual void stop() override { m_xThrobber->stop(); }
3136 };
3137 
3138 class SalInstanceProgressBar : public SalInstanceWidget, public virtual weld::ProgressBar
3139 {
3140 private:
3141     VclPtr<::ProgressBar> m_xProgressBar;
3142 
3143 public:
SalInstanceProgressBar(::ProgressBar * pProgressBar,SalInstanceBuilder * pBuilder,bool bTakeOwnership)3144     SalInstanceProgressBar(::ProgressBar* pProgressBar, SalInstanceBuilder* pBuilder,
3145                            bool bTakeOwnership)
3146         : SalInstanceWidget(pProgressBar, pBuilder, bTakeOwnership)
3147         , m_xProgressBar(pProgressBar)
3148     {
3149     }
3150 
set_percentage(int value)3151     virtual void set_percentage(int value) override { m_xProgressBar->SetValue(value); }
3152 
get_text() const3153     virtual OUString get_text() const override { return m_xProgressBar->GetText(); }
3154 
set_text(const OUString & rText)3155     virtual void set_text(const OUString& rText) override { m_xProgressBar->SetText(rText); }
3156 };
3157 
3158 class SalInstanceImage : public SalInstanceWidget, public virtual weld::Image
3159 {
3160 private:
3161     VclPtr<FixedImage> m_xImage;
3162 
3163 public:
SalInstanceImage(FixedImage * pImage,SalInstanceBuilder * pBuilder,bool bTakeOwnership)3164     SalInstanceImage(FixedImage* pImage, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3165         : SalInstanceWidget(pImage, pBuilder, bTakeOwnership)
3166         , m_xImage(pImage)
3167     {
3168     }
3169 
set_from_icon_name(const OUString & rIconName)3170     virtual void set_from_icon_name(const OUString& rIconName) override
3171     {
3172         m_xImage->SetImage(::Image(StockImage::Yes, rIconName));
3173     }
3174 
set_image(VirtualDevice * pDevice)3175     virtual void set_image(VirtualDevice* pDevice) override
3176     {
3177         if (pDevice)
3178             m_xImage->SetImage(createImage(*pDevice));
3179         else
3180             m_xImage->SetImage(::Image());
3181     }
3182 
set_image(const css::uno::Reference<css::graphic::XGraphic> & rImage)3183     virtual void set_image(const css::uno::Reference<css::graphic::XGraphic>& rImage) override
3184     {
3185         m_xImage->SetImage(::Image(rImage));
3186     }
3187 };
3188 
3189 class SalInstanceCalendar : public SalInstanceWidget, public virtual weld::Calendar
3190 {
3191 private:
3192     VclPtr<::Calendar> m_xCalendar;
3193 
3194     DECL_LINK(SelectHdl, ::Calendar*, void);
3195     DECL_LINK(ActivateHdl, ::Calendar*, void);
3196 
3197 public:
SalInstanceCalendar(::Calendar * pCalendar,SalInstanceBuilder * pBuilder,bool bTakeOwnership)3198     SalInstanceCalendar(::Calendar* pCalendar, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3199         : SalInstanceWidget(pCalendar, pBuilder, bTakeOwnership)
3200         , m_xCalendar(pCalendar)
3201     {
3202         m_xCalendar->SetSelectHdl(LINK(this, SalInstanceCalendar, SelectHdl));
3203         m_xCalendar->SetActivateHdl(LINK(this, SalInstanceCalendar, ActivateHdl));
3204     }
3205 
set_date(const Date & rDate)3206     virtual void set_date(const Date& rDate) override { m_xCalendar->SetCurDate(rDate); }
3207 
get_date() const3208     virtual Date get_date() const override { return m_xCalendar->GetFirstSelectedDate(); }
3209 
~SalInstanceCalendar()3210     virtual ~SalInstanceCalendar() override
3211     {
3212         m_xCalendar->SetSelectHdl(Link<::Calendar*, void>());
3213         m_xCalendar->SetActivateHdl(Link<::Calendar*, void>());
3214     }
3215 };
3216 }
3217 
IMPL_LINK_NOARG(SalInstanceCalendar,SelectHdl,::Calendar *,void)3218 IMPL_LINK_NOARG(SalInstanceCalendar, SelectHdl, ::Calendar*, void)
3219 {
3220     if (notify_events_disabled())
3221         return;
3222     signal_selected();
3223 }
3224 
IMPL_LINK_NOARG(SalInstanceCalendar,ActivateHdl,::Calendar *,void)3225 IMPL_LINK_NOARG(SalInstanceCalendar, ActivateHdl, ::Calendar*, void)
3226 {
3227     if (notify_events_disabled())
3228         return;
3229     signal_activated();
3230 }
3231 
WeldTextFilter(Link<OUString &,bool> & rInsertTextHdl)3232 WeldTextFilter::WeldTextFilter(Link<OUString&, bool>& rInsertTextHdl)
3233     : TextFilter(OUString())
3234     , m_rInsertTextHdl(rInsertTextHdl)
3235 {
3236 }
3237 
filter(const OUString & rText)3238 OUString WeldTextFilter::filter(const OUString& rText)
3239 {
3240     if (!m_rInsertTextHdl.IsSet())
3241         return rText;
3242     OUString sText(rText);
3243     const bool bContinue = m_rInsertTextHdl.Call(sText);
3244     if (!bContinue)
3245         return OUString();
3246     return sText;
3247 }
3248 
SalInstanceEntry(Edit * pEntry,SalInstanceBuilder * pBuilder,bool bTakeOwnership)3249 SalInstanceEntry::SalInstanceEntry(Edit* pEntry, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3250     : SalInstanceWidget(pEntry, pBuilder, bTakeOwnership)
3251     , m_xEntry(pEntry)
3252     , m_aTextFilter(m_aInsertTextHdl)
3253 {
3254     m_xEntry->SetModifyHdl(LINK(this, SalInstanceEntry, ChangeHdl));
3255     m_xEntry->SetActivateHdl(LINK(this, SalInstanceEntry, ActivateHdl));
3256     m_xEntry->SetTextFilter(&m_aTextFilter);
3257 }
3258 
set_text(const OUString & rText)3259 void SalInstanceEntry::set_text(const OUString& rText)
3260 {
3261     disable_notify_events();
3262     m_xEntry->SetText(rText);
3263     enable_notify_events();
3264 }
3265 
get_text() const3266 OUString SalInstanceEntry::get_text() const { return m_xEntry->GetText(); }
3267 
set_width_chars(int nChars)3268 void SalInstanceEntry::set_width_chars(int nChars) { m_xEntry->SetWidthInChars(nChars); }
3269 
get_width_chars() const3270 int SalInstanceEntry::get_width_chars() const { return m_xEntry->GetWidthInChars(); }
3271 
set_max_length(int nChars)3272 void SalInstanceEntry::set_max_length(int nChars) { m_xEntry->SetMaxTextLen(nChars); }
3273 
select_region(int nStartPos,int nEndPos)3274 void SalInstanceEntry::select_region(int nStartPos, int nEndPos)
3275 {
3276     disable_notify_events();
3277     tools::Long nStart = nStartPos < 0 ? SELECTION_MAX : nStartPos;
3278     tools::Long nEnd = nEndPos < 0 ? SELECTION_MAX : nEndPos;
3279     m_xEntry->SetSelection(Selection(nStart, nEnd));
3280     enable_notify_events();
3281 }
3282 
get_selection_bounds(int & rStartPos,int & rEndPos)3283 bool SalInstanceEntry::get_selection_bounds(int& rStartPos, int& rEndPos)
3284 {
3285     const Selection& rSelection = m_xEntry->GetSelection();
3286     rStartPos = rSelection.Min();
3287     rEndPos = rSelection.Max();
3288     return rSelection.Len();
3289 }
3290 
replace_selection(const OUString & rText)3291 void SalInstanceEntry::replace_selection(const OUString& rText)
3292 {
3293     m_xEntry->ReplaceSelected(rText);
3294 }
3295 
set_position(int nCursorPos)3296 void SalInstanceEntry::set_position(int nCursorPos)
3297 {
3298     disable_notify_events();
3299     if (nCursorPos < 0)
3300         m_xEntry->SetCursorAtLast();
3301     else
3302         m_xEntry->SetSelection(Selection(nCursorPos, nCursorPos));
3303     enable_notify_events();
3304 }
3305 
get_position() const3306 int SalInstanceEntry::get_position() const { return m_xEntry->GetSelection().Max(); }
3307 
set_editable(bool bEditable)3308 void SalInstanceEntry::set_editable(bool bEditable) { m_xEntry->SetReadOnly(!bEditable); }
3309 
get_editable() const3310 bool SalInstanceEntry::get_editable() const { return !m_xEntry->IsReadOnly(); }
3311 
set_overwrite_mode(bool bOn)3312 void SalInstanceEntry::set_overwrite_mode(bool bOn) { m_xEntry->SetInsertMode(!bOn); }
3313 
get_overwrite_mode() const3314 bool SalInstanceEntry::get_overwrite_mode() const { return !m_xEntry->IsInsertMode(); }
3315 
set_message_type(weld::EntryMessageType eType)3316 void SalInstanceEntry::set_message_type(weld::EntryMessageType eType)
3317 {
3318     switch (eType)
3319     {
3320         case weld::EntryMessageType::Normal:
3321             m_xEntry->SetForceControlBackground(false);
3322             m_xEntry->SetControlForeground();
3323             m_xEntry->SetControlBackground();
3324             break;
3325         case weld::EntryMessageType::Warning:
3326             // tdf#114603: enable setting the background to a different color;
3327             // relevant for GTK; see also #i75179#
3328             m_xEntry->SetForceControlBackground(true);
3329             m_xEntry->SetControlForeground(COL_BLACK);
3330             m_xEntry->SetControlBackground(COL_YELLOW);
3331             break;
3332         case weld::EntryMessageType::Error:
3333             // tdf#114603: enable setting the background to a different color;
3334             // relevant for GTK; see also #i75179#
3335             m_xEntry->SetForceControlBackground(true);
3336             m_xEntry->SetControlForeground(COL_WHITE);
3337             m_xEntry->SetControlBackground(0xff6563);
3338             break;
3339     }
3340 }
3341 
set_font(const vcl::Font & rFont)3342 void SalInstanceEntry::set_font(const vcl::Font& rFont)
3343 {
3344     m_xEntry->SetPointFont(*m_xEntry->GetOutDev(), rFont);
3345     m_xEntry->SetControlFont(rFont);
3346     m_xEntry->Invalidate();
3347 }
3348 
set_font_color(const Color & rColor)3349 void SalInstanceEntry::set_font_color(const Color& rColor)
3350 {
3351     if (rColor == COL_AUTO)
3352         m_xEntry->SetControlForeground();
3353     else
3354         m_xEntry->SetControlForeground(rColor);
3355 }
3356 
connect_cursor_position(const Link<Entry &,void> & rLink)3357 void SalInstanceEntry::connect_cursor_position(const Link<Entry&, void>& rLink)
3358 {
3359     assert(!m_aCursorPositionHdl.IsSet());
3360     m_xEntry->AddEventListener(LINK(this, SalInstanceEntry, CursorListener));
3361     weld::Entry::connect_cursor_position(rLink);
3362 }
3363 
set_placeholder_text(const OUString & rText)3364 void SalInstanceEntry::set_placeholder_text(const OUString& rText)
3365 {
3366     m_xEntry->SetPlaceholderText(rText);
3367 }
3368 
getEntry()3369 Edit& SalInstanceEntry::getEntry() { return *m_xEntry; }
3370 
fire_signal_changed()3371 void SalInstanceEntry::fire_signal_changed() { signal_changed(); }
3372 
cut_clipboard()3373 void SalInstanceEntry::cut_clipboard()
3374 {
3375     m_xEntry->Cut();
3376     m_xEntry->Modify();
3377 }
3378 
copy_clipboard()3379 void SalInstanceEntry::copy_clipboard() { m_xEntry->Copy(); }
3380 
paste_clipboard()3381 void SalInstanceEntry::paste_clipboard()
3382 {
3383     m_xEntry->Paste();
3384     m_xEntry->Modify();
3385 }
3386 
3387 namespace
3388 {
set_alignment(Edit & rEntry,TxtAlign eXAlign)3389 void set_alignment(Edit& rEntry, TxtAlign eXAlign)
3390 {
3391     WinBits nAlign(0);
3392     switch (eXAlign)
3393     {
3394         case TxtAlign::Left:
3395             nAlign = WB_LEFT;
3396             break;
3397         case TxtAlign::Center:
3398             nAlign = WB_CENTER;
3399             break;
3400         case TxtAlign::Right:
3401             nAlign = WB_RIGHT;
3402             break;
3403     }
3404     WinBits nBits = rEntry.GetStyle();
3405     nBits &= ~(WB_LEFT | WB_CENTER | WB_RIGHT);
3406     rEntry.SetStyle(nBits | nAlign);
3407 }
3408 }
3409 
set_alignment(TxtAlign eXAlign)3410 void SalInstanceEntry::set_alignment(TxtAlign eXAlign) { ::set_alignment(*m_xEntry, eXAlign); }
3411 
~SalInstanceEntry()3412 SalInstanceEntry::~SalInstanceEntry()
3413 {
3414     if (m_aCursorPositionHdl.IsSet())
3415         m_xEntry->RemoveEventListener(LINK(this, SalInstanceEntry, CursorListener));
3416     m_xEntry->SetTextFilter(nullptr);
3417     m_xEntry->SetActivateHdl(Link<Edit&, bool>());
3418     m_xEntry->SetModifyHdl(Link<Edit&, void>());
3419 }
3420 
IMPL_LINK_NOARG(SalInstanceEntry,ChangeHdl,Edit &,void)3421 IMPL_LINK_NOARG(SalInstanceEntry, ChangeHdl, Edit&, void) { signal_changed(); }
3422 
IMPL_LINK(SalInstanceEntry,CursorListener,VclWindowEvent &,rEvent,void)3423 IMPL_LINK(SalInstanceEntry, CursorListener, VclWindowEvent&, rEvent, void)
3424 {
3425     if (notify_events_disabled())
3426         return;
3427     if (rEvent.GetId() == VclEventId::EditSelectionChanged
3428         || rEvent.GetId() == VclEventId::EditCaretChanged)
3429         signal_cursor_position();
3430 }
3431 
IMPL_LINK_NOARG(SalInstanceEntry,ActivateHdl,Edit &,bool)3432 IMPL_LINK_NOARG(SalInstanceEntry, ActivateHdl, Edit&, bool) { return m_aActivateHdl.Call(*this); }
3433 
3434 class SalInstanceTreeView;
3435 
3436 static SalInstanceTreeView* g_DragSource;
3437 
3438 namespace
3439 {
3440 // tdf#131581 if the TreeView is hidden then there are possibly additional
3441 // optimizations available
3442 class UpdateGuardIfHidden
3443 {
3444 private:
3445     SvTabListBox& m_rTreeView;
3446     bool m_bOrigUpdate;
3447     bool m_bOrigEnableInvalidate;
3448 
3449 public:
UpdateGuardIfHidden(SvTabListBox & rTreeView)3450     UpdateGuardIfHidden(SvTabListBox& rTreeView)
3451         : m_rTreeView(rTreeView)
3452         // tdf#136962 only do SetUpdateMode(false) optimization if the widget is currently hidden
3453         , m_bOrigUpdate(!m_rTreeView.IsVisible() && m_rTreeView.IsUpdateMode())
3454         // tdf#137432 only do EnableInvalidate(false) optimization if the widget is currently hidden
3455         , m_bOrigEnableInvalidate(!m_rTreeView.IsVisible()
3456                                   && m_rTreeView.GetModel()->IsEnableInvalidate())
3457     {
3458         if (m_bOrigUpdate)
3459             m_rTreeView.SetUpdateMode(false);
3460         if (m_bOrigEnableInvalidate)
3461             m_rTreeView.GetModel()->EnableInvalidate(false);
3462     }
3463 
~UpdateGuardIfHidden()3464     ~UpdateGuardIfHidden()
3465     {
3466         if (m_bOrigEnableInvalidate)
3467             m_rTreeView.GetModel()->EnableInvalidate(true);
3468         if (m_bOrigUpdate)
3469             m_rTreeView.SetUpdateMode(true);
3470     }
3471 };
3472 }
3473 
3474 // Each row has a cell for the expander image, (and an optional cell for a
3475 // checkbutton if enable_toggle_buttons has been called) which precede
3476 // index 0
to_internal_model(int col) const3477 int SalInstanceTreeView::to_internal_model(int col) const
3478 {
3479     if (m_xTreeView->nTreeFlags & SvTreeFlags::CHKBTN)
3480         ++col; // skip checkbutton column
3481     ++col; //skip expander column
3482     return col;
3483 }
3484 
to_external_model(int col) const3485 int SalInstanceTreeView::to_external_model(int col) const
3486 {
3487     if (m_xTreeView->nTreeFlags & SvTreeFlags::CHKBTN)
3488         --col; // skip checkbutton column
3489     --col; //skip expander column
3490     return col;
3491 }
3492 
IsDummyEntry(SvTreeListEntry * pEntry) const3493 bool SalInstanceTreeView::IsDummyEntry(SvTreeListEntry* pEntry) const
3494 {
3495     return m_xTreeView->GetEntryText(pEntry).trim() == "<dummy>";
3496 }
3497 
GetPlaceHolderChild(SvTreeListEntry * pEntry) const3498 SvTreeListEntry* SalInstanceTreeView::GetPlaceHolderChild(SvTreeListEntry* pEntry) const
3499 {
3500     if (pEntry->HasChildren())
3501     {
3502         auto pChild = m_xTreeView->FirstChild(pEntry);
3503         assert(pChild);
3504         if (IsDummyEntry(pChild))
3505             return pChild;
3506     }
3507     return nullptr;
3508 }
3509 
set_font_color(SvTreeListEntry * pEntry,const Color & rColor)3510 void SalInstanceTreeView::set_font_color(SvTreeListEntry* pEntry, const Color& rColor)
3511 {
3512     if (rColor == COL_AUTO)
3513         pEntry->SetTextColor(std::optional<Color>());
3514     else
3515         pEntry->SetTextColor(rColor);
3516 }
3517 
AddStringItem(SvTreeListEntry * pEntry,const OUString & rStr,int nCol)3518 void SalInstanceTreeView::AddStringItem(SvTreeListEntry* pEntry, const OUString& rStr, int nCol)
3519 {
3520     auto xCell = std::make_unique<SvLBoxString>(rStr);
3521     if (m_aCustomRenders.count(nCol))
3522         xCell->SetCustomRender();
3523     pEntry->AddItem(std::move(xCell));
3524 }
3525 
do_insert(const weld::TreeIter * pParent,int pos,const OUString * pStr,const OUString * pId,const OUString * pIconName,const VirtualDevice * pImageSurface,bool bChildrenOnDemand,weld::TreeIter * pRet,bool bIsSeparator)3526 void SalInstanceTreeView::do_insert(const weld::TreeIter* pParent, int pos, const OUString* pStr,
3527                                     const OUString* pId, const OUString* pIconName,
3528                                     const VirtualDevice* pImageSurface, bool bChildrenOnDemand,
3529                                     weld::TreeIter* pRet, bool bIsSeparator)
3530 {
3531     disable_notify_events();
3532     const SalInstanceTreeIter* pVclIter = static_cast<const SalInstanceTreeIter*>(pParent);
3533     SvTreeListEntry* iter = pVclIter ? pVclIter->iter : nullptr;
3534     auto nInsertPos = pos == -1 ? TREELIST_APPEND : pos;
3535     void* pUserData;
3536     if (pId)
3537     {
3538         m_aUserData.emplace_back(std::make_unique<OUString>(*pId));
3539         pUserData = m_aUserData.back().get();
3540     }
3541     else
3542         pUserData = nullptr;
3543 
3544     SvTreeListEntry* pEntry = new SvTreeListEntry;
3545     if (bIsSeparator)
3546         pEntry->SetFlags(pEntry->GetFlags() | SvTLEntryFlags::IS_SEPARATOR);
3547 
3548     if (m_xTreeView->nTreeFlags & SvTreeFlags::CHKBTN)
3549         AddStringItem(pEntry, "", -1);
3550 
3551     if (pIconName || pImageSurface)
3552     {
3553         Image aImage(pIconName ? createImage(*pIconName) : createImage(*pImageSurface));
3554         pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(aImage, aImage, false));
3555     }
3556     else
3557     {
3558         Image aDummy;
3559         pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(aDummy, aDummy, false));
3560     }
3561     if (pStr)
3562         AddStringItem(pEntry, *pStr, 0);
3563     pEntry->SetUserData(pUserData);
3564     m_xTreeView->Insert(pEntry, iter, nInsertPos);
3565 
3566     if (pRet)
3567     {
3568         SalInstanceTreeIter* pVclRetIter = static_cast<SalInstanceTreeIter*>(pRet);
3569         pVclRetIter->iter = pEntry;
3570     }
3571 
3572     if (bChildrenOnDemand)
3573     {
3574         SvTreeListEntry* pPlaceHolder
3575             = m_xTreeView->InsertEntry("<dummy>", pEntry, false, 0, nullptr);
3576         SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pPlaceHolder);
3577         pViewData->SetSelectable(false);
3578     }
3579 
3580     if (bIsSeparator)
3581     {
3582         SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry);
3583         pViewData->SetSelectable(false);
3584     }
3585 
3586     enable_notify_events();
3587 }
3588 
update_checkbutton_column_width(SvTreeListEntry * pEntry)3589 void SalInstanceTreeView::update_checkbutton_column_width(SvTreeListEntry* pEntry)
3590 {
3591     SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry);
3592     m_xTreeView->InitViewData(pViewData, pEntry);
3593     m_xTreeView->CheckBoxInserted(pEntry);
3594 }
3595 
InvalidateModelEntry(SvTreeListEntry * pEntry)3596 void SalInstanceTreeView::InvalidateModelEntry(SvTreeListEntry* pEntry)
3597 {
3598     if (!m_xTreeView->GetModel()->IsEnableInvalidate())
3599         return;
3600     m_xTreeView->ModelHasEntryInvalidated(pEntry);
3601 }
3602 
do_set_toggle(SvTreeListEntry * pEntry,TriState eState,int col)3603 void SalInstanceTreeView::do_set_toggle(SvTreeListEntry* pEntry, TriState eState, int col)
3604 {
3605     assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
3606     // if its the placeholder to allow a blank column, replace it now
3607     if (pEntry->GetItem(col).GetType() != SvLBoxItemType::Button)
3608     {
3609         SvLBoxButtonData* pData = m_bTogglesAsRadio ? &m_aRadioButtonData : &m_aCheckButtonData;
3610         pEntry->ReplaceItem(std::make_unique<SvLBoxButton>(pData), 0);
3611         update_checkbutton_column_width(pEntry);
3612     }
3613     SvLBoxItem& rItem = pEntry->GetItem(col);
3614     assert(dynamic_cast<SvLBoxButton*>(&rItem));
3615     switch (eState)
3616     {
3617         case TRISTATE_TRUE:
3618             static_cast<SvLBoxButton&>(rItem).SetStateChecked();
3619             break;
3620         case TRISTATE_FALSE:
3621             static_cast<SvLBoxButton&>(rItem).SetStateUnchecked();
3622             break;
3623         case TRISTATE_INDET:
3624             static_cast<SvLBoxButton&>(rItem).SetStateTristate();
3625             break;
3626     }
3627 
3628     InvalidateModelEntry(pEntry);
3629 }
3630 
do_get_toggle(SvTreeListEntry * pEntry,int col)3631 TriState SalInstanceTreeView::do_get_toggle(SvTreeListEntry* pEntry, int col)
3632 {
3633     if (static_cast<size_t>(col) == pEntry->ItemCount())
3634         return TRISTATE_FALSE;
3635 
3636     assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
3637     SvLBoxItem& rItem = pEntry->GetItem(col);
3638     assert(dynamic_cast<SvLBoxButton*>(&rItem));
3639     SvLBoxButton& rToggle = static_cast<SvLBoxButton&>(rItem);
3640     if (rToggle.IsStateTristate())
3641         return TRISTATE_INDET;
3642     else if (rToggle.IsStateChecked())
3643         return TRISTATE_TRUE;
3644     return TRISTATE_FALSE;
3645 }
3646 
get_toggle(SvTreeListEntry * pEntry,int col) const3647 TriState SalInstanceTreeView::get_toggle(SvTreeListEntry* pEntry, int col) const
3648 {
3649     if (col == -1)
3650     {
3651         assert(m_xTreeView->nTreeFlags & SvTreeFlags::CHKBTN);
3652         return do_get_toggle(pEntry, 0);
3653     }
3654     col = to_internal_model(col);
3655     return do_get_toggle(pEntry, col);
3656 }
3657 
set_toggle(SvTreeListEntry * pEntry,TriState eState,int col)3658 void SalInstanceTreeView::set_toggle(SvTreeListEntry* pEntry, TriState eState, int col)
3659 {
3660     if (col == -1)
3661     {
3662         assert(m_xTreeView->nTreeFlags & SvTreeFlags::CHKBTN);
3663         do_set_toggle(pEntry, eState, 0);
3664         return;
3665     }
3666 
3667     col = to_internal_model(col);
3668 
3669     // blank out missing entries
3670     for (int i = pEntry->ItemCount(); i < col; ++i)
3671         AddStringItem(pEntry, "", i - 1);
3672 
3673     if (static_cast<size_t>(col) == pEntry->ItemCount())
3674     {
3675         SvLBoxButtonData* pData = m_bTogglesAsRadio ? &m_aRadioButtonData : &m_aCheckButtonData;
3676         pEntry->AddItem(std::make_unique<SvLBoxButton>(pData));
3677         update_checkbutton_column_width(pEntry);
3678     }
3679 
3680     do_set_toggle(pEntry, eState, col);
3681 }
3682 
get_text_emphasis(SvTreeListEntry * pEntry,int col) const3683 bool SalInstanceTreeView::get_text_emphasis(SvTreeListEntry* pEntry, int col) const
3684 {
3685     col = to_internal_model(col);
3686 
3687     assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
3688     SvLBoxItem& rItem = pEntry->GetItem(col);
3689     assert(dynamic_cast<SvLBoxString*>(&rItem));
3690     return static_cast<SvLBoxString&>(rItem).IsEmphasized();
3691 }
3692 
set_header_item_width(const std::vector<int> & rWidths)3693 void SalInstanceTreeView::set_header_item_width(const std::vector<int>& rWidths)
3694 {
3695     LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
3696     if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
3697     {
3698         for (size_t i = 0; i < rWidths.size(); ++i)
3699             pHeaderBar->SetItemSize(pHeaderBar->GetItemId(i), rWidths[i]);
3700     }
3701 }
3702 
SalInstanceTreeView(SvTabListBox * pTreeView,SalInstanceBuilder * pBuilder,bool bTakeOwnership)3703 SalInstanceTreeView::SalInstanceTreeView(SvTabListBox* pTreeView, SalInstanceBuilder* pBuilder,
3704                                          bool bTakeOwnership)
3705     : SalInstanceWidget(pTreeView, pBuilder, bTakeOwnership)
3706     , m_xTreeView(pTreeView)
3707     , m_aCheckButtonData(pTreeView, false)
3708     , m_aRadioButtonData(pTreeView, true)
3709     , m_bTogglesAsRadio(false)
3710     , m_nSortColumn(-1)
3711 {
3712     m_xTreeView->SetNodeDefaultImages();
3713     m_xTreeView->SetForceMakeVisible(true);
3714     m_xTreeView->SetSelectHdl(LINK(this, SalInstanceTreeView, SelectHdl));
3715     m_xTreeView->SetDeselectHdl(LINK(this, SalInstanceTreeView, DeSelectHdl));
3716     m_xTreeView->SetDoubleClickHdl(LINK(this, SalInstanceTreeView, DoubleClickHdl));
3717     m_xTreeView->SetExpandingHdl(LINK(this, SalInstanceTreeView, ExpandingHdl));
3718     m_xTreeView->SetPopupMenuHdl(LINK(this, SalInstanceTreeView, PopupMenuHdl));
3719     m_xTreeView->SetCustomRenderHdl(LINK(this, SalInstanceTreeView, CustomRenderHdl));
3720     m_xTreeView->SetCustomMeasureHdl(LINK(this, SalInstanceTreeView, CustomMeasureHdl));
3721     const tools::Long aTabPositions[] = { 0 };
3722     m_xTreeView->SetTabs(SAL_N_ELEMENTS(aTabPositions), aTabPositions);
3723     LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
3724 
3725     if (pHeaderBox)
3726     {
3727         if (HeaderBar* pHeaderBar = pHeaderBox->GetHeaderBar())
3728         {
3729             //make the last entry fill available space
3730             pHeaderBar->SetItemSize(pHeaderBar->GetItemId(pHeaderBar->GetItemCount() - 1),
3731                                     HEADERBAR_FULLSIZE);
3732             pHeaderBar->SetEndDragHdl(LINK(this, SalInstanceTreeView, EndDragHdl));
3733             pHeaderBar->SetSelectHdl(LINK(this, SalInstanceTreeView, HeaderBarClickedHdl));
3734         }
3735         pHeaderBox->SetEditingEntryHdl(LINK(this, SalInstanceTreeView, EditingEntryHdl));
3736         pHeaderBox->SetEditedEntryHdl(LINK(this, SalInstanceTreeView, EditedEntryHdl));
3737     }
3738     else
3739     {
3740         static_cast<LclTabListBox&>(*m_xTreeView)
3741             .SetModelChangedHdl(LINK(this, SalInstanceTreeView, ModelChangedHdl));
3742         static_cast<LclTabListBox&>(*m_xTreeView)
3743             .SetStartDragHdl(LINK(this, SalInstanceTreeView, StartDragHdl));
3744         static_cast<LclTabListBox&>(*m_xTreeView)
3745             .SetEndDragHdl(LINK(this, SalInstanceTreeView, FinishDragHdl));
3746         static_cast<LclTabListBox&>(*m_xTreeView)
3747             .SetEditingEntryHdl(LINK(this, SalInstanceTreeView, EditingEntryHdl));
3748         static_cast<LclTabListBox&>(*m_xTreeView)
3749             .SetEditedEntryHdl(LINK(this, SalInstanceTreeView, EditedEntryHdl));
3750     }
3751     m_aCheckButtonData.SetLink(LINK(this, SalInstanceTreeView, ToggleHdl));
3752     m_aRadioButtonData.SetLink(LINK(this, SalInstanceTreeView, ToggleHdl));
3753 }
3754 
connect_query_tooltip(const Link<const weld::TreeIter &,OUString> & rLink)3755 void SalInstanceTreeView::connect_query_tooltip(const Link<const weld::TreeIter&, OUString>& rLink)
3756 {
3757     weld::TreeView::connect_query_tooltip(rLink);
3758     m_xTreeView->SetTooltipHdl(LINK(this, SalInstanceTreeView, TooltipHdl));
3759 }
3760 
columns_autosize()3761 void SalInstanceTreeView::columns_autosize()
3762 {
3763     std::vector<tools::Long> aWidths;
3764     m_xTreeView->getPreferredDimensions(aWidths);
3765     if (aWidths.size() > 2)
3766     {
3767         std::vector<int> aColWidths;
3768         for (size_t i = 1; i < aWidths.size() - 1; ++i)
3769             aColWidths.push_back(aWidths[i] - aWidths[i - 1]);
3770         set_column_fixed_widths(aColWidths);
3771     }
3772 }
3773 
freeze()3774 void SalInstanceTreeView::freeze()
3775 {
3776     bool bIsFirstFreeze = IsFirstFreeze();
3777     SalInstanceWidget::freeze();
3778     if (bIsFirstFreeze)
3779     {
3780         m_xTreeView->SetUpdateMode(false);
3781         m_xTreeView->GetModel()->EnableInvalidate(false);
3782     }
3783 }
3784 
thaw()3785 void SalInstanceTreeView::thaw()
3786 {
3787     bool bIsLastThaw = IsLastThaw();
3788     if (bIsLastThaw)
3789     {
3790         m_xTreeView->GetModel()->EnableInvalidate(true);
3791         m_xTreeView->SetUpdateMode(true);
3792     }
3793     SalInstanceWidget::thaw();
3794 }
3795 
set_column_fixed_widths(const std::vector<int> & rWidths)3796 void SalInstanceTreeView::set_column_fixed_widths(const std::vector<int>& rWidths)
3797 {
3798     std::vector<tools::Long> aTabPositions;
3799     aTabPositions.push_back(0);
3800     for (size_t i = 0; i < rWidths.size(); ++i)
3801         aTabPositions.push_back(aTabPositions[i] + rWidths[i]);
3802     m_xTreeView->SetTabs(aTabPositions.size(), aTabPositions.data(), MapUnit::MapPixel);
3803     set_header_item_width(rWidths);
3804     // call Resize to recalculate based on the new tabs
3805     m_xTreeView->Resize();
3806 }
3807 
set_column_editables(const std::vector<bool> & rEditables)3808 void SalInstanceTreeView::set_column_editables(const std::vector<bool>& rEditables)
3809 {
3810     size_t nTabCount = rEditables.size();
3811     for (size_t i = 0; i < nTabCount; ++i)
3812         m_xTreeView->SetTabEditable(i, rEditables[i]);
3813 }
3814 
set_centered_column(int nCol)3815 void SalInstanceTreeView::set_centered_column(int nCol)
3816 {
3817     m_xTreeView->SetTabJustify(nCol, SvTabJustify::AdjustCenter);
3818 }
3819 
get_column_width(int nColumn) const3820 int SalInstanceTreeView::get_column_width(int nColumn) const
3821 {
3822     LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
3823     if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
3824         return pHeaderBar->GetItemSize(pHeaderBar->GetItemId(nColumn));
3825     // GetTab(0) gives the position of the bitmap which is automatically inserted by the TabListBox.
3826     // So the first text column's width is Tab(2)-Tab(1).
3827     auto nWidthPixel
3828         = m_xTreeView->GetLogicTab(nColumn + 2) - m_xTreeView->GetLogicTab(nColumn + 1);
3829     nWidthPixel -= SV_TAB_BORDER;
3830     return nWidthPixel;
3831 }
3832 
get_column_title(int nColumn) const3833 OUString SalInstanceTreeView::get_column_title(int nColumn) const
3834 {
3835     LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
3836     if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
3837     {
3838         return pHeaderBar->GetItemText(pHeaderBar->GetItemId(nColumn));
3839     }
3840     return OUString();
3841 }
3842 
set_column_title(int nColumn,const OUString & rTitle)3843 void SalInstanceTreeView::set_column_title(int nColumn, const OUString& rTitle)
3844 {
3845     LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
3846     if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
3847     {
3848         return pHeaderBar->SetItemText(pHeaderBar->GetItemId(nColumn), rTitle);
3849     }
3850 }
3851 
set_column_custom_renderer(int nColumn,bool bEnable)3852 void SalInstanceTreeView::set_column_custom_renderer(int nColumn, bool bEnable)
3853 {
3854     assert(n_children() == 0 && "tree must be empty");
3855     if (bEnable)
3856         m_aCustomRenders.insert(nColumn);
3857     else
3858         m_aCustomRenders.erase(nColumn);
3859 }
3860 
queue_draw()3861 void SalInstanceTreeView::queue_draw()
3862 {
3863     // invalidate the entries
3864     SvTreeList* pModel = m_xTreeView->GetModel();
3865     for (SvTreeListEntry* pEntry = m_xTreeView->First(); pEntry; pEntry = m_xTreeView->Next(pEntry))
3866         pModel->InvalidateEntry(pEntry);
3867 }
3868 
show()3869 void SalInstanceTreeView::show()
3870 {
3871     if (LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get()))
3872         pHeaderBox->GetParent()->Show();
3873     SalInstanceWidget::show();
3874 }
3875 
hide()3876 void SalInstanceTreeView::hide()
3877 {
3878     if (LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get()))
3879         pHeaderBox->GetParent()->Hide();
3880     SalInstanceWidget::hide();
3881 }
3882 
insert(const weld::TreeIter * pParent,int pos,const OUString * pStr,const OUString * pId,const OUString * pIconName,VirtualDevice * pImageSurface,bool bChildrenOnDemand,weld::TreeIter * pRet)3883 void SalInstanceTreeView::insert(const weld::TreeIter* pParent, int pos, const OUString* pStr,
3884                                  const OUString* pId, const OUString* pIconName,
3885                                  VirtualDevice* pImageSurface, bool bChildrenOnDemand,
3886                                  weld::TreeIter* pRet)
3887 {
3888     do_insert(pParent, pos, pStr, pId, pIconName, pImageSurface, bChildrenOnDemand, pRet, false);
3889 }
3890 
insert_separator(int pos,const OUString &)3891 void SalInstanceTreeView::insert_separator(int pos, const OUString& /*rId*/)
3892 {
3893     OUString sSep(VclResId(STR_SEPARATOR));
3894     do_insert(nullptr, pos, &sSep, nullptr, nullptr, nullptr, false, nullptr, true);
3895 }
3896 
bulk_insert_for_each(int nSourceCount,const std::function<void (weld::TreeIter &,int nSourceIndex)> & func,const weld::TreeIter * pParent,const std::vector<int> * pFixedWidths)3897 void SalInstanceTreeView::bulk_insert_for_each(
3898     int nSourceCount, const std::function<void(weld::TreeIter&, int nSourceIndex)>& func,
3899     const weld::TreeIter* pParent, const std::vector<int>* pFixedWidths)
3900 {
3901     const SalInstanceTreeIter* pVclIter = static_cast<const SalInstanceTreeIter*>(pParent);
3902     SvTreeListEntry* pVclParent = pVclIter ? pVclIter->iter : nullptr;
3903 
3904     freeze();
3905     if (!pVclParent)
3906         clear();
3907     else
3908     {
3909         while (SvTreeListEntry* pChild = m_xTreeView->FirstChild(pVclParent))
3910             m_xTreeView->RemoveEntry(pChild);
3911     }
3912     SalInstanceTreeIter aVclIter(static_cast<SvTreeListEntry*>(nullptr));
3913 
3914     m_xTreeView->nTreeFlags |= SvTreeFlags::MANINS;
3915 
3916     if (pFixedWidths)
3917         set_header_item_width(*pFixedWidths);
3918 
3919     bool bHasAutoCheckButton(m_xTreeView->nTreeFlags & SvTreeFlags::CHKBTN);
3920     size_t nExtraCols = bHasAutoCheckButton ? 2 : 1;
3921 
3922     Image aDummy;
3923     for (int i = 0; i < nSourceCount; ++i)
3924     {
3925         aVclIter.iter = new SvTreeListEntry;
3926         if (bHasAutoCheckButton)
3927             AddStringItem(aVclIter.iter, "", -1);
3928         aVclIter.iter->AddItem(std::make_unique<SvLBoxContextBmp>(aDummy, aDummy, false));
3929         m_xTreeView->Insert(aVclIter.iter, pVclParent, TREELIST_APPEND);
3930         func(aVclIter, i);
3931 
3932         if (!pFixedWidths)
3933             continue;
3934 
3935         size_t nFixedWidths = std::min(pFixedWidths->size(), aVclIter.iter->ItemCount());
3936         for (size_t j = 0; j < nFixedWidths; ++j)
3937         {
3938             SvLBoxItem& rItem = aVclIter.iter->GetItem(j + nExtraCols);
3939             SvViewDataItem* pViewDataItem = m_xTreeView->GetViewDataItem(aVclIter.iter, &rItem);
3940             pViewDataItem->mnWidth = (*pFixedWidths)[j];
3941         }
3942     }
3943 
3944     m_xTreeView->nTreeFlags &= ~SvTreeFlags::MANINS;
3945 
3946     thaw();
3947 }
3948 
set_font_color(int pos,const Color & rColor)3949 void SalInstanceTreeView::set_font_color(int pos, const Color& rColor)
3950 {
3951     SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
3952     set_font_color(pEntry, rColor);
3953 }
3954 
set_font_color(const weld::TreeIter & rIter,const Color & rColor)3955 void SalInstanceTreeView::set_font_color(const weld::TreeIter& rIter, const Color& rColor)
3956 {
3957     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
3958     set_font_color(rVclIter.iter, rColor);
3959 }
3960 
remove(int pos)3961 void SalInstanceTreeView::remove(int pos)
3962 {
3963     disable_notify_events();
3964     SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
3965     m_xTreeView->RemoveEntry(pEntry);
3966     enable_notify_events();
3967 }
3968 
find_text(const OUString & rText) const3969 int SalInstanceTreeView::find_text(const OUString& rText) const
3970 {
3971     for (SvTreeListEntry* pEntry = m_xTreeView->First(); pEntry; pEntry = m_xTreeView->Next(pEntry))
3972     {
3973         if (SvTabListBox::GetEntryText(pEntry, 0) == rText)
3974             return SvTreeList::GetRelPos(pEntry);
3975     }
3976     return -1;
3977 }
3978 
find_id(const OUString & rId) const3979 int SalInstanceTreeView::find_id(const OUString& rId) const
3980 {
3981     for (SvTreeListEntry* pEntry = m_xTreeView->First(); pEntry; pEntry = m_xTreeView->Next(pEntry))
3982     {
3983         const OUString* pId = static_cast<const OUString*>(pEntry->GetUserData());
3984         if (!pId)
3985             continue;
3986         if (rId == *pId)
3987             return SvTreeList::GetRelPos(pEntry);
3988     }
3989     return -1;
3990 }
3991 
swap(int pos1,int pos2)3992 void SalInstanceTreeView::swap(int pos1, int pos2)
3993 {
3994     int min = std::min(pos1, pos2);
3995     int max = std::max(pos1, pos2);
3996     SvTreeList* pModel = m_xTreeView->GetModel();
3997     SvTreeListEntry* pEntry1 = pModel->GetEntry(nullptr, min);
3998     SvTreeListEntry* pEntry2 = pModel->GetEntry(nullptr, max);
3999     pModel->Move(pEntry1, pEntry2);
4000 }
4001 
clear()4002 void SalInstanceTreeView::clear()
4003 {
4004     disable_notify_events();
4005     m_xTreeView->Clear();
4006     m_aUserData.clear();
4007     enable_notify_events();
4008 }
4009 
n_children() const4010 int SalInstanceTreeView::n_children() const
4011 {
4012     return m_xTreeView->GetModel()->GetChildList(nullptr).size();
4013 }
4014 
iter_n_children(const weld::TreeIter & rIter) const4015 int SalInstanceTreeView::iter_n_children(const weld::TreeIter& rIter) const
4016 {
4017     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4018     return m_xTreeView->GetModel()->GetChildList(rVclIter.iter).size();
4019 }
4020 
select(int pos)4021 void SalInstanceTreeView::select(int pos)
4022 {
4023     assert(m_xTreeView->IsUpdateMode()
4024            && "don't select when frozen, select after thaw. Note selection doesn't survive a "
4025               "freeze");
4026     disable_notify_events();
4027     if (pos == -1 || (pos == 0 && n_children() == 0))
4028         m_xTreeView->SelectAll(false);
4029     else
4030     {
4031         SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4032         assert(pEntry && "bad pos?");
4033         m_xTreeView->Select(pEntry, true);
4034         m_xTreeView->MakeVisible(pEntry);
4035     }
4036     enable_notify_events();
4037 }
4038 
get_cursor_index() const4039 int SalInstanceTreeView::get_cursor_index() const
4040 {
4041     SvTreeListEntry* pEntry = m_xTreeView->GetCurEntry();
4042     if (!pEntry)
4043         return -1;
4044     return SvTreeList::GetRelPos(pEntry);
4045 }
4046 
set_cursor(int pos)4047 void SalInstanceTreeView::set_cursor(int pos)
4048 {
4049     disable_notify_events();
4050     if (pos == -1)
4051         m_xTreeView->SetCurEntry(nullptr);
4052     else
4053     {
4054         SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4055         m_xTreeView->SetCurEntry(pEntry);
4056     }
4057     enable_notify_events();
4058 }
4059 
scroll_to_row(int pos)4060 void SalInstanceTreeView::scroll_to_row(int pos)
4061 {
4062     assert(m_xTreeView->IsUpdateMode()
4063            && "don't select when frozen, select after thaw. Note selection doesn't survive a "
4064               "freeze");
4065     disable_notify_events();
4066     SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4067     m_xTreeView->MakeVisible(pEntry);
4068     enable_notify_events();
4069 }
4070 
is_selected(int pos) const4071 bool SalInstanceTreeView::is_selected(int pos) const
4072 {
4073     SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4074     return m_xTreeView->IsSelected(pEntry);
4075 }
4076 
unselect(int pos)4077 void SalInstanceTreeView::unselect(int pos)
4078 {
4079     assert(m_xTreeView->IsUpdateMode()
4080            && "don't select when frozen, select after thaw. Note selection doesn't survive a "
4081               "freeze");
4082     disable_notify_events();
4083     if (pos == -1)
4084         m_xTreeView->SelectAll(true);
4085     else
4086     {
4087         SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4088         m_xTreeView->Select(pEntry, false);
4089     }
4090     enable_notify_events();
4091 }
4092 
get_selected_rows() const4093 std::vector<int> SalInstanceTreeView::get_selected_rows() const
4094 {
4095     std::vector<int> aRows;
4096 
4097     aRows.reserve(m_xTreeView->GetSelectionCount());
4098     for (SvTreeListEntry* pEntry = m_xTreeView->FirstSelected(); pEntry;
4099          pEntry = m_xTreeView->NextSelected(pEntry))
4100         aRows.push_back(SvTreeList::GetRelPos(pEntry));
4101 
4102     return aRows;
4103 }
4104 
get_text(SvTreeListEntry * pEntry,int col) const4105 OUString SalInstanceTreeView::get_text(SvTreeListEntry* pEntry, int col) const
4106 {
4107     if (col == -1)
4108         return SvTabListBox::GetEntryText(pEntry, 0);
4109 
4110     col = to_internal_model(col);
4111 
4112     if (static_cast<size_t>(col) == pEntry->ItemCount())
4113         return OUString();
4114 
4115     assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
4116     SvLBoxItem& rItem = pEntry->GetItem(col);
4117     assert(dynamic_cast<SvLBoxString*>(&rItem));
4118     return static_cast<SvLBoxString&>(rItem).GetText();
4119 }
4120 
get_text(int pos,int col) const4121 OUString SalInstanceTreeView::get_text(int pos, int col) const
4122 {
4123     SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4124     return get_text(pEntry, col);
4125 }
4126 
set_text(SvTreeListEntry * pEntry,const OUString & rText,int col)4127 void SalInstanceTreeView::set_text(SvTreeListEntry* pEntry, const OUString& rText, int col)
4128 {
4129     if (col == -1)
4130     {
4131         m_xTreeView->SetEntryText(pEntry, rText);
4132         return;
4133     }
4134 
4135     col = to_internal_model(col);
4136 
4137     // blank out missing entries
4138     for (int i = pEntry->ItemCount(); i < col; ++i)
4139         AddStringItem(pEntry, "", i - 1);
4140 
4141     if (static_cast<size_t>(col) == pEntry->ItemCount())
4142     {
4143         AddStringItem(pEntry, rText, col - 1);
4144         SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry);
4145         m_xTreeView->InitViewData(pViewData, pEntry);
4146     }
4147     else
4148     {
4149         assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
4150         SvLBoxItem& rItem = pEntry->GetItem(col);
4151         assert(dynamic_cast<SvLBoxString*>(&rItem));
4152         static_cast<SvLBoxString&>(rItem).SetText(rText);
4153     }
4154 
4155     InvalidateModelEntry(pEntry);
4156 }
4157 
set_text(int pos,const OUString & rText,int col)4158 void SalInstanceTreeView::set_text(int pos, const OUString& rText, int col)
4159 {
4160     SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4161     set_text(pEntry, rText, col);
4162 }
4163 
set_sensitive(SvTreeListEntry * pEntry,bool bSensitive,int col)4164 void SalInstanceTreeView::set_sensitive(SvTreeListEntry* pEntry, bool bSensitive, int col)
4165 {
4166     if (col == -1)
4167     {
4168         auto nFlags = pEntry->GetFlags() & ~SvTLEntryFlags::SEMITRANSPARENT;
4169         if (!bSensitive)
4170             nFlags = nFlags | SvTLEntryFlags::SEMITRANSPARENT;
4171         pEntry->SetFlags(nFlags);
4172         const sal_uInt16 nCount = pEntry->ItemCount();
4173         for (sal_uInt16 nCur = 0; nCur < nCount; ++nCur)
4174         {
4175             SvLBoxItem& rItem = pEntry->GetItem(nCur);
4176             if (rItem.GetType() == SvLBoxItemType::String)
4177             {
4178                 rItem.Enable(bSensitive);
4179                 InvalidateModelEntry(pEntry);
4180                 break;
4181             }
4182         }
4183         return;
4184     }
4185 
4186     col = to_internal_model(col);
4187 
4188     assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
4189     SvLBoxItem& rItem = pEntry->GetItem(col);
4190     rItem.Enable(bSensitive);
4191 
4192     InvalidateModelEntry(pEntry);
4193 }
4194 
set_sensitive(int pos,bool bSensitive,int col)4195 void SalInstanceTreeView::set_sensitive(int pos, bool bSensitive, int col)
4196 {
4197     SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4198     set_sensitive(pEntry, bSensitive, col);
4199 }
4200 
set_sensitive(const weld::TreeIter & rIter,bool bSensitive,int col)4201 void SalInstanceTreeView::set_sensitive(const weld::TreeIter& rIter, bool bSensitive, int col)
4202 {
4203     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4204     set_sensitive(rVclIter.iter, bSensitive, col);
4205 }
4206 
get_toggle(int pos,int col) const4207 TriState SalInstanceTreeView::get_toggle(int pos, int col) const
4208 {
4209     SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4210     return get_toggle(pEntry, col);
4211 }
4212 
get_toggle(const weld::TreeIter & rIter,int col) const4213 TriState SalInstanceTreeView::get_toggle(const weld::TreeIter& rIter, int col) const
4214 {
4215     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4216     return get_toggle(rVclIter.iter, col);
4217 }
4218 
enable_toggle_buttons(weld::ColumnToggleType eType)4219 void SalInstanceTreeView::enable_toggle_buttons(weld::ColumnToggleType eType)
4220 {
4221     assert(n_children() == 0 && "tree must be empty");
4222     m_bTogglesAsRadio = eType == weld::ColumnToggleType::Radio;
4223 
4224     SvLBoxButtonData* pData = m_bTogglesAsRadio ? &m_aRadioButtonData : &m_aCheckButtonData;
4225     m_xTreeView->EnableCheckButton(pData);
4226     // EnableCheckButton clobbered this, restore it
4227     pData->SetLink(LINK(this, SalInstanceTreeView, ToggleHdl));
4228 }
4229 
set_toggle(int pos,TriState eState,int col)4230 void SalInstanceTreeView::set_toggle(int pos, TriState eState, int col)
4231 {
4232     SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4233     set_toggle(pEntry, eState, col);
4234 }
4235 
set_toggle(const weld::TreeIter & rIter,TriState eState,int col)4236 void SalInstanceTreeView::set_toggle(const weld::TreeIter& rIter, TriState eState, int col)
4237 {
4238     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4239     set_toggle(rVclIter.iter, eState, col);
4240 }
4241 
set_clicks_to_toggle(int nToggleBehavior)4242 void SalInstanceTreeView::set_clicks_to_toggle(int nToggleBehavior)
4243 {
4244     m_xTreeView->SetClicksToToggle(nToggleBehavior);
4245 }
4246 
set_extra_row_indent(const weld::TreeIter & rIter,int nIndentLevel)4247 void SalInstanceTreeView::set_extra_row_indent(const weld::TreeIter& rIter, int nIndentLevel)
4248 {
4249     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4250     rVclIter.iter->SetExtraIndent(nIndentLevel);
4251 }
4252 
set_text_emphasis(SvTreeListEntry * pEntry,bool bOn,int col)4253 void SalInstanceTreeView::set_text_emphasis(SvTreeListEntry* pEntry, bool bOn, int col)
4254 {
4255     col = to_internal_model(col);
4256 
4257     assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
4258     SvLBoxItem& rItem = pEntry->GetItem(col);
4259     assert(dynamic_cast<SvLBoxString*>(&rItem));
4260     static_cast<SvLBoxString&>(rItem).Emphasize(bOn);
4261 
4262     InvalidateModelEntry(pEntry);
4263 }
4264 
set_text_emphasis(const weld::TreeIter & rIter,bool bOn,int col)4265 void SalInstanceTreeView::set_text_emphasis(const weld::TreeIter& rIter, bool bOn, int col)
4266 {
4267     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4268     set_text_emphasis(rVclIter.iter, bOn, col);
4269 }
4270 
set_text_emphasis(int pos,bool bOn,int col)4271 void SalInstanceTreeView::set_text_emphasis(int pos, bool bOn, int col)
4272 {
4273     SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4274     set_text_emphasis(pEntry, bOn, col);
4275 }
4276 
get_text_emphasis(const weld::TreeIter & rIter,int col) const4277 bool SalInstanceTreeView::get_text_emphasis(const weld::TreeIter& rIter, int col) const
4278 {
4279     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4280     return get_text_emphasis(rVclIter.iter, col);
4281 }
4282 
get_text_emphasis(int pos,int col) const4283 bool SalInstanceTreeView::get_text_emphasis(int pos, int col) const
4284 {
4285     SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4286     return get_text_emphasis(pEntry, col);
4287 }
4288 
set_text_align(SvTreeListEntry * pEntry,double fAlign,int col)4289 void SalInstanceTreeView::set_text_align(SvTreeListEntry* pEntry, double fAlign, int col)
4290 {
4291     col = to_internal_model(col);
4292 
4293     assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
4294     SvLBoxItem& rItem = pEntry->GetItem(col);
4295     assert(dynamic_cast<SvLBoxString*>(&rItem));
4296     static_cast<SvLBoxString&>(rItem).Align(fAlign);
4297 
4298     InvalidateModelEntry(pEntry);
4299 }
4300 
set_text_align(const weld::TreeIter & rIter,double fAlign,int col)4301 void SalInstanceTreeView::set_text_align(const weld::TreeIter& rIter, double fAlign, int col)
4302 {
4303     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4304     set_text_align(rVclIter.iter, fAlign, col);
4305 }
4306 
set_text_align(int pos,double fAlign,int col)4307 void SalInstanceTreeView::set_text_align(int pos, double fAlign, int col)
4308 {
4309     SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4310     set_text_align(pEntry, fAlign, col);
4311 }
4312 
connect_editing(const Link<const weld::TreeIter &,bool> & rStartLink,const Link<const iter_string &,bool> & rEndLink)4313 void SalInstanceTreeView::connect_editing(const Link<const weld::TreeIter&, bool>& rStartLink,
4314                                           const Link<const iter_string&, bool>& rEndLink)
4315 {
4316     m_xTreeView->EnableInplaceEditing(rStartLink.IsSet() || rEndLink.IsSet());
4317     weld::TreeView::connect_editing(rStartLink, rEndLink);
4318 }
4319 
start_editing(const weld::TreeIter & rIter)4320 void SalInstanceTreeView::start_editing(const weld::TreeIter& rIter)
4321 {
4322     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4323     m_xTreeView->EditEntry(rVclIter.iter);
4324 }
4325 
end_editing()4326 void SalInstanceTreeView::end_editing() { m_xTreeView->EndEditing(); }
4327 
set_image(SvTreeListEntry * pEntry,const Image & rImage,int col)4328 void SalInstanceTreeView::set_image(SvTreeListEntry* pEntry, const Image& rImage, int col)
4329 {
4330     if (col == -1)
4331     {
4332         m_xTreeView->SetExpandedEntryBmp(pEntry, rImage);
4333         m_xTreeView->SetCollapsedEntryBmp(pEntry, rImage);
4334         return;
4335     }
4336 
4337     col = to_internal_model(col);
4338 
4339     // blank out missing entries
4340     for (int i = pEntry->ItemCount(); i < col; ++i)
4341         AddStringItem(pEntry, "", i - 1);
4342 
4343     if (static_cast<size_t>(col) == pEntry->ItemCount())
4344     {
4345         pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(rImage, rImage, false));
4346         SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry);
4347         m_xTreeView->InitViewData(pViewData, pEntry);
4348     }
4349     else
4350     {
4351         assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
4352         SvLBoxItem& rItem = pEntry->GetItem(col);
4353         assert(dynamic_cast<SvLBoxContextBmp*>(&rItem));
4354         static_cast<SvLBoxContextBmp&>(rItem).SetBitmap1(rImage);
4355         static_cast<SvLBoxContextBmp&>(rItem).SetBitmap2(rImage);
4356     }
4357 
4358     m_xTreeView->SetEntryHeight(pEntry);
4359     InvalidateModelEntry(pEntry);
4360 }
4361 
set_image(int pos,const OUString & rImage,int col)4362 void SalInstanceTreeView::set_image(int pos, const OUString& rImage, int col)
4363 {
4364     set_image(m_xTreeView->GetEntry(nullptr, pos), createImage(rImage), col);
4365 }
4366 
set_image(int pos,const css::uno::Reference<css::graphic::XGraphic> & rImage,int col)4367 void SalInstanceTreeView::set_image(int pos,
4368                                     const css::uno::Reference<css::graphic::XGraphic>& rImage,
4369                                     int col)
4370 {
4371     set_image(m_xTreeView->GetEntry(nullptr, pos), Image(rImage), col);
4372 }
4373 
set_image(int pos,VirtualDevice & rImage,int col)4374 void SalInstanceTreeView::set_image(int pos, VirtualDevice& rImage, int col)
4375 {
4376     set_image(m_xTreeView->GetEntry(nullptr, pos), createImage(rImage), col);
4377 }
4378 
set_image(const weld::TreeIter & rIter,const OUString & rImage,int col)4379 void SalInstanceTreeView::set_image(const weld::TreeIter& rIter, const OUString& rImage, int col)
4380 {
4381     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4382     set_image(rVclIter.iter, createImage(rImage), col);
4383 }
4384 
set_image(const weld::TreeIter & rIter,const css::uno::Reference<css::graphic::XGraphic> & rImage,int col)4385 void SalInstanceTreeView::set_image(const weld::TreeIter& rIter,
4386                                     const css::uno::Reference<css::graphic::XGraphic>& rImage,
4387                                     int col)
4388 {
4389     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4390     set_image(rVclIter.iter, Image(rImage), col);
4391 }
4392 
set_image(const weld::TreeIter & rIter,VirtualDevice & rImage,int col)4393 void SalInstanceTreeView::set_image(const weld::TreeIter& rIter, VirtualDevice& rImage, int col)
4394 {
4395     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4396     set_image(rVclIter.iter, createImage(rImage), col);
4397 }
4398 
getEntryData(int index) const4399 const OUString* SalInstanceTreeView::getEntryData(int index) const
4400 {
4401     SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, index);
4402     return pEntry ? static_cast<const OUString*>(pEntry->GetUserData()) : nullptr;
4403 }
4404 
get_id(int pos) const4405 OUString SalInstanceTreeView::get_id(int pos) const
4406 {
4407     const OUString* pRet = getEntryData(pos);
4408     if (!pRet)
4409         return OUString();
4410     return *pRet;
4411 }
4412 
set_id(SvTreeListEntry * pEntry,const OUString & rId)4413 void SalInstanceTreeView::set_id(SvTreeListEntry* pEntry, const OUString& rId)
4414 {
4415     m_aUserData.emplace_back(std::make_unique<OUString>(rId));
4416     pEntry->SetUserData(m_aUserData.back().get());
4417 }
4418 
set_id(int pos,const OUString & rId)4419 void SalInstanceTreeView::set_id(int pos, const OUString& rId)
4420 {
4421     SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4422     set_id(pEntry, rId);
4423 }
4424 
get_selected_index() const4425 int SalInstanceTreeView::get_selected_index() const
4426 {
4427     assert(m_xTreeView->IsUpdateMode() && "don't request selection when frozen");
4428     SvTreeListEntry* pEntry = m_xTreeView->FirstSelected();
4429     if (!pEntry)
4430         return -1;
4431     return SvTreeList::GetRelPos(pEntry);
4432 }
4433 
get_selected_text() const4434 OUString SalInstanceTreeView::get_selected_text() const
4435 {
4436     assert(m_xTreeView->IsUpdateMode() && "don't request selection when frozen");
4437     if (SvTreeListEntry* pEntry = m_xTreeView->FirstSelected())
4438         return SvTabListBox::GetEntryText(pEntry, 0);
4439     return OUString();
4440 }
4441 
get_selected_id() const4442 OUString SalInstanceTreeView::get_selected_id() const
4443 {
4444     assert(m_xTreeView->IsUpdateMode() && "don't request selection when frozen");
4445     if (SvTreeListEntry* pEntry = m_xTreeView->FirstSelected())
4446     {
4447         if (const OUString* pStr = static_cast<const OUString*>(pEntry->GetUserData()))
4448             return *pStr;
4449     }
4450     return OUString();
4451 }
4452 
4453 std::unique_ptr<weld::TreeIter>
make_iterator(const weld::TreeIter * pOrig) const4454 SalInstanceTreeView::make_iterator(const weld::TreeIter* pOrig) const
4455 {
4456     return std::unique_ptr<weld::TreeIter>(
4457         new SalInstanceTreeIter(static_cast<const SalInstanceTreeIter*>(pOrig)));
4458 }
4459 
copy_iterator(const weld::TreeIter & rSource,weld::TreeIter & rDest) const4460 void SalInstanceTreeView::copy_iterator(const weld::TreeIter& rSource, weld::TreeIter& rDest) const
4461 {
4462     const SalInstanceTreeIter& rVclSource(static_cast<const SalInstanceTreeIter&>(rSource));
4463     SalInstanceTreeIter& rVclDest(static_cast<SalInstanceTreeIter&>(rDest));
4464     rVclDest.iter = rVclSource.iter;
4465 }
4466 
get_selected(weld::TreeIter * pIter) const4467 bool SalInstanceTreeView::get_selected(weld::TreeIter* pIter) const
4468 {
4469     SvTreeListEntry* pEntry = m_xTreeView->FirstSelected();
4470     auto pVclIter = static_cast<SalInstanceTreeIter*>(pIter);
4471     if (pVclIter)
4472         pVclIter->iter = pEntry;
4473     return pEntry != nullptr;
4474 }
4475 
get_cursor(weld::TreeIter * pIter) const4476 bool SalInstanceTreeView::get_cursor(weld::TreeIter* pIter) const
4477 {
4478     SvTreeListEntry* pEntry = m_xTreeView->GetCurEntry();
4479     auto pVclIter = static_cast<SalInstanceTreeIter*>(pIter);
4480     if (pVclIter)
4481         pVclIter->iter = pEntry;
4482     return pEntry != nullptr;
4483 }
4484 
set_cursor(const weld::TreeIter & rIter)4485 void SalInstanceTreeView::set_cursor(const weld::TreeIter& rIter)
4486 {
4487     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4488     disable_notify_events();
4489     m_xTreeView->SetCurEntry(rVclIter.iter);
4490     enable_notify_events();
4491 }
4492 
get_iter_first(weld::TreeIter & rIter) const4493 bool SalInstanceTreeView::get_iter_first(weld::TreeIter& rIter) const
4494 {
4495     SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
4496     rVclIter.iter = m_xTreeView->GetEntry(0);
4497     return rVclIter.iter != nullptr;
4498 }
4499 
get_iter_abs_pos(weld::TreeIter & rIter,int nAbsPos) const4500 bool SalInstanceTreeView::get_iter_abs_pos(weld::TreeIter& rIter, int nAbsPos) const
4501 {
4502     SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
4503     rVclIter.iter = m_xTreeView->GetEntryAtAbsPos(nAbsPos);
4504     return rVclIter.iter != nullptr;
4505 }
4506 
iter_next_sibling(weld::TreeIter & rIter) const4507 bool SalInstanceTreeView::iter_next_sibling(weld::TreeIter& rIter) const
4508 {
4509     SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
4510     rVclIter.iter = rVclIter.iter->NextSibling();
4511     return rVclIter.iter != nullptr;
4512 }
4513 
iter_previous_sibling(weld::TreeIter & rIter) const4514 bool SalInstanceTreeView::iter_previous_sibling(weld::TreeIter& rIter) const
4515 {
4516     SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
4517     rVclIter.iter = rVclIter.iter->PrevSibling();
4518     return rVclIter.iter != nullptr;
4519 }
4520 
iter_next(weld::TreeIter & rIter) const4521 bool SalInstanceTreeView::iter_next(weld::TreeIter& rIter) const
4522 {
4523     SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
4524     rVclIter.iter = m_xTreeView->Next(rVclIter.iter);
4525     if (rVclIter.iter && IsDummyEntry(rVclIter.iter))
4526         return iter_next(rVclIter);
4527     return rVclIter.iter != nullptr;
4528 }
4529 
iter_previous(weld::TreeIter & rIter) const4530 bool SalInstanceTreeView::iter_previous(weld::TreeIter& rIter) const
4531 {
4532     SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
4533     rVclIter.iter = m_xTreeView->Prev(rVclIter.iter);
4534     if (rVclIter.iter && IsDummyEntry(rVclIter.iter))
4535         return iter_previous(rVclIter);
4536     return rVclIter.iter != nullptr;
4537 }
4538 
iter_children(weld::TreeIter & rIter) const4539 bool SalInstanceTreeView::iter_children(weld::TreeIter& rIter) const
4540 {
4541     SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
4542     rVclIter.iter = m_xTreeView->FirstChild(rVclIter.iter);
4543     bool bRet = rVclIter.iter != nullptr;
4544     if (bRet)
4545     {
4546         //on-demand dummy entry doesn't count
4547         return !IsDummyEntry(rVclIter.iter);
4548     }
4549     return bRet;
4550 }
4551 
iter_parent(weld::TreeIter & rIter) const4552 bool SalInstanceTreeView::iter_parent(weld::TreeIter& rIter) const
4553 {
4554     SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
4555     rVclIter.iter = m_xTreeView->GetParent(rVclIter.iter);
4556     return rVclIter.iter != nullptr;
4557 }
4558 
remove(const weld::TreeIter & rIter)4559 void SalInstanceTreeView::remove(const weld::TreeIter& rIter)
4560 {
4561     disable_notify_events();
4562     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4563     m_xTreeView->RemoveEntry(rVclIter.iter);
4564     enable_notify_events();
4565 }
4566 
select(const weld::TreeIter & rIter)4567 void SalInstanceTreeView::select(const weld::TreeIter& rIter)
4568 {
4569     assert(m_xTreeView->IsUpdateMode()
4570            && "don't select when frozen, select after thaw. Note selection doesn't survive a "
4571               "freeze");
4572     disable_notify_events();
4573     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4574     m_xTreeView->Select(rVclIter.iter, true);
4575     enable_notify_events();
4576 }
4577 
scroll_to_row(const weld::TreeIter & rIter)4578 void SalInstanceTreeView::scroll_to_row(const weld::TreeIter& rIter)
4579 {
4580     assert(m_xTreeView->IsUpdateMode()
4581            && "don't select when frozen, select after thaw. Note selection doesn't survive a "
4582               "freeze");
4583     disable_notify_events();
4584     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4585     m_xTreeView->MakeVisible(rVclIter.iter);
4586     enable_notify_events();
4587 }
4588 
unselect(const weld::TreeIter & rIter)4589 void SalInstanceTreeView::unselect(const weld::TreeIter& rIter)
4590 {
4591     assert(m_xTreeView->IsUpdateMode() && "don't unselect when frozen");
4592     disable_notify_events();
4593     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4594     m_xTreeView->Select(rVclIter.iter, false);
4595     enable_notify_events();
4596 }
4597 
get_iter_depth(const weld::TreeIter & rIter) const4598 int SalInstanceTreeView::get_iter_depth(const weld::TreeIter& rIter) const
4599 {
4600     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4601     return m_xTreeView->GetModel()->GetDepth(rVclIter.iter);
4602 }
4603 
iter_has_child(const weld::TreeIter & rIter) const4604 bool SalInstanceTreeView::iter_has_child(const weld::TreeIter& rIter) const
4605 {
4606     SalInstanceTreeIter aTempCopy(static_cast<const SalInstanceTreeIter*>(&rIter));
4607     return iter_children(aTempCopy);
4608 }
4609 
get_row_expanded(const weld::TreeIter & rIter) const4610 bool SalInstanceTreeView::get_row_expanded(const weld::TreeIter& rIter) const
4611 {
4612     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4613     return m_xTreeView->IsExpanded(rVclIter.iter);
4614 }
4615 
get_children_on_demand(const weld::TreeIter & rIter) const4616 bool SalInstanceTreeView::get_children_on_demand(const weld::TreeIter& rIter) const
4617 {
4618     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4619     if (m_aExpandingPlaceHolderParents.count(rVclIter.iter))
4620         return true;
4621     return GetPlaceHolderChild(rVclIter.iter) != nullptr;
4622 }
4623 
set_children_on_demand(const weld::TreeIter & rIter,bool bChildrenOnDemand)4624 void SalInstanceTreeView::set_children_on_demand(const weld::TreeIter& rIter,
4625                                                  bool bChildrenOnDemand)
4626 {
4627     disable_notify_events();
4628 
4629     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4630 
4631     SvTreeListEntry* pPlaceHolder = GetPlaceHolderChild(rVclIter.iter);
4632 
4633     if (bChildrenOnDemand && !pPlaceHolder)
4634     {
4635         pPlaceHolder = m_xTreeView->InsertEntry("<dummy>", rVclIter.iter, false, 0, nullptr);
4636         SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pPlaceHolder);
4637         pViewData->SetSelectable(false);
4638     }
4639     else if (!bChildrenOnDemand && pPlaceHolder)
4640         m_xTreeView->RemoveEntry(pPlaceHolder);
4641 
4642     enable_notify_events();
4643 }
4644 
expand_row(const weld::TreeIter & rIter)4645 void SalInstanceTreeView::expand_row(const weld::TreeIter& rIter)
4646 {
4647     assert(m_xTreeView->IsUpdateMode() && "don't expand when frozen");
4648     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4649     if (!m_xTreeView->IsExpanded(rVclIter.iter) && signal_expanding(rIter))
4650         m_xTreeView->Expand(rVclIter.iter);
4651 }
4652 
collapse_row(const weld::TreeIter & rIter)4653 void SalInstanceTreeView::collapse_row(const weld::TreeIter& rIter)
4654 {
4655     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4656     if (m_xTreeView->IsExpanded(rVclIter.iter) && signal_collapsing(rIter))
4657         m_xTreeView->Collapse(rVclIter.iter);
4658 }
4659 
get_text(const weld::TreeIter & rIter,int col) const4660 OUString SalInstanceTreeView::get_text(const weld::TreeIter& rIter, int col) const
4661 {
4662     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4663     return get_text(rVclIter.iter, col);
4664 }
4665 
set_text(const weld::TreeIter & rIter,const OUString & rText,int col)4666 void SalInstanceTreeView::set_text(const weld::TreeIter& rIter, const OUString& rText, int col)
4667 {
4668     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4669     set_text(rVclIter.iter, rText, col);
4670 }
4671 
get_id(const weld::TreeIter & rIter) const4672 OUString SalInstanceTreeView::get_id(const weld::TreeIter& rIter) const
4673 {
4674     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4675     const OUString* pStr = static_cast<const OUString*>(rVclIter.iter->GetUserData());
4676     if (pStr)
4677         return *pStr;
4678     return OUString();
4679 }
4680 
set_id(const weld::TreeIter & rIter,const OUString & rId)4681 void SalInstanceTreeView::set_id(const weld::TreeIter& rIter, const OUString& rId)
4682 {
4683     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4684     set_id(rVclIter.iter, rId);
4685 }
4686 
enable_drag_source(rtl::Reference<TransferDataContainer> & rHelper,sal_uInt8 eDNDConstants)4687 void SalInstanceTreeView::enable_drag_source(rtl::Reference<TransferDataContainer>& rHelper,
4688                                              sal_uInt8 eDNDConstants)
4689 {
4690     m_xTreeView->SetDragHelper(rHelper, eDNDConstants);
4691 }
4692 
set_selection_mode(SelectionMode eMode)4693 void SalInstanceTreeView::set_selection_mode(SelectionMode eMode)
4694 {
4695     m_xTreeView->SetSelectionMode(eMode);
4696 }
4697 
all_foreach(const std::function<bool (weld::TreeIter &)> & func)4698 void SalInstanceTreeView::all_foreach(const std::function<bool(weld::TreeIter&)>& func)
4699 {
4700     UpdateGuardIfHidden aGuard(*m_xTreeView);
4701 
4702     SalInstanceTreeIter aVclIter(m_xTreeView->First());
4703     while (aVclIter.iter)
4704     {
4705         if (func(aVclIter))
4706             return;
4707         iter_next(aVclIter);
4708     }
4709 }
4710 
selected_foreach(const std::function<bool (weld::TreeIter &)> & func)4711 void SalInstanceTreeView::selected_foreach(const std::function<bool(weld::TreeIter&)>& func)
4712 {
4713     UpdateGuardIfHidden aGuard(*m_xTreeView);
4714 
4715     SalInstanceTreeIter aVclIter(m_xTreeView->FirstSelected());
4716     while (aVclIter.iter)
4717     {
4718         if (func(aVclIter))
4719             return;
4720         aVclIter.iter = m_xTreeView->NextSelected(aVclIter.iter);
4721     }
4722 }
4723 
visible_foreach(const std::function<bool (weld::TreeIter &)> & func)4724 void SalInstanceTreeView::visible_foreach(const std::function<bool(weld::TreeIter&)>& func)
4725 {
4726     UpdateGuardIfHidden aGuard(*m_xTreeView);
4727 
4728     SalInstanceTreeIter aVclIter(m_xTreeView->GetFirstEntryInView());
4729     while (aVclIter.iter)
4730     {
4731         if (func(aVclIter))
4732             return;
4733         aVclIter.iter = m_xTreeView->GetNextEntryInView(aVclIter.iter);
4734     }
4735 }
4736 
connect_visible_range_changed(const Link<weld::TreeView &,void> & rLink)4737 void SalInstanceTreeView::connect_visible_range_changed(const Link<weld::TreeView&, void>& rLink)
4738 {
4739     weld::TreeView::connect_visible_range_changed(rLink);
4740     m_xTreeView->SetScrolledHdl(LINK(this, SalInstanceTreeView, VisibleRangeChangedHdl));
4741 }
4742 
remove_selection()4743 void SalInstanceTreeView::remove_selection()
4744 {
4745     disable_notify_events();
4746     SvTreeListEntry* pSelected = m_xTreeView->FirstSelected();
4747     while (pSelected)
4748     {
4749         SvTreeListEntry* pNextSelected = m_xTreeView->NextSelected(pSelected);
4750         m_xTreeView->RemoveEntry(pSelected);
4751         pSelected = pNextSelected;
4752     }
4753     enable_notify_events();
4754 }
4755 
is_selected(const weld::TreeIter & rIter) const4756 bool SalInstanceTreeView::is_selected(const weld::TreeIter& rIter) const
4757 {
4758     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4759     return m_xTreeView->IsSelected(rVclIter.iter);
4760 }
4761 
get_iter_index_in_parent(const weld::TreeIter & rIter) const4762 int SalInstanceTreeView::get_iter_index_in_parent(const weld::TreeIter& rIter) const
4763 {
4764     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4765     return SvTreeList::GetRelPos(rVclIter.iter);
4766 }
4767 
iter_compare(const weld::TreeIter & a,const weld::TreeIter & b) const4768 int SalInstanceTreeView::iter_compare(const weld::TreeIter& a, const weld::TreeIter& b) const
4769 {
4770     const SalInstanceTreeIter& rVclIterA = static_cast<const SalInstanceTreeIter&>(a);
4771     const SalInstanceTreeIter& rVclIterB = static_cast<const SalInstanceTreeIter&>(b);
4772     const SvTreeList* pModel = m_xTreeView->GetModel();
4773     auto nAbsPosA = pModel->GetAbsPos(rVclIterA.iter);
4774     auto nAbsPosB = pModel->GetAbsPos(rVclIterB.iter);
4775     if (nAbsPosA < nAbsPosB)
4776         return -1;
4777     if (nAbsPosA > nAbsPosB)
4778         return 1;
4779     return 0;
4780 }
4781 
move_subtree(weld::TreeIter & rNode,const weld::TreeIter * pNewParent,int nIndexInNewParent)4782 void SalInstanceTreeView::move_subtree(weld::TreeIter& rNode, const weld::TreeIter* pNewParent,
4783                                        int nIndexInNewParent)
4784 {
4785     SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rNode);
4786     const SalInstanceTreeIter* pVclParentIter = static_cast<const SalInstanceTreeIter*>(pNewParent);
4787     m_xTreeView->GetModel()->Move(rVclIter.iter, pVclParentIter ? pVclParentIter->iter : nullptr,
4788                                   nIndexInNewParent);
4789 }
4790 
count_selected_rows() const4791 int SalInstanceTreeView::count_selected_rows() const { return m_xTreeView->GetSelectionCount(); }
4792 
get_height_rows(int nRows) const4793 int SalInstanceTreeView::get_height_rows(int nRows) const
4794 {
4795     int nHeight = m_xTreeView->GetEntryHeight() * nRows;
4796 
4797     sal_Int32 nLeftBorder(0), nTopBorder(0), nRightBorder(0), nBottomBorder(0);
4798     m_xTreeView->GetBorder(nLeftBorder, nTopBorder, nRightBorder, nBottomBorder);
4799     nHeight += nTopBorder + nBottomBorder;
4800 
4801     return nHeight;
4802 }
4803 
make_sorted()4804 void SalInstanceTreeView::make_sorted()
4805 {
4806     assert(m_xTreeView->IsUpdateMode() && "don't sort when frozen");
4807     m_xTreeView->SetStyle(m_xTreeView->GetStyle() | WB_SORT);
4808     m_xTreeView->GetModel()->SetCompareHdl(LINK(this, SalInstanceTreeView, CompareHdl));
4809     set_sort_order(true);
4810 }
4811 
set_sort_func(const std::function<int (const weld::TreeIter &,const weld::TreeIter &)> & func)4812 void SalInstanceTreeView::set_sort_func(
4813     const std::function<int(const weld::TreeIter&, const weld::TreeIter&)>& func)
4814 {
4815     weld::TreeView::set_sort_func(func);
4816     SvTreeList* pListModel = m_xTreeView->GetModel();
4817     pListModel->Resort();
4818 }
4819 
make_unsorted()4820 void SalInstanceTreeView::make_unsorted()
4821 {
4822     m_xTreeView->SetStyle(m_xTreeView->GetStyle() & ~WB_SORT);
4823 }
4824 
set_sort_order(bool bAscending)4825 void SalInstanceTreeView::set_sort_order(bool bAscending)
4826 {
4827     SvTreeList* pListModel = m_xTreeView->GetModel();
4828     pListModel->SetSortMode(bAscending ? SortAscending : SortDescending);
4829     pListModel->Resort();
4830 }
4831 
get_sort_order() const4832 bool SalInstanceTreeView::get_sort_order() const
4833 {
4834     return m_xTreeView->GetModel()->GetSortMode() == SortAscending;
4835 }
4836 
set_sort_indicator(TriState eState,int col)4837 void SalInstanceTreeView::set_sort_indicator(TriState eState, int col)
4838 {
4839     assert(col >= 0 && "cannot sort on expander column");
4840 
4841     LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
4842     HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr;
4843     if (!pHeaderBar)
4844         return;
4845 
4846     sal_uInt16 nTextId = pHeaderBar->GetItemId(col);
4847     HeaderBarItemBits nBits = pHeaderBar->GetItemBits(nTextId);
4848     nBits &= ~HeaderBarItemBits::UPARROW;
4849     nBits &= ~HeaderBarItemBits::DOWNARROW;
4850     if (eState != TRISTATE_INDET)
4851     {
4852         if (eState == TRISTATE_TRUE)
4853             nBits |= HeaderBarItemBits::DOWNARROW;
4854         else
4855             nBits |= HeaderBarItemBits::UPARROW;
4856     }
4857     pHeaderBar->SetItemBits(nTextId, nBits);
4858 }
4859 
get_sort_indicator(int col) const4860 TriState SalInstanceTreeView::get_sort_indicator(int col) const
4861 {
4862     assert(col >= 0 && "cannot sort on expander column");
4863 
4864     LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
4865     if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
4866     {
4867         sal_uInt16 nTextId = pHeaderBar->GetItemId(col);
4868         HeaderBarItemBits nBits = pHeaderBar->GetItemBits(nTextId);
4869         if (nBits & HeaderBarItemBits::DOWNARROW)
4870             return TRISTATE_TRUE;
4871         if (nBits & HeaderBarItemBits::UPARROW)
4872             return TRISTATE_FALSE;
4873     }
4874 
4875     return TRISTATE_INDET;
4876 }
4877 
get_sort_column() const4878 int SalInstanceTreeView::get_sort_column() const { return m_nSortColumn; }
4879 
set_sort_column(int nColumn)4880 void SalInstanceTreeView::set_sort_column(int nColumn)
4881 {
4882     if (nColumn == -1)
4883     {
4884         make_unsorted();
4885         m_nSortColumn = -1;
4886         return;
4887     }
4888 
4889     if (nColumn != m_nSortColumn)
4890     {
4891         m_nSortColumn = nColumn;
4892         m_xTreeView->GetModel()->Resort();
4893     }
4894 }
4895 
getTreeView()4896 SvTabListBox& SalInstanceTreeView::getTreeView() { return *m_xTreeView; }
4897 
get_dest_row_at_pos(const Point & rPos,weld::TreeIter * pResult,bool bDnDMode)4898 bool SalInstanceTreeView::get_dest_row_at_pos(const Point& rPos, weld::TreeIter* pResult,
4899                                               bool bDnDMode)
4900 {
4901     LclTabListBox* pTreeView
4902         = !bDnDMode ? dynamic_cast<LclTabListBox*>(m_xTreeView.get()) : nullptr;
4903     SvTreeListEntry* pTarget
4904         = pTreeView ? pTreeView->GetTargetAtPoint(rPos, false) : m_xTreeView->GetDropTarget(rPos);
4905 
4906     if (pTarget && pResult)
4907     {
4908         SalInstanceTreeIter& rSalIter = static_cast<SalInstanceTreeIter&>(*pResult);
4909         rSalIter.iter = pTarget;
4910     }
4911 
4912     return pTarget != nullptr;
4913 }
4914 
unset_drag_dest_row()4915 void SalInstanceTreeView::unset_drag_dest_row() { m_xTreeView->UnsetDropTarget(); }
4916 
get_row_area(const weld::TreeIter & rIter) const4917 tools::Rectangle SalInstanceTreeView::get_row_area(const weld::TreeIter& rIter) const
4918 {
4919     return m_xTreeView->GetBoundingRect(static_cast<const SalInstanceTreeIter&>(rIter).iter);
4920 }
4921 
get_drag_source() const4922 weld::TreeView* SalInstanceTreeView::get_drag_source() const { return g_DragSource; }
4923 
vadjustment_get_value() const4924 int SalInstanceTreeView::vadjustment_get_value() const
4925 {
4926     int nValue = -1;
4927     const SvTreeListEntry* pEntry = m_xTreeView->GetFirstEntryInView();
4928     if (pEntry)
4929         nValue = m_xTreeView->GetAbsPos(pEntry);
4930     return nValue;
4931 }
4932 
vadjustment_set_value(int nValue)4933 void SalInstanceTreeView::vadjustment_set_value(int nValue)
4934 {
4935     if (nValue == -1)
4936         return;
4937     bool bUpdate = m_xTreeView->IsUpdateMode();
4938     if (bUpdate)
4939         m_xTreeView->SetUpdateMode(false);
4940     m_xTreeView->ScrollToAbsPos(nValue);
4941     if (bUpdate)
4942         m_xTreeView->SetUpdateMode(true);
4943 }
4944 
set_show_expanders(bool bShow)4945 void SalInstanceTreeView::set_show_expanders(bool bShow)
4946 {
4947     m_xTreeView->set_property("show-expanders", OUString::boolean(bShow));
4948 }
4949 
~SalInstanceTreeView()4950 SalInstanceTreeView::~SalInstanceTreeView()
4951 {
4952     LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
4953     if (pHeaderBox)
4954     {
4955         if (HeaderBar* pHeaderBar = pHeaderBox->GetHeaderBar())
4956         {
4957             pHeaderBar->SetSelectHdl(Link<HeaderBar*, void>());
4958             pHeaderBar->SetEndDragHdl(Link<HeaderBar*, void>());
4959         }
4960     }
4961     else
4962     {
4963         static_cast<LclTabListBox&>(*m_xTreeView).SetEndDragHdl(Link<SvTreeListBox*, void>());
4964         static_cast<LclTabListBox&>(*m_xTreeView).SetStartDragHdl(Link<SvTreeListBox*, bool>());
4965         static_cast<LclTabListBox&>(*m_xTreeView).SetModelChangedHdl(Link<SvTreeListBox*, void>());
4966     }
4967     m_xTreeView->SetPopupMenuHdl(Link<const CommandEvent&, bool>());
4968     m_xTreeView->SetExpandingHdl(Link<SvTreeListBox*, bool>());
4969     m_xTreeView->SetDoubleClickHdl(Link<SvTreeListBox*, bool>());
4970     m_xTreeView->SetSelectHdl(Link<SvTreeListBox*, void>());
4971     m_xTreeView->SetDeselectHdl(Link<SvTreeListBox*, void>());
4972     m_xTreeView->SetScrolledHdl(Link<SvTreeListBox*, void>());
4973     m_xTreeView->SetTooltipHdl(Link<const HelpEvent&, bool>());
4974     m_xTreeView->SetCustomRenderHdl(Link<svtree_render_args, void>());
4975     m_xTreeView->SetCustomMeasureHdl(Link<svtree_measure_args, Size>());
4976 }
4977 
IMPL_LINK(SalInstanceTreeView,TooltipHdl,const HelpEvent &,rHEvt,bool)4978 IMPL_LINK(SalInstanceTreeView, TooltipHdl, const HelpEvent&, rHEvt, bool)
4979 {
4980     if (notify_events_disabled())
4981         return false;
4982     Point aPos(m_xTreeView->ScreenToOutputPixel(rHEvt.GetMousePosPixel()));
4983     SvTreeListEntry* pEntry = m_xTreeView->GetEntry(aPos);
4984     if (pEntry)
4985     {
4986         SalInstanceTreeIter aIter(pEntry);
4987         OUString aTooltip = signal_query_tooltip(aIter);
4988         if (aTooltip.isEmpty())
4989             return false;
4990         Size aSize(m_xTreeView->GetOutputSizePixel().Width(), m_xTreeView->GetEntryHeight());
4991         tools::Rectangle aScreenRect(
4992             m_xTreeView->OutputToScreenPixel(m_xTreeView->GetEntryPosition(pEntry)), aSize);
4993         Help::ShowQuickHelp(m_xTreeView, aScreenRect, aTooltip);
4994     }
4995     return true;
4996 }
4997 
IMPL_LINK(SalInstanceTreeView,CustomRenderHdl,svtree_render_args,payload,void)4998 IMPL_LINK(SalInstanceTreeView, CustomRenderHdl, svtree_render_args, payload, void)
4999 {
5000     vcl::RenderContext& rRenderDevice = std::get<0>(payload);
5001     const tools::Rectangle& rRect = std::get<1>(payload);
5002     const SvTreeListEntry& rEntry = std::get<2>(payload);
5003     const OUString* pId = static_cast<const OUString*>(rEntry.GetUserData());
5004     if (!pId)
5005         return;
5006     signal_custom_render(rRenderDevice, rRect, m_xTreeView->IsSelected(&rEntry), *pId);
5007 }
5008 
IMPL_LINK(SalInstanceTreeView,CustomMeasureHdl,svtree_measure_args,payload,Size)5009 IMPL_LINK(SalInstanceTreeView, CustomMeasureHdl, svtree_measure_args, payload, Size)
5010 {
5011     vcl::RenderContext& rRenderDevice = payload.first;
5012     const SvTreeListEntry& rEntry = payload.second;
5013     const OUString* pId = static_cast<const OUString*>(rEntry.GetUserData());
5014     if (!pId)
5015         return Size();
5016     return signal_custom_get_size(rRenderDevice, *pId);
5017 }
5018 
IMPL_LINK(SalInstanceTreeView,CompareHdl,const SvSortData &,rSortData,sal_Int32)5019 IMPL_LINK(SalInstanceTreeView, CompareHdl, const SvSortData&, rSortData, sal_Int32)
5020 {
5021     const SvTreeListEntry* pLHS = rSortData.pLeft;
5022     const SvTreeListEntry* pRHS = rSortData.pRight;
5023     assert(pLHS && pRHS);
5024 
5025     if (m_aCustomSort)
5026         return m_aCustomSort(SalInstanceTreeIter(const_cast<SvTreeListEntry*>(pLHS)),
5027                              SalInstanceTreeIter(const_cast<SvTreeListEntry*>(pRHS)));
5028 
5029     const SvLBoxString* pLeftTextItem;
5030     const SvLBoxString* pRightTextItem;
5031 
5032     if (m_nSortColumn != -1)
5033     {
5034         size_t col = to_internal_model(m_nSortColumn);
5035 
5036         if (col < pLHS->ItemCount())
5037         {
5038             const SvLBoxString& rLeftTextItem
5039                 = static_cast<const SvLBoxString&>(pLHS->GetItem(col));
5040             pLeftTextItem = &rLeftTextItem;
5041         }
5042         else
5043             pLeftTextItem = nullptr;
5044         if (col < pRHS->ItemCount())
5045         {
5046             const SvLBoxString& rRightTextItem
5047                 = static_cast<const SvLBoxString&>(pRHS->GetItem(col));
5048             pRightTextItem = &rRightTextItem;
5049         }
5050         else
5051             pRightTextItem = nullptr;
5052     }
5053     else
5054     {
5055         pLeftTextItem
5056             = static_cast<const SvLBoxString*>(pLHS->GetFirstItem(SvLBoxItemType::String));
5057         pRightTextItem
5058             = static_cast<const SvLBoxString*>(pRHS->GetFirstItem(SvLBoxItemType::String));
5059     }
5060 
5061     return m_xTreeView->DefaultCompare(pLeftTextItem, pRightTextItem);
5062 }
5063 
IMPL_LINK_NOARG(SalInstanceTreeView,VisibleRangeChangedHdl,SvTreeListBox *,void)5064 IMPL_LINK_NOARG(SalInstanceTreeView, VisibleRangeChangedHdl, SvTreeListBox*, void)
5065 {
5066     if (notify_events_disabled())
5067         return;
5068     signal_visible_range_changed();
5069 }
5070 
IMPL_LINK_NOARG(SalInstanceTreeView,ModelChangedHdl,SvTreeListBox *,void)5071 IMPL_LINK_NOARG(SalInstanceTreeView, ModelChangedHdl, SvTreeListBox*, void)
5072 {
5073     if (notify_events_disabled())
5074         return;
5075     signal_model_changed();
5076 }
5077 
IMPL_LINK_NOARG(SalInstanceTreeView,StartDragHdl,SvTreeListBox *,bool)5078 IMPL_LINK_NOARG(SalInstanceTreeView, StartDragHdl, SvTreeListBox*, bool)
5079 {
5080     bool bUnsetDragIcon(false); // ignored for vcl
5081     if (m_aDragBeginHdl.Call(bUnsetDragIcon))
5082         return true;
5083     g_DragSource = this;
5084     return false;
5085 }
5086 
IMPL_STATIC_LINK_NOARG(SalInstanceTreeView,FinishDragHdl,SvTreeListBox *,void)5087 IMPL_STATIC_LINK_NOARG(SalInstanceTreeView, FinishDragHdl, SvTreeListBox*, void)
5088 {
5089     g_DragSource = nullptr;
5090 }
5091 
IMPL_LINK(SalInstanceTreeView,ToggleHdl,SvLBoxButtonData *,pData,void)5092 IMPL_LINK(SalInstanceTreeView, ToggleHdl, SvLBoxButtonData*, pData, void)
5093 {
5094     SvTreeListEntry* pEntry = pData->GetActEntry();
5095     SvLBoxButton* pBox = pData->GetActBox();
5096 
5097     // tdf#122874 Select the row, calling SelectHdl, before handling
5098     // the toggle
5099     if (!m_xTreeView->IsSelected(pEntry))
5100     {
5101         m_xTreeView->SelectAll(false);
5102         m_xTreeView->Select(pEntry, true);
5103     }
5104 
5105     // additionally set the cursor into the row the toggled element is in
5106     m_xTreeView->pImpl->m_pCursor = pEntry;
5107 
5108     for (int i = 0, nCount = pEntry->ItemCount(); i < nCount; ++i)
5109     {
5110         SvLBoxItem& rItem = pEntry->GetItem(i);
5111         if (&rItem == pBox)
5112         {
5113             int nCol = to_external_model(i);
5114             signal_toggled(iter_col(SalInstanceTreeIter(pEntry), nCol));
5115             break;
5116         }
5117     }
5118 }
5119 
IMPL_LINK_NOARG(SalInstanceTreeView,SelectHdl,SvTreeListBox *,void)5120 IMPL_LINK_NOARG(SalInstanceTreeView, SelectHdl, SvTreeListBox*, void)
5121 {
5122     if (notify_events_disabled())
5123         return;
5124     signal_changed();
5125 }
5126 
IMPL_LINK_NOARG(SalInstanceTreeView,DeSelectHdl,SvTreeListBox *,void)5127 IMPL_LINK_NOARG(SalInstanceTreeView, DeSelectHdl, SvTreeListBox*, void)
5128 {
5129     if (notify_events_disabled())
5130         return;
5131     if (m_xTreeView->GetSelectionMode() == SelectionMode::Single
5132         && !m_xTreeView->GetHoverSelection())
5133         return;
5134     signal_changed();
5135 }
5136 
IMPL_LINK_NOARG(SalInstanceTreeView,DoubleClickHdl,SvTreeListBox *,bool)5137 IMPL_LINK_NOARG(SalInstanceTreeView, DoubleClickHdl, SvTreeListBox*, bool)
5138 {
5139     if (notify_events_disabled())
5140         return false;
5141     return !signal_row_activated();
5142 }
5143 
IMPL_LINK(SalInstanceTreeView,EndDragHdl,HeaderBar *,pHeaderBar,void)5144 IMPL_LINK(SalInstanceTreeView, EndDragHdl, HeaderBar*, pHeaderBar, void)
5145 {
5146     std::vector<tools::Long> aTabPositions;
5147     aTabPositions.push_back(0);
5148     for (int i = 0; i < pHeaderBar->GetItemCount() - 1; ++i)
5149         aTabPositions.push_back(aTabPositions[i]
5150                                 + pHeaderBar->GetItemSize(pHeaderBar->GetItemId(i)));
5151     m_xTreeView->SetTabs(aTabPositions.size(), aTabPositions.data(), MapUnit::MapPixel);
5152 }
5153 
IMPL_LINK(SalInstanceTreeView,HeaderBarClickedHdl,HeaderBar *,pHeaderBar,void)5154 IMPL_LINK(SalInstanceTreeView, HeaderBarClickedHdl, HeaderBar*, pHeaderBar, void)
5155 {
5156     sal_uInt16 nId = pHeaderBar->GetCurItemId();
5157     if (!(pHeaderBar->GetItemBits(nId) & HeaderBarItemBits::CLICKABLE))
5158         return;
5159     signal_column_clicked(pHeaderBar->GetItemPos(nId));
5160 }
5161 
IMPL_LINK_NOARG(SalInstanceTreeView,ExpandingHdl,SvTreeListBox *,bool)5162 IMPL_LINK_NOARG(SalInstanceTreeView, ExpandingHdl, SvTreeListBox*, bool)
5163 {
5164     SvTreeListEntry* pEntry = m_xTreeView->GetHdlEntry();
5165     SalInstanceTreeIter aIter(pEntry);
5166 
5167     if (m_xTreeView->IsExpanded(pEntry))
5168     {
5169         //collapsing;
5170         return signal_collapsing(aIter);
5171     }
5172 
5173     // expanding
5174 
5175     // if there's a preexisting placeholder child, required to make this
5176     // potentially expandable in the first place, now we remove it
5177     SvTreeListEntry* pPlaceHolder = GetPlaceHolderChild(pEntry);
5178     if (pPlaceHolder)
5179     {
5180         m_aExpandingPlaceHolderParents.insert(pEntry);
5181         m_xTreeView->RemoveEntry(pPlaceHolder);
5182     }
5183 
5184     bool bRet = signal_expanding(aIter);
5185 
5186     if (pPlaceHolder)
5187     {
5188         //expand disallowed, restore placeholder
5189         if (!bRet)
5190         {
5191             pPlaceHolder = m_xTreeView->InsertEntry("<dummy>", pEntry, false, 0, nullptr);
5192             SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pPlaceHolder);
5193             pViewData->SetSelectable(false);
5194         }
5195         m_aExpandingPlaceHolderParents.erase(pEntry);
5196     }
5197 
5198     return bRet;
5199 }
5200 
IMPL_LINK(SalInstanceTreeView,PopupMenuHdl,const CommandEvent &,rEvent,bool)5201 IMPL_LINK(SalInstanceTreeView, PopupMenuHdl, const CommandEvent&, rEvent, bool)
5202 {
5203     return m_aPopupMenuHdl.Call(rEvent);
5204 }
5205 
IMPL_LINK(SalInstanceTreeView,EditingEntryHdl,SvTreeListEntry *,pEntry,bool)5206 IMPL_LINK(SalInstanceTreeView, EditingEntryHdl, SvTreeListEntry*, pEntry, bool)
5207 {
5208     return signal_editing_started(SalInstanceTreeIter(pEntry));
5209 }
5210 
IMPL_LINK(SalInstanceTreeView,EditedEntryHdl,IterString,rIterString,bool)5211 IMPL_LINK(SalInstanceTreeView, EditedEntryHdl, IterString, rIterString, bool)
5212 {
5213     return signal_editing_done(
5214         iter_string(SalInstanceTreeIter(rIterString.first), rIterString.second));
5215 }
5216 
SalInstanceIconView(::IconView * pIconView,SalInstanceBuilder * pBuilder,bool bTakeOwnership)5217 SalInstanceIconView::SalInstanceIconView(::IconView* pIconView, SalInstanceBuilder* pBuilder,
5218                                          bool bTakeOwnership)
5219     : SalInstanceWidget(pIconView, pBuilder, bTakeOwnership)
5220     , m_xIconView(pIconView)
5221 {
5222     m_xIconView->SetSelectHdl(LINK(this, SalInstanceIconView, SelectHdl));
5223     m_xIconView->SetDeselectHdl(LINK(this, SalInstanceIconView, DeSelectHdl));
5224     m_xIconView->SetDoubleClickHdl(LINK(this, SalInstanceIconView, DoubleClickHdl));
5225     m_xIconView->SetPopupMenuHdl(LINK(this, SalInstanceIconView, CommandHdl));
5226 }
5227 
freeze()5228 void SalInstanceIconView::freeze()
5229 {
5230     bool bIsFirstFreeze = IsFirstFreeze();
5231     SalInstanceWidget::freeze();
5232     if (bIsFirstFreeze)
5233         m_xIconView->SetUpdateMode(false);
5234 }
5235 
thaw()5236 void SalInstanceIconView::thaw()
5237 {
5238     bool bIsLastThaw = IsLastThaw();
5239     if (bIsLastThaw)
5240         m_xIconView->SetUpdateMode(true);
5241     SalInstanceWidget::thaw();
5242 }
5243 
insert(int pos,const OUString * pStr,const OUString * pId,const OUString * pIconName,weld::TreeIter * pRet)5244 void SalInstanceIconView::insert(int pos, const OUString* pStr, const OUString* pId,
5245                                  const OUString* pIconName, weld::TreeIter* pRet)
5246 {
5247     disable_notify_events();
5248     auto nInsertPos = pos == -1 ? TREELIST_APPEND : pos;
5249     void* pUserData;
5250     if (pId)
5251     {
5252         m_aUserData.emplace_back(std::make_unique<OUString>(*pId));
5253         pUserData = m_aUserData.back().get();
5254     }
5255     else
5256         pUserData = nullptr;
5257 
5258     SvTreeListEntry* pEntry = new SvTreeListEntry;
5259     if (pIconName)
5260     {
5261         Image aImage(createImage(*pIconName));
5262         pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(aImage, aImage, false));
5263     }
5264     else
5265     {
5266         Image aDummy;
5267         pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(aDummy, aDummy, false));
5268     }
5269     if (pStr)
5270         pEntry->AddItem(std::make_unique<SvLBoxString>(*pStr));
5271     pEntry->SetUserData(pUserData);
5272     m_xIconView->Insert(pEntry, nullptr, nInsertPos);
5273 
5274     if (pRet)
5275     {
5276         SalInstanceTreeIter* pVclRetIter = static_cast<SalInstanceTreeIter*>(pRet);
5277         pVclRetIter->iter = pEntry;
5278     }
5279 
5280     enable_notify_events();
5281 }
5282 
insert(int pos,const OUString * pStr,const OUString * pId,const VirtualDevice * pIcon,weld::TreeIter * pRet)5283 void SalInstanceIconView::insert(int pos, const OUString* pStr, const OUString* pId,
5284                                  const VirtualDevice* pIcon, weld::TreeIter* pRet)
5285 {
5286     disable_notify_events();
5287     auto nInsertPos = pos == -1 ? TREELIST_APPEND : pos;
5288     void* pUserData;
5289     if (pId)
5290     {
5291         m_aUserData.emplace_back(std::make_unique<OUString>(*pId));
5292         pUserData = m_aUserData.back().get();
5293     }
5294     else
5295         pUserData = nullptr;
5296 
5297     SvTreeListEntry* pEntry = new SvTreeListEntry;
5298     if (pIcon)
5299     {
5300         const Point aNull(0, 0);
5301         const Size aSize = pIcon->GetOutputSizePixel();
5302         Image aImage(pIcon->GetBitmapEx(aNull, aSize));
5303         pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(aImage, aImage, false));
5304     }
5305     else
5306     {
5307         Image aDummy;
5308         pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(aDummy, aDummy, false));
5309     }
5310     if (pStr)
5311         pEntry->AddItem(std::make_unique<SvLBoxString>(*pStr));
5312     pEntry->SetUserData(pUserData);
5313     m_xIconView->Insert(pEntry, nullptr, nInsertPos);
5314 
5315     if (pRet)
5316     {
5317         SalInstanceTreeIter* pVclRetIter = static_cast<SalInstanceTreeIter*>(pRet);
5318         pVclRetIter->iter = pEntry;
5319     }
5320 
5321     enable_notify_events();
5322 }
5323 
get_selected_id() const5324 OUString SalInstanceIconView::get_selected_id() const
5325 {
5326     assert(m_xIconView->IsUpdateMode() && "don't request selection when frozen");
5327     if (SvTreeListEntry* pEntry = m_xIconView->FirstSelected())
5328     {
5329         if (const OUString* pStr = static_cast<const OUString*>(pEntry->GetUserData()))
5330             return *pStr;
5331     }
5332     return OUString();
5333 }
5334 
get_selected_text() const5335 OUString SalInstanceIconView::get_selected_text() const
5336 {
5337     assert(m_xIconView->IsUpdateMode() && "don't request selection when frozen");
5338     if (SvTreeListEntry* pEntry = m_xIconView->FirstSelected())
5339         return m_xIconView->GetEntryText(pEntry);
5340     return OUString();
5341 }
5342 
count_selected_items() const5343 int SalInstanceIconView::count_selected_items() const { return m_xIconView->GetSelectionCount(); }
5344 
select(int pos)5345 void SalInstanceIconView::select(int pos)
5346 {
5347     assert(m_xIconView->IsUpdateMode()
5348            && "don't select when frozen, select after thaw. Note selection doesn't survive a "
5349               "freeze");
5350     disable_notify_events();
5351     if (pos == -1 || (pos == 0 && n_children() == 0))
5352         m_xIconView->SelectAll(false);
5353     else
5354     {
5355         SvTreeListEntry* pEntry = m_xIconView->GetEntry(nullptr, pos);
5356         m_xIconView->Select(pEntry, true);
5357         m_xIconView->MakeVisible(pEntry);
5358     }
5359     enable_notify_events();
5360 }
5361 
unselect(int pos)5362 void SalInstanceIconView::unselect(int pos)
5363 {
5364     assert(m_xIconView->IsUpdateMode()
5365            && "don't select when frozen, select after thaw. Note selection doesn't survive a "
5366               "freeze");
5367     disable_notify_events();
5368     if (pos == -1)
5369         m_xIconView->SelectAll(true);
5370     else
5371     {
5372         SvTreeListEntry* pEntry = m_xIconView->GetEntry(nullptr, pos);
5373         m_xIconView->Select(pEntry, false);
5374     }
5375     enable_notify_events();
5376 }
5377 
n_children() const5378 int SalInstanceIconView::n_children() const
5379 {
5380     return m_xIconView->GetModel()->GetChildList(nullptr).size();
5381 }
5382 
5383 std::unique_ptr<weld::TreeIter>
make_iterator(const weld::TreeIter * pOrig) const5384 SalInstanceIconView::make_iterator(const weld::TreeIter* pOrig) const
5385 {
5386     return std::unique_ptr<weld::TreeIter>(
5387         new SalInstanceTreeIter(static_cast<const SalInstanceTreeIter*>(pOrig)));
5388 }
5389 
get_selected(weld::TreeIter * pIter) const5390 bool SalInstanceIconView::get_selected(weld::TreeIter* pIter) const
5391 {
5392     SvTreeListEntry* pEntry = m_xIconView->FirstSelected();
5393     auto pVclIter = static_cast<SalInstanceTreeIter*>(pIter);
5394     if (pVclIter)
5395         pVclIter->iter = pEntry;
5396     return pEntry != nullptr;
5397 }
5398 
get_cursor(weld::TreeIter * pIter) const5399 bool SalInstanceIconView::get_cursor(weld::TreeIter* pIter) const
5400 {
5401     SvTreeListEntry* pEntry = m_xIconView->GetCurEntry();
5402     auto pVclIter = static_cast<SalInstanceTreeIter*>(pIter);
5403     if (pVclIter)
5404         pVclIter->iter = pEntry;
5405     return pEntry != nullptr;
5406 }
5407 
set_cursor(const weld::TreeIter & rIter)5408 void SalInstanceIconView::set_cursor(const weld::TreeIter& rIter)
5409 {
5410     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
5411     disable_notify_events();
5412     m_xIconView->SetCurEntry(rVclIter.iter);
5413     enable_notify_events();
5414 }
5415 
get_iter_first(weld::TreeIter & rIter) const5416 bool SalInstanceIconView::get_iter_first(weld::TreeIter& rIter) const
5417 {
5418     SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
5419     rVclIter.iter = m_xIconView->GetEntry(0);
5420     return rVclIter.iter != nullptr;
5421 }
5422 
scroll_to_item(const weld::TreeIter & rIter)5423 void SalInstanceIconView::scroll_to_item(const weld::TreeIter& rIter)
5424 {
5425     assert(m_xIconView->IsUpdateMode()
5426            && "don't select when frozen, select after thaw. Note selection doesn't survive a "
5427               "freeze");
5428     disable_notify_events();
5429     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
5430     m_xIconView->MakeVisible(rVclIter.iter);
5431     enable_notify_events();
5432 }
5433 
selected_foreach(const std::function<bool (weld::TreeIter &)> & func)5434 void SalInstanceIconView::selected_foreach(const std::function<bool(weld::TreeIter&)>& func)
5435 {
5436     SalInstanceTreeIter aVclIter(m_xIconView->FirstSelected());
5437     while (aVclIter.iter)
5438     {
5439         if (func(aVclIter))
5440             return;
5441         aVclIter.iter = m_xIconView->NextSelected(aVclIter.iter);
5442     }
5443 }
5444 
get_id(const weld::TreeIter & rIter) const5445 OUString SalInstanceIconView::get_id(const weld::TreeIter& rIter) const
5446 {
5447     const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
5448     const OUString* pStr = static_cast<const OUString*>(rVclIter.iter->GetUserData());
5449     if (pStr)
5450         return *pStr;
5451     return OUString();
5452 }
5453 
clear()5454 void SalInstanceIconView::clear()
5455 {
5456     disable_notify_events();
5457     m_xIconView->Clear();
5458     m_aUserData.clear();
5459     enable_notify_events();
5460 }
5461 
~SalInstanceIconView()5462 SalInstanceIconView::~SalInstanceIconView()
5463 {
5464     m_xIconView->SetDoubleClickHdl(Link<SvTreeListBox*, bool>());
5465     m_xIconView->SetSelectHdl(Link<SvTreeListBox*, void>());
5466     m_xIconView->SetDeselectHdl(Link<SvTreeListBox*, void>());
5467 }
5468 
IMPL_LINK_NOARG(SalInstanceIconView,SelectHdl,SvTreeListBox *,void)5469 IMPL_LINK_NOARG(SalInstanceIconView, SelectHdl, SvTreeListBox*, void)
5470 {
5471     if (notify_events_disabled())
5472         return;
5473     signal_selection_changed();
5474 }
5475 
IMPL_LINK_NOARG(SalInstanceIconView,DeSelectHdl,SvTreeListBox *,void)5476 IMPL_LINK_NOARG(SalInstanceIconView, DeSelectHdl, SvTreeListBox*, void)
5477 {
5478     if (notify_events_disabled())
5479         return;
5480     if (m_xIconView->GetSelectionMode() == SelectionMode::Single)
5481         return;
5482     signal_selection_changed();
5483 }
5484 
IMPL_LINK_NOARG(SalInstanceIconView,DoubleClickHdl,SvTreeListBox *,bool)5485 IMPL_LINK_NOARG(SalInstanceIconView, DoubleClickHdl, SvTreeListBox*, bool)
5486 {
5487     if (notify_events_disabled())
5488         return false;
5489     return !signal_item_activated();
5490 }
5491 
IMPL_LINK(SalInstanceIconView,CommandHdl,const CommandEvent &,rEvent,bool)5492 IMPL_LINK(SalInstanceIconView, CommandHdl, const CommandEvent&, rEvent, bool)
5493 {
5494     return m_aCommandHdl.Call(rEvent);
5495 }
5496 
toField(int nValue) const5497 double SalInstanceSpinButton::toField(int nValue) const
5498 {
5499     return static_cast<double>(nValue) / Power10(get_digits());
5500 }
5501 
fromField(double fValue) const5502 int SalInstanceSpinButton::fromField(double fValue) const
5503 {
5504     return FRound(fValue * Power10(get_digits()));
5505 }
5506 
SalInstanceSpinButton(FormattedField * pButton,SalInstanceBuilder * pBuilder,bool bTakeOwnership)5507 SalInstanceSpinButton::SalInstanceSpinButton(FormattedField* pButton, SalInstanceBuilder* pBuilder,
5508                                              bool bTakeOwnership)
5509     : SalInstanceEntry(pButton, pBuilder, bTakeOwnership)
5510     , m_xButton(pButton)
5511     , m_rFormatter(m_xButton->GetFormatter())
5512 {
5513     m_rFormatter.SetThousandsSep(false); //off by default, MetricSpinButton enables it
5514     m_xButton->SetUpHdl(LINK(this, SalInstanceSpinButton, UpDownHdl));
5515     m_xButton->SetDownHdl(LINK(this, SalInstanceSpinButton, UpDownHdl));
5516     m_xButton->SetLoseFocusHdl(LINK(this, SalInstanceSpinButton, LoseFocusHdl));
5517     m_rFormatter.SetOutputHdl(LINK(this, SalInstanceSpinButton, OutputHdl));
5518     m_rFormatter.SetInputHdl(LINK(this, SalInstanceSpinButton, InputHdl));
5519     if (Edit* pEdit = m_xButton->GetSubEdit())
5520         pEdit->SetActivateHdl(LINK(this, SalInstanceSpinButton, ActivateHdl));
5521     else
5522         m_xButton->SetActivateHdl(LINK(this, SalInstanceSpinButton, ActivateHdl));
5523 }
5524 
get_value() const5525 int SalInstanceSpinButton::get_value() const { return fromField(m_rFormatter.GetValue()); }
5526 
set_value(int value)5527 void SalInstanceSpinButton::set_value(int value) { m_rFormatter.SetValue(toField(value)); }
5528 
set_range(int min,int max)5529 void SalInstanceSpinButton::set_range(int min, int max)
5530 {
5531     m_rFormatter.SetMinValue(toField(min));
5532     m_rFormatter.SetMaxValue(toField(max));
5533 }
5534 
get_range(int & min,int & max) const5535 void SalInstanceSpinButton::get_range(int& min, int& max) const
5536 {
5537     min = fromField(m_rFormatter.GetMinValue());
5538     max = fromField(m_rFormatter.GetMaxValue());
5539 }
5540 
set_increments(int step,int)5541 void SalInstanceSpinButton::set_increments(int step, int /*page*/)
5542 {
5543     m_rFormatter.SetSpinSize(toField(step));
5544 }
5545 
get_increments(int & step,int & page) const5546 void SalInstanceSpinButton::get_increments(int& step, int& page) const
5547 {
5548     step = fromField(m_rFormatter.GetSpinSize());
5549     page = fromField(m_rFormatter.GetSpinSize());
5550 }
5551 
set_digits(unsigned int digits)5552 void SalInstanceSpinButton::set_digits(unsigned int digits)
5553 {
5554     m_rFormatter.SetDecimalDigits(digits);
5555 }
5556 
5557 // SpinButton may be comprised of multiple subwidgets, consider the lot as
5558 // one thing for focus
has_focus() const5559 bool SalInstanceSpinButton::has_focus() const { return m_xWidget->HasChildPathFocus(); }
5560 
5561 //off by default for direct SpinButtons, MetricSpinButton enables it
SetUseThousandSep()5562 void SalInstanceSpinButton::SetUseThousandSep() { m_rFormatter.SetThousandsSep(true); }
5563 
get_digits() const5564 unsigned int SalInstanceSpinButton::get_digits() const { return m_rFormatter.GetDecimalDigits(); }
5565 
~SalInstanceSpinButton()5566 SalInstanceSpinButton::~SalInstanceSpinButton()
5567 {
5568     if (Edit* pEdit = m_xButton->GetSubEdit())
5569         pEdit->SetActivateHdl(Link<Edit&, bool>());
5570     else
5571         m_xButton->SetActivateHdl(Link<Edit&, bool>());
5572     m_rFormatter.SetInputHdl(Link<sal_Int64*, TriState>());
5573     m_rFormatter.SetOutputHdl(Link<LinkParamNone*, bool>());
5574     m_xButton->SetLoseFocusHdl(Link<Control&, void>());
5575     m_xButton->SetDownHdl(Link<SpinField&, void>());
5576     m_xButton->SetUpHdl(Link<SpinField&, void>());
5577 }
5578 
IMPL_LINK_NOARG(SalInstanceSpinButton,ActivateHdl,Edit &,bool)5579 IMPL_LINK_NOARG(SalInstanceSpinButton, ActivateHdl, Edit&, bool)
5580 {
5581     // tdf#122348 return pressed to end dialog
5582     signal_value_changed();
5583     return m_aActivateHdl.Call(*this);
5584 }
5585 
IMPL_LINK_NOARG(SalInstanceSpinButton,UpDownHdl,SpinField &,void)5586 IMPL_LINK_NOARG(SalInstanceSpinButton, UpDownHdl, SpinField&, void) { signal_value_changed(); }
5587 
IMPL_LINK_NOARG(SalInstanceSpinButton,LoseFocusHdl,Control &,void)5588 IMPL_LINK_NOARG(SalInstanceSpinButton, LoseFocusHdl, Control&, void) { signal_value_changed(); }
5589 
IMPL_LINK_NOARG(SalInstanceSpinButton,OutputHdl,LinkParamNone *,bool)5590 IMPL_LINK_NOARG(SalInstanceSpinButton, OutputHdl, LinkParamNone*, bool) { return signal_output(); }
5591 
IMPL_LINK(SalInstanceSpinButton,InputHdl,sal_Int64 *,pResult,TriState)5592 IMPL_LINK(SalInstanceSpinButton, InputHdl, sal_Int64*, pResult, TriState)
5593 {
5594     int nResult;
5595     TriState eRet = signal_input(&nResult);
5596     if (eRet == TRISTATE_TRUE)
5597         *pResult = nResult;
5598     return eRet;
5599 }
5600 
5601 namespace
5602 {
5603 class SalInstanceFormattedSpinButton : public SalInstanceEntry,
5604                                        public virtual weld::FormattedSpinButton
5605 {
5606 private:
5607     VclPtr<FormattedField> m_xButton;
5608     weld::EntryFormatter* m_pFormatter;
5609     Link<weld::Widget&, void> m_aLoseFocusHdl;
5610 
5611     DECL_LINK(UpDownHdl, SpinField&, void);
5612     DECL_LINK(LoseFocusHdl, Control&, void);
5613 
5614 public:
SalInstanceFormattedSpinButton(FormattedField * pButton,SalInstanceBuilder * pBuilder,bool bTakeOwnership)5615     SalInstanceFormattedSpinButton(FormattedField* pButton, SalInstanceBuilder* pBuilder,
5616                                    bool bTakeOwnership)
5617         : SalInstanceEntry(pButton, pBuilder, bTakeOwnership)
5618         , m_xButton(pButton)
5619         , m_pFormatter(nullptr)
5620     {
5621         m_xButton->SetUpHdl(LINK(this, SalInstanceFormattedSpinButton, UpDownHdl));
5622         m_xButton->SetDownHdl(LINK(this, SalInstanceFormattedSpinButton, UpDownHdl));
5623         m_xButton->SetLoseFocusHdl(LINK(this, SalInstanceFormattedSpinButton, LoseFocusHdl));
5624     }
5625 
set_text(const OUString & rText)5626     virtual void set_text(const OUString& rText) override
5627     {
5628         disable_notify_events();
5629         m_xButton->SpinField::SetText(rText);
5630         enable_notify_events();
5631     }
5632 
connect_changed(const Link<weld::Entry &,void> & rLink)5633     virtual void connect_changed(const Link<weld::Entry&, void>& rLink) override
5634     {
5635         if (!m_pFormatter) // once a formatter is set, it takes over "changed"
5636         {
5637             SalInstanceEntry::connect_changed(rLink);
5638             return;
5639         }
5640         m_pFormatter->connect_changed(rLink);
5641     }
5642 
connect_focus_out(const Link<weld::Widget &,void> & rLink)5643     virtual void connect_focus_out(const Link<weld::Widget&, void>& rLink) override
5644     {
5645         if (!m_pFormatter) // once a formatter is set, it takes over "focus-out"
5646         {
5647             m_aLoseFocusHdl = rLink;
5648             return;
5649         }
5650         m_pFormatter->connect_focus_out(rLink);
5651     }
5652 
SetFormatter(weld::EntryFormatter * pFormatter)5653     virtual void SetFormatter(weld::EntryFormatter* pFormatter) override
5654     {
5655         m_pFormatter = pFormatter;
5656         m_xButton->SetFormatter(pFormatter);
5657     }
5658 
sync_value_from_formatter()5659     virtual void sync_value_from_formatter() override
5660     {
5661         // no-op for gen
5662     }
5663 
sync_range_from_formatter()5664     virtual void sync_range_from_formatter() override
5665     {
5666         // no-op for gen
5667     }
5668 
sync_increments_from_formatter()5669     virtual void sync_increments_from_formatter() override
5670     {
5671         // no-op for gen
5672     }
5673 
GetFormatter()5674     virtual Formatter& GetFormatter() override { return m_xButton->GetFormatter(); }
5675 
~SalInstanceFormattedSpinButton()5676     virtual ~SalInstanceFormattedSpinButton() override
5677     {
5678         m_xButton->SetLoseFocusHdl(Link<Control&, void>());
5679         m_xButton->SetDownHdl(Link<SpinField&, void>());
5680         m_xButton->SetUpHdl(Link<SpinField&, void>());
5681     }
5682 };
5683 
IMPL_LINK_NOARG(SalInstanceFormattedSpinButton,UpDownHdl,SpinField &,void)5684 IMPL_LINK_NOARG(SalInstanceFormattedSpinButton, UpDownHdl, SpinField&, void)
5685 {
5686     signal_value_changed();
5687 }
5688 
IMPL_LINK_NOARG(SalInstanceFormattedSpinButton,LoseFocusHdl,Control &,void)5689 IMPL_LINK_NOARG(SalInstanceFormattedSpinButton, LoseFocusHdl, Control&, void)
5690 {
5691     signal_value_changed();
5692     m_aLoseFocusHdl.Call(*this);
5693 }
5694 }
5695 
SalInstanceLabel(Control * pLabel,SalInstanceBuilder * pBuilder,bool bTakeOwnership)5696 SalInstanceLabel::SalInstanceLabel(Control* pLabel, SalInstanceBuilder* pBuilder,
5697                                    bool bTakeOwnership)
5698     : SalInstanceWidget(pLabel, pBuilder, bTakeOwnership)
5699     , m_xLabel(pLabel)
5700 {
5701 }
5702 
set_label(const OUString & rText)5703 void SalInstanceLabel::set_label(const OUString& rText) { m_xLabel->SetText(rText); }
5704 
get_label() const5705 OUString SalInstanceLabel::get_label() const { return m_xLabel->GetText(); }
5706 
set_mnemonic_widget(Widget * pTarget)5707 void SalInstanceLabel::set_mnemonic_widget(Widget* pTarget)
5708 {
5709     FixedText* pLabel = dynamic_cast<FixedText*>(m_xLabel.get());
5710     assert(pLabel && "can't use set_mnemonic_widget on SelectableFixedText");
5711     SalInstanceWidget* pTargetWidget = dynamic_cast<SalInstanceWidget*>(pTarget);
5712     pLabel->set_mnemonic_widget(pTargetWidget ? pTargetWidget->getWidget() : nullptr);
5713 }
5714 
set_label_type(weld::LabelType eType)5715 void SalInstanceLabel::set_label_type(weld::LabelType eType)
5716 {
5717     switch (eType)
5718     {
5719         case weld::LabelType::Normal:
5720             m_xLabel->SetControlForeground();
5721             m_xLabel->SetControlBackground();
5722             break;
5723         case weld::LabelType::Warning:
5724             m_xLabel->SetControlForeground();
5725             m_xLabel->SetControlBackground(COL_YELLOW);
5726             break;
5727         case weld::LabelType::Error:
5728             m_xLabel->SetControlForeground();
5729             m_xLabel->SetControlBackground(
5730                 m_xLabel->GetSettings().GetStyleSettings().GetHighlightColor());
5731             break;
5732         case weld::LabelType::Title:
5733             m_xLabel->SetControlForeground(
5734                 m_xLabel->GetSettings().GetStyleSettings().GetLightColor());
5735             m_xLabel->SetControlBackground();
5736             break;
5737     }
5738 }
5739 
set_font_color(const Color & rColor)5740 void SalInstanceLabel::set_font_color(const Color& rColor)
5741 {
5742     if (rColor != COL_AUTO)
5743         m_xLabel->SetControlForeground(rColor);
5744     else
5745         m_xLabel->SetControlForeground();
5746 }
5747 
set_font(const vcl::Font & rFont)5748 void SalInstanceLabel::set_font(const vcl::Font& rFont)
5749 {
5750     m_xLabel->SetControlFont(rFont);
5751     m_xLabel->Invalidate();
5752 }
5753 
weld_label_widget() const5754 std::unique_ptr<weld::Label> SalInstanceFrame::weld_label_widget() const
5755 {
5756     FixedText* pLabel = dynamic_cast<FixedText*>(m_xFrame->get_label_widget());
5757     if (!pLabel)
5758         return nullptr;
5759     return std::make_unique<SalInstanceLabel>(pLabel, m_pBuilder, false);
5760 }
5761 
SalInstanceTextView(VclMultiLineEdit * pTextView,SalInstanceBuilder * pBuilder,bool bTakeOwnership)5762 SalInstanceTextView::SalInstanceTextView(VclMultiLineEdit* pTextView, SalInstanceBuilder* pBuilder,
5763                                          bool bTakeOwnership)
5764     : SalInstanceWidget(pTextView, pBuilder, bTakeOwnership)
5765     , m_xTextView(pTextView)
5766 {
5767     m_xTextView->SetModifyHdl(LINK(this, SalInstanceTextView, ChangeHdl));
5768     ScrollBar& rVertScrollBar = m_xTextView->GetVScrollBar();
5769     m_aOrigVScrollHdl = rVertScrollBar.GetScrollHdl();
5770     rVertScrollBar.SetScrollHdl(LINK(this, SalInstanceTextView, VscrollHdl));
5771 }
5772 
set_text(const OUString & rText)5773 void SalInstanceTextView::set_text(const OUString& rText)
5774 {
5775     disable_notify_events();
5776     m_xTextView->SetText(rText);
5777     enable_notify_events();
5778 }
5779 
replace_selection(const OUString & rText)5780 void SalInstanceTextView::replace_selection(const OUString& rText)
5781 {
5782     disable_notify_events();
5783     m_xTextView->ReplaceSelected(rText);
5784     enable_notify_events();
5785 }
5786 
get_text() const5787 OUString SalInstanceTextView::get_text() const { return m_xTextView->GetText(); }
5788 
get_selection_bounds(int & rStartPos,int & rEndPos)5789 bool SalInstanceTextView::get_selection_bounds(int& rStartPos, int& rEndPos)
5790 {
5791     const Selection& rSelection = m_xTextView->GetSelection();
5792     rStartPos = rSelection.Min();
5793     rEndPos = rSelection.Max();
5794     return rSelection.Len();
5795 }
5796 
select_region(int nStartPos,int nEndPos)5797 void SalInstanceTextView::select_region(int nStartPos, int nEndPos)
5798 {
5799     disable_notify_events();
5800     tools::Long nStart = nStartPos < 0 ? SELECTION_MAX : nStartPos;
5801     tools::Long nEnd = nEndPos < 0 ? SELECTION_MAX : nEndPos;
5802     m_xTextView->SetSelection(Selection(nStart, nEnd));
5803     enable_notify_events();
5804 }
5805 
set_editable(bool bEditable)5806 void SalInstanceTextView::set_editable(bool bEditable) { m_xTextView->SetReadOnly(!bEditable); }
get_editable() const5807 bool SalInstanceTextView::get_editable() const { return !m_xTextView->IsReadOnly(); }
set_max_length(int nChars)5808 void SalInstanceTextView::set_max_length(int nChars) { m_xTextView->SetMaxTextLen(nChars); }
5809 
set_monospace(bool bMonospace)5810 void SalInstanceTextView::set_monospace(bool bMonospace)
5811 {
5812     vcl::Font aOrigFont = m_xTextView->GetControlFont();
5813     vcl::Font aFont;
5814     if (bMonospace)
5815         aFont
5816             = OutputDevice::GetDefaultFont(DefaultFontType::UI_FIXED, LANGUAGE_DONTKNOW,
5817                                            GetDefaultFontFlags::OnlyOne, m_xTextView->GetOutDev());
5818     else
5819         aFont = Application::GetSettings().GetStyleSettings().GetFieldFont();
5820     aFont.SetFontHeight(aOrigFont.GetFontHeight());
5821     set_font(aFont);
5822 }
5823 
set_font_color(const Color & rColor)5824 void SalInstanceTextView::set_font_color(const Color& rColor)
5825 {
5826     if (rColor != COL_AUTO)
5827         m_xTextView->SetControlForeground(rColor);
5828     else
5829         m_xTextView->SetControlForeground();
5830 }
5831 
set_font(const vcl::Font & rFont)5832 void SalInstanceTextView::set_font(const vcl::Font& rFont)
5833 {
5834     m_xTextView->SetFont(rFont);
5835     m_xTextView->SetControlFont(rFont);
5836     m_xTextView->Invalidate();
5837 }
5838 
connect_cursor_position(const Link<TextView &,void> & rLink)5839 void SalInstanceTextView::connect_cursor_position(const Link<TextView&, void>& rLink)
5840 {
5841     assert(!m_aCursorPositionHdl.IsSet());
5842     m_xTextView->AddEventListener(LINK(this, SalInstanceTextView, CursorListener));
5843     weld::TextView::connect_cursor_position(rLink);
5844 }
5845 
can_move_cursor_with_up() const5846 bool SalInstanceTextView::can_move_cursor_with_up() const
5847 {
5848     bool bNoSelection = !m_xTextView->GetSelection();
5849     return !bNoSelection || m_xTextView->CanUp();
5850 }
5851 
can_move_cursor_with_down() const5852 bool SalInstanceTextView::can_move_cursor_with_down() const
5853 {
5854     bool bNoSelection = !m_xTextView->GetSelection();
5855     return !bNoSelection || m_xTextView->CanDown();
5856 }
5857 
cut_clipboard()5858 void SalInstanceTextView::cut_clipboard() { m_xTextView->Cut(); }
5859 
copy_clipboard()5860 void SalInstanceTextView::copy_clipboard() { m_xTextView->Copy(); }
5861 
paste_clipboard()5862 void SalInstanceTextView::paste_clipboard() { m_xTextView->Paste(); }
5863 
set_alignment(TxtAlign eXAlign)5864 void SalInstanceTextView::set_alignment(TxtAlign eXAlign)
5865 {
5866     ::set_alignment(*m_xTextView, eXAlign);
5867 }
5868 
vadjustment_get_value() const5869 int SalInstanceTextView::vadjustment_get_value() const
5870 {
5871     ScrollBar& rVertScrollBar = m_xTextView->GetVScrollBar();
5872     return rVertScrollBar.GetThumbPos();
5873 }
5874 
vadjustment_set_value(int value)5875 void SalInstanceTextView::vadjustment_set_value(int value)
5876 {
5877     ScrollBar& rVertScrollBar = m_xTextView->GetVScrollBar();
5878     rVertScrollBar.SetThumbPos(value);
5879     m_aOrigVScrollHdl.Call(&rVertScrollBar);
5880 }
5881 
vadjustment_get_upper() const5882 int SalInstanceTextView::vadjustment_get_upper() const
5883 {
5884     ScrollBar& rVertScrollBar = m_xTextView->GetVScrollBar();
5885     return rVertScrollBar.GetRangeMax();
5886 }
5887 
vadjustment_get_lower() const5888 int SalInstanceTextView::vadjustment_get_lower() const
5889 {
5890     ScrollBar& rVertScrollBar = m_xTextView->GetVScrollBar();
5891     return rVertScrollBar.GetRangeMin();
5892 }
5893 
vadjustment_get_page_size() const5894 int SalInstanceTextView::vadjustment_get_page_size() const
5895 {
5896     ScrollBar& rVertScrollBar = m_xTextView->GetVScrollBar();
5897     return rVertScrollBar.GetVisibleSize();
5898 }
5899 
has_focus() const5900 bool SalInstanceTextView::has_focus() const { return m_xTextView->HasChildPathFocus(); }
5901 
~SalInstanceTextView()5902 SalInstanceTextView::~SalInstanceTextView()
5903 {
5904     if (!m_xTextView->isDisposed())
5905     {
5906         if (m_aCursorPositionHdl.IsSet())
5907             m_xTextView->RemoveEventListener(LINK(this, SalInstanceTextView, CursorListener));
5908         m_xTextView->SetModifyHdl(Link<Edit&, void>());
5909         ScrollBar& rVertScrollBar = m_xTextView->GetVScrollBar();
5910         rVertScrollBar.SetScrollHdl(m_aOrigVScrollHdl);
5911     }
5912 }
5913 
IMPL_LINK(SalInstanceTextView,VscrollHdl,ScrollBar *,pScrollBar,void)5914 IMPL_LINK(SalInstanceTextView, VscrollHdl, ScrollBar*, pScrollBar, void)
5915 {
5916     signal_vadjustment_changed();
5917     m_aOrigVScrollHdl.Call(pScrollBar);
5918 }
5919 
IMPL_LINK_NOARG(SalInstanceTextView,ChangeHdl,Edit &,void)5920 IMPL_LINK_NOARG(SalInstanceTextView, ChangeHdl, Edit&, void) { signal_changed(); }
5921 
IMPL_LINK(SalInstanceTextView,CursorListener,VclWindowEvent &,rEvent,void)5922 IMPL_LINK(SalInstanceTextView, CursorListener, VclWindowEvent&, rEvent, void)
5923 {
5924     if (notify_events_disabled())
5925         return;
5926     if (rEvent.GetId() == VclEventId::EditSelectionChanged
5927         || rEvent.GetId() == VclEventId::EditCaretChanged)
5928         signal_cursor_position();
5929 }
5930 
SalInstanceExpander(VclExpander * pExpander,SalInstanceBuilder * pBuilder,bool bTakeOwnership)5931 SalInstanceExpander::SalInstanceExpander(VclExpander* pExpander, SalInstanceBuilder* pBuilder,
5932                                          bool bTakeOwnership)
5933     : SalInstanceWidget(pExpander, pBuilder, bTakeOwnership)
5934     , m_xExpander(pExpander)
5935 {
5936     m_xExpander->SetExpandedHdl(LINK(this, SalInstanceExpander, ExpandedHdl));
5937 }
5938 
set_label(const OUString & rText)5939 void SalInstanceExpander::set_label(const OUString& rText) { m_xExpander->set_label(rText); }
5940 
get_label() const5941 OUString SalInstanceExpander::get_label() const { return m_xExpander->get_label(); }
5942 
get_expanded() const5943 bool SalInstanceExpander::get_expanded() const { return m_xExpander->get_expanded(); }
5944 
set_expanded(bool bExpand)5945 void SalInstanceExpander::set_expanded(bool bExpand) { m_xExpander->set_expanded(bExpand); }
5946 
has_focus() const5947 bool SalInstanceExpander::has_focus() const
5948 {
5949     return m_xExpander->get_label_widget()->HasFocus() || SalInstanceWidget::has_focus();
5950 }
5951 
grab_focus()5952 void SalInstanceExpander::grab_focus() { return m_xExpander->get_label_widget()->GrabFocus(); }
5953 
~SalInstanceExpander()5954 SalInstanceExpander::~SalInstanceExpander()
5955 {
5956     m_xExpander->SetExpandedHdl(Link<VclExpander&, void>());
5957 }
5958 
IMPL_LINK_NOARG(SalInstanceExpander,ExpandedHdl,VclExpander &,void)5959 IMPL_LINK_NOARG(SalInstanceExpander, ExpandedHdl, VclExpander&, void) { signal_expanded(); }
5960 
5961 // SalInstanceWidget has a generic listener for all these
5962 // events, ignore the ones we have specializations for
5963 // in VclDrawingArea
HandleEventListener(VclWindowEvent & rEvent)5964 void SalInstanceDrawingArea::HandleEventListener(VclWindowEvent& rEvent)
5965 {
5966     if (rEvent.GetId() == VclEventId::WindowResize)
5967         return;
5968     SalInstanceWidget::HandleEventListener(rEvent);
5969 }
5970 
HandleMouseEventListener(VclWindowEvent & rEvent)5971 void SalInstanceDrawingArea::HandleMouseEventListener(VclWindowEvent& rEvent)
5972 {
5973     if (rEvent.GetId() == VclEventId::WindowMouseButtonDown
5974         || rEvent.GetId() == VclEventId::WindowMouseButtonUp
5975         || rEvent.GetId() == VclEventId::WindowMouseMove)
5976     {
5977         return;
5978     }
5979     SalInstanceWidget::HandleMouseEventListener(rEvent);
5980 }
5981 
HandleKeyEventListener(VclWindowEvent &)5982 bool SalInstanceDrawingArea::HandleKeyEventListener(VclWindowEvent& /*rEvent*/) { return false; }
5983 
SalInstanceDrawingArea(VclDrawingArea * pDrawingArea,SalInstanceBuilder * pBuilder,const a11yref & rAlly,FactoryFunction pUITestFactoryFunction,void * pUserData,bool bTakeOwnership)5984 SalInstanceDrawingArea::SalInstanceDrawingArea(VclDrawingArea* pDrawingArea,
5985                                                SalInstanceBuilder* pBuilder, const a11yref& rAlly,
5986                                                FactoryFunction pUITestFactoryFunction,
5987                                                void* pUserData, bool bTakeOwnership)
5988     : SalInstanceWidget(pDrawingArea, pBuilder, bTakeOwnership)
5989     , m_xDrawingArea(pDrawingArea)
5990 {
5991     m_xDrawingArea->SetAccessible(rAlly);
5992     m_xDrawingArea->SetUITestFactory(std::move(pUITestFactoryFunction), pUserData);
5993     m_xDrawingArea->SetPaintHdl(LINK(this, SalInstanceDrawingArea, PaintHdl));
5994     m_xDrawingArea->SetResizeHdl(LINK(this, SalInstanceDrawingArea, ResizeHdl));
5995     m_xDrawingArea->SetMousePressHdl(LINK(this, SalInstanceDrawingArea, MousePressHdl));
5996     m_xDrawingArea->SetMouseMoveHdl(LINK(this, SalInstanceDrawingArea, MouseMoveHdl));
5997     m_xDrawingArea->SetMouseReleaseHdl(LINK(this, SalInstanceDrawingArea, MouseReleaseHdl));
5998     m_xDrawingArea->SetKeyPressHdl(LINK(this, SalInstanceDrawingArea, KeyPressHdl));
5999     m_xDrawingArea->SetKeyReleaseHdl(LINK(this, SalInstanceDrawingArea, KeyReleaseHdl));
6000     m_xDrawingArea->SetStyleUpdatedHdl(LINK(this, SalInstanceDrawingArea, StyleUpdatedHdl));
6001     m_xDrawingArea->SetCommandHdl(LINK(this, SalInstanceDrawingArea, CommandHdl));
6002     m_xDrawingArea->SetQueryTooltipHdl(LINK(this, SalInstanceDrawingArea, QueryTooltipHdl));
6003     m_xDrawingArea->SetGetSurroundingHdl(LINK(this, SalInstanceDrawingArea, GetSurroundingHdl));
6004     m_xDrawingArea->SetDeleteSurroundingHdl(
6005         LINK(this, SalInstanceDrawingArea, DeleteSurroundingHdl));
6006     m_xDrawingArea->SetStartDragHdl(LINK(this, SalInstanceDrawingArea, StartDragHdl));
6007 }
6008 
queue_draw()6009 void SalInstanceDrawingArea::queue_draw() { m_xDrawingArea->Invalidate(); }
6010 
queue_draw_area(int x,int y,int width,int height)6011 void SalInstanceDrawingArea::queue_draw_area(int x, int y, int width, int height)
6012 {
6013     m_xDrawingArea->Invalidate(tools::Rectangle(Point(x, y), Size(width, height)));
6014 }
6015 
connect_size_allocate(const Link<const Size &,void> & rLink)6016 void SalInstanceDrawingArea::connect_size_allocate(const Link<const Size&, void>& rLink)
6017 {
6018     weld::Widget::connect_size_allocate(rLink);
6019 }
6020 
connect_key_press(const Link<const KeyEvent &,bool> & rLink)6021 void SalInstanceDrawingArea::connect_key_press(const Link<const KeyEvent&, bool>& rLink)
6022 {
6023     weld::Widget::connect_key_press(rLink);
6024 }
6025 
connect_key_release(const Link<const KeyEvent &,bool> & rLink)6026 void SalInstanceDrawingArea::connect_key_release(const Link<const KeyEvent&, bool>& rLink)
6027 {
6028     weld::Widget::connect_key_release(rLink);
6029 }
6030 
set_cursor(PointerStyle ePointerStyle)6031 void SalInstanceDrawingArea::set_cursor(PointerStyle ePointerStyle)
6032 {
6033     m_xDrawingArea->SetPointer(ePointerStyle);
6034 }
6035 
set_input_context(const InputContext & rInputContext)6036 void SalInstanceDrawingArea::set_input_context(const InputContext& rInputContext)
6037 {
6038     m_xDrawingArea->SetInputContext(rInputContext);
6039 }
6040 
im_context_set_cursor_location(const tools::Rectangle & rCursorRect,int nExtTextInputWidth)6041 void SalInstanceDrawingArea::im_context_set_cursor_location(const tools::Rectangle& rCursorRect,
6042                                                             int nExtTextInputWidth)
6043 {
6044     tools::Rectangle aCursorRect = m_xDrawingArea->PixelToLogic(rCursorRect);
6045     m_xDrawingArea->SetCursorRect(
6046         &aCursorRect, m_xDrawingArea->PixelToLogic(Size(nExtTextInputWidth, 0)).Width());
6047 }
6048 
get_accessible_parent()6049 a11yref SalInstanceDrawingArea::get_accessible_parent()
6050 {
6051     vcl::Window* pParent = m_xDrawingArea->GetParent();
6052     if (pParent)
6053         return pParent->GetAccessible();
6054     return css::uno::Reference<css::accessibility::XAccessible>();
6055 }
6056 
get_accessible_relation_set()6057 a11yrelationset SalInstanceDrawingArea::get_accessible_relation_set()
6058 {
6059     rtl::Reference<utl::AccessibleRelationSetHelper> pRelationSetHelper
6060         = new utl::AccessibleRelationSetHelper;
6061     vcl::Window* pWindow = m_xDrawingArea.get();
6062     if (pWindow)
6063     {
6064         vcl::Window* pLabeledBy = pWindow->GetAccessibleRelationLabeledBy();
6065         if (pLabeledBy && pLabeledBy != pWindow)
6066         {
6067             css::uno::Sequence<css::uno::Reference<css::uno::XInterface>> aSequence{
6068                 pLabeledBy->GetAccessible()
6069             };
6070             pRelationSetHelper->AddRelation(css::accessibility::AccessibleRelation(
6071                 css::accessibility::AccessibleRelationType::LABELED_BY, aSequence));
6072         }
6073         vcl::Window* pMemberOf = pWindow->GetAccessibleRelationMemberOf();
6074         if (pMemberOf && pMemberOf != pWindow)
6075         {
6076             css::uno::Sequence<css::uno::Reference<css::uno::XInterface>> aSequence{
6077                 pMemberOf->GetAccessible()
6078             };
6079             pRelationSetHelper->AddRelation(css::accessibility::AccessibleRelation(
6080                 css::accessibility::AccessibleRelationType::MEMBER_OF, aSequence));
6081         }
6082     }
6083     return pRelationSetHelper;
6084 }
6085 
get_accessible_location_on_screen()6086 Point SalInstanceDrawingArea::get_accessible_location_on_screen()
6087 {
6088     return m_xDrawingArea->OutputToAbsoluteScreenPixel(Point());
6089 }
6090 
get_pointer_position() const6091 Point SalInstanceDrawingArea::get_pointer_position() const
6092 {
6093     return m_xDrawingArea->GetPointerPosPixel();
6094 }
6095 
enable_drag_source(rtl::Reference<TransferDataContainer> & rHelper,sal_uInt8 eDNDConstants)6096 void SalInstanceDrawingArea::enable_drag_source(rtl::Reference<TransferDataContainer>& rHelper,
6097                                                 sal_uInt8 eDNDConstants)
6098 {
6099     m_xDrawingArea->SetDragHelper(rHelper, eDNDConstants);
6100 }
6101 
~SalInstanceDrawingArea()6102 SalInstanceDrawingArea::~SalInstanceDrawingArea()
6103 {
6104     m_xDrawingArea->SetDeleteSurroundingHdl(Link<const Selection&, bool>());
6105     m_xDrawingArea->SetGetSurroundingHdl(Link<OUString&, int>());
6106     m_xDrawingArea->SetQueryTooltipHdl(Link<tools::Rectangle&, OUString>());
6107     m_xDrawingArea->SetCommandHdl(Link<const CommandEvent&, bool>());
6108     m_xDrawingArea->SetStyleUpdatedHdl(Link<VclDrawingArea&, void>());
6109     m_xDrawingArea->SetMousePressHdl(Link<const MouseEvent&, bool>());
6110     m_xDrawingArea->SetMouseMoveHdl(Link<const MouseEvent&, bool>());
6111     m_xDrawingArea->SetMouseReleaseHdl(Link<const MouseEvent&, bool>());
6112     m_xDrawingArea->SetKeyPressHdl(Link<const KeyEvent&, bool>());
6113     m_xDrawingArea->SetKeyReleaseHdl(Link<const KeyEvent&, bool>());
6114     m_xDrawingArea->SetResizeHdl(Link<const Size&, void>());
6115     m_xDrawingArea->SetPaintHdl(
6116         Link<std::pair<vcl::RenderContext&, const tools::Rectangle&>, void>());
6117 }
6118 
get_ref_device()6119 OutputDevice& SalInstanceDrawingArea::get_ref_device() { return *m_xDrawingArea->GetOutDev(); }
6120 
click(const Point & rPos)6121 void SalInstanceDrawingArea::click(const Point& rPos)
6122 {
6123     MouseEvent aEvent(rPos, 1, MouseEventModifiers::NONE, MOUSE_LEFT, 0);
6124     m_xDrawingArea->MouseButtonDown(aEvent);
6125     m_xDrawingArea->MouseButtonUp(aEvent);
6126 }
6127 
IMPL_LINK(SalInstanceDrawingArea,PaintHdl,target_and_area,aPayload,void)6128 IMPL_LINK(SalInstanceDrawingArea, PaintHdl, target_and_area, aPayload, void)
6129 {
6130     m_aDrawHdl.Call(aPayload);
6131     tools::Rectangle aFocusRect(m_aGetFocusRectHdl.Call(*this));
6132     if (!aFocusRect.IsEmpty())
6133         InvertFocusRect(aPayload.first, aFocusRect);
6134 }
6135 
IMPL_LINK(SalInstanceDrawingArea,ResizeHdl,const Size &,rSize,void)6136 IMPL_LINK(SalInstanceDrawingArea, ResizeHdl, const Size&, rSize, void)
6137 {
6138     m_aSizeAllocateHdl.Call(rSize);
6139 }
6140 
IMPL_LINK(SalInstanceDrawingArea,MousePressHdl,const MouseEvent &,rEvent,bool)6141 IMPL_LINK(SalInstanceDrawingArea, MousePressHdl, const MouseEvent&, rEvent, bool)
6142 {
6143     return m_aMousePressHdl.Call(rEvent);
6144 }
6145 
IMPL_LINK(SalInstanceDrawingArea,MouseMoveHdl,const MouseEvent &,rEvent,bool)6146 IMPL_LINK(SalInstanceDrawingArea, MouseMoveHdl, const MouseEvent&, rEvent, bool)
6147 {
6148     return m_aMouseMotionHdl.Call(rEvent);
6149 }
6150 
IMPL_LINK(SalInstanceDrawingArea,MouseReleaseHdl,const MouseEvent &,rEvent,bool)6151 IMPL_LINK(SalInstanceDrawingArea, MouseReleaseHdl, const MouseEvent&, rEvent, bool)
6152 {
6153     return m_aMouseReleaseHdl.Call(rEvent);
6154 }
6155 
IMPL_LINK(SalInstanceDrawingArea,KeyPressHdl,const KeyEvent &,rEvent,bool)6156 IMPL_LINK(SalInstanceDrawingArea, KeyPressHdl, const KeyEvent&, rEvent, bool)
6157 {
6158     return m_aKeyPressHdl.Call(rEvent);
6159 }
6160 
IMPL_LINK(SalInstanceDrawingArea,KeyReleaseHdl,const KeyEvent &,rEvent,bool)6161 IMPL_LINK(SalInstanceDrawingArea, KeyReleaseHdl, const KeyEvent&, rEvent, bool)
6162 {
6163     return m_aKeyReleaseHdl.Call(rEvent);
6164 }
6165 
IMPL_LINK_NOARG(SalInstanceDrawingArea,StyleUpdatedHdl,VclDrawingArea &,void)6166 IMPL_LINK_NOARG(SalInstanceDrawingArea, StyleUpdatedHdl, VclDrawingArea&, void)
6167 {
6168     m_aStyleUpdatedHdl.Call(*this);
6169 }
6170 
IMPL_LINK(SalInstanceDrawingArea,CommandHdl,const CommandEvent &,rEvent,bool)6171 IMPL_LINK(SalInstanceDrawingArea, CommandHdl, const CommandEvent&, rEvent, bool)
6172 {
6173     return m_aCommandHdl.Call(rEvent);
6174 }
6175 
IMPL_LINK(SalInstanceDrawingArea,GetSurroundingHdl,OUString &,rSurrounding,int)6176 IMPL_LINK(SalInstanceDrawingArea, GetSurroundingHdl, OUString&, rSurrounding, int)
6177 {
6178     return m_aGetSurroundingHdl.Call(rSurrounding);
6179 }
6180 
IMPL_LINK(SalInstanceDrawingArea,DeleteSurroundingHdl,const Selection &,rSelection,bool)6181 IMPL_LINK(SalInstanceDrawingArea, DeleteSurroundingHdl, const Selection&, rSelection, bool)
6182 {
6183     return m_aDeleteSurroundingHdl.Call(rSelection);
6184 }
6185 
IMPL_LINK(SalInstanceDrawingArea,QueryTooltipHdl,tools::Rectangle &,rHelpArea,OUString)6186 IMPL_LINK(SalInstanceDrawingArea, QueryTooltipHdl, tools::Rectangle&, rHelpArea, OUString)
6187 {
6188     return m_aQueryTooltipHdl.Call(rHelpArea);
6189 }
6190 
IMPL_LINK_NOARG(SalInstanceDrawingArea,StartDragHdl,VclDrawingArea *,bool)6191 IMPL_LINK_NOARG(SalInstanceDrawingArea, StartDragHdl, VclDrawingArea*, bool)
6192 {
6193     if (m_aDragBeginHdl.Call(*this))
6194         return true;
6195     return false;
6196 }
6197 
SalInstanceComboBoxWithoutEdit(ListBox * pListBox,SalInstanceBuilder * pBuilder,bool bTakeOwnership)6198 SalInstanceComboBoxWithoutEdit::SalInstanceComboBoxWithoutEdit(ListBox* pListBox,
6199                                                                SalInstanceBuilder* pBuilder,
6200                                                                bool bTakeOwnership)
6201     : SalInstanceComboBox<ListBox>(pListBox, pBuilder, bTakeOwnership)
6202 {
6203     m_xComboBox->SetSelectHdl(LINK(this, SalInstanceComboBoxWithoutEdit, SelectHdl));
6204 }
6205 
get_active_text() const6206 OUString SalInstanceComboBoxWithoutEdit::get_active_text() const
6207 {
6208     return m_xComboBox->GetSelectedEntry();
6209 }
6210 
remove(int pos)6211 void SalInstanceComboBoxWithoutEdit::remove(int pos) { m_xComboBox->RemoveEntry(pos); }
6212 
insert(int pos,const OUString & rStr,const OUString * pId,const OUString * pIconName,VirtualDevice * pImageSurface)6213 void SalInstanceComboBoxWithoutEdit::insert(int pos, const OUString& rStr, const OUString* pId,
6214                                             const OUString* pIconName, VirtualDevice* pImageSurface)
6215 {
6216     auto nInsertPos = pos == -1 ? COMBOBOX_APPEND : pos;
6217     sal_Int32 nInsertedAt;
6218     if (!pIconName && !pImageSurface)
6219         nInsertedAt = m_xComboBox->InsertEntry(rStr, nInsertPos);
6220     else if (pIconName)
6221         nInsertedAt = m_xComboBox->InsertEntry(rStr, createImage(*pIconName), nInsertPos);
6222     else
6223         nInsertedAt = m_xComboBox->InsertEntry(rStr, createImage(*pImageSurface), nInsertPos);
6224     if (pId)
6225     {
6226         m_aUserData.emplace_back(std::make_unique<OUString>(*pId));
6227         m_xComboBox->SetEntryData(nInsertedAt, m_aUserData.back().get());
6228     }
6229 }
6230 
insert_separator(int pos,const OUString &)6231 void SalInstanceComboBoxWithoutEdit::insert_separator(int pos, const OUString& /*rId*/)
6232 {
6233     auto nInsertPos = pos == -1 ? m_xComboBox->GetEntryCount() : pos;
6234     m_xComboBox->AddSeparator(nInsertPos - 1);
6235 }
6236 
has_entry() const6237 bool SalInstanceComboBoxWithoutEdit::has_entry() const { return false; }
6238 
changed_by_direct_pick() const6239 bool SalInstanceComboBoxWithoutEdit::changed_by_direct_pick() const { return true; }
6240 
set_entry_message_type(weld::EntryMessageType)6241 void SalInstanceComboBoxWithoutEdit::set_entry_message_type(weld::EntryMessageType /*eType*/)
6242 {
6243     assert(false);
6244 }
6245 
set_entry_text(const OUString &)6246 void SalInstanceComboBoxWithoutEdit::set_entry_text(const OUString& /*rText*/) { assert(false); }
6247 
select_entry_region(int,int)6248 void SalInstanceComboBoxWithoutEdit::select_entry_region(int /*nStartPos*/, int /*nEndPos*/)
6249 {
6250     assert(false);
6251 }
6252 
get_entry_selection_bounds(int &,int &)6253 bool SalInstanceComboBoxWithoutEdit::get_entry_selection_bounds(int& /*rStartPos*/,
6254                                                                 int& /*rEndPos*/)
6255 {
6256     assert(false);
6257     return false;
6258 }
6259 
set_entry_width_chars(int)6260 void SalInstanceComboBoxWithoutEdit::set_entry_width_chars(int /*nChars*/) { assert(false); }
6261 
set_entry_max_length(int)6262 void SalInstanceComboBoxWithoutEdit::set_entry_max_length(int /*nChars*/) { assert(false); }
6263 
set_entry_completion(bool,bool)6264 void SalInstanceComboBoxWithoutEdit::set_entry_completion(bool, bool) { assert(false); }
6265 
set_entry_placeholder_text(const OUString &)6266 void SalInstanceComboBoxWithoutEdit::set_entry_placeholder_text(const OUString&) { assert(false); }
6267 
set_entry_editable(bool)6268 void SalInstanceComboBoxWithoutEdit::set_entry_editable(bool /*bEditable*/) { assert(false); }
6269 
cut_entry_clipboard()6270 void SalInstanceComboBoxWithoutEdit::cut_entry_clipboard() { assert(false); }
6271 
copy_entry_clipboard()6272 void SalInstanceComboBoxWithoutEdit::copy_entry_clipboard() { assert(false); }
6273 
paste_entry_clipboard()6274 void SalInstanceComboBoxWithoutEdit::paste_entry_clipboard() { assert(false); }
6275 
set_font(const vcl::Font & rFont)6276 void SalInstanceComboBoxWithoutEdit::set_font(const vcl::Font& rFont)
6277 {
6278     m_xComboBox->SetControlFont(rFont);
6279     m_xComboBox->Invalidate();
6280 }
6281 
set_entry_font(const vcl::Font &)6282 void SalInstanceComboBoxWithoutEdit::set_entry_font(const vcl::Font&) { assert(false); }
6283 
get_entry_font()6284 vcl::Font SalInstanceComboBoxWithoutEdit::get_entry_font()
6285 {
6286     assert(false);
6287     return vcl::Font();
6288 }
6289 
set_custom_renderer(bool)6290 void SalInstanceComboBoxWithoutEdit::set_custom_renderer(bool /*bOn*/)
6291 {
6292     assert(false && "not implemented");
6293 }
6294 
get_max_mru_count() const6295 int SalInstanceComboBoxWithoutEdit::get_max_mru_count() const
6296 {
6297     assert(false && "not implemented");
6298     return 0;
6299 }
6300 
set_max_mru_count(int)6301 void SalInstanceComboBoxWithoutEdit::set_max_mru_count(int) { assert(false && "not implemented"); }
6302 
get_mru_entries() const6303 OUString SalInstanceComboBoxWithoutEdit::get_mru_entries() const
6304 {
6305     assert(false && "not implemented");
6306     return OUString();
6307 }
6308 
set_mru_entries(const OUString &)6309 void SalInstanceComboBoxWithoutEdit::set_mru_entries(const OUString&)
6310 {
6311     assert(false && "not implemented");
6312 }
6313 
HandleEventListener(VclWindowEvent & rEvent)6314 void SalInstanceComboBoxWithoutEdit::HandleEventListener(VclWindowEvent& rEvent)
6315 {
6316     CallHandleEventListener(rEvent);
6317 }
6318 
~SalInstanceComboBoxWithoutEdit()6319 SalInstanceComboBoxWithoutEdit::~SalInstanceComboBoxWithoutEdit()
6320 {
6321     m_xComboBox->SetSelectHdl(Link<ListBox&, void>());
6322 }
6323 
IMPL_LINK_NOARG(SalInstanceComboBoxWithoutEdit,SelectHdl,ListBox &,void)6324 IMPL_LINK_NOARG(SalInstanceComboBoxWithoutEdit, SelectHdl, ListBox&, void)
6325 {
6326     return signal_changed();
6327 }
6328 
SalInstanceComboBoxWithEdit(::ComboBox * pComboBox,SalInstanceBuilder * pBuilder,bool bTakeOwnership)6329 SalInstanceComboBoxWithEdit::SalInstanceComboBoxWithEdit(::ComboBox* pComboBox,
6330                                                          SalInstanceBuilder* pBuilder,
6331                                                          bool bTakeOwnership)
6332     : SalInstanceComboBox<::ComboBox>(pComboBox, pBuilder, bTakeOwnership)
6333     , m_aTextFilter(m_aEntryInsertTextHdl)
6334     , m_bInSelect(false)
6335 {
6336     m_xComboBox->SetModifyHdl(LINK(this, SalInstanceComboBoxWithEdit, ChangeHdl));
6337     m_xComboBox->SetSelectHdl(LINK(this, SalInstanceComboBoxWithEdit, SelectHdl));
6338     m_xComboBox->SetEntryActivateHdl(LINK(this, SalInstanceComboBoxWithEdit, EntryActivateHdl));
6339     m_xComboBox->SetTextFilter(&m_aTextFilter);
6340 }
6341 
has_entry() const6342 bool SalInstanceComboBoxWithEdit::has_entry() const { return true; }
6343 
changed_by_direct_pick() const6344 bool SalInstanceComboBoxWithEdit::changed_by_direct_pick() const
6345 {
6346     return m_bInSelect && !m_xComboBox->IsModifyByKeyboard() && !m_xComboBox->IsTravelSelect();
6347 }
6348 
set_entry_message_type(weld::EntryMessageType eType)6349 void SalInstanceComboBoxWithEdit::set_entry_message_type(weld::EntryMessageType eType)
6350 {
6351     switch (eType)
6352     {
6353         case weld::EntryMessageType::Normal:
6354             m_xComboBox->SetControlForeground();
6355             break;
6356         case weld::EntryMessageType::Warning:
6357             m_xComboBox->SetControlForeground(COL_YELLOW);
6358             break;
6359         case weld::EntryMessageType::Error:
6360             m_xComboBox->SetControlForeground(Color(0xf0, 0, 0));
6361             break;
6362     }
6363 }
6364 
get_active_text() const6365 OUString SalInstanceComboBoxWithEdit::get_active_text() const { return m_xComboBox->GetText(); }
6366 
remove(int pos)6367 void SalInstanceComboBoxWithEdit::remove(int pos) { m_xComboBox->RemoveEntryAt(pos); }
6368 
insert(int pos,const OUString & rStr,const OUString * pId,const OUString * pIconName,VirtualDevice * pImageSurface)6369 void SalInstanceComboBoxWithEdit::insert(int pos, const OUString& rStr, const OUString* pId,
6370                                          const OUString* pIconName, VirtualDevice* pImageSurface)
6371 {
6372     auto nInsertPos = pos == -1 ? COMBOBOX_APPEND : pos;
6373     sal_Int32 nInsertedAt;
6374     if (!pIconName && !pImageSurface)
6375         nInsertedAt = m_xComboBox->InsertEntry(rStr, nInsertPos);
6376     else if (pIconName)
6377         nInsertedAt = m_xComboBox->InsertEntryWithImage(rStr, createImage(*pIconName), nInsertPos);
6378     else
6379         nInsertedAt
6380             = m_xComboBox->InsertEntryWithImage(rStr, createImage(*pImageSurface), nInsertPos);
6381     if (pId)
6382     {
6383         m_aUserData.emplace_back(std::make_unique<OUString>(*pId));
6384         m_xComboBox->SetEntryData(nInsertedAt, m_aUserData.back().get());
6385     }
6386 }
6387 
insert_separator(int pos,const OUString &)6388 void SalInstanceComboBoxWithEdit::insert_separator(int pos, const OUString& /*rId*/)
6389 {
6390     auto nInsertPos = pos == -1 ? m_xComboBox->GetEntryCount() : pos;
6391     m_xComboBox->AddSeparator(nInsertPos - 1);
6392 }
6393 
set_entry_text(const OUString & rText)6394 void SalInstanceComboBoxWithEdit::set_entry_text(const OUString& rText)
6395 {
6396     m_xComboBox->SetText(rText);
6397 }
6398 
set_entry_width_chars(int nChars)6399 void SalInstanceComboBoxWithEdit::set_entry_width_chars(int nChars)
6400 {
6401     m_xComboBox->SetWidthInChars(nChars);
6402 }
6403 
set_entry_max_length(int nChars)6404 void SalInstanceComboBoxWithEdit::set_entry_max_length(int nChars)
6405 {
6406     m_xComboBox->SetMaxTextLen(nChars);
6407 }
6408 
set_entry_completion(bool bEnable,bool bCaseSensitive)6409 void SalInstanceComboBoxWithEdit::set_entry_completion(bool bEnable, bool bCaseSensitive)
6410 {
6411     m_xComboBox->EnableAutocomplete(bEnable, bCaseSensitive);
6412 }
6413 
set_entry_placeholder_text(const OUString & rText)6414 void SalInstanceComboBoxWithEdit::set_entry_placeholder_text(const OUString& rText)
6415 {
6416     m_xComboBox->SetPlaceholderText(rText);
6417 }
6418 
set_entry_editable(bool bEditable)6419 void SalInstanceComboBoxWithEdit::set_entry_editable(bool bEditable)
6420 {
6421     m_xComboBox->SetReadOnly(!bEditable);
6422 }
6423 
cut_entry_clipboard()6424 void SalInstanceComboBoxWithEdit::cut_entry_clipboard() { m_xComboBox->Cut(); }
6425 
copy_entry_clipboard()6426 void SalInstanceComboBoxWithEdit::copy_entry_clipboard() { m_xComboBox->Copy(); }
6427 
paste_entry_clipboard()6428 void SalInstanceComboBoxWithEdit::paste_entry_clipboard() { m_xComboBox->Paste(); }
6429 
select_entry_region(int nStartPos,int nEndPos)6430 void SalInstanceComboBoxWithEdit::select_entry_region(int nStartPos, int nEndPos)
6431 {
6432     m_xComboBox->SetSelection(Selection(nStartPos, nEndPos < 0 ? SELECTION_MAX : nEndPos));
6433 }
6434 
get_entry_selection_bounds(int & rStartPos,int & rEndPos)6435 bool SalInstanceComboBoxWithEdit::get_entry_selection_bounds(int& rStartPos, int& rEndPos)
6436 {
6437     const Selection& rSelection = m_xComboBox->GetSelection();
6438     rStartPos = rSelection.Min();
6439     rEndPos = rSelection.Max();
6440     return rSelection.Len();
6441 }
6442 
set_font(const vcl::Font & rFont)6443 void SalInstanceComboBoxWithEdit::set_font(const vcl::Font& rFont)
6444 {
6445     m_xComboBox->SetControlFont(rFont);
6446     m_xComboBox->Invalidate();
6447 }
6448 
set_entry_font(const vcl::Font & rFont)6449 void SalInstanceComboBoxWithEdit::set_entry_font(const vcl::Font& rFont)
6450 {
6451     Edit* pEdit = m_xComboBox->GetSubEdit();
6452     assert(pEdit);
6453     pEdit->SetControlFont(rFont); // tdf#134601 set it as control font to take effect properly
6454     pEdit->Invalidate();
6455 }
6456 
get_entry_font()6457 vcl::Font SalInstanceComboBoxWithEdit::get_entry_font()
6458 {
6459     Edit* pEdit = m_xComboBox->GetSubEdit();
6460     assert(pEdit);
6461     return pEdit->GetPointFont(*pEdit->GetOutDev());
6462 }
6463 
set_custom_renderer(bool bOn)6464 void SalInstanceComboBoxWithEdit::set_custom_renderer(bool bOn)
6465 {
6466     if (m_xComboBox->IsUserDrawEnabled() == bOn)
6467         return;
6468 
6469     auto nOldEntryHeight = m_xComboBox->GetDropDownEntryHeight();
6470     auto nDropDownLineCount = m_xComboBox->GetDropDownLineCount();
6471 
6472     m_xComboBox->EnableUserDraw(bOn);
6473     if (bOn)
6474         m_xComboBox->SetUserDrawHdl(LINK(this, SalInstanceComboBoxWithEdit, UserDrawHdl));
6475     else
6476         m_xComboBox->SetUserDrawHdl(Link<UserDrawEvent*, void>());
6477 
6478     // adjust the line count to fit approx the height it would have been before
6479     // changing the renderer
6480     auto nNewEntryHeight = m_xComboBox->GetDropDownEntryHeight();
6481     double fRatio = nOldEntryHeight / static_cast<double>(nNewEntryHeight);
6482     m_xComboBox->SetDropDownLineCount(nDropDownLineCount * fRatio);
6483 }
6484 
get_max_mru_count() const6485 int SalInstanceComboBoxWithEdit::get_max_mru_count() const { return m_xComboBox->GetMaxMRUCount(); }
6486 
set_max_mru_count(int nCount)6487 void SalInstanceComboBoxWithEdit::set_max_mru_count(int nCount)
6488 {
6489     return m_xComboBox->SetMaxMRUCount(nCount);
6490 }
6491 
get_mru_entries() const6492 OUString SalInstanceComboBoxWithEdit::get_mru_entries() const
6493 {
6494     return m_xComboBox->GetMRUEntries();
6495 }
6496 
set_mru_entries(const OUString & rEntries)6497 void SalInstanceComboBoxWithEdit::set_mru_entries(const OUString& rEntries)
6498 {
6499     m_xComboBox->SetMRUEntries(rEntries);
6500 }
6501 
HandleEventListener(VclWindowEvent & rEvent)6502 void SalInstanceComboBoxWithEdit::HandleEventListener(VclWindowEvent& rEvent)
6503 {
6504     if (rEvent.GetId() == VclEventId::DropdownPreOpen)
6505     {
6506         Size aRowSize(signal_custom_get_size(*m_xComboBox->GetOutDev()));
6507         m_xComboBox->SetUserItemSize(aRowSize);
6508     }
6509     CallHandleEventListener(rEvent);
6510 }
6511 
~SalInstanceComboBoxWithEdit()6512 SalInstanceComboBoxWithEdit::~SalInstanceComboBoxWithEdit()
6513 {
6514     m_xComboBox->SetTextFilter(nullptr);
6515     m_xComboBox->SetEntryActivateHdl(Link<Edit&, bool>());
6516     m_xComboBox->SetModifyHdl(Link<Edit&, void>());
6517     m_xComboBox->SetSelectHdl(Link<::ComboBox&, void>());
6518 }
6519 
IMPL_LINK_NOARG(SalInstanceComboBoxWithEdit,ChangeHdl,Edit &,void)6520 IMPL_LINK_NOARG(SalInstanceComboBoxWithEdit, ChangeHdl, Edit&, void)
6521 {
6522     if (!m_xComboBox->IsSyntheticModify()) // SelectHdl will be called
6523         signal_changed();
6524 }
6525 
IMPL_LINK_NOARG(SalInstanceComboBoxWithEdit,SelectHdl,::ComboBox &,void)6526 IMPL_LINK_NOARG(SalInstanceComboBoxWithEdit, SelectHdl, ::ComboBox&, void)
6527 {
6528     m_bInSelect = true;
6529     signal_changed();
6530     m_bInSelect = false;
6531 }
6532 
IMPL_LINK_NOARG(SalInstanceComboBoxWithEdit,EntryActivateHdl,Edit &,bool)6533 IMPL_LINK_NOARG(SalInstanceComboBoxWithEdit, EntryActivateHdl, Edit&, bool)
6534 {
6535     return m_aEntryActivateHdl.Call(*this);
6536 }
6537 
IMPL_LINK(SalInstanceComboBoxWithEdit,UserDrawHdl,UserDrawEvent *,pEvent,void)6538 IMPL_LINK(SalInstanceComboBoxWithEdit, UserDrawHdl, UserDrawEvent*, pEvent, void)
6539 {
6540     call_signal_custom_render(pEvent);
6541 }
6542 
6543 class SalInstanceEntryTreeView : public SalInstanceContainer, public virtual weld::EntryTreeView
6544 {
6545 private:
6546     DECL_LINK(AutocompleteHdl, Edit&, void);
6547     DECL_LINK(KeyPressListener, VclWindowEvent&, void);
6548     SalInstanceEntry* m_pEntry;
6549     SalInstanceTreeView* m_pTreeView;
6550     bool m_bTreeChange;
6551 
6552 public:
SalInstanceEntryTreeView(vcl::Window * pContainer,SalInstanceBuilder * pBuilder,bool bTakeOwnership,std::unique_ptr<weld::Entry> xEntry,std::unique_ptr<weld::TreeView> xTreeView)6553     SalInstanceEntryTreeView(vcl::Window* pContainer, SalInstanceBuilder* pBuilder,
6554                              bool bTakeOwnership, std::unique_ptr<weld::Entry> xEntry,
6555                              std::unique_ptr<weld::TreeView> xTreeView)
6556         : EntryTreeView(std::move(xEntry), std::move(xTreeView))
6557         , SalInstanceContainer(pContainer, pBuilder, bTakeOwnership)
6558         , m_pEntry(dynamic_cast<SalInstanceEntry*>(m_xEntry.get()))
6559         , m_pTreeView(dynamic_cast<SalInstanceTreeView*>(m_xTreeView.get()))
6560         , m_bTreeChange(false)
6561     {
6562         assert(m_pEntry && m_pTreeView);
6563 
6564         Edit& rEntry = m_pEntry->getEntry();
6565         rEntry.SetAutocompleteHdl(LINK(this, SalInstanceEntryTreeView, AutocompleteHdl));
6566         rEntry.AddEventListener(LINK(this, SalInstanceEntryTreeView, KeyPressListener));
6567     }
6568 
insert_separator(int,const OUString &)6569     virtual void insert_separator(int /*pos*/, const OUString& /*rId*/) override { assert(false); }
6570 
make_sorted()6571     virtual void make_sorted() override
6572     {
6573         vcl::Window* pTreeView = m_pTreeView->getWidget();
6574         pTreeView->SetStyle(pTreeView->GetStyle() | WB_SORT);
6575     }
6576 
set_entry_completion(bool bEnable,bool)6577     virtual void set_entry_completion(bool bEnable, bool /*bCaseSensitive*/) override
6578     {
6579         assert(!bEnable && "not implemented yet");
6580         (void)bEnable;
6581         Edit& rEntry = m_pEntry->getEntry();
6582         rEntry.SetAutocompleteHdl(Link<Edit&, void>());
6583     }
6584 
set_font(const vcl::Font &)6585     virtual void set_font(const vcl::Font&) override { assert(false && "not implemented"); }
6586 
set_entry_font(const vcl::Font & rFont)6587     virtual void set_entry_font(const vcl::Font& rFont) override
6588     {
6589         Edit& rEntry = m_pEntry->getEntry();
6590         rEntry.SetPointFont(*rEntry.GetOutDev(), rFont);
6591         rEntry.SetControlFont(rFont);
6592         rEntry.Invalidate();
6593     }
6594 
get_entry_font()6595     virtual vcl::Font get_entry_font() override
6596     {
6597         Edit& rEntry = m_pEntry->getEntry();
6598         return rEntry.GetPointFont(*rEntry.GetOutDev());
6599     }
6600 
set_entry_placeholder_text(const OUString & rText)6601     virtual void set_entry_placeholder_text(const OUString& rText) override
6602     {
6603         Edit& rEntry = m_pEntry->getEntry();
6604         rEntry.SetPlaceholderText(rText);
6605     }
6606 
set_entry_editable(bool bEditable)6607     virtual void set_entry_editable(bool bEditable) override
6608     {
6609         Edit& rEntry = m_pEntry->getEntry();
6610         rEntry.SetReadOnly(!bEditable);
6611     }
6612 
cut_entry_clipboard()6613     virtual void cut_entry_clipboard() override
6614     {
6615         Edit& rEntry = m_pEntry->getEntry();
6616         rEntry.Cut();
6617     }
6618 
copy_entry_clipboard()6619     virtual void copy_entry_clipboard() override
6620     {
6621         Edit& rEntry = m_pEntry->getEntry();
6622         rEntry.Copy();
6623     }
6624 
paste_entry_clipboard()6625     virtual void paste_entry_clipboard() override
6626     {
6627         Edit& rEntry = m_pEntry->getEntry();
6628         rEntry.Paste();
6629     }
6630 
grab_focus()6631     virtual void grab_focus() override { m_xEntry->grab_focus(); }
6632 
connect_focus_in(const Link<Widget &,void> & rLink)6633     virtual void connect_focus_in(const Link<Widget&, void>& rLink) override
6634     {
6635         m_xEntry->connect_focus_in(rLink);
6636     }
6637 
connect_focus_out(const Link<Widget &,void> & rLink)6638     virtual void connect_focus_out(const Link<Widget&, void>& rLink) override
6639     {
6640         m_xEntry->connect_focus_out(rLink);
6641     }
6642 
changed_by_direct_pick() const6643     virtual bool changed_by_direct_pick() const override { return m_bTreeChange; }
6644 
set_custom_renderer(bool)6645     virtual void set_custom_renderer(bool /*bOn*/) override { assert(false && "not implemented"); }
6646 
get_max_mru_count() const6647     virtual int get_max_mru_count() const override
6648     {
6649         assert(false && "not implemented");
6650         return 0;
6651     }
6652 
set_max_mru_count(int)6653     virtual void set_max_mru_count(int) override { assert(false && "not implemented"); }
6654 
get_mru_entries() const6655     virtual OUString get_mru_entries() const override
6656     {
6657         assert(false && "not implemented");
6658         return OUString();
6659     }
6660 
set_mru_entries(const OUString &)6661     virtual void set_mru_entries(const OUString&) override { assert(false && "not implemented"); }
6662 
set_item_menu(const OString &,weld::Menu *)6663     virtual void set_item_menu(const OString&, weld::Menu*) override
6664     {
6665         assert(false && "not implemented");
6666     }
6667 
get_menu_button_width() const6668     int get_menu_button_width() const override
6669     {
6670         assert(false && "not implemented");
6671         return 0;
6672     }
6673 
create_render_virtual_device() const6674     VclPtr<VirtualDevice> create_render_virtual_device() const override
6675     {
6676         return VclPtr<VirtualDevice>::Create();
6677     }
6678 
~SalInstanceEntryTreeView()6679     virtual ~SalInstanceEntryTreeView() override
6680     {
6681         Edit& rEntry = m_pEntry->getEntry();
6682         rEntry.RemoveEventListener(LINK(this, SalInstanceEntryTreeView, KeyPressListener));
6683         rEntry.SetAutocompleteHdl(Link<Edit&, void>());
6684     }
6685 };
6686 
IMPL_LINK(SalInstanceEntryTreeView,KeyPressListener,VclWindowEvent &,rEvent,void)6687 IMPL_LINK(SalInstanceEntryTreeView, KeyPressListener, VclWindowEvent&, rEvent, void)
6688 {
6689     if (rEvent.GetId() != VclEventId::WindowKeyInput)
6690         return;
6691     const KeyEvent& rKeyEvent = *static_cast<KeyEvent*>(rEvent.GetData());
6692     sal_uInt16 nKeyCode = rKeyEvent.GetKeyCode().GetCode();
6693     if (!(nKeyCode == KEY_UP || nKeyCode == KEY_DOWN || nKeyCode == KEY_PAGEUP
6694           || nKeyCode == KEY_PAGEDOWN))
6695         return;
6696 
6697     m_pTreeView->disable_notify_events();
6698     auto& rListBox = m_pTreeView->getTreeView();
6699     if (!rListBox.FirstSelected())
6700     {
6701         if (SvTreeListEntry* pEntry = rListBox.First())
6702             rListBox.Select(pEntry, true);
6703     }
6704     else
6705         rListBox.KeyInput(rKeyEvent);
6706     m_xEntry->set_text(m_xTreeView->get_selected_text());
6707     m_xEntry->select_region(0, -1);
6708     m_pTreeView->enable_notify_events();
6709     m_bTreeChange = true;
6710     m_pEntry->fire_signal_changed();
6711     m_bTreeChange = false;
6712 }
6713 
IMPL_LINK(SalInstanceEntryTreeView,AutocompleteHdl,Edit &,rEdit,void)6714 IMPL_LINK(SalInstanceEntryTreeView, AutocompleteHdl, Edit&, rEdit, void)
6715 {
6716     Selection aSel = rEdit.GetSelection();
6717 
6718     OUString aFullText = rEdit.GetText();
6719     OUString aStartText = aFullText.copy(0, static_cast<sal_Int32>(aSel.Max()));
6720 
6721     int nPos = -1;
6722     int nCount = m_xTreeView->n_children();
6723     for (int i = 0; i < nCount; ++i)
6724     {
6725         if (m_xTreeView->get_text(i).startsWithIgnoreAsciiCase(aStartText))
6726         {
6727             nPos = i;
6728             break;
6729         }
6730     }
6731 
6732     m_xTreeView->select(nPos);
6733 
6734     if (nPos != -1)
6735     {
6736         OUString aText = m_xTreeView->get_text(nPos);
6737         Selection aSelection(aText.getLength(), aStartText.getLength());
6738         rEdit.SetText(aText, aSelection);
6739     }
6740 }
6741 
6742 namespace
6743 {
6744 class SalInstancePopover : public SalInstanceContainer, public virtual weld::Popover
6745 {
6746 private:
6747     VclPtr<DockingWindow> m_xPopover;
6748 
6749     DECL_LINK(PopupModeEndHdl, FloatingWindow*, void);
6750 
6751 public:
SalInstancePopover(DockingWindow * pPopover,SalInstanceBuilder * pBuilder,bool bTakeOwnership)6752     SalInstancePopover(DockingWindow* pPopover, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
6753         : SalInstanceContainer(pPopover, pBuilder, bTakeOwnership)
6754         , m_xPopover(pPopover)
6755     {
6756     }
6757 
~SalInstancePopover()6758     ~SalInstancePopover() { signal_closed(); }
6759 
popup_at_rect(weld::Widget * pParent,const tools::Rectangle & rRect)6760     virtual void popup_at_rect(weld::Widget* pParent, const tools::Rectangle& rRect) override
6761     {
6762         SalInstanceWidget* pVclWidget = dynamic_cast<SalInstanceWidget*>(pParent);
6763         assert(pVclWidget);
6764         vcl::Window* pWidget = pVclWidget->getWidget();
6765 
6766         tools::Rectangle aRect;
6767         Point aPt = pWidget->OutputToScreenPixel(rRect.TopLeft());
6768         aRect.SetLeft(aPt.X());
6769         aRect.SetTop(aPt.Y());
6770         aPt = pWidget->OutputToScreenPixel(rRect.BottomRight());
6771         aRect.SetRight(aPt.X());
6772         aRect.SetBottom(aPt.Y());
6773 
6774         FloatWinPopupFlags nFlags = FloatWinPopupFlags::Down | FloatWinPopupFlags::GrabFocus
6775                                     | FloatWinPopupFlags::NoMouseUpClose;
6776         m_xPopover->EnableDocking();
6777         DockingManager* pDockingManager = vcl::Window::GetDockingManager();
6778         pDockingManager->SetPopupModeEndHdl(m_xPopover,
6779                                             LINK(this, SalInstancePopover, PopupModeEndHdl));
6780         pDockingManager->StartPopupMode(m_xPopover, aRect, nFlags);
6781     }
6782 
popdown()6783     virtual void popdown() override
6784     {
6785         vcl::Window::GetDockingManager()->EndPopupMode(m_xPopover);
6786         m_xPopover->EnableDocking(false);
6787         signal_closed();
6788     }
6789 };
6790 }
6791 
IMPL_LINK_NOARG(SalInstancePopover,PopupModeEndHdl,FloatingWindow *,void)6792 IMPL_LINK_NOARG(SalInstancePopover, PopupModeEndHdl, FloatingWindow*, void) { signal_closed(); }
6793 
SalInstanceBuilder(vcl::Window * pParent,const OUString & rUIRoot,const OUString & rUIFile,const css::uno::Reference<css::frame::XFrame> & rFrame)6794 SalInstanceBuilder::SalInstanceBuilder(vcl::Window* pParent, const OUString& rUIRoot,
6795                                        const OUString& rUIFile,
6796                                        const css::uno::Reference<css::frame::XFrame>& rFrame)
6797     : weld::Builder()
6798     , m_xBuilder(new VclBuilder(pParent, rUIRoot, rUIFile, OString(), rFrame, false))
6799 {
6800 }
6801 
weld_message_dialog(const OString & id)6802 std::unique_ptr<weld::MessageDialog> SalInstanceBuilder::weld_message_dialog(const OString& id)
6803 {
6804     MessageDialog* pMessageDialog = m_xBuilder->get<MessageDialog>(id);
6805     std::unique_ptr<weld::MessageDialog> pRet(
6806         pMessageDialog ? new SalInstanceMessageDialog(pMessageDialog, this, false) : nullptr);
6807     if (pMessageDialog)
6808     {
6809         assert(!m_aOwnedToplevel && "only one toplevel per .ui allowed");
6810         m_aOwnedToplevel.set(pMessageDialog);
6811         m_xBuilder->drop_ownership(pMessageDialog);
6812     }
6813     return pRet;
6814 }
6815 
weld_dialog(const OString & id)6816 std::unique_ptr<weld::Dialog> SalInstanceBuilder::weld_dialog(const OString& id)
6817 {
6818     Dialog* pDialog = m_xBuilder->get<Dialog>(id);
6819     std::unique_ptr<weld::Dialog> pRet(pDialog ? new SalInstanceDialog(pDialog, this, false)
6820                                                : nullptr);
6821     if (pDialog)
6822     {
6823         assert(!m_aOwnedToplevel && "only one toplevel per .ui allowed");
6824         m_aOwnedToplevel.set(pDialog);
6825         m_xBuilder->drop_ownership(pDialog);
6826     }
6827     return pRet;
6828 }
6829 
weld_assistant(const OString & id)6830 std::unique_ptr<weld::Assistant> SalInstanceBuilder::weld_assistant(const OString& id)
6831 {
6832     vcl::RoadmapWizard* pDialog = m_xBuilder->get<vcl::RoadmapWizard>(id);
6833     std::unique_ptr<weld::Assistant> pRet(pDialog ? new SalInstanceAssistant(pDialog, this, false)
6834                                                   : nullptr);
6835     if (pDialog)
6836     {
6837         assert(!m_aOwnedToplevel && "only one toplevel per .ui allowed");
6838         m_aOwnedToplevel.set(pDialog);
6839         m_xBuilder->drop_ownership(pDialog);
6840     }
6841     return pRet;
6842 }
6843 
create_screenshot_window()6844 std::unique_ptr<weld::Window> SalInstanceBuilder::create_screenshot_window()
6845 {
6846     assert(!m_aOwnedToplevel && "only one toplevel per .ui allowed");
6847 
6848     vcl::Window* pRoot = m_xBuilder->get_widget_root();
6849     if (SystemWindow* pWindow = dynamic_cast<SystemWindow*>(pRoot))
6850     {
6851         std::unique_ptr<weld::Window> xRet(new SalInstanceWindow(pWindow, this, false));
6852         m_aOwnedToplevel.set(pWindow);
6853         m_xBuilder->drop_ownership(pWindow);
6854         return xRet;
6855     }
6856 
6857     VclPtrInstance<Dialog> xDialog(nullptr, WB_HIDE | WB_STDDIALOG | WB_SIZEABLE | WB_CLOSEABLE,
6858                                    Dialog::InitFlag::NoParent);
6859     xDialog->SetText(utl::ConfigManager::getProductName());
6860 
6861     auto xContentArea = VclPtr<VclVBox>::Create(xDialog, false, 12);
6862     pRoot->SetParent(xContentArea);
6863     assert(pRoot == xContentArea->GetWindow(GetWindowType::FirstChild));
6864     xContentArea->Show();
6865     pRoot->Show();
6866     xDialog->SetHelpId(pRoot->GetHelpId());
6867 
6868     m_aOwnedToplevel.set(xDialog);
6869 
6870     return std::unique_ptr<weld::Dialog>(new SalInstanceDialog(xDialog, this, false));
6871 }
6872 
weld_widget(const OString & id)6873 std::unique_ptr<weld::Widget> SalInstanceBuilder::weld_widget(const OString& id)
6874 {
6875     vcl::Window* pWidget = m_xBuilder->get(id);
6876     return pWidget ? std::make_unique<SalInstanceWidget>(pWidget, this, false) : nullptr;
6877 }
6878 
weld_container(const OString & id)6879 std::unique_ptr<weld::Container> SalInstanceBuilder::weld_container(const OString& id)
6880 {
6881     vcl::Window* pContainer = m_xBuilder->get(id);
6882     return pContainer ? std::make_unique<SalInstanceContainer>(pContainer, this, false) : nullptr;
6883 }
6884 
weld_box(const OString & id)6885 std::unique_ptr<weld::Box> SalInstanceBuilder::weld_box(const OString& id)
6886 {
6887     VclBox* pContainer = m_xBuilder->get<VclBox>(id);
6888     return pContainer ? std::make_unique<SalInstanceBox>(pContainer, this, false) : nullptr;
6889 }
6890 
weld_paned(const OString & id)6891 std::unique_ptr<weld::Paned> SalInstanceBuilder::weld_paned(const OString& id)
6892 {
6893     VclPaned* pPaned = m_xBuilder->get<VclPaned>(id);
6894     return pPaned ? std::make_unique<SalInstancePaned>(pPaned, this, false) : nullptr;
6895 }
6896 
weld_frame(const OString & id)6897 std::unique_ptr<weld::Frame> SalInstanceBuilder::weld_frame(const OString& id)
6898 {
6899     VclFrame* pFrame = m_xBuilder->get<VclFrame>(id);
6900     std::unique_ptr<weld::Frame> pRet(pFrame ? new SalInstanceFrame(pFrame, this, false) : nullptr);
6901     return pRet;
6902 }
6903 
6904 std::unique_ptr<weld::ScrolledWindow>
weld_scrolled_window(const OString & id,bool bUserManagedScrolling)6905 SalInstanceBuilder::weld_scrolled_window(const OString& id, bool bUserManagedScrolling)
6906 {
6907     VclScrolledWindow* pScrolledWindow = m_xBuilder->get<VclScrolledWindow>(id);
6908     return pScrolledWindow ? std::make_unique<SalInstanceScrolledWindow>(
6909                                  pScrolledWindow, this, false, bUserManagedScrolling)
6910                            : nullptr;
6911 }
6912 
weld_notebook(const OString & id)6913 std::unique_ptr<weld::Notebook> SalInstanceBuilder::weld_notebook(const OString& id)
6914 {
6915     vcl::Window* pNotebook = m_xBuilder->get(id);
6916     if (!pNotebook)
6917         return nullptr;
6918     if (pNotebook->GetType() == WindowType::TABCONTROL)
6919         return std::make_unique<SalInstanceNotebook>(static_cast<TabControl*>(pNotebook), this,
6920                                                      false);
6921     if (pNotebook->GetType() == WindowType::VERTICALTABCONTROL)
6922         return std::make_unique<SalInstanceVerticalNotebook>(
6923             static_cast<VerticalTabControl*>(pNotebook), this, false);
6924     return nullptr;
6925 }
6926 
weld_button(const OString & id)6927 std::unique_ptr<weld::Button> SalInstanceBuilder::weld_button(const OString& id)
6928 {
6929     Button* pButton = m_xBuilder->get<Button>(id);
6930     return pButton ? std::make_unique<SalInstanceButton>(pButton, this, false) : nullptr;
6931 }
6932 
weld_menu_button(const OString & id)6933 std::unique_ptr<weld::MenuButton> SalInstanceBuilder::weld_menu_button(const OString& id)
6934 {
6935     MenuButton* pButton = m_xBuilder->get<MenuButton>(id);
6936     return pButton ? std::make_unique<SalInstanceMenuButton>(pButton, this, false) : nullptr;
6937 }
6938 
6939 std::unique_ptr<weld::MenuToggleButton>
weld_menu_toggle_button(const OString & id)6940 SalInstanceBuilder::weld_menu_toggle_button(const OString& id)
6941 {
6942     MenuToggleButton* pButton = m_xBuilder->get<MenuToggleButton>(id);
6943     return pButton ? std::make_unique<SalInstanceMenuToggleButton>(pButton, this, false) : nullptr;
6944 }
6945 
weld_link_button(const OString & id)6946 std::unique_ptr<weld::LinkButton> SalInstanceBuilder::weld_link_button(const OString& id)
6947 {
6948     FixedHyperlink* pButton = m_xBuilder->get<FixedHyperlink>(id);
6949     return pButton ? std::make_unique<SalInstanceLinkButton>(pButton, this, false) : nullptr;
6950 }
6951 
weld_toggle_button(const OString & id)6952 std::unique_ptr<weld::ToggleButton> SalInstanceBuilder::weld_toggle_button(const OString& id)
6953 {
6954     PushButton* pToggleButton = m_xBuilder->get<PushButton>(id);
6955     return pToggleButton ? std::make_unique<SalInstanceToggleButton>(pToggleButton, this, false)
6956                          : nullptr;
6957 }
6958 
weld_radio_button(const OString & id)6959 std::unique_ptr<weld::RadioButton> SalInstanceBuilder::weld_radio_button(const OString& id)
6960 {
6961     RadioButton* pRadioButton = m_xBuilder->get<RadioButton>(id);
6962     return pRadioButton ? std::make_unique<SalInstanceRadioButton>(pRadioButton, this, false)
6963                         : nullptr;
6964 }
6965 
weld_check_button(const OString & id)6966 std::unique_ptr<weld::CheckButton> SalInstanceBuilder::weld_check_button(const OString& id)
6967 {
6968     CheckBox* pCheckButton = m_xBuilder->get<CheckBox>(id);
6969     return pCheckButton ? std::make_unique<SalInstanceCheckButton>(pCheckButton, this, false)
6970                         : nullptr;
6971 }
6972 
weld_scale(const OString & id)6973 std::unique_ptr<weld::Scale> SalInstanceBuilder::weld_scale(const OString& id)
6974 {
6975     Slider* pSlider = m_xBuilder->get<Slider>(id);
6976     return pSlider ? std::make_unique<SalInstanceScale>(pSlider, this, false) : nullptr;
6977 }
6978 
weld_progress_bar(const OString & id)6979 std::unique_ptr<weld::ProgressBar> SalInstanceBuilder::weld_progress_bar(const OString& id)
6980 {
6981     ::ProgressBar* pProgress = m_xBuilder->get<::ProgressBar>(id);
6982     return pProgress ? std::make_unique<SalInstanceProgressBar>(pProgress, this, false) : nullptr;
6983 }
6984 
weld_spinner(const OString & id)6985 std::unique_ptr<weld::Spinner> SalInstanceBuilder::weld_spinner(const OString& id)
6986 {
6987     Throbber* pThrobber = m_xBuilder->get<Throbber>(id);
6988     return pThrobber ? std::make_unique<SalInstanceSpinner>(pThrobber, this, false) : nullptr;
6989 }
6990 
weld_image(const OString & id)6991 std::unique_ptr<weld::Image> SalInstanceBuilder::weld_image(const OString& id)
6992 {
6993     FixedImage* pImage = m_xBuilder->get<FixedImage>(id);
6994     return pImage ? std::make_unique<SalInstanceImage>(pImage, this, false) : nullptr;
6995 }
6996 
weld_calendar(const OString & id)6997 std::unique_ptr<weld::Calendar> SalInstanceBuilder::weld_calendar(const OString& id)
6998 {
6999     Calendar* pCalendar = m_xBuilder->get<Calendar>(id);
7000     return pCalendar ? std::make_unique<SalInstanceCalendar>(pCalendar, this, false) : nullptr;
7001 }
7002 
weld_entry(const OString & id)7003 std::unique_ptr<weld::Entry> SalInstanceBuilder::weld_entry(const OString& id)
7004 {
7005     Edit* pEntry = m_xBuilder->get<Edit>(id);
7006     return pEntry ? std::make_unique<SalInstanceEntry>(pEntry, this, false) : nullptr;
7007 }
7008 
weld_spin_button(const OString & id)7009 std::unique_ptr<weld::SpinButton> SalInstanceBuilder::weld_spin_button(const OString& id)
7010 {
7011     FormattedField* pSpinButton = m_xBuilder->get<FormattedField>(id);
7012     return pSpinButton ? std::make_unique<SalInstanceSpinButton>(pSpinButton, this, false)
7013                        : nullptr;
7014 }
7015 
7016 std::unique_ptr<weld::MetricSpinButton>
weld_metric_spin_button(const OString & id,FieldUnit eUnit)7017 SalInstanceBuilder::weld_metric_spin_button(const OString& id, FieldUnit eUnit)
7018 {
7019     std::unique_ptr<weld::SpinButton> xButton(weld_spin_button(id));
7020     if (xButton)
7021     {
7022         SalInstanceSpinButton& rButton = dynamic_cast<SalInstanceSpinButton&>(*xButton);
7023         rButton.SetUseThousandSep();
7024     }
7025     return std::make_unique<weld::MetricSpinButton>(std::move(xButton), eUnit);
7026 }
7027 
7028 std::unique_ptr<weld::FormattedSpinButton>
weld_formatted_spin_button(const OString & id)7029 SalInstanceBuilder::weld_formatted_spin_button(const OString& id)
7030 {
7031     FormattedField* pSpinButton = m_xBuilder->get<FormattedField>(id);
7032     return pSpinButton ? std::make_unique<SalInstanceFormattedSpinButton>(pSpinButton, this, false)
7033                        : nullptr;
7034 }
7035 
weld_combo_box(const OString & id)7036 std::unique_ptr<weld::ComboBox> SalInstanceBuilder::weld_combo_box(const OString& id)
7037 {
7038     vcl::Window* pWidget = m_xBuilder->get(id);
7039     ::ComboBox* pComboBox = dynamic_cast<::ComboBox*>(pWidget);
7040     if (pComboBox)
7041         return std::make_unique<SalInstanceComboBoxWithEdit>(pComboBox, this, false);
7042     ListBox* pListBox = dynamic_cast<ListBox*>(pWidget);
7043     return pListBox ? std::make_unique<SalInstanceComboBoxWithoutEdit>(pListBox, this, false)
7044                     : nullptr;
7045 }
7046 
7047 std::unique_ptr<weld::EntryTreeView>
weld_entry_tree_view(const OString & containerid,const OString & entryid,const OString & treeviewid)7048 SalInstanceBuilder::weld_entry_tree_view(const OString& containerid, const OString& entryid,
7049                                          const OString& treeviewid)
7050 {
7051     vcl::Window* pContainer = m_xBuilder->get(containerid);
7052     return pContainer ? std::make_unique<SalInstanceEntryTreeView>(pContainer, this, false,
7053                                                                    weld_entry(entryid),
7054                                                                    weld_tree_view(treeviewid))
7055                       : nullptr;
7056 }
7057 
weld_tree_view(const OString & id)7058 std::unique_ptr<weld::TreeView> SalInstanceBuilder::weld_tree_view(const OString& id)
7059 {
7060     SvTabListBox* pTreeView = m_xBuilder->get<SvTabListBox>(id);
7061     return pTreeView ? std::make_unique<SalInstanceTreeView>(pTreeView, this, false) : nullptr;
7062 }
7063 
weld_icon_view(const OString & id)7064 std::unique_ptr<weld::IconView> SalInstanceBuilder::weld_icon_view(const OString& id)
7065 {
7066     IconView* pIconView = m_xBuilder->get<IconView>(id);
7067     return pIconView ? std::make_unique<SalInstanceIconView>(pIconView, this, false) : nullptr;
7068 }
7069 
weld_label(const OString & id)7070 std::unique_ptr<weld::Label> SalInstanceBuilder::weld_label(const OString& id)
7071 {
7072     Control* pLabel = m_xBuilder->get<Control>(id);
7073     return pLabel ? std::make_unique<SalInstanceLabel>(pLabel, this, false) : nullptr;
7074 }
7075 
weld_text_view(const OString & id)7076 std::unique_ptr<weld::TextView> SalInstanceBuilder::weld_text_view(const OString& id)
7077 {
7078     VclMultiLineEdit* pTextView = m_xBuilder->get<VclMultiLineEdit>(id);
7079     return pTextView ? std::make_unique<SalInstanceTextView>(pTextView, this, false) : nullptr;
7080 }
7081 
weld_expander(const OString & id)7082 std::unique_ptr<weld::Expander> SalInstanceBuilder::weld_expander(const OString& id)
7083 {
7084     VclExpander* pExpander = m_xBuilder->get<VclExpander>(id);
7085     return pExpander ? std::make_unique<SalInstanceExpander>(pExpander, this, false) : nullptr;
7086 }
7087 
7088 std::unique_ptr<weld::DrawingArea>
weld_drawing_area(const OString & id,const a11yref & rA11yImpl,FactoryFunction pUITestFactoryFunction,void * pUserData)7089 SalInstanceBuilder::weld_drawing_area(const OString& id, const a11yref& rA11yImpl,
7090                                       FactoryFunction pUITestFactoryFunction, void* pUserData)
7091 {
7092     VclDrawingArea* pDrawingArea = m_xBuilder->get<VclDrawingArea>(id);
7093     return pDrawingArea
7094                ? std::make_unique<SalInstanceDrawingArea>(pDrawingArea, this, rA11yImpl,
7095                                                           pUITestFactoryFunction, pUserData, false)
7096                : nullptr;
7097 }
7098 
weld_menu(const OString & id)7099 std::unique_ptr<weld::Menu> SalInstanceBuilder::weld_menu(const OString& id)
7100 {
7101     PopupMenu* pMenu = m_xBuilder->get_menu(id);
7102     return pMenu ? std::make_unique<SalInstanceMenu>(pMenu, true) : nullptr;
7103 }
7104 
weld_popover(const OString & id)7105 std::unique_ptr<weld::Popover> SalInstanceBuilder::weld_popover(const OString& id)
7106 {
7107     DockingWindow* pDockingWindow = m_xBuilder->get<DockingWindow>(id);
7108     std::unique_ptr<weld::Popover> pRet(
7109         pDockingWindow ? new SalInstancePopover(pDockingWindow, this, false) : nullptr);
7110     if (pDockingWindow)
7111     {
7112         assert(!m_aOwnedToplevel && "only one toplevel per .ui allowed");
7113         m_aOwnedToplevel.set(pDockingWindow);
7114         m_xBuilder->drop_ownership(pDockingWindow);
7115     }
7116     return pRet;
7117 }
7118 
weld_toolbar(const OString & id)7119 std::unique_ptr<weld::Toolbar> SalInstanceBuilder::weld_toolbar(const OString& id)
7120 {
7121     ToolBox* pToolBox = m_xBuilder->get<ToolBox>(id);
7122     return pToolBox ? std::make_unique<SalInstanceToolbar>(pToolBox, this, false) : nullptr;
7123 }
7124 
create_size_group()7125 std::unique_ptr<weld::SizeGroup> SalInstanceBuilder::create_size_group()
7126 {
7127     return std::make_unique<SalInstanceSizeGroup>();
7128 }
7129 
get_current_page_help_id() const7130 OString SalInstanceBuilder::get_current_page_help_id() const
7131 {
7132     vcl::Window* pCtrl = m_xBuilder->get("tabcontrol");
7133     if (!pCtrl)
7134         return OString();
7135     VclPtr<vcl::Window> xTabPage;
7136     if (pCtrl->GetType() == WindowType::TABCONTROL)
7137     {
7138         TabControl* pTabCtrl = static_cast<TabControl*>(pCtrl);
7139         xTabPage = pTabCtrl->GetTabPage(pTabCtrl->GetCurPageId());
7140     }
7141     else if (pCtrl->GetType() == WindowType::VERTICALTABCONTROL)
7142     {
7143         VerticalTabControl* pTabCtrl = static_cast<VerticalTabControl*>(pCtrl);
7144         xTabPage = pTabCtrl->GetPage(pTabCtrl->GetCurPageId());
7145     }
7146     vcl::Window* pTabChild = xTabPage ? xTabPage->GetWindow(GetWindowType::FirstChild) : nullptr;
7147     pTabChild = pTabChild ? pTabChild->GetWindow(GetWindowType::FirstChild) : nullptr;
7148     if (pTabChild)
7149         return pTabChild->GetHelpId();
7150     return OString();
7151 }
7152 
~SalInstanceBuilder()7153 SalInstanceBuilder::~SalInstanceBuilder()
7154 {
7155     if (VclBuilderContainer* pOwnedToplevel
7156         = dynamic_cast<VclBuilderContainer*>(m_aOwnedToplevel.get()))
7157         pOwnedToplevel->m_pUIBuilder = std::move(m_xBuilder);
7158     else
7159         m_xBuilder.reset();
7160     m_aOwnedToplevel.disposeAndClear();
7161 }
7162 
CreateBuilder(weld::Widget * pParent,const OUString & rUIRoot,const OUString & rUIFile)7163 weld::Builder* SalInstance::CreateBuilder(weld::Widget* pParent, const OUString& rUIRoot,
7164                                           const OUString& rUIFile)
7165 {
7166     SalInstanceWidget* pParentInstance = dynamic_cast<SalInstanceWidget*>(pParent);
7167     vcl::Window* pParentWidget = pParentInstance ? pParentInstance->getWidget() : nullptr;
7168     return new SalInstanceBuilder(pParentWidget, rUIRoot, rUIFile);
7169 }
7170 
CreateInterimBuilder(vcl::Window * pParent,const OUString & rUIRoot,const OUString & rUIFile,bool,sal_uInt64)7171 weld::Builder* SalInstance::CreateInterimBuilder(vcl::Window* pParent, const OUString& rUIRoot,
7172                                                  const OUString& rUIFile, bool, sal_uInt64)
7173 {
7174     return new SalInstanceBuilder(pParent, rUIRoot, rUIFile);
7175 }
7176 
help()7177 void SalInstanceWindow::help()
7178 {
7179     //show help for widget with keyboard focus
7180     vcl::Window* pWidget = ImplGetSVData()->mpWinData->mpFocusWin;
7181     if (!pWidget || comphelper::LibreOfficeKit::isActive())
7182         pWidget = m_xWindow;
7183     OString sHelpId = pWidget->GetHelpId();
7184     while (sHelpId.isEmpty())
7185     {
7186         pWidget = pWidget->GetParent();
7187         if (!pWidget)
7188             break;
7189         sHelpId = pWidget->GetHelpId();
7190     }
7191     std::unique_ptr<weld::Widget> xTemp(
7192         pWidget != m_xWindow ? new SalInstanceWidget(pWidget, m_pBuilder, false) : nullptr);
7193     weld::Widget* pSource = xTemp ? xTemp.get() : this;
7194     bool bRunNormalHelpRequest = !m_aHelpRequestHdl.IsSet() || m_aHelpRequestHdl.Call(*pSource);
7195     Help* pHelp = bRunNormalHelpRequest ? Application::GetHelp() : nullptr;
7196     if (!pHelp)
7197         return;
7198 
7199     // tdf#126007, there's a nice fallback route for offline help where
7200     // the current page of a notebook will get checked when the help
7201     // button is pressed and there was no help for the dialog found.
7202     //
7203     // But for online help that route doesn't get taken, so bodge this here
7204     // by using the page help id if available and if the help button itself
7205     // was the original id
7206     if (m_pBuilder && sHelpId.endsWith("/help"))
7207     {
7208         OString sPageId = m_pBuilder->get_current_page_help_id();
7209         if (!sPageId.isEmpty())
7210             sHelpId = sPageId;
7211         else
7212         {
7213             // tdf#129068 likewise the help for the wrapping dialog is less
7214             // helpful than the help for the content area could be
7215             vcl::Window* pContentArea = nullptr;
7216             if (::Dialog* pDialog = dynamic_cast<::Dialog*>(m_xWindow.get()))
7217                 pContentArea = pDialog->get_content_area();
7218             if (pContentArea)
7219             {
7220                 vcl::Window* pContentWidget = pContentArea->GetWindow(GetWindowType::LastChild);
7221                 if (pContentWidget)
7222                     sHelpId = pContentWidget->GetHelpId();
7223             }
7224         }
7225     }
7226     pHelp->Start(OStringToOUString(sHelpId, RTL_TEXTENCODING_UTF8), pSource);
7227 }
7228 
7229 //iterate upwards through the hierarchy from this widgets through its parents
7230 //calling func with their helpid until func returns true or we run out of parents
help_hierarchy_foreach(const std::function<bool (const OString &)> & func)7231 void SalInstanceWidget::help_hierarchy_foreach(const std::function<bool(const OString&)>& func)
7232 {
7233     vcl::Window* pParent = m_xWidget;
7234     while ((pParent = pParent->GetParent()))
7235     {
7236         if (func(pParent->GetHelpId()))
7237             return;
7238     }
7239 }
7240 
CreateMessageDialog(weld::Widget * pParent,VclMessageType eMessageType,VclButtonsType eButtonsType,const OUString & rPrimaryMessage)7241 weld::MessageDialog* SalInstance::CreateMessageDialog(weld::Widget* pParent,
7242                                                       VclMessageType eMessageType,
7243                                                       VclButtonsType eButtonsType,
7244                                                       const OUString& rPrimaryMessage)
7245 {
7246     SalInstanceWidget* pParentInstance = dynamic_cast<SalInstanceWidget*>(pParent);
7247     SystemWindow* pParentWidget = pParentInstance ? pParentInstance->getSystemWindow() : nullptr;
7248     VclPtrInstance<MessageDialog> xMessageDialog(pParentWidget, rPrimaryMessage, eMessageType,
7249                                                  eButtonsType);
7250     return new SalInstanceMessageDialog(xMessageDialog, nullptr, true);
7251 }
7252 
GetFrameWeld(const css::uno::Reference<css::awt::XWindow> & rWindow)7253 weld::Window* SalInstance::GetFrameWeld(const css::uno::Reference<css::awt::XWindow>& rWindow)
7254 {
7255     UnoWrapperBase* pWrapper = UnoWrapperBase::GetUnoWrapper();
7256     if (!pWrapper)
7257         return nullptr;
7258     VclPtr<vcl::Window> xWindow = pWrapper->GetWindow(rWindow);
7259     if (!xWindow)
7260         return nullptr;
7261     return xWindow->GetFrameWeld();
7262 }
7263 
GetFrameWeld() const7264 weld::Window* SalFrame::GetFrameWeld() const
7265 {
7266     if (!m_xFrameWeld)
7267     {
7268         vcl::Window* pWindow = GetWindow();
7269         if (pWindow)
7270         {
7271             assert(pWindow == pWindow->GetFrameWindow());
7272             m_xFrameWeld.reset(new SalInstanceWindow(pWindow, nullptr, false));
7273         }
7274     }
7275     return m_xFrameWeld.get();
7276 }
7277 
7278 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
7279