1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
21 #include <com/sun/star/awt/XWindow.hpp>
22 #include <officecfg/Office/Common.hxx>
23 #include <iconview.hxx>
24 #include <salframe.hxx>
25 #include <salinst.hxx>
26 #include <salvd.hxx>
27 #include <salprn.hxx>
28 #include <saltimer.hxx>
29 #include <salsession.hxx>
30 #include <salsys.hxx>
31 #include <salbmp.hxx>
32 #include <salobj.hxx>
33 #include <salmenu.hxx>
34 #include <strings.hrc>
35 #include <svdata.hxx>
36 #include <svimpbox.hxx>
37 #include <messagedialog.hxx>
38 #include <treeglue.hxx>
39 #include <unotools/accessiblerelationsethelper.hxx>
40 #include <unotools/configmgr.hxx>
41 #include <utility>
42 #include <tools/helpers.hxx>
43 #include <vcl/abstdlg.hxx>
44 #include <vcl/builder.hxx>
45 #include <vcl/calendar.hxx>
46 #include <vcl/combobox.hxx>
47 #include <vcl/lstbox.hxx>
48 #include <vcl/dialog.hxx>
49 #include <vcl/fixed.hxx>
50 #include <vcl/toolkit/fixedhyper.hxx>
51 #include <vcl/fmtfield.hxx>
52 #include <vcl/headbar.hxx>
53 #include <vcl/ivctrl.hxx>
54 #include <vcl/layout.hxx>
55 #include <vcl/menubtn.hxx>
56 #include <vcl/toolkit/prgsbar.hxx>
57 #include <vcl/ptrstyle.hxx>
58 #include <vcl/slider.hxx>
59 #include <vcl/sysdata.hxx>
60 #include <vcl/svlbitm.hxx>
61 #include <vcl/svtabbx.hxx>
62 #include <vcl/tabctrl.hxx>
63 #include <vcl/tabpage.hxx>
64 #include <vcl/treelistentry.hxx>
65 #include <vcl/toolkit/throbber.hxx>
66 #include <vcl/toolkit/unowrap.hxx>
67 #include <vcl/weld.hxx>
68 #include <vcl/vclmedit.hxx>
69 #include <vcl/viewdataentry.hxx>
70 #include <vcl/virdev.hxx>
71 #include <aboutdialog.hxx>
72 #include <bitmaps.hlst>
73 #include <wizdlg.hxx>
74
SalFrame()75 SalFrame::SalFrame()
76 : m_pWindow(nullptr)
77 , m_pProc(nullptr)
78 {
79 }
80
81 // this file contains the virtual destructors of the sal interface
82 // compilers usually put their vtables where the destructor is
83
~SalFrame()84 SalFrame::~SalFrame()
85 {
86 }
87
SetCallback(vcl::Window * pWindow,SALFRAMEPROC pProc)88 void SalFrame::SetCallback( vcl::Window* pWindow, SALFRAMEPROC pProc )
89 {
90 m_pWindow = pWindow;
91 m_pProc = pProc;
92 }
93
94 // default to full-frame flushes
95 // on ports where partial-flushes are much cheaper this method should be overridden
Flush(const tools::Rectangle &)96 void SalFrame::Flush( const tools::Rectangle& )
97 {
98 Flush();
99 }
100
SetRepresentedURL(const OUString &)101 void SalFrame::SetRepresentedURL( const OUString& )
102 {
103 // currently this is Mac only functionality
104 }
105
SalInstance(std::unique_ptr<comphelper::SolarMutex> pMutex)106 SalInstance::SalInstance(std::unique_ptr<comphelper::SolarMutex> pMutex)
107 : m_pYieldMutex(std::move(pMutex))
108 {
109 }
110
~SalInstance()111 SalInstance::~SalInstance()
112 {
113 }
114
GetYieldMutex()115 comphelper::SolarMutex* SalInstance::GetYieldMutex()
116 {
117 return m_pYieldMutex.get();
118 }
119
ReleaseYieldMutexAll()120 sal_uInt32 SalInstance::ReleaseYieldMutexAll()
121 {
122 return m_pYieldMutex->release(true);
123 }
124
AcquireYieldMutex(sal_uInt32 nCount)125 void SalInstance::AcquireYieldMutex(sal_uInt32 nCount)
126 {
127 m_pYieldMutex->acquire(nCount);
128 }
129
CreateSalSession()130 std::unique_ptr<SalSession> SalInstance::CreateSalSession()
131 {
132 return nullptr;
133 }
134
CreateMenu(bool,Menu *)135 std::unique_ptr<SalMenu> SalInstance::CreateMenu( bool, Menu* )
136 {
137 // default: no native menus
138 return nullptr;
139 }
140
CreateMenuItem(const SalItemParams &)141 std::unique_ptr<SalMenuItem> SalInstance::CreateMenuItem( const SalItemParams & )
142 {
143 return nullptr;
144 }
145
CallEventCallback(void const * pEvent,int nBytes)146 bool SalInstance::CallEventCallback( void const * pEvent, int nBytes )
147 {
148 return m_pEventInst.is() && m_pEventInst->dispatchEvent( pEvent, nBytes );
149 }
150
~SalTimer()151 SalTimer::~SalTimer() COVERITY_NOEXCEPT_FALSE
152 {
153 }
154
DropScaledCache()155 void SalBitmap::DropScaledCache()
156 {
157 if (ImplSVData* pSVData = ImplGetSVData())
158 {
159 auto& rCache = pSVData->maGDIData.maScaleCache;
160 rCache.remove_if([this] (const o3tl::lru_map<SalBitmap*, BitmapEx>::key_value_pair_t& rKeyValuePair)
161 { return rKeyValuePair.first == this; });
162 }
163 }
164
~SalBitmap()165 SalBitmap::~SalBitmap()
166 {
167 DropScaledCache();
168 }
169
~SalSystem()170 SalSystem::~SalSystem()
171 {
172 }
173
~SalPrinter()174 SalPrinter::~SalPrinter()
175 {
176 }
177
StartJob(const OUString *,const OUString &,const OUString &,ImplJobSetup *,vcl::PrinterController &)178 bool SalPrinter::StartJob( const OUString*, const OUString&, const OUString&,
179 ImplJobSetup*, vcl::PrinterController& )
180 {
181 return false;
182 }
183
~SalInfoPrinter()184 SalInfoPrinter::~SalInfoPrinter()
185 {
186 }
187
~SalVirtualDevice()188 SalVirtualDevice::~SalVirtualDevice()
189 {
190 }
191
~SalObject()192 SalObject::~SalObject()
193 {
194 }
195
~SalMenu()196 SalMenu::~SalMenu()
197 {
198 }
199
ShowNativePopupMenu(FloatingWindow *,const tools::Rectangle &,FloatWinPopupFlags)200 bool SalMenu::ShowNativePopupMenu(FloatingWindow *, const tools::Rectangle&, FloatWinPopupFlags )
201 {
202 return false;
203 }
204
ShowCloseButton(bool)205 void SalMenu::ShowCloseButton(bool)
206 {
207 }
208
AddMenuBarButton(const SalMenuButtonItem &)209 bool SalMenu::AddMenuBarButton( const SalMenuButtonItem& )
210 {
211 return false;
212 }
213
RemoveMenuBarButton(sal_uInt16)214 void SalMenu::RemoveMenuBarButton( sal_uInt16 )
215 {
216 }
217
GetMenuBarButtonRectPixel(sal_uInt16,SalFrame *)218 tools::Rectangle SalMenu::GetMenuBarButtonRectPixel( sal_uInt16, SalFrame* )
219 {
220 return tools::Rectangle();
221 }
222
GetMenuBarHeight() const223 int SalMenu::GetMenuBarHeight() const
224 {
225 return 0;
226 }
227
ApplyPersona()228 void SalMenu::ApplyPersona()
229 {
230 }
231
~SalMenuItem()232 SalMenuItem::~SalMenuItem()
233 {
234 }
235
236 class SalInstanceBuilder;
237
238 class SalInstanceWidget : public virtual weld::Widget
239 {
240 protected:
241 VclPtr<vcl::Window> m_xWidget;
242 SalInstanceBuilder* m_pBuilder;
243
244 private:
245 DECL_LINK(EventListener, VclWindowEvent&, void);
246 DECL_LINK(KeyEventListener, VclWindowEvent&, bool);
247 DECL_LINK(MouseEventListener, VclSimpleEvent&, void);
248 DECL_LINK(MnemonicActivateHdl, vcl::Window&, bool);
249
250 const bool m_bTakeOwnership;
251 bool m_bEventListener;
252 bool m_bKeyEventListener;
253 bool m_bMouseEventListener;
254 int m_nBlockNotify;
255
256 protected:
ensure_event_listener()257 void ensure_event_listener()
258 {
259 if (!m_bEventListener)
260 {
261 m_xWidget->AddEventListener(LINK(this, SalInstanceWidget, EventListener));
262 m_bEventListener = true;
263 }
264 }
265
266 // we want the ability to mark key events as handled, so use this variant
267 // for those, we get all keystrokes in this case, so we will need to filter
268 // them later
ensure_key_listener()269 void ensure_key_listener()
270 {
271 if (!m_bKeyEventListener)
272 {
273 Application::AddKeyListener(LINK(this, SalInstanceWidget, KeyEventListener));
274 m_bKeyEventListener = true;
275 }
276 }
277
278 // we want the ability to know about mouse events that happen in our children
279 // so use this variant, we will need to filter them later
ensure_mouse_listener()280 void ensure_mouse_listener()
281 {
282 if (!m_bMouseEventListener)
283 {
284 Application::AddEventListener(LINK(this, SalInstanceWidget, MouseEventListener));
285 m_bMouseEventListener = true;
286 }
287 }
288
289 virtual void HandleEventListener(VclWindowEvent& rEvent);
290 virtual bool HandleKeyEventListener(VclWindowEvent& rEvent);
291 virtual void HandleMouseEventListener(VclSimpleEvent& rEvent);
292
set_background(const Color & rColor)293 void set_background(const Color& rColor)
294 {
295 m_xWidget->SetControlBackground(rColor);
296 m_xWidget->SetBackground(m_xWidget->GetControlBackground());
297 // turn off WB_CLIPCHILDREN otherwise the bg won't extend "under"
298 // transparent children of the widget
299 m_xWidget->SetStyle(m_xWidget->GetStyle() & ~WB_CLIPCHILDREN);
300 }
301
302 public:
SalInstanceWidget(vcl::Window * pWidget,SalInstanceBuilder * pBuilder,bool bTakeOwnership)303 SalInstanceWidget(vcl::Window* pWidget, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
304 : m_xWidget(pWidget)
305 , m_pBuilder(pBuilder)
306 , m_bTakeOwnership(bTakeOwnership)
307 , m_bEventListener(false)
308 , m_bKeyEventListener(false)
309 , m_bMouseEventListener(false)
310 , m_nBlockNotify(0)
311 {
312 }
313
set_sensitive(bool sensitive)314 virtual void set_sensitive(bool sensitive) override
315 {
316 m_xWidget->Enable(sensitive);
317 }
318
get_sensitive() const319 virtual bool get_sensitive() const override
320 {
321 return m_xWidget->IsEnabled();
322 }
323
get_visible() const324 virtual bool get_visible() const override
325 {
326 return m_xWidget->IsVisible();
327 }
328
is_visible() const329 virtual bool is_visible() const override
330 {
331 return m_xWidget->IsReallyVisible();
332 }
333
set_can_focus(bool bCanFocus)334 virtual void set_can_focus(bool bCanFocus) override
335 {
336 auto nStyle = m_xWidget->GetStyle() & ~(WB_TABSTOP | WB_NOTABSTOP);
337 if (bCanFocus)
338 nStyle |= WB_TABSTOP;
339 else
340 nStyle |= WB_NOTABSTOP;
341 m_xWidget->SetStyle(nStyle);
342 }
343
grab_focus()344 virtual void grab_focus() override
345 {
346 m_xWidget->GrabFocus();
347 }
348
has_focus() const349 virtual bool has_focus() const override
350 {
351 return m_xWidget->HasFocus();
352 }
353
is_active() const354 virtual bool is_active() const override
355 {
356 return m_xWidget->IsActive();
357 }
358
set_has_default(bool has_default)359 virtual void set_has_default(bool has_default) override
360 {
361 m_xWidget->set_property("has-default", OUString::boolean(has_default));
362 }
363
get_has_default() const364 virtual bool get_has_default() const override
365 {
366 return m_xWidget->GetStyle() & WB_DEFBUTTON;
367 }
368
show()369 virtual void show() override
370 {
371 m_xWidget->Show();
372 }
373
hide()374 virtual void hide() override
375 {
376 m_xWidget->Hide();
377 }
378
set_size_request(int nWidth,int nHeight)379 virtual void set_size_request(int nWidth, int nHeight) override
380 {
381 m_xWidget->set_width_request(nWidth);
382 m_xWidget->set_height_request(nHeight);
383 }
384
get_size_request() const385 virtual Size get_size_request() const override
386 {
387 return Size(m_xWidget->get_width_request(),
388 m_xWidget->get_height_request());
389 }
390
get_preferred_size() const391 virtual Size get_preferred_size() const override
392 {
393 return m_xWidget->get_preferred_size();
394 }
395
get_approximate_digit_width() const396 virtual float get_approximate_digit_width() const override
397 {
398 return m_xWidget->approximate_digit_width();
399 }
400
get_text_height() const401 virtual int get_text_height() const override
402 {
403 return m_xWidget->GetTextHeight();
404 }
405
get_pixel_size(const OUString & rText) const406 virtual Size get_pixel_size(const OUString& rText) const override
407 {
408 //TODO, or do I want GetTextBoundRect ?, just using width at the moment anyway
409 return Size(m_xWidget->GetTextWidth(rText), m_xWidget->GetTextHeight());
410 }
411
get_font()412 virtual vcl::Font get_font() override
413 {
414 return m_xWidget->GetPointFont(*m_xWidget);
415 }
416
get_buildable_name() const417 virtual OString get_buildable_name() const override
418 {
419 return m_xWidget->get_id().toUtf8();
420 }
421
set_help_id(const OString & rId)422 virtual void set_help_id(const OString& rId) override
423 {
424 return m_xWidget->SetHelpId(rId);
425 }
426
get_help_id() const427 virtual OString get_help_id() const override
428 {
429 return m_xWidget->GetHelpId();
430 }
431
set_grid_left_attach(int nAttach)432 virtual void set_grid_left_attach(int nAttach) override
433 {
434 m_xWidget->set_grid_left_attach(nAttach);
435 }
436
get_grid_left_attach() const437 virtual int get_grid_left_attach() const override
438 {
439 return m_xWidget->get_grid_left_attach();
440 }
441
set_grid_width(int nCols)442 virtual void set_grid_width(int nCols) override
443 {
444 m_xWidget->set_grid_width(nCols);
445 }
446
set_grid_top_attach(int nAttach)447 virtual void set_grid_top_attach(int nAttach) override
448 {
449 m_xWidget->set_grid_top_attach(nAttach);
450 }
451
get_grid_top_attach() const452 virtual int get_grid_top_attach() const override
453 {
454 return m_xWidget->get_grid_top_attach();
455 }
456
set_hexpand(bool bExpand)457 virtual void set_hexpand(bool bExpand) override
458 {
459 m_xWidget->set_hexpand(bExpand);
460 }
461
get_hexpand() const462 virtual bool get_hexpand() const override
463 {
464 return m_xWidget->get_hexpand();
465 }
466
set_vexpand(bool bExpand)467 virtual void set_vexpand(bool bExpand) override
468 {
469 m_xWidget->set_vexpand(bExpand);
470 }
471
get_vexpand() const472 virtual bool get_vexpand() const override
473 {
474 return m_xWidget->get_vexpand();
475 }
476
set_secondary(bool bSecondary)477 virtual void set_secondary(bool bSecondary) override
478 {
479 m_xWidget->set_secondary(bSecondary);
480 }
481
set_margin_top(int nMargin)482 virtual void set_margin_top(int nMargin) override
483 {
484 m_xWidget->set_margin_top(nMargin);
485 }
486
set_margin_bottom(int nMargin)487 virtual void set_margin_bottom(int nMargin) override
488 {
489 m_xWidget->set_margin_bottom(nMargin);
490 }
491
set_margin_left(int nMargin)492 virtual void set_margin_left(int nMargin) override
493 {
494 m_xWidget->set_margin_left(nMargin);
495 }
496
set_margin_right(int nMargin)497 virtual void set_margin_right(int nMargin) override
498 {
499 m_xWidget->set_margin_bottom(nMargin);
500 }
501
get_margin_top() const502 virtual int get_margin_top() const override
503 {
504 return m_xWidget->get_margin_top();
505 }
506
get_margin_bottom() const507 virtual int get_margin_bottom() const override
508 {
509 return m_xWidget->get_margin_bottom();
510 }
511
get_margin_left() const512 virtual int get_margin_left() const override
513 {
514 return m_xWidget->get_margin_left();
515 }
516
get_margin_right() const517 virtual int get_margin_right() const override
518 {
519 return m_xWidget->get_margin_bottom();
520 }
521
set_accessible_name(const OUString & rName)522 virtual void set_accessible_name(const OUString& rName) override
523 {
524 m_xWidget->SetAccessibleName(rName);
525 }
526
get_accessible_name() const527 virtual OUString get_accessible_name() const override
528 {
529 return m_xWidget->GetAccessibleName();
530 }
531
get_accessible_description() const532 virtual OUString get_accessible_description() const override
533 {
534 return m_xWidget->GetAccessibleDescription();
535 }
536
set_accessible_relation_labeled_by(weld::Widget * pLabel)537 virtual void set_accessible_relation_labeled_by(weld::Widget* pLabel) override
538 {
539 vcl::Window* pAtkLabel = pLabel ? dynamic_cast<SalInstanceWidget&>(*pLabel).getWidget() : nullptr;
540 m_xWidget->SetAccessibleRelationLabeledBy(pAtkLabel);
541 }
542
set_accessible_relation_label_for(weld::Widget * pLabeled)543 virtual void set_accessible_relation_label_for(weld::Widget* pLabeled) override
544 {
545 vcl::Window* pAtkLabeled = pLabeled ? dynamic_cast<SalInstanceWidget&>(*pLabeled).getWidget() : nullptr;
546 m_xWidget->SetAccessibleRelationLabelFor(pAtkLabeled);
547 }
548
set_tooltip_text(const OUString & rTip)549 virtual void set_tooltip_text(const OUString& rTip) override
550 {
551 m_xWidget->SetQuickHelpText(rTip);
552 }
553
get_tooltip_text() const554 virtual OUString get_tooltip_text() const override
555 {
556 return m_xWidget->GetQuickHelpText();
557 }
558
connect_focus_in(const Link<Widget &,void> & rLink)559 virtual void connect_focus_in(const Link<Widget&, void>& rLink) override
560 {
561 ensure_event_listener();
562 weld::Widget::connect_focus_in(rLink);
563 }
564
connect_mnemonic_activate(const Link<Widget &,bool> & rLink)565 virtual void connect_mnemonic_activate(const Link<Widget&, bool>& rLink) override
566 {
567 m_xWidget->SetMnemonicActivateHdl(LINK(this, SalInstanceWidget, MnemonicActivateHdl));
568 weld::Widget::connect_mnemonic_activate(rLink);
569 }
570
connect_focus_out(const Link<Widget &,void> & rLink)571 virtual void connect_focus_out(const Link<Widget&, void>& rLink) override
572 {
573 ensure_event_listener();
574 weld::Widget::connect_focus_out(rLink);
575 }
576
connect_size_allocate(const Link<const Size &,void> & rLink)577 virtual void connect_size_allocate(const Link<const Size&, void>& rLink) override
578 {
579 ensure_event_listener();
580 weld::Widget::connect_size_allocate(rLink);
581 }
582
connect_mouse_press(const Link<const MouseEvent &,bool> & rLink)583 virtual void connect_mouse_press(const Link<const MouseEvent&, bool>& rLink) override
584 {
585 ensure_mouse_listener();
586 weld::Widget::connect_mouse_press(rLink);
587 }
588
connect_mouse_move(const Link<const MouseEvent &,bool> & rLink)589 virtual void connect_mouse_move(const Link<const MouseEvent&, bool>& rLink) override
590 {
591 ensure_mouse_listener();
592 weld::Widget::connect_mouse_move(rLink);
593 }
594
connect_mouse_release(const Link<const MouseEvent &,bool> & rLink)595 virtual void connect_mouse_release(const Link<const MouseEvent&, bool>& rLink) override
596 {
597 ensure_mouse_listener();
598 weld::Widget::connect_mouse_release(rLink);
599 }
600
connect_key_press(const Link<const KeyEvent &,bool> & rLink)601 virtual void connect_key_press(const Link<const KeyEvent&, bool>& rLink) override
602 {
603 ensure_key_listener();
604 weld::Widget::connect_key_press(rLink);
605 }
606
connect_key_release(const Link<const KeyEvent &,bool> & rLink)607 virtual void connect_key_release(const Link<const KeyEvent&, bool>& rLink) override
608 {
609 ensure_key_listener();
610 weld::Widget::connect_key_release(rLink);
611 }
612
get_extents_relative_to(Widget & rRelative,int & x,int & y,int & width,int & height)613 virtual bool get_extents_relative_to(Widget& rRelative, int& x, int &y, int& width, int &height) override
614 {
615 tools::Rectangle aRect(m_xWidget->GetWindowExtentsRelative(dynamic_cast<SalInstanceWidget&>(rRelative).getWidget()));
616 x = aRect.Left();
617 y = aRect.Top();
618 width = aRect.GetWidth();
619 height = aRect.GetHeight();
620 return true;
621 }
622
grab_add()623 virtual void grab_add() override
624 {
625 m_xWidget->CaptureMouse();
626 }
627
has_grab() const628 virtual bool has_grab() const override
629 {
630 return m_xWidget->IsMouseCaptured();
631 }
632
grab_remove()633 virtual void grab_remove() override
634 {
635 m_xWidget->ReleaseMouse();
636 }
637
get_direction() const638 virtual bool get_direction() const override
639 {
640 return m_xWidget->IsRTLEnabled();
641 }
642
set_direction(bool bRTL)643 virtual void set_direction(bool bRTL) override
644 {
645 m_xWidget->EnableRTL(bRTL);
646 }
647
freeze()648 virtual void freeze() override
649 {
650 m_xWidget->SetUpdateMode(false);
651 }
652
thaw()653 virtual void thaw() override
654 {
655 m_xWidget->SetUpdateMode(true);
656 }
657
658 virtual std::unique_ptr<weld::Container> weld_parent() const override;
659
~SalInstanceWidget()660 virtual ~SalInstanceWidget() override
661 {
662 if (m_aMnemonicActivateHdl.IsSet())
663 m_xWidget->SetMnemonicActivateHdl(Link<vcl::Window&,bool>());
664 if (m_bMouseEventListener)
665 Application::RemoveEventListener(LINK(this, SalInstanceWidget, MouseEventListener));
666 if (m_bKeyEventListener)
667 Application::RemoveKeyListener(LINK(this, SalInstanceWidget, KeyEventListener));
668 if (m_bEventListener)
669 m_xWidget->RemoveEventListener(LINK(this, SalInstanceWidget, EventListener));
670 if (m_bTakeOwnership)
671 m_xWidget.disposeAndClear();
672 }
673
getWidget()674 vcl::Window* getWidget()
675 {
676 return m_xWidget;
677 }
678
disable_notify_events()679 void disable_notify_events()
680 {
681 ++m_nBlockNotify;
682 }
683
notify_events_disabled()684 bool notify_events_disabled()
685 {
686 return m_nBlockNotify != 0;
687 }
688
enable_notify_events()689 void enable_notify_events()
690 {
691 --m_nBlockNotify;
692 }
693
694 virtual void help_hierarchy_foreach(const std::function<bool(const OString&)>& func) override;
695
strip_mnemonic(const OUString & rLabel) const696 virtual OUString strip_mnemonic(const OUString &rLabel) const override
697 {
698 return rLabel.replaceFirst("~", "");
699 }
700
create_virtual_device() const701 virtual VclPtr<VirtualDevice> create_virtual_device() const override
702 {
703 // create with (annoying) separate alpha layer that LibreOffice itself uses
704 return VclPtr<VirtualDevice>::Create(*Application::GetDefaultDevice(), DeviceFormat::DEFAULT, DeviceFormat::DEFAULT);
705 }
706
get_drop_target()707 virtual css::uno::Reference<css::datatransfer::dnd::XDropTarget> get_drop_target() override
708 {
709 return m_xWidget->GetDropTarget();
710 }
711
set_stack_background()712 virtual void set_stack_background() override
713 {
714 set_background(m_xWidget->GetSettings().GetStyleSettings().GetWindowColor());;
715 }
716
set_highlight_background()717 virtual void set_highlight_background() override
718 {
719 set_background(m_xWidget->GetSettings().GetStyleSettings().GetHighlightColor());;
720 }
721
getSystemWindow()722 SystemWindow* getSystemWindow()
723 {
724 return m_xWidget->GetSystemWindow();
725 }
726 };
727
HandleEventListener(VclWindowEvent & rEvent)728 void SalInstanceWidget::HandleEventListener(VclWindowEvent& rEvent)
729 {
730 if (rEvent.GetId() == VclEventId::WindowGetFocus)
731 m_aFocusInHdl.Call(*this);
732 else if (rEvent.GetId() == VclEventId::WindowLoseFocus)
733 m_aFocusOutHdl.Call(*this);
734 else if (rEvent.GetId() == VclEventId::WindowResize)
735 m_aSizeAllocateHdl.Call(m_xWidget->GetSizePixel());
736 }
737
HandleMouseEventListener(VclSimpleEvent & rEvent)738 void SalInstanceWidget::HandleMouseEventListener(VclSimpleEvent& rEvent)
739 {
740 if (rEvent.GetId() == VclEventId::WindowMouseButtonDown)
741 {
742 auto& rWinEvent = static_cast<VclWindowEvent&>(rEvent);
743 if (m_xWidget->IsWindowOrChild(rWinEvent.GetWindow()))
744 {
745 const MouseEvent* pMouseEvent = static_cast<const MouseEvent*>(rWinEvent.GetData());
746 m_aMousePressHdl.Call(*pMouseEvent);
747 }
748 }
749 else if (rEvent.GetId() == VclEventId::WindowMouseButtonUp)
750 {
751 auto& rWinEvent = static_cast<VclWindowEvent&>(rEvent);
752 if (m_xWidget->IsWindowOrChild(rWinEvent.GetWindow()))
753 {
754 const MouseEvent* pMouseEvent = static_cast<const MouseEvent*>(rWinEvent.GetData());
755 m_aMouseReleaseHdl.Call(*pMouseEvent);
756 }
757 }
758 else if (rEvent.GetId() == VclEventId::WindowMouseMove)
759 {
760 auto& rWinEvent = static_cast<VclWindowEvent&>(rEvent);
761 if (m_xWidget->IsWindowOrChild(rWinEvent.GetWindow()))
762 {
763 const MouseEvent* pMouseEvent = static_cast<const MouseEvent*>(rWinEvent.GetData());
764 m_aMouseMotionHdl.Call(*pMouseEvent);
765 }
766 }
767 }
768
HandleKeyEventListener(VclWindowEvent & rEvent)769 bool SalInstanceWidget::HandleKeyEventListener(VclWindowEvent& rEvent)
770 {
771 // we get all key events here, ignore them unless we have focus
772 if (!has_focus())
773 return false;
774 if (rEvent.GetId() == VclEventId::WindowKeyInput)
775 {
776 const KeyEvent* pKeyEvent = static_cast<const KeyEvent*>(rEvent.GetData());
777 return m_aKeyPressHdl.Call(*pKeyEvent);
778 }
779 else if (rEvent.GetId() == VclEventId::WindowKeyUp)
780 {
781 const KeyEvent* pKeyEvent = static_cast<const KeyEvent*>(rEvent.GetData());
782 return m_aKeyReleaseHdl.Call(*pKeyEvent);
783 }
784 return false;
785 }
786
IMPL_LINK(SalInstanceWidget,EventListener,VclWindowEvent &,rEvent,void)787 IMPL_LINK(SalInstanceWidget, EventListener, VclWindowEvent&, rEvent, void)
788 {
789 HandleEventListener(rEvent);
790 }
791
IMPL_LINK(SalInstanceWidget,KeyEventListener,VclWindowEvent &,rEvent,bool)792 IMPL_LINK(SalInstanceWidget, KeyEventListener, VclWindowEvent&, rEvent, bool)
793 {
794 return HandleKeyEventListener(rEvent);
795 }
796
IMPL_LINK(SalInstanceWidget,MouseEventListener,VclSimpleEvent &,rEvent,void)797 IMPL_LINK(SalInstanceWidget, MouseEventListener, VclSimpleEvent&, rEvent, void)
798 {
799 HandleMouseEventListener(rEvent);
800 }
801
IMPL_LINK_NOARG(SalInstanceWidget,MnemonicActivateHdl,vcl::Window &,bool)802 IMPL_LINK_NOARG(SalInstanceWidget, MnemonicActivateHdl, vcl::Window&, bool)
803 {
804 return m_aMnemonicActivateHdl.Call(*this);
805 }
806
807 namespace
808 {
createImage(const OUString & rImage)809 Image createImage(const OUString& rImage)
810 {
811 if (rImage.isEmpty())
812 return Image();
813 if (rImage.lastIndexOf('.') != rImage.getLength() - 4)
814 {
815 assert((rImage == "dialog-warning" || rImage == "dialog-error" || rImage == "dialog-information") && "unknown stock image");
816 if (rImage == "dialog-warning")
817 return Image(StockImage::Yes, IMG_WARN);
818 else if (rImage == "dialog-error")
819 return Image(StockImage::Yes, IMG_ERROR);
820 else if (rImage == "dialog-information")
821 return Image(StockImage::Yes, IMG_INFO);
822 }
823 return Image(StockImage::Yes, rImage);
824 }
825
createImage(const VirtualDevice & rDevice)826 Image createImage(const VirtualDevice& rDevice)
827 {
828 return Image(rDevice.GetBitmapEx(Point(), rDevice.GetOutputSizePixel()));
829 }
830
insert_to_menu(sal_uInt16 nLastId,PopupMenu * pMenu,int pos,const OUString & rId,const OUString & rStr,const OUString * pIconName,const VirtualDevice * pImageSurface,bool bCheck)831 sal_uInt16 insert_to_menu(sal_uInt16 nLastId, PopupMenu* pMenu, int pos, const OUString& rId, const OUString& rStr,
832 const OUString* pIconName, const VirtualDevice* pImageSurface, bool bCheck)
833 {
834 const sal_uInt16 nNewid = nLastId + 1;
835 pMenu->InsertItem(nNewid, rStr, bCheck ? MenuItemBits::CHECKABLE : MenuItemBits::NONE,
836 OUStringToOString(rId, RTL_TEXTENCODING_UTF8), pos == -1 ? MENU_APPEND : pos);
837 if (pIconName)
838 {
839 pMenu->SetItemImage(nNewid, createImage(*pIconName));
840 }
841 else if (pImageSurface)
842 {
843 pMenu->SetItemImage(nNewid, createImage(*pImageSurface));
844 }
845 return nNewid;
846 }
847 }
848
849 class SalInstanceMenu : public weld::Menu
850 {
851 private:
852 VclPtr<PopupMenu> m_xMenu;
853
854 bool const m_bTakeOwnership;
855 sal_uInt16 m_nLastId;
856
857 DECL_LINK(SelectMenuHdl, ::Menu*, bool);
858 public:
SalInstanceMenu(PopupMenu * pMenu,bool bTakeOwnership)859 SalInstanceMenu(PopupMenu* pMenu, bool bTakeOwnership)
860 : m_xMenu(pMenu)
861 , m_bTakeOwnership(bTakeOwnership)
862 {
863 const auto nCount = m_xMenu->GetItemCount();
864 m_nLastId = nCount ? pMenu->GetItemId(nCount-1) : 0;
865 m_xMenu->SetSelectHdl(LINK(this, SalInstanceMenu, SelectMenuHdl));
866 }
popup_at_rect(weld::Widget * pParent,const tools::Rectangle & rRect)867 virtual OString popup_at_rect(weld::Widget* pParent, const tools::Rectangle &rRect) override
868 {
869 SalInstanceWidget* pVclWidget = dynamic_cast<SalInstanceWidget*>(pParent);
870 assert(pVclWidget);
871 m_xMenu->Execute(pVclWidget->getWidget(), rRect, PopupMenuFlags::ExecuteDown | PopupMenuFlags::NoMouseUpClose);
872 return m_xMenu->GetCurItemIdent();
873 }
set_sensitive(const OString & rIdent,bool bSensitive)874 virtual void set_sensitive(const OString& rIdent, bool bSensitive) override
875 {
876 m_xMenu->EnableItem(rIdent, bSensitive);
877 }
set_active(const OString & rIdent,bool bActive)878 virtual void set_active(const OString& rIdent, bool bActive) override
879 {
880 m_xMenu->CheckItem(rIdent, bActive);
881 }
get_active(const OString & rIdent) const882 virtual bool get_active(const OString& rIdent) const override
883 {
884 return m_xMenu->IsItemChecked(m_xMenu->GetItemId(rIdent));
885 }
set_label(const OString & rIdent,const OUString & rLabel)886 virtual void set_label(const OString& rIdent, const OUString& rLabel) override
887 {
888 m_xMenu->SetItemText(m_xMenu->GetItemId(rIdent), rLabel);
889 }
set_visible(const OString & rIdent,bool bShow)890 virtual void set_visible(const OString& rIdent, bool bShow) override
891 {
892 m_xMenu->ShowItem(m_xMenu->GetItemId(rIdent), bShow);
893 }
clear()894 virtual void clear() override
895 {
896 m_xMenu->Clear();
897 }
insert(int pos,const OUString & rId,const OUString & rStr,const OUString * pIconName,VirtualDevice * pImageSurface,bool bCheck)898 virtual void insert(int pos, const OUString& rId, const OUString& rStr,
899 const OUString* pIconName, VirtualDevice* pImageSurface, bool bCheck) override
900 {
901 m_nLastId = insert_to_menu(m_nLastId, m_xMenu, pos, rId, rStr, pIconName, pImageSurface, bCheck);
902 }
insert_separator(int pos,const OUString & rId)903 virtual void insert_separator(int pos, const OUString& rId) override
904 {
905 auto nInsertPos = pos == -1 ? MENU_APPEND : pos;
906 m_xMenu->InsertSeparator(rId.toUtf8(), nInsertPos);
907 }
getMenu() const908 PopupMenu* getMenu() const
909 {
910 return m_xMenu.get();
911 }
~SalInstanceMenu()912 virtual ~SalInstanceMenu() override
913 {
914 m_xMenu->SetSelectHdl(Link<::Menu*, bool>());
915 if (m_bTakeOwnership)
916 m_xMenu.disposeAndClear();
917 }
918 };
919
IMPL_LINK_NOARG(SalInstanceMenu,SelectMenuHdl,::Menu *,bool)920 IMPL_LINK_NOARG(SalInstanceMenu, SelectMenuHdl, ::Menu*, bool)
921 {
922 signal_activate(m_xMenu->GetCurItemIdent());
923 /* tdf#131333 Menu::Select depends on a false here to allow
924 propogating a submens's selected id to its parent menu to become its
925 selected id.
926
927 without this, while gen menus already have propogated this to its parent
928 in MenuFloatingWindow::EndExecute, SalMenus as used under kf5/macOS
929 won't propogate the selected id
930 */
931 return false;
932 }
933
934 class SalInstanceToolbar : public SalInstanceWidget, public virtual weld::Toolbar
935 {
936 private:
937 VclPtr<ToolBox> m_xToolBox;
938 std::map<sal_uInt16, VclPtr<vcl::Window>> m_aFloats;
939 std::map<sal_uInt16, VclPtr<PopupMenu>> m_aMenus;
940
941 DECL_LINK(ClickHdl, ToolBox*, void);
942 DECL_LINK(DropdownClick, ToolBox*, void);
943 public:
SalInstanceToolbar(ToolBox * pToolBox,SalInstanceBuilder * pBuilder,bool bTakeOwnership)944 SalInstanceToolbar(ToolBox* pToolBox, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
945 : SalInstanceWidget(pToolBox, pBuilder, bTakeOwnership)
946 , m_xToolBox(pToolBox)
947 {
948 m_xToolBox->SetSelectHdl(LINK(this, SalInstanceToolbar, ClickHdl));
949 m_xToolBox->SetDropdownClickHdl(LINK(this, SalInstanceToolbar, DropdownClick));
950 }
951
set_item_sensitive(const OString & rIdent,bool bSensitive)952 virtual void set_item_sensitive(const OString& rIdent, bool bSensitive) override
953 {
954 m_xToolBox->EnableItem(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), bSensitive);
955 }
956
get_item_sensitive(const OString & rIdent) const957 virtual bool get_item_sensitive(const OString& rIdent) const override
958 {
959 return m_xToolBox->IsItemEnabled(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)));
960 }
961
set_item_active(const OString & rIdent,bool bActive)962 virtual void set_item_active(const OString& rIdent, bool bActive) override
963 {
964 sal_uInt16 nItemId = m_xToolBox->GetItemId(OUString::fromUtf8(rIdent));
965 m_xToolBox->CheckItem(nItemId, bActive);
966
967 if (m_xToolBox->GetItemBits(nItemId) & ToolBoxItemBits::DROPDOWN)
968 {
969 auto pFloat = m_aFloats[nItemId];
970 if (pFloat)
971 {
972 if (bActive)
973 vcl::Window::GetDockingManager()->StartPopupMode(m_xToolBox, pFloat, FloatWinPopupFlags::GrabFocus);
974 else
975 vcl::Window::GetDockingManager()->EndPopupMode(pFloat);
976 }
977 auto pPopup = m_aMenus[nItemId];
978 if (pPopup)
979 {
980 if (bActive)
981 {
982 tools::Rectangle aRect = m_xToolBox->GetItemRect(nItemId);
983 pPopup->Execute(m_xToolBox, aRect, PopupMenuFlags::ExecuteDown);
984 }
985 else
986 pPopup->EndExecute();
987 }
988 }
989 }
990
get_item_active(const OString & rIdent) const991 virtual bool get_item_active(const OString& rIdent) const override
992 {
993 return m_xToolBox->IsItemChecked(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)));
994 }
995
set_item_popover(const OString & rIdent,weld::Widget * pPopover)996 virtual void set_item_popover(const OString& rIdent, weld::Widget* pPopover) override
997 {
998 SalInstanceWidget* pPopoverWidget = dynamic_cast<SalInstanceWidget*>(pPopover);
999
1000 vcl::Window* pFloat = pPopoverWidget ? pPopoverWidget->getWidget() : nullptr;
1001 if (pFloat)
1002 pFloat->EnableDocking();
1003
1004 sal_uInt16 nId = m_xToolBox->GetItemId(OUString::fromUtf8(rIdent));
1005 m_aFloats[nId] = pFloat;
1006 m_aMenus[nId] = nullptr;
1007 }
1008
set_item_menu(const OString & rIdent,weld::Menu * pMenu)1009 virtual void set_item_menu(const OString& rIdent, weld::Menu* pMenu) override
1010 {
1011 SalInstanceMenu* pInstanceMenu = dynamic_cast<SalInstanceMenu*>(pMenu);
1012
1013 PopupMenu* pPopup = pInstanceMenu? pInstanceMenu->getMenu() : nullptr;
1014
1015 sal_uInt16 nId = m_xToolBox->GetItemId(OUString::fromUtf8(rIdent));
1016 m_aMenus[nId] = pPopup;
1017 m_aFloats[nId] = nullptr;
1018 }
1019
insert_separator(int pos,const OUString &)1020 virtual void insert_separator(int pos, const OUString& /*rId*/) override
1021 {
1022 auto nInsertPos = pos == -1 ? ToolBox::APPEND : pos;
1023 m_xToolBox->InsertSeparator(nInsertPos, 5);
1024 }
1025
get_n_items() const1026 virtual int get_n_items() const override
1027 {
1028 return m_xToolBox->GetItemCount();
1029 }
1030
get_item_ident(int nIndex) const1031 virtual OString get_item_ident(int nIndex) const override
1032 {
1033 return m_xToolBox->GetItemCommand(m_xToolBox->GetItemId(nIndex)).toUtf8();
1034 }
1035
set_item_label(int nIndex,const OUString & rLabel)1036 virtual void set_item_label(int nIndex, const OUString& rLabel) override
1037 {
1038 m_xToolBox->SetItemText(m_xToolBox->GetItemId(nIndex), rLabel);
1039 }
1040
set_item_icon(int nIndex,const css::uno::Reference<css::graphic::XGraphic> & rIcon)1041 virtual void set_item_icon(int nIndex, const css::uno::Reference<css::graphic::XGraphic>& rIcon) override
1042 {
1043 m_xToolBox->SetItemImage(m_xToolBox->GetItemId(nIndex), Image(rIcon));
1044 }
1045
set_item_tooltip_text(int nIndex,const OUString & rTip)1046 virtual void set_item_tooltip_text(int nIndex, const OUString& rTip) override
1047 {
1048 m_xToolBox->SetQuickHelpText(m_xToolBox->GetItemId(nIndex), rTip);
1049 }
1050
get_icon_size() const1051 virtual vcl::ImageType get_icon_size() const override
1052 {
1053 return m_xToolBox->GetImageSize();
1054 }
1055
~SalInstanceToolbar()1056 virtual ~SalInstanceToolbar() override
1057 {
1058 m_xToolBox->SetDropdownClickHdl(Link<ToolBox*, void>());
1059 m_xToolBox->SetSelectHdl(Link<ToolBox*, void>());
1060 }
1061 };
1062
IMPL_LINK_NOARG(SalInstanceToolbar,ClickHdl,ToolBox *,void)1063 IMPL_LINK_NOARG(SalInstanceToolbar, ClickHdl, ToolBox*, void)
1064 {
1065 sal_uInt16 nItemId = m_xToolBox->GetCurItemId();
1066 signal_clicked(m_xToolBox->GetItemCommand(nItemId).toUtf8());
1067 }
1068
IMPL_LINK_NOARG(SalInstanceToolbar,DropdownClick,ToolBox *,void)1069 IMPL_LINK_NOARG(SalInstanceToolbar, DropdownClick, ToolBox*, void)
1070 {
1071 sal_uInt16 nItemId = m_xToolBox->GetCurItemId();
1072 set_item_active(m_xToolBox->GetItemCommand(nItemId).toUtf8(), true);
1073 }
1074
1075 class SalInstanceSizeGroup : public weld::SizeGroup
1076 {
1077 private:
1078 std::shared_ptr<VclSizeGroup> m_xGroup;
1079 public:
SalInstanceSizeGroup()1080 SalInstanceSizeGroup()
1081 : m_xGroup(new VclSizeGroup)
1082 {
1083 }
add_widget(weld::Widget * pWidget)1084 virtual void add_widget(weld::Widget* pWidget) override
1085 {
1086 SalInstanceWidget* pVclWidget = dynamic_cast<SalInstanceWidget*>(pWidget);
1087 assert(pVclWidget);
1088 m_xGroup->insert(pVclWidget->getWidget());
1089 }
set_mode(VclSizeGroupMode eMode)1090 virtual void set_mode(VclSizeGroupMode eMode) override
1091 {
1092 m_xGroup->set_mode(eMode);
1093 }
1094 };
1095
1096 class SalInstanceContainer : public SalInstanceWidget, public virtual weld::Container
1097 {
1098 protected:
1099 VclPtr<vcl::Window> m_xContainer;
1100
1101 private:
implResetDefault(const vcl::Window * _pWindow)1102 void implResetDefault(const vcl::Window* _pWindow)
1103 {
1104 vcl::Window* pChildLoop = _pWindow->GetWindow(GetWindowType::FirstChild);
1105 while (pChildLoop)
1106 {
1107 // does the window participate in the tabbing order?
1108 if (pChildLoop->GetStyle() & WB_DIALOGCONTROL)
1109 implResetDefault(pChildLoop);
1110
1111 // is it a button?
1112 WindowType eType = pChildLoop->GetType();
1113 if ( (WindowType::PUSHBUTTON == eType)
1114 || (WindowType::OKBUTTON == eType)
1115 || (WindowType::CANCELBUTTON == eType)
1116 || (WindowType::HELPBUTTON == eType)
1117 || (WindowType::IMAGEBUTTON == eType)
1118 || (WindowType::MENUBUTTON == eType)
1119 || (WindowType::MOREBUTTON == eType)
1120 )
1121 {
1122 pChildLoop->SetStyle(pChildLoop->GetStyle() & ~WB_DEFBUTTON);
1123 }
1124
1125 // the next one ...
1126 pChildLoop = pChildLoop->GetWindow(GetWindowType::Next);
1127 }
1128 }
1129
1130 public:
SalInstanceContainer(vcl::Window * pContainer,SalInstanceBuilder * pBuilder,bool bTakeOwnership)1131 SalInstanceContainer(vcl::Window* pContainer, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
1132 : SalInstanceWidget(pContainer, pBuilder, bTakeOwnership)
1133 , m_xContainer(pContainer)
1134 {
1135 }
move(weld::Widget * pWidget,weld::Container * pNewParent)1136 virtual void move(weld::Widget* pWidget, weld::Container* pNewParent) override
1137 {
1138 SalInstanceWidget* pVclWidget = dynamic_cast<SalInstanceWidget*>(pWidget);
1139 assert(pVclWidget);
1140 SalInstanceContainer* pNewVclParent = dynamic_cast<SalInstanceContainer*>(pNewParent);
1141 assert(!pNewParent || pNewVclParent);
1142 pVclWidget->getWidget()->SetParent(pNewVclParent ? pNewVclParent->getWidget() : nullptr);
1143 }
recursively_unset_default_buttons()1144 virtual void recursively_unset_default_buttons() override
1145 {
1146 implResetDefault(m_xContainer.get());
1147 }
CreateChildFrame()1148 virtual css::uno::Reference<css::awt::XWindow> CreateChildFrame() override
1149 {
1150 auto xPage = VclPtr<VclBin>::Create(m_xContainer.get());
1151 xPage->set_expand(true);
1152 xPage->Show();
1153 return css::uno::Reference<css::awt::XWindow>(xPage->GetComponentInterface(), css::uno::UNO_QUERY);
1154 }
1155 };
1156
weld_parent() const1157 std::unique_ptr<weld::Container> SalInstanceWidget::weld_parent() const
1158 {
1159 vcl::Window* pParent = m_xWidget->GetParent();
1160 if (!pParent)
1161 return nullptr;
1162 return std::make_unique<SalInstanceContainer>(pParent, m_pBuilder, false);
1163 }
1164
1165 class SalInstanceBox : public SalInstanceContainer, public virtual weld::Box
1166 {
1167 public:
SalInstanceBox(vcl::Window * pContainer,SalInstanceBuilder * pBuilder,bool bTakeOwnership)1168 SalInstanceBox(vcl::Window* pContainer, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
1169 : SalInstanceContainer(pContainer, pBuilder, bTakeOwnership)
1170 {
1171 }
reorder_child(weld::Widget * pWidget,int nNewPosition)1172 virtual void reorder_child(weld::Widget* pWidget, int nNewPosition) override
1173 {
1174 SalInstanceWidget* pVclWidget = dynamic_cast<SalInstanceWidget*>(pWidget);
1175 assert(pVclWidget);
1176 pVclWidget->getWidget()->reorderWithinParent(nNewPosition);
1177 }
1178 };
1179
1180 namespace
1181 {
CollectChildren(const vcl::Window & rCurrent,const basegfx::B2IPoint & rTopLeft,weld::ScreenShotCollection & rControlDataCollection)1182 void CollectChildren(const vcl::Window& rCurrent, const basegfx::B2IPoint& rTopLeft, weld::ScreenShotCollection& rControlDataCollection)
1183 {
1184 if (rCurrent.IsVisible())
1185 {
1186 const Point aCurrentPos(rCurrent.GetPosPixel());
1187 const Size aCurrentSize(rCurrent.GetSizePixel());
1188 const basegfx::B2IPoint aCurrentTopLeft(rTopLeft.getX() + aCurrentPos.X(), rTopLeft.getY() + aCurrentPos.Y());
1189 const basegfx::B2IRange aCurrentRange(aCurrentTopLeft, aCurrentTopLeft + basegfx::B2IPoint(aCurrentSize.Width(), aCurrentSize.Height()));
1190
1191 if (!aCurrentRange.isEmpty())
1192 {
1193 rControlDataCollection.emplace_back(rCurrent.GetHelpId(), aCurrentRange);
1194 }
1195
1196 for (sal_uInt16 a(0); a < rCurrent.GetChildCount(); a++)
1197 {
1198 vcl::Window* pChild = rCurrent.GetChild(a);
1199 if (nullptr != pChild)
1200 {
1201 CollectChildren(*pChild, aCurrentTopLeft, rControlDataCollection);
1202 }
1203 }
1204 }
1205 }
1206 }
1207
1208 class SalInstanceWindow : public SalInstanceContainer, public virtual weld::Window
1209 {
1210 private:
1211 VclPtr<vcl::Window> m_xWindow;
1212
1213 DECL_LINK(HelpHdl, vcl::Window&, bool);
1214
override_child_help(vcl::Window * pParent)1215 void override_child_help(vcl::Window* pParent)
1216 {
1217 for (vcl::Window *pChild = pParent->GetWindow(GetWindowType::FirstChild); pChild; pChild = pChild->GetWindow(GetWindowType::Next))
1218 override_child_help(pChild);
1219 pParent->SetHelpHdl(LINK(this, SalInstanceWindow, HelpHdl));
1220 }
1221
clear_child_help(vcl::Window * pParent)1222 void clear_child_help(vcl::Window* pParent)
1223 {
1224 for (vcl::Window *pChild = pParent->GetWindow(GetWindowType::FirstChild); pChild; pChild = pChild->GetWindow(GetWindowType::Next))
1225 clear_child_help(pChild);
1226 pParent->SetHelpHdl(Link<vcl::Window&,bool>());
1227 }
1228
1229 public:
SalInstanceWindow(vcl::Window * pWindow,SalInstanceBuilder * pBuilder,bool bTakeOwnership)1230 SalInstanceWindow(vcl::Window* pWindow, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
1231 : SalInstanceContainer(pWindow, pBuilder, bTakeOwnership)
1232 , m_xWindow(pWindow)
1233 {
1234 override_child_help(m_xWindow);
1235 }
1236
set_title(const OUString & rTitle)1237 virtual void set_title(const OUString& rTitle) override
1238 {
1239 m_xWindow->SetText(rTitle);
1240 }
1241
get_title() const1242 virtual OUString get_title() const override
1243 {
1244 return m_xWindow->GetText();
1245 }
1246
1247 void help();
1248
set_busy_cursor(bool bBusy)1249 virtual void set_busy_cursor(bool bBusy) override
1250 {
1251 if (bBusy)
1252 m_xWindow->EnterWait();
1253 else
1254 m_xWindow->LeaveWait();
1255 }
1256
GetXWindow()1257 virtual css::uno::Reference<css::awt::XWindow> GetXWindow() override
1258 {
1259 css::uno::Reference<css::awt::XWindow> xWindow(m_xWindow->GetComponentInterface(), css::uno::UNO_QUERY);
1260 return xWindow;
1261 }
1262
resize_to_request()1263 virtual void resize_to_request() override
1264 {
1265 if (SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(m_xWindow.get()))
1266 {
1267 pSysWin->setOptimalLayoutSize();
1268 return;
1269 }
1270 if (DockingWindow* pDockWin = dynamic_cast<DockingWindow*>(m_xWindow.get()))
1271 {
1272 pDockWin->setOptimalLayoutSize();
1273 return;
1274 }
1275 assert(false && "must be system or docking window");
1276 }
1277
set_modal(bool bModal)1278 virtual void set_modal(bool bModal) override
1279 {
1280 m_xWindow->ImplGetFrame()->SetModal(bModal);
1281 }
1282
get_modal() const1283 virtual bool get_modal() const override
1284 {
1285 return m_xWindow->ImplGetFrame()->GetModal();
1286 }
1287
window_move(int x,int y)1288 virtual void window_move(int x, int y) override
1289 {
1290 m_xWindow->SetPosPixel(Point(x, y));
1291 }
1292
get_size() const1293 virtual Size get_size() const override
1294 {
1295 return m_xWindow->GetSizePixel();
1296 }
1297
get_position() const1298 virtual Point get_position() const override
1299 {
1300 return m_xWindow->GetPosPixel();
1301 }
1302
get_monitor_workarea() const1303 virtual tools::Rectangle get_monitor_workarea() const override
1304 {
1305 return m_xWindow->GetDesktopRectPixel();
1306 }
1307
set_centered_on_parent(bool)1308 virtual void set_centered_on_parent(bool /*bTrackGeometryRequests*/) override
1309 {
1310 if (vcl::Window* pParent = m_xWidget->GetParent())
1311 {
1312 Size aParentGeometry(pParent->GetSizePixel());
1313 Size aGeometry(m_xWidget->get_preferred_size());
1314 auto nX = (aParentGeometry.Width() - aGeometry.Width()) / 2;
1315 auto nY = (aParentGeometry.Height() - aGeometry.Height()) / 2;
1316 m_xWidget->SetPosPixel(Point(nX, nY));
1317 }
1318 }
1319
get_resizable() const1320 virtual bool get_resizable() const override
1321 {
1322 return m_xWindow->GetStyle() & WB_SIZEABLE;
1323 }
1324
has_toplevel_focus() const1325 virtual bool has_toplevel_focus() const override
1326 {
1327 return m_xWindow->HasChildPathFocus();
1328 }
1329
present()1330 virtual void present() override
1331 {
1332 m_xWindow->ToTop(ToTopFlags::RestoreWhenMin | ToTopFlags::ForegroundTask);
1333 }
1334
set_window_state(const OString & rStr)1335 virtual void set_window_state(const OString& rStr) override
1336 {
1337 SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(m_xWindow.get());
1338 assert(pSysWin);
1339 pSysWin->SetWindowState(rStr);
1340 }
1341
get_window_state(WindowStateMask nMask) const1342 virtual OString get_window_state(WindowStateMask nMask) const override
1343 {
1344 SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(m_xWindow.get());
1345 assert(pSysWin);
1346 return pSysWin->GetWindowState(nMask);
1347 }
1348
get_system_data() const1349 virtual SystemEnvData get_system_data() const override
1350 {
1351 return *m_xWindow->GetSystemData();
1352 }
1353
connect_toplevel_focus_changed(const Link<weld::Widget &,void> & rLink)1354 virtual void connect_toplevel_focus_changed(const Link<weld::Widget&, void>& rLink) override
1355 {
1356 ensure_event_listener();
1357 weld::Window::connect_toplevel_focus_changed(rLink);
1358 }
1359
HandleEventListener(VclWindowEvent & rEvent)1360 virtual void HandleEventListener(VclWindowEvent& rEvent) override
1361 {
1362 if (rEvent.GetId() == VclEventId::WindowActivate || rEvent.GetId() == VclEventId::WindowDeactivate)
1363 {
1364 signal_toplevel_focus_changed();
1365 return;
1366 }
1367 SalInstanceContainer::HandleEventListener(rEvent);
1368 }
1369
draw(VirtualDevice & rOutput)1370 virtual void draw(VirtualDevice& rOutput) override
1371 {
1372 SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(m_xWindow.get());
1373 assert(pSysWin);
1374 pSysWin->createScreenshot(rOutput);
1375 }
1376
collect_screenshot_data()1377 virtual weld::ScreenShotCollection collect_screenshot_data() override
1378 {
1379 weld::ScreenShotCollection aRet;
1380
1381 // collect all children. Choose start pos to be negative
1382 // of target dialog's position to get all positions relative to (0,0)
1383 const Point aParentPos(m_xWindow->GetPosPixel());
1384 const basegfx::B2IPoint aTopLeft(-aParentPos.X(), -aParentPos.Y());
1385 CollectChildren(*m_xWindow, aTopLeft, aRet);
1386
1387 return aRet;
1388 }
1389
~SalInstanceWindow()1390 virtual ~SalInstanceWindow() override
1391 {
1392 clear_child_help(m_xWindow);
1393 }
1394 };
1395
IMPL_LINK_NOARG(SalInstanceWindow,HelpHdl,vcl::Window &,bool)1396 IMPL_LINK_NOARG(SalInstanceWindow, HelpHdl, vcl::Window&, bool)
1397 {
1398 help();
1399 return false;
1400 }
1401
1402 typedef std::set<VclPtr<vcl::Window> > winset;
1403
1404 namespace
1405 {
hideUnless(const vcl::Window * pTop,const winset & rVisibleWidgets,std::vector<VclPtr<vcl::Window>> & rWasVisibleWidgets)1406 void hideUnless(const vcl::Window *pTop, const winset& rVisibleWidgets,
1407 std::vector<VclPtr<vcl::Window> > &rWasVisibleWidgets)
1408 {
1409 for (vcl::Window* pChild = pTop->GetWindow(GetWindowType::FirstChild); pChild;
1410 pChild = pChild->GetWindow(GetWindowType::Next))
1411 {
1412 if (!pChild->IsVisible())
1413 continue;
1414 if (rVisibleWidgets.find(pChild) == rVisibleWidgets.end())
1415 {
1416 rWasVisibleWidgets.emplace_back(pChild);
1417 pChild->Hide();
1418 }
1419 else if (isContainerWindow(pChild))
1420 {
1421 hideUnless(pChild, rVisibleWidgets, rWasVisibleWidgets);
1422 }
1423 }
1424 }
1425 }
1426
1427 class SalInstanceDialog : public SalInstanceWindow, public virtual weld::Dialog
1428 {
1429 private:
1430 VclPtr<::Dialog> m_xDialog;
1431
1432 // for calc ref dialog that shrink to range selection widgets and resize back
1433 VclPtr<vcl::Window> m_xRefEdit;
1434 std::vector<VclPtr<vcl::Window> > m_aHiddenWidgets; // vector of hidden Controls
1435 long m_nOldEditWidthReq; // Original width request of the input field
1436 sal_Int32 m_nOldBorderWidth; // border width for expanded dialog
1437
1438 DECL_LINK(PopupScreenShotMenuHdl, const CommandEvent&, bool);
1439
1440 public:
SalInstanceDialog(::Dialog * pDialog,SalInstanceBuilder * pBuilder,bool bTakeOwnership)1441 SalInstanceDialog(::Dialog* pDialog, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
1442 : SalInstanceWindow(pDialog, pBuilder, bTakeOwnership)
1443 , m_xDialog(pDialog)
1444 , m_nOldEditWidthReq(0)
1445 , m_nOldBorderWidth(0)
1446 {
1447 const bool bScreenshotMode(officecfg::Office::Common::Misc::ScreenshotMode::get());
1448 if (bScreenshotMode)
1449 {
1450 m_xDialog->SetPopupMenuHdl(LINK(this, SalInstanceDialog, PopupScreenShotMenuHdl));
1451 }
1452 }
1453
runAsync(std::shared_ptr<weld::DialogController> aOwner,const std::function<void (sal_Int32)> & rEndDialogFn)1454 virtual bool runAsync(std::shared_ptr<weld::DialogController> aOwner, const std::function<void(sal_Int32)> &rEndDialogFn) override
1455 {
1456 VclAbstractDialog::AsyncContext aCtx;
1457 aCtx.mxOwnerDialogController = aOwner;
1458 aCtx.maEndDialogFn = rEndDialogFn;
1459 VclButtonBox* pActionArea = m_xDialog->get_action_area();
1460 if (pActionArea)
1461 pActionArea->sort_native_button_order();
1462 return m_xDialog->StartExecuteAsync(aCtx);
1463 }
1464
runAsync(std::shared_ptr<Dialog> const & rxSelf,const std::function<void (sal_Int32)> & rEndDialogFn)1465 virtual bool runAsync(std::shared_ptr<Dialog> const & rxSelf, const std::function<void(sal_Int32)> &rEndDialogFn) override
1466 {
1467 assert( rxSelf.get() == this );
1468 VclAbstractDialog::AsyncContext aCtx;
1469 // In order to store a shared_ptr to ourself, we have to have been constructed by make_shared,
1470 // which is that rxSelf enforces.
1471 aCtx.mxOwnerSelf = rxSelf;
1472 aCtx.maEndDialogFn = rEndDialogFn;
1473 VclButtonBox* pActionArea = m_xDialog->get_action_area();
1474 if (pActionArea)
1475 pActionArea->sort_native_button_order();
1476 return m_xDialog->StartExecuteAsync(aCtx);
1477 }
1478
collapse(weld::Widget * pEdit,weld::Widget * pButton)1479 virtual void collapse(weld::Widget* pEdit, weld::Widget* pButton) override
1480 {
1481 SalInstanceWidget* pVclEdit = dynamic_cast<SalInstanceWidget*>(pEdit);
1482 assert(pVclEdit);
1483 SalInstanceWidget* pVclButton = dynamic_cast<SalInstanceWidget*>(pButton);
1484
1485 vcl::Window* pRefEdit = pVclEdit->getWidget();
1486 vcl::Window* pRefBtn = pVclButton ? pVclButton->getWidget() : nullptr;
1487
1488 auto nOldEditWidth = pRefEdit->GetSizePixel().Width();
1489 m_nOldEditWidthReq = pRefEdit->get_width_request();
1490
1491 //We want just pRefBtn and pRefEdit to be shown
1492 //mark widgets we want to be visible, starting with pRefEdit
1493 //and all its direct parents.
1494 winset aVisibleWidgets;
1495 vcl::Window *pContentArea = m_xDialog->get_content_area();
1496 for (vcl::Window *pCandidate = pRefEdit;
1497 pCandidate && (pCandidate != pContentArea && pCandidate->IsVisible());
1498 pCandidate = pCandidate->GetWindow(GetWindowType::RealParent))
1499 {
1500 aVisibleWidgets.insert(pCandidate);
1501 }
1502 //same again with pRefBtn, except stop if there's a
1503 //shared parent in the existing widgets
1504 for (vcl::Window *pCandidate = pRefBtn;
1505 pCandidate && (pCandidate != pContentArea && pCandidate->IsVisible());
1506 pCandidate = pCandidate->GetWindow(GetWindowType::RealParent))
1507 {
1508 if (aVisibleWidgets.insert(pCandidate).second)
1509 break;
1510 }
1511
1512 //hide everything except the aVisibleWidgets
1513 hideUnless(pContentArea, aVisibleWidgets, m_aHiddenWidgets);
1514
1515 // the insert function case has an initially hidden edit widget, so it has
1516 // not start size, so take larger of actual size and size request
1517 pRefEdit->set_width_request(std::max(nOldEditWidth, m_nOldEditWidthReq));
1518 m_nOldBorderWidth = m_xDialog->get_border_width();
1519 m_xDialog->set_border_width(0);
1520 if (vcl::Window *pActionArea = m_xDialog->get_action_area())
1521 pActionArea->Hide();
1522 m_xDialog->setOptimalLayoutSize();
1523 m_xRefEdit = pRefEdit;
1524 }
1525
undo_collapse()1526 virtual void undo_collapse() override
1527 {
1528 // All others: Show();
1529 for (VclPtr<vcl::Window> const & pWindow : m_aHiddenWidgets)
1530 {
1531 pWindow->Show();
1532 }
1533 m_aHiddenWidgets.clear();
1534
1535 m_xRefEdit->set_width_request(m_nOldEditWidthReq);
1536 m_xRefEdit.clear();
1537 m_xDialog->set_border_width(m_nOldBorderWidth);
1538 if (vcl::Window *pActionArea = m_xDialog->get_action_area())
1539 pActionArea->Show();
1540 m_xDialog->setOptimalLayoutSize();
1541 }
1542
SetInstallLOKNotifierHdl(const Link<void *,vcl::ILibreOfficeKitNotifier * > & rLink)1543 virtual void SetInstallLOKNotifierHdl(const Link<void*, vcl::ILibreOfficeKitNotifier*>& rLink) override
1544 {
1545 m_xDialog->SetInstallLOKNotifierHdl(rLink);
1546 }
1547
run()1548 virtual int run() override
1549 {
1550 VclButtonBox* pActionArea = m_xDialog->get_action_area();
1551 if (pActionArea)
1552 pActionArea->sort_native_button_order();
1553 return m_xDialog->Execute();
1554 }
1555
response(int nResponse)1556 virtual void response(int nResponse) override
1557 {
1558 m_xDialog->EndDialog(nResponse);
1559 }
1560
add_button(const OUString & rText,int nResponse,const OString & rHelpId)1561 virtual void add_button(const OUString& rText, int nResponse, const OString& rHelpId) override
1562 {
1563 VclButtonBox* pBox = m_xDialog->get_action_area();
1564 VclPtr<PushButton> xButton(VclPtr<PushButton>::Create(pBox, WB_CLIPCHILDREN|WB_CENTER|WB_VCENTER));
1565 xButton->SetText(rText);
1566 xButton->SetHelpId(rHelpId);
1567
1568 switch (nResponse)
1569 {
1570 case RET_OK:
1571 xButton->set_id("ok");
1572 break;
1573 case RET_CLOSE:
1574 xButton->set_id("close");
1575 break;
1576 case RET_CANCEL:
1577 xButton->set_id("cancel");
1578 break;
1579 case RET_YES:
1580 xButton->set_id("yes");
1581 break;
1582 case RET_NO:
1583 xButton->set_id("no");
1584 break;
1585 }
1586
1587 xButton->Show();
1588 m_xDialog->add_button(xButton, nResponse, true);
1589 }
1590
set_modal(bool bModal)1591 virtual void set_modal(bool bModal) override
1592 {
1593 if (get_modal() == bModal)
1594 return;
1595 m_xDialog->SetModalInputMode(bModal);
1596 }
1597
get_modal() const1598 virtual bool get_modal() const override
1599 {
1600 return m_xDialog->IsModalInputMode();
1601 }
1602
1603 virtual weld::Button* weld_widget_for_response(int nResponse) override;
1604
set_default_response(int nResponse)1605 virtual void set_default_response(int nResponse) override
1606 {
1607 m_xDialog->set_default_response(nResponse);
1608 }
1609
weld_content_area()1610 virtual Container* weld_content_area() override
1611 {
1612 return new SalInstanceContainer(m_xDialog->get_content_area(), m_pBuilder, false);
1613 }
1614
1615 };
1616
IMPL_LINK(SalInstanceDialog,PopupScreenShotMenuHdl,const CommandEvent &,rCEvt,bool)1617 IMPL_LINK(SalInstanceDialog, PopupScreenShotMenuHdl, const CommandEvent&, rCEvt, bool)
1618 {
1619 if (CommandEventId::ContextMenu == rCEvt.GetCommand())
1620 {
1621 const Point aMenuPos(rCEvt.GetMousePosPixel());
1622 ScopedVclPtrInstance<PopupMenu> aMenu;
1623 sal_uInt16 nLocalID(1);
1624
1625 aMenu->InsertItem(nLocalID, VclResId(SV_BUTTONTEXT_SCREENSHOT));
1626 aMenu->SetHelpText(nLocalID, VclResId(SV_HELPTEXT_SCREENSHOT));
1627 aMenu->SetHelpId(nLocalID, "InteractiveScreenshotMode");
1628 aMenu->EnableItem(nLocalID);
1629
1630 const sal_uInt16 nId(aMenu->Execute(m_xDialog, aMenuPos));
1631
1632 // 0 == no selection (so not usable as ID)
1633 if (0 != nId)
1634 {
1635 // open screenshot annotation dialog
1636 VclAbstractDialogFactory* pFact = VclAbstractDialogFactory::Create();
1637 VclPtr<AbstractScreenshotAnnotationDlg> pTmp = pFact->CreateScreenshotAnnotationDlg(*this);
1638 ScopedVclPtr<AbstractScreenshotAnnotationDlg> pDialog(pTmp);
1639
1640 if (pDialog)
1641 {
1642 // currently just execute the dialog, no need to do
1643 // different things for ok/cancel. This may change later,
1644 // for that case use 'if (pDlg->Execute() == RET_OK)'
1645 pDialog->Execute();
1646 }
1647 }
1648
1649 // consume event when:
1650 // - CommandEventId::ContextMenu
1651 // - bScreenshotMode
1652 return true;
1653 }
1654
1655 return false;
1656 }
1657
1658 class SalInstanceMessageDialog : public SalInstanceDialog, public virtual weld::MessageDialog
1659 {
1660 private:
1661 VclPtr<::MessageDialog> m_xMessageDialog;
1662 public:
SalInstanceMessageDialog(::MessageDialog * pDialog,SalInstanceBuilder * pBuilder,bool bTakeOwnership)1663 SalInstanceMessageDialog(::MessageDialog* pDialog, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
1664 : SalInstanceDialog(pDialog, pBuilder, bTakeOwnership)
1665 , m_xMessageDialog(pDialog)
1666 {
1667 }
1668
set_primary_text(const OUString & rText)1669 virtual void set_primary_text(const OUString& rText) override
1670 {
1671 m_xMessageDialog->set_primary_text(rText);
1672 }
1673
get_primary_text() const1674 virtual OUString get_primary_text() const override
1675 {
1676 return m_xMessageDialog->get_primary_text();
1677 }
1678
set_secondary_text(const OUString & rText)1679 virtual void set_secondary_text(const OUString& rText) override
1680 {
1681 m_xMessageDialog->set_secondary_text(rText);
1682 }
1683
get_secondary_text() const1684 virtual OUString get_secondary_text() const override
1685 {
1686 return m_xMessageDialog->get_secondary_text();
1687 }
1688
weld_message_area()1689 virtual Container* weld_message_area() override
1690 {
1691 return new SalInstanceContainer(m_xMessageDialog->get_message_area(), m_pBuilder, false);
1692 }
1693 };
1694
1695 class SalInstanceAboutDialog : public SalInstanceDialog, public virtual weld::AboutDialog
1696 {
1697 private:
1698 VclPtr<vcl::AboutDialog> m_xAboutDialog;
1699 public:
SalInstanceAboutDialog(vcl::AboutDialog * pDialog,SalInstanceBuilder * pBuilder,bool bTakeOwnership)1700 SalInstanceAboutDialog(vcl::AboutDialog* pDialog, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
1701 : SalInstanceDialog(pDialog, pBuilder, bTakeOwnership)
1702 , m_xAboutDialog(pDialog)
1703 {
1704 }
set_version(const OUString & rVersion)1705 virtual void set_version(const OUString& rVersion) override
1706 {
1707 m_xAboutDialog->SetVersion(rVersion);
1708 }
set_copyright(const OUString & rCopyright)1709 virtual void set_copyright(const OUString& rCopyright) override
1710 {
1711 m_xAboutDialog->SetCopyright(rCopyright);
1712 }
set_website(const OUString & rURL)1713 virtual void set_website(const OUString& rURL) override
1714 {
1715 m_xAboutDialog->SetWebsiteLink(rURL);
1716 }
set_website_label(const OUString & rLabel)1717 virtual void set_website_label(const OUString& rLabel) override
1718 {
1719 m_xAboutDialog->SetWebsiteLabel(rLabel);
1720 }
get_website_label() const1721 virtual OUString get_website_label() const override
1722 {
1723 return m_xAboutDialog->GetWebsiteLabel();
1724 }
set_logo(const css::uno::Reference<css::graphic::XGraphic> & rImage)1725 virtual void set_logo(const css::uno::Reference<css::graphic::XGraphic>& rImage) override
1726 {
1727 m_xAboutDialog->SetLogo(Image(rImage));
1728 }
set_background(const css::uno::Reference<css::graphic::XGraphic> & rImage)1729 virtual void set_background(const css::uno::Reference<css::graphic::XGraphic>& rImage) override
1730 {
1731 m_xAboutDialog->SetBackground(Image(rImage));
1732 }
1733 };
1734
1735 class SalInstanceAssistant : public SalInstanceDialog, public virtual weld::Assistant
1736 {
1737 private:
1738 VclPtr<vcl::RoadmapWizard> m_xWizard;
1739 std::vector<std::unique_ptr<SalInstanceContainer>> m_aPages;
1740 std::vector<VclPtr<TabPage>> m_aAddedPages;
1741 std::vector<int> m_aIds;
1742 std::vector<VclPtr<VclGrid>> m_aAddedGrids;
1743 Idle m_aUpdateRoadmapIdle;
1744
find_page(const OString & rIdent) const1745 int find_page(const OString& rIdent) const
1746 {
1747 for (size_t i = 0; i < m_aAddedPages.size(); ++i)
1748 {
1749 if (m_aAddedPages[i]->get_id().toUtf8() == rIdent)
1750 return i;
1751 }
1752 return -1;
1753 }
1754
find_id(int nId) const1755 int find_id(int nId) const
1756 {
1757 for (size_t i = 0; i < m_aIds.size(); ++i)
1758 {
1759 if (nId == m_aIds[i])
1760 return i;
1761 }
1762 return -1;
1763 }
1764
1765 DECL_LINK(OnRoadmapItemSelected, LinkParamNone*, void);
1766 DECL_LINK(UpdateRoadmap_Hdl, Timer*, void);
1767
1768 public:
SalInstanceAssistant(vcl::RoadmapWizard * pDialog,SalInstanceBuilder * pBuilder,bool bTakeOwnership)1769 SalInstanceAssistant(vcl::RoadmapWizard* pDialog, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
1770 : SalInstanceDialog(pDialog, pBuilder, bTakeOwnership)
1771 , m_xWizard(pDialog)
1772 {
1773 m_xWizard->SetItemSelectHdl(LINK(this, SalInstanceAssistant, OnRoadmapItemSelected));
1774
1775 m_aUpdateRoadmapIdle.SetInvokeHandler(LINK(this, SalInstanceAssistant, UpdateRoadmap_Hdl));
1776 m_aUpdateRoadmapIdle.SetPriority(TaskPriority::HIGHEST);
1777 }
1778
get_current_page() const1779 virtual int get_current_page() const override
1780 {
1781 return find_id(m_xWizard->GetCurLevel());
1782 }
1783
get_n_pages() const1784 virtual int get_n_pages() const override
1785 {
1786 return m_aAddedPages.size();
1787 }
1788
get_page_ident(int nPage) const1789 virtual OString get_page_ident(int nPage) const override
1790 {
1791 return m_aAddedPages[nPage]->get_id().toUtf8();
1792 }
1793
get_current_page_ident() const1794 virtual OString get_current_page_ident() const override
1795 {
1796 return get_page_ident(get_current_page());
1797 }
1798
set_current_page(int nPage)1799 virtual void set_current_page(int nPage) override
1800 {
1801 disable_notify_events();
1802
1803 // take the first shown page as the size for all pages
1804 if (m_xWizard->GetPageSizePixel().Width() == 0)
1805 {
1806 Size aFinalSize;
1807 for (int i = 0, nPages = get_n_pages(); i < nPages; ++i)
1808 {
1809 TabPage* pPage = m_xWizard->GetPage(m_aIds[i]);
1810 assert(pPage);
1811 Size aPageSize(pPage->get_preferred_size());
1812 if (aPageSize.Width() > aFinalSize.Width())
1813 aFinalSize.setWidth(aPageSize.Width());
1814 if (aPageSize.Height() > aFinalSize.Height())
1815 aFinalSize.setHeight(aPageSize.Height());
1816 }
1817 m_xWizard->SetPageSizePixel(aFinalSize);
1818 }
1819
1820 (void)m_xWizard->ShowPage(m_aIds[nPage]);
1821 enable_notify_events();
1822 }
1823
set_current_page(const OString & rIdent)1824 virtual void set_current_page(const OString& rIdent) override
1825 {
1826 int nIndex = find_page(rIdent);
1827 if (nIndex == -1)
1828 return;
1829 set_current_page(nIndex);
1830 }
1831
set_page_index(const OString & rIdent,int nNewIndex)1832 virtual void set_page_index(const OString& rIdent, int nNewIndex) override
1833 {
1834 int nOldIndex = find_page(rIdent);
1835
1836 if (nOldIndex == -1)
1837 return;
1838
1839 if (nOldIndex == nNewIndex)
1840 return;
1841
1842 disable_notify_events();
1843
1844 auto entry = std::move(m_aAddedPages[nOldIndex]);
1845 m_aAddedPages.erase(m_aAddedPages.begin() + nOldIndex);
1846 m_aAddedPages.insert(m_aAddedPages.begin() + nNewIndex, std::move(entry));
1847
1848 int nId = m_aIds[nOldIndex];
1849 m_aIds.erase(m_aIds.begin() + nOldIndex);
1850 m_aIds.insert(m_aIds.begin() + nNewIndex, nId);
1851
1852 m_aUpdateRoadmapIdle.Start();
1853
1854 enable_notify_events();
1855 }
1856
append_page(const OString & rIdent)1857 virtual weld::Container* append_page(const OString& rIdent) override
1858 {
1859 VclPtrInstance<TabPage> xPage(m_xWizard);
1860 VclPtrInstance<VclGrid> xGrid(xPage);
1861 xPage->set_id(OUString::fromUtf8(rIdent));
1862 xPage->Show();
1863 xGrid->set_hexpand(true);
1864 xGrid->set_vexpand(true);
1865 xGrid->Show();
1866 m_xWizard->AddPage(xPage);
1867 m_aIds.push_back(m_aAddedPages.size());
1868 m_xWizard->SetPage(m_aIds.back(), xPage);
1869 m_aAddedPages.push_back(xPage);
1870 m_aAddedGrids.push_back(xGrid);
1871
1872 m_aUpdateRoadmapIdle.Start();
1873
1874 m_aPages.emplace_back(new SalInstanceContainer(xGrid, m_pBuilder, false));
1875 return m_aPages.back().get();
1876 }
1877
get_page_title(const OString & rIdent) const1878 virtual OUString get_page_title(const OString& rIdent) const override
1879 {
1880 int nIndex = find_page(rIdent);
1881 if (nIndex == -1)
1882 return OUString();
1883 return m_aAddedPages[nIndex]->GetText();
1884 }
1885
set_page_title(const OString & rIdent,const OUString & rTitle)1886 virtual void set_page_title(const OString& rIdent, const OUString& rTitle) override
1887 {
1888 int nIndex = find_page(rIdent);
1889 if (nIndex == -1)
1890 return;
1891 if (m_aAddedPages[nIndex]->GetText() != rTitle)
1892 {
1893 disable_notify_events();
1894 m_aAddedPages[nIndex]->SetText(rTitle);
1895 m_aUpdateRoadmapIdle.Start();
1896 enable_notify_events();
1897 }
1898 }
1899
set_page_sensitive(const OString & rIdent,bool bSensitive)1900 virtual void set_page_sensitive(const OString& rIdent, bool bSensitive) override
1901 {
1902 int nIndex = find_page(rIdent);
1903 if (nIndex == -1)
1904 return;
1905 if (m_aAddedPages[nIndex]->IsEnabled() != bSensitive)
1906 {
1907 disable_notify_events();
1908 m_aAddedPages[nIndex]->Enable(bSensitive);
1909 m_aUpdateRoadmapIdle.Start();
1910 enable_notify_events();
1911 }
1912 }
1913
set_page_side_help_id(const OString & rHelpId)1914 virtual void set_page_side_help_id(const OString& rHelpId) override
1915 {
1916 m_xWizard->SetRoadmapHelpId(rHelpId);
1917 }
1918
1919 weld::Button* weld_widget_for_response(int nResponse) override;
1920
~SalInstanceAssistant()1921 virtual ~SalInstanceAssistant() override
1922 {
1923 for (auto &rGrid : m_aAddedGrids)
1924 rGrid.disposeAndClear();
1925 for (auto &rPage : m_aAddedPages)
1926 rPage.disposeAndClear();
1927 }
1928 };
1929
IMPL_LINK_NOARG(SalInstanceAssistant,OnRoadmapItemSelected,LinkParamNone *,void)1930 IMPL_LINK_NOARG(SalInstanceAssistant, OnRoadmapItemSelected, LinkParamNone*, void)
1931 {
1932 if (notify_events_disabled())
1933 return;
1934 auto nCurItemId = m_xWizard->GetCurrentRoadmapItemID();
1935 int nPageIndex(find_id(nCurItemId));
1936 if (!signal_jump_page(get_page_ident(nPageIndex)) && nCurItemId != m_xWizard->GetCurLevel())
1937 m_xWizard->SelectRoadmapItemByID(m_xWizard->GetCurLevel());
1938 }
1939
IMPL_LINK_NOARG(SalInstanceAssistant,UpdateRoadmap_Hdl,Timer *,void)1940 IMPL_LINK_NOARG(SalInstanceAssistant, UpdateRoadmap_Hdl, Timer*, void)
1941 {
1942 disable_notify_events();
1943
1944 m_xWizard->DeleteRoadmapItems();
1945
1946 int nPos = 0;
1947 for (size_t i = 0; i < m_aAddedPages.size(); ++i)
1948 {
1949 const OUString& rLabel = m_aAddedPages[i]->GetText();
1950 bool bSensitive = m_aAddedPages[i]->IsEnabled();
1951 if (rLabel.isEmpty())
1952 continue;
1953 m_xWizard->InsertRoadmapItem(nPos++, rLabel, m_aIds[i], bSensitive);
1954 }
1955
1956 m_xWizard->SelectRoadmapItemByID(m_aIds[get_current_page()]);
1957
1958 m_xWizard->ShowRoadmap(nPos != 0);
1959
1960 enable_notify_events();
1961 }
1962
1963 class SalInstanceFrame : public SalInstanceContainer, public virtual weld::Frame
1964 {
1965 private:
1966 VclPtr<VclFrame> m_xFrame;
1967 public:
SalInstanceFrame(VclFrame * pFrame,SalInstanceBuilder * pBuilder,bool bTakeOwnership)1968 SalInstanceFrame(VclFrame* pFrame, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
1969 : SalInstanceContainer(pFrame, pBuilder, bTakeOwnership)
1970 , m_xFrame(pFrame)
1971 {
1972 }
1973
set_label(const OUString & rText)1974 virtual void set_label(const OUString& rText) override
1975 {
1976 m_xFrame->set_label(rText);
1977 }
1978
get_label() const1979 virtual OUString get_label() const override
1980 {
1981 return m_xFrame->get_label();
1982 }
1983
1984 virtual std::unique_ptr<weld::Label> weld_label_widget() const override;
1985 };
1986
1987 class SalInstanceScrolledWindow : public SalInstanceContainer, public virtual weld::ScrolledWindow
1988 {
1989 private:
1990 VclPtr<VclScrolledWindow> m_xScrolledWindow;
1991 Link<ScrollBar*,void> m_aOrigVScrollHdl;
1992 Link<ScrollBar*,void> m_aOrigHScrollHdl;
1993 bool m_bUserManagedScrolling;
1994
1995 DECL_LINK(VscrollHdl, ScrollBar*, void);
1996 DECL_LINK(HscrollHdl, ScrollBar*, void);
1997
1998 public:
SalInstanceScrolledWindow(VclScrolledWindow * pScrolledWindow,SalInstanceBuilder * pBuilder,bool bTakeOwnership)1999 SalInstanceScrolledWindow(VclScrolledWindow* pScrolledWindow, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2000 : SalInstanceContainer(pScrolledWindow, pBuilder, bTakeOwnership)
2001 , m_xScrolledWindow(pScrolledWindow)
2002 , m_bUserManagedScrolling(false)
2003 {
2004 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2005 m_aOrigVScrollHdl = rVertScrollBar.GetScrollHdl();
2006 rVertScrollBar.SetScrollHdl(LINK(this, SalInstanceScrolledWindow, VscrollHdl));
2007 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2008 m_aOrigHScrollHdl = rHorzScrollBar.GetScrollHdl();
2009 rHorzScrollBar.SetScrollHdl(LINK(this, SalInstanceScrolledWindow, HscrollHdl));
2010 }
2011
hadjustment_configure(int value,int lower,int upper,int step_increment,int page_increment,int page_size)2012 virtual void hadjustment_configure(int value, int lower, int upper,
2013 int step_increment, int page_increment,
2014 int page_size) override
2015 {
2016 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2017 rHorzScrollBar.SetRangeMin(lower);
2018 rHorzScrollBar.SetRangeMax(upper);
2019 rHorzScrollBar.SetLineSize(step_increment);
2020 rHorzScrollBar.SetPageSize(page_increment);
2021 rHorzScrollBar.SetThumbPos(value);
2022 rHorzScrollBar.SetVisibleSize(page_size);
2023 }
2024
hadjustment_get_value() const2025 virtual int hadjustment_get_value() const override
2026 {
2027 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2028 return rHorzScrollBar.GetThumbPos();
2029 }
2030
hadjustment_set_value(int value)2031 virtual void hadjustment_set_value(int value) override
2032 {
2033 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2034 rHorzScrollBar.SetThumbPos(value);
2035 if (!m_bUserManagedScrolling)
2036 m_aOrigHScrollHdl.Call(&rHorzScrollBar);
2037 }
2038
hadjustment_get_upper() const2039 virtual int hadjustment_get_upper() const override
2040 {
2041 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2042 return rHorzScrollBar.GetRangeMax();
2043 }
2044
hadjustment_set_upper(int upper)2045 virtual void hadjustment_set_upper(int upper) override
2046 {
2047 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2048 rHorzScrollBar.SetRangeMax(upper);
2049 }
2050
hadjustment_get_page_size() const2051 virtual int hadjustment_get_page_size() const override
2052 {
2053 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2054 return rHorzScrollBar.GetVisibleSize();
2055 }
2056
hadjustment_set_page_size(int size)2057 virtual void hadjustment_set_page_size(int size) override
2058 {
2059 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2060 return rHorzScrollBar.SetVisibleSize(size);
2061 }
2062
hadjustment_set_page_increment(int size)2063 virtual void hadjustment_set_page_increment(int size) override
2064 {
2065 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2066 return rHorzScrollBar.SetPageSize(size);
2067 }
2068
hadjustment_set_step_increment(int size)2069 virtual void hadjustment_set_step_increment(int size) override
2070 {
2071 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2072 return rHorzScrollBar.SetLineSize(size);
2073 }
2074
set_hpolicy(VclPolicyType eHPolicy)2075 virtual void set_hpolicy(VclPolicyType eHPolicy) override
2076 {
2077 WinBits nWinBits = m_xScrolledWindow->GetStyle() & ~(WB_AUTOHSCROLL|WB_HSCROLL);
2078 if (eHPolicy == VclPolicyType::ALWAYS)
2079 nWinBits |= WB_HSCROLL;
2080 else if (eHPolicy == VclPolicyType::AUTOMATIC)
2081 nWinBits |= WB_AUTOHSCROLL;
2082 m_xScrolledWindow->SetStyle(nWinBits);
2083 m_xScrolledWindow->queue_resize();
2084 }
2085
get_hpolicy() const2086 virtual VclPolicyType get_hpolicy() const override
2087 {
2088 WinBits nWinBits = m_xScrolledWindow->GetStyle();
2089 if (nWinBits & WB_AUTOHSCROLL)
2090 return VclPolicyType::AUTOMATIC;
2091 else if (nWinBits & WB_HSCROLL)
2092 return VclPolicyType::ALWAYS;
2093 return VclPolicyType::NEVER;
2094 }
2095
get_hscroll_height() const2096 virtual int get_hscroll_height() const override
2097 {
2098 return m_xScrolledWindow->getHorzScrollBar().get_preferred_size().Height();
2099 }
2100
vadjustment_configure(int value,int lower,int upper,int step_increment,int page_increment,int page_size)2101 virtual void vadjustment_configure(int value, int lower, int upper,
2102 int step_increment, int page_increment,
2103 int page_size) override
2104 {
2105 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2106 rVertScrollBar.SetRangeMin(lower);
2107 rVertScrollBar.SetRangeMax(upper);
2108 rVertScrollBar.SetLineSize(step_increment);
2109 rVertScrollBar.SetPageSize(page_increment);
2110 rVertScrollBar.SetThumbPos(value);
2111 rVertScrollBar.SetVisibleSize(page_size);
2112 }
2113
vadjustment_get_value() const2114 virtual int vadjustment_get_value() const override
2115 {
2116 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2117 return rVertScrollBar.GetThumbPos();
2118 }
2119
vadjustment_set_value(int value)2120 virtual void vadjustment_set_value(int value) override
2121 {
2122 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2123 rVertScrollBar.SetThumbPos(value);
2124 if (!m_bUserManagedScrolling)
2125 m_aOrigVScrollHdl.Call(&rVertScrollBar);
2126 }
2127
vadjustment_get_upper() const2128 virtual int vadjustment_get_upper() const override
2129 {
2130 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2131 return rVertScrollBar.GetRangeMax();
2132 }
2133
vadjustment_set_upper(int upper)2134 virtual void vadjustment_set_upper(int upper) override
2135 {
2136 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2137 rVertScrollBar.SetRangeMax(upper);
2138 }
2139
vadjustment_get_lower() const2140 virtual int vadjustment_get_lower() const override
2141 {
2142 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2143 return rVertScrollBar.GetRangeMin();
2144 }
2145
vadjustment_set_lower(int lower)2146 virtual void vadjustment_set_lower(int lower) override
2147 {
2148 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2149 rVertScrollBar.SetRangeMin(lower);
2150 }
2151
vadjustment_get_page_size() const2152 virtual int vadjustment_get_page_size() const override
2153 {
2154 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2155 return rVertScrollBar.GetVisibleSize();
2156 }
2157
vadjustment_set_page_size(int size)2158 virtual void vadjustment_set_page_size(int size) override
2159 {
2160 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2161 return rVertScrollBar.SetVisibleSize(size);
2162 }
2163
vadjustment_set_page_increment(int size)2164 virtual void vadjustment_set_page_increment(int size) override
2165 {
2166 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2167 return rVertScrollBar.SetPageSize(size);
2168 }
2169
vadjustment_set_step_increment(int size)2170 virtual void vadjustment_set_step_increment(int size) override
2171 {
2172 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2173 return rVertScrollBar.SetLineSize(size);
2174 }
2175
set_vpolicy(VclPolicyType eVPolicy)2176 virtual void set_vpolicy(VclPolicyType eVPolicy) override
2177 {
2178 WinBits nWinBits = m_xScrolledWindow->GetStyle() & ~(WB_AUTOVSCROLL|WB_VSCROLL);
2179 if (eVPolicy == VclPolicyType::ALWAYS)
2180 nWinBits |= WB_VSCROLL;
2181 else if (eVPolicy == VclPolicyType::AUTOMATIC)
2182 nWinBits |= WB_AUTOVSCROLL;
2183 m_xScrolledWindow->SetStyle(nWinBits);
2184 m_xScrolledWindow->queue_resize();
2185 }
2186
get_vpolicy() const2187 virtual VclPolicyType get_vpolicy() const override
2188 {
2189 WinBits nWinBits = m_xScrolledWindow->GetStyle();
2190 if (nWinBits & WB_AUTOVSCROLL)
2191 return VclPolicyType::AUTOMATIC;
2192 else if (nWinBits & WB_VSCROLL)
2193 return VclPolicyType::ALWAYS;
2194 return VclPolicyType::NEVER;
2195 }
2196
get_vscroll_width() const2197 virtual int get_vscroll_width() const override
2198 {
2199 return m_xScrolledWindow->getVertScrollBar().get_preferred_size().Width();
2200 }
2201
set_user_managed_scrolling()2202 virtual void set_user_managed_scrolling() override
2203 {
2204 m_bUserManagedScrolling = true;
2205 m_xScrolledWindow->setUserManagedScrolling(true);
2206 }
2207
~SalInstanceScrolledWindow()2208 virtual ~SalInstanceScrolledWindow() override
2209 {
2210 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2211 rVertScrollBar.SetScrollHdl(m_aOrigVScrollHdl);
2212 }
2213 };
2214
IMPL_LINK(SalInstanceScrolledWindow,VscrollHdl,ScrollBar *,pScrollBar,void)2215 IMPL_LINK(SalInstanceScrolledWindow, VscrollHdl, ScrollBar*, pScrollBar, void)
2216 {
2217 signal_vadjustment_changed();
2218 if (!m_bUserManagedScrolling)
2219 m_aOrigVScrollHdl.Call(pScrollBar);
2220 }
2221
IMPL_LINK_NOARG(SalInstanceScrolledWindow,HscrollHdl,ScrollBar *,void)2222 IMPL_LINK_NOARG(SalInstanceScrolledWindow, HscrollHdl, ScrollBar*, void)
2223 {
2224 signal_hadjustment_changed();
2225 if (!m_bUserManagedScrolling)
2226 m_aOrigHScrollHdl.Call(&m_xScrolledWindow->getHorzScrollBar());
2227 }
2228
2229 class SalInstanceNotebook : public SalInstanceContainer, public virtual weld::Notebook
2230 {
2231 private:
2232 VclPtr<TabControl> m_xNotebook;
2233 mutable std::vector<std::unique_ptr<SalInstanceContainer>> m_aPages;
2234 std::vector<VclPtr<TabPage>> m_aAddedPages;
2235 std::vector<VclPtr<VclGrid>> m_aAddedGrids;
2236
2237 DECL_LINK(DeactivatePageHdl, TabControl*, bool);
2238 DECL_LINK(ActivatePageHdl, TabControl*, void);
2239
2240 public:
SalInstanceNotebook(TabControl * pNotebook,SalInstanceBuilder * pBuilder,bool bTakeOwnership)2241 SalInstanceNotebook(TabControl* pNotebook, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2242 : SalInstanceContainer(pNotebook, pBuilder, bTakeOwnership)
2243 , m_xNotebook(pNotebook)
2244 {
2245 m_xNotebook->SetActivatePageHdl(LINK(this, SalInstanceNotebook, ActivatePageHdl));
2246 m_xNotebook->SetDeactivatePageHdl(LINK(this, SalInstanceNotebook, DeactivatePageHdl));
2247 }
2248
get_current_page() const2249 virtual int get_current_page() const override
2250 {
2251 return m_xNotebook->GetPagePos(m_xNotebook->GetCurPageId());
2252 }
2253
get_page_ident(int nPage) const2254 virtual OString get_page_ident(int nPage) const override
2255 {
2256 return m_xNotebook->GetPageName(m_xNotebook->GetPageId(nPage));
2257 }
2258
get_current_page_ident() const2259 virtual OString get_current_page_ident() const override
2260 {
2261 return m_xNotebook->GetPageName(m_xNotebook->GetCurPageId());
2262 }
2263
get_page(const OString & rIdent) const2264 virtual weld::Container* get_page(const OString& rIdent) const override
2265 {
2266 sal_uInt16 nPageId = m_xNotebook->GetPageId(rIdent);
2267 sal_uInt16 nPageIndex = m_xNotebook->GetPagePos(nPageId);
2268 if (nPageIndex == TAB_PAGE_NOTFOUND)
2269 return nullptr;
2270 TabPage* pPage = m_xNotebook->GetTabPage(nPageId);
2271 vcl::Window* pChild = pPage->GetChild(0);
2272 if (m_aPages.size() < nPageIndex + 1U)
2273 m_aPages.resize(nPageIndex + 1U);
2274 if (!m_aPages[nPageIndex])
2275 m_aPages[nPageIndex].reset(new SalInstanceContainer(pChild, m_pBuilder, false));
2276 return m_aPages[nPageIndex].get();
2277 }
2278
set_current_page(int nPage)2279 virtual void set_current_page(int nPage) override
2280 {
2281 m_xNotebook->SetCurPageId(m_xNotebook->GetPageId(nPage));
2282 }
2283
set_current_page(const OString & rIdent)2284 virtual void set_current_page(const OString& rIdent) override
2285 {
2286 m_xNotebook->SetCurPageId(m_xNotebook->GetPageId(rIdent));
2287 }
2288
remove_page(const OString & rIdent)2289 virtual void remove_page(const OString& rIdent) override
2290 {
2291 m_xNotebook->RemovePage(m_xNotebook->GetPageId(rIdent));
2292 }
2293
append_page(const OString & rIdent,const OUString & rLabel)2294 virtual void append_page(const OString& rIdent, const OUString& rLabel) override
2295 {
2296 sal_uInt16 nPageCount = m_xNotebook->GetPageCount();
2297 sal_uInt16 nLastPageId = nPageCount ? m_xNotebook->GetPageId(nPageCount - 1) : 0;
2298 sal_uInt16 nNewPageId = nLastPageId + 1;
2299 m_xNotebook->InsertPage(nNewPageId, rLabel);
2300 VclPtrInstance<TabPage> xPage(m_xNotebook);
2301 VclPtrInstance<VclGrid> xGrid(xPage);
2302 xPage->Show();
2303 xGrid->set_hexpand(true);
2304 xGrid->set_vexpand(true);
2305 xGrid->Show();
2306 m_xNotebook->SetTabPage(nNewPageId, xPage);
2307 m_xNotebook->SetPageName(nNewPageId, rIdent);
2308 m_aAddedPages.push_back(xPage);
2309 m_aAddedGrids.push_back(xGrid);
2310 }
2311
get_n_pages() const2312 virtual int get_n_pages() const override
2313 {
2314 return m_xNotebook->GetPageCount();
2315 }
2316
get_tab_label_text(const OString & rIdent) const2317 virtual OUString get_tab_label_text(const OString& rIdent) const override
2318 {
2319 return m_xNotebook->GetPageText(m_xNotebook->GetPageId(rIdent));
2320 }
2321
set_tab_label_text(const OString & rIdent,const OUString & rText)2322 virtual void set_tab_label_text(const OString& rIdent, const OUString& rText) override
2323 {
2324 return m_xNotebook->SetPageText(m_xNotebook->GetPageId(rIdent), rText);
2325 }
2326
~SalInstanceNotebook()2327 virtual ~SalInstanceNotebook() override
2328 {
2329 for (auto &rGrid : m_aAddedGrids)
2330 rGrid.disposeAndClear();
2331 for (auto &rPage : m_aAddedPages)
2332 rPage.disposeAndClear();
2333 m_xNotebook->SetActivatePageHdl(Link<TabControl*,void>());
2334 m_xNotebook->SetDeactivatePageHdl(Link<TabControl*,bool>());
2335 }
2336 };
2337
IMPL_LINK_NOARG(SalInstanceNotebook,DeactivatePageHdl,TabControl *,bool)2338 IMPL_LINK_NOARG(SalInstanceNotebook, DeactivatePageHdl, TabControl*, bool)
2339 {
2340 return !m_aLeavePageHdl.IsSet() || m_aLeavePageHdl.Call(get_current_page_ident());
2341 }
2342
IMPL_LINK_NOARG(SalInstanceNotebook,ActivatePageHdl,TabControl *,void)2343 IMPL_LINK_NOARG(SalInstanceNotebook, ActivatePageHdl, TabControl*, void)
2344 {
2345 m_aEnterPageHdl.Call(get_current_page_ident());
2346 }
2347
2348 class SalInstanceVerticalNotebook : public SalInstanceContainer, public virtual weld::Notebook
2349 {
2350 private:
2351 VclPtr<VerticalTabControl> m_xNotebook;
2352 mutable std::vector<std::unique_ptr<SalInstanceContainer>> m_aPages;
2353
2354 DECL_LINK(DeactivatePageHdl, VerticalTabControl*, bool);
2355 DECL_LINK(ActivatePageHdl, VerticalTabControl*, void);
2356
2357 public:
SalInstanceVerticalNotebook(VerticalTabControl * pNotebook,SalInstanceBuilder * pBuilder,bool bTakeOwnership)2358 SalInstanceVerticalNotebook(VerticalTabControl* pNotebook, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2359 : SalInstanceContainer(pNotebook, pBuilder, bTakeOwnership)
2360 , m_xNotebook(pNotebook)
2361 {
2362 m_xNotebook->SetActivatePageHdl(LINK(this, SalInstanceVerticalNotebook, ActivatePageHdl));
2363 m_xNotebook->SetDeactivatePageHdl(LINK(this, SalInstanceVerticalNotebook, DeactivatePageHdl));
2364 }
2365
get_current_page() const2366 virtual int get_current_page() const override
2367 {
2368 return m_xNotebook->GetPagePos(m_xNotebook->GetCurPageId());
2369 }
2370
get_page_ident(int nPage) const2371 virtual OString get_page_ident(int nPage) const override
2372 {
2373 return m_xNotebook->GetPageId(nPage);
2374 }
2375
get_current_page_ident() const2376 virtual OString get_current_page_ident() const override
2377 {
2378 return m_xNotebook->GetCurPageId();
2379 }
2380
get_page(const OString & rIdent) const2381 virtual weld::Container* get_page(const OString& rIdent) const override
2382 {
2383 sal_uInt16 nPageIndex = m_xNotebook->GetPagePos(rIdent);
2384 if (nPageIndex == TAB_PAGE_NOTFOUND)
2385 return nullptr;
2386 auto pChild = m_xNotebook->GetPage(rIdent);
2387 if (m_aPages.size() < nPageIndex + 1U)
2388 m_aPages.resize(nPageIndex + 1U);
2389 if (!m_aPages[nPageIndex])
2390 m_aPages[nPageIndex].reset(new SalInstanceContainer(pChild, m_pBuilder, false));
2391 return m_aPages[nPageIndex].get();
2392 }
2393
set_current_page(int nPage)2394 virtual void set_current_page(int nPage) override
2395 {
2396 m_xNotebook->SetCurPageId(m_xNotebook->GetPageId(nPage));
2397 }
2398
set_current_page(const OString & rIdent)2399 virtual void set_current_page(const OString& rIdent) override
2400 {
2401 m_xNotebook->SetCurPageId(rIdent);
2402 }
2403
remove_page(const OString & rIdent)2404 virtual void remove_page(const OString& rIdent) override
2405 {
2406 m_xNotebook->RemovePage(rIdent);
2407 }
2408
append_page(const OString & rIdent,const OUString & rLabel)2409 virtual void append_page(const OString& rIdent, const OUString& rLabel) override
2410 {
2411 VclPtrInstance<VclGrid> xGrid(m_xNotebook->GetPageParent());
2412 xGrid->set_hexpand(true);
2413 xGrid->set_vexpand(true);
2414 m_xNotebook->InsertPage(rIdent, rLabel, Image(), "", xGrid);
2415 }
2416
get_n_pages() const2417 virtual int get_n_pages() const override
2418 {
2419 return m_xNotebook->GetPageCount();
2420 }
2421
set_tab_label_text(const OString & rIdent,const OUString & rText)2422 virtual void set_tab_label_text(const OString& rIdent, const OUString& rText) override
2423 {
2424 return m_xNotebook->SetPageText(rIdent, rText);
2425 }
2426
get_tab_label_text(const OString & rIdent) const2427 virtual OUString get_tab_label_text(const OString& rIdent) const override
2428 {
2429 return m_xNotebook->GetPageText(rIdent);
2430 }
2431
~SalInstanceVerticalNotebook()2432 virtual ~SalInstanceVerticalNotebook() override
2433 {
2434 m_xNotebook->SetActivatePageHdl(Link<VerticalTabControl*,void>());
2435 m_xNotebook->SetDeactivatePageHdl(Link<VerticalTabControl*,bool>());
2436 }
2437 };
2438
IMPL_LINK_NOARG(SalInstanceVerticalNotebook,DeactivatePageHdl,VerticalTabControl *,bool)2439 IMPL_LINK_NOARG(SalInstanceVerticalNotebook, DeactivatePageHdl, VerticalTabControl*, bool)
2440 {
2441 return !m_aLeavePageHdl.IsSet() || m_aLeavePageHdl.Call(get_current_page_ident());
2442 }
2443
IMPL_LINK_NOARG(SalInstanceVerticalNotebook,ActivatePageHdl,VerticalTabControl *,void)2444 IMPL_LINK_NOARG(SalInstanceVerticalNotebook, ActivatePageHdl, VerticalTabControl*, void)
2445 {
2446 m_aEnterPageHdl.Call(get_current_page_ident());
2447 }
2448
2449 class SalInstanceButton : public SalInstanceContainer, public virtual weld::Button
2450 {
2451 private:
2452 VclPtr<::Button> m_xButton;
2453 Link<::Button*,void> const m_aOldClickHdl;
2454
2455 DECL_LINK(ClickHdl, ::Button*, void);
2456 public:
SalInstanceButton(::Button * pButton,SalInstanceBuilder * pBuilder,bool bTakeOwnership)2457 SalInstanceButton(::Button* pButton, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2458 : SalInstanceContainer(pButton, pBuilder, bTakeOwnership)
2459 , m_xButton(pButton)
2460 , m_aOldClickHdl(pButton->GetClickHdl())
2461 {
2462 m_xButton->SetClickHdl(LINK(this, SalInstanceButton, ClickHdl));
2463 }
2464
set_label(const OUString & rText)2465 virtual void set_label(const OUString& rText) override
2466 {
2467 m_xButton->SetText(rText);
2468 }
2469
set_image(VirtualDevice * pDevice)2470 virtual void set_image(VirtualDevice* pDevice) override
2471 {
2472 m_xButton->SetImageAlign(ImageAlign::Left);
2473 if (pDevice)
2474 m_xButton->SetModeImage(createImage(*pDevice));
2475 else
2476 m_xButton->SetModeImage(Image());
2477 }
2478
set_image(const css::uno::Reference<css::graphic::XGraphic> & rImage)2479 virtual void set_image(const css::uno::Reference<css::graphic::XGraphic>& rImage) override
2480 {
2481 m_xButton->SetImageAlign(ImageAlign::Left);
2482 m_xButton->SetModeImage(Image(rImage));
2483 }
2484
set_from_icon_name(const OUString & rIconName)2485 virtual void set_from_icon_name(const OUString& rIconName) override
2486 {
2487 m_xButton->SetModeImage(Image(StockImage::Yes, rIconName));
2488 }
2489
set_label_line_wrap(bool wrap)2490 virtual void set_label_line_wrap(bool wrap) override
2491 {
2492 WinBits nBits = m_xButton->GetStyle();
2493 nBits &= ~WB_WORDBREAK;
2494 if (wrap)
2495 nBits |= WB_WORDBREAK;
2496 m_xButton->SetStyle(nBits);
2497 m_xButton->queue_resize();
2498 }
2499
get_label() const2500 virtual OUString get_label() const override
2501 {
2502 return m_xButton->GetText();
2503 }
2504
~SalInstanceButton()2505 virtual ~SalInstanceButton() override
2506 {
2507 m_xButton->SetClickHdl(Link<::Button*,void>());
2508 }
2509 };
2510
IMPL_LINK(SalInstanceButton,ClickHdl,::Button *,pButton,void)2511 IMPL_LINK(SalInstanceButton, ClickHdl, ::Button*, pButton, void)
2512 {
2513 //if there's no handler set, disengage our intercept and
2514 //run the click again to get default behaviour for cancel/ok
2515 //etc buttons.
2516 if (!m_aClickHdl.IsSet())
2517 {
2518 pButton->SetClickHdl(m_aOldClickHdl);
2519 pButton->Click();
2520 pButton->SetClickHdl(LINK(this, SalInstanceButton, ClickHdl));
2521 return;
2522 }
2523 signal_clicked();
2524 }
2525
weld_widget_for_response(int nResponse)2526 weld::Button* SalInstanceDialog::weld_widget_for_response(int nResponse)
2527 {
2528 PushButton* pButton = dynamic_cast<PushButton*>(m_xDialog->get_widget_for_response(nResponse));
2529 return pButton ? new SalInstanceButton(pButton, nullptr, false) : nullptr;
2530 }
2531
weld_widget_for_response(int nResponse)2532 weld::Button* SalInstanceAssistant::weld_widget_for_response(int nResponse)
2533 {
2534 PushButton* pButton = nullptr;
2535 if (nResponse == RET_YES)
2536 pButton = m_xWizard->m_pNextPage;
2537 else if (nResponse == RET_NO)
2538 pButton = m_xWizard->m_pPrevPage;
2539 else if (nResponse == RET_OK)
2540 pButton = m_xWizard->m_pFinish;
2541 else if (nResponse == RET_CANCEL)
2542 pButton = m_xWizard->m_pCancel;
2543 else if (nResponse == RET_HELP)
2544 pButton = m_xWizard->m_pHelp;
2545 if (pButton)
2546 return new SalInstanceButton(pButton, nullptr, false);
2547 return nullptr;
2548 }
2549
2550 class SalInstanceMenuButton : public SalInstanceButton, public virtual weld::MenuButton
2551 {
2552 private:
2553 VclPtr<::MenuButton> m_xMenuButton;
2554 sal_uInt16 m_nLastId;
2555
2556 DECL_LINK(MenuSelectHdl, ::MenuButton*, void);
2557 DECL_LINK(ActivateHdl, ::MenuButton*, void);
2558
2559 public:
SalInstanceMenuButton(::MenuButton * pButton,SalInstanceBuilder * pBuilder,bool bTakeOwnership)2560 SalInstanceMenuButton(::MenuButton* pButton, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2561 : SalInstanceButton(pButton, pBuilder, bTakeOwnership)
2562 , m_xMenuButton(pButton)
2563 , m_nLastId(0)
2564 {
2565 m_xMenuButton->SetActivateHdl(LINK(this, SalInstanceMenuButton, ActivateHdl));
2566 m_xMenuButton->SetSelectHdl(LINK(this, SalInstanceMenuButton, MenuSelectHdl));
2567 if (PopupMenu* pMenu = m_xMenuButton->GetPopupMenu())
2568 {
2569 pMenu->SetMenuFlags(MenuFlags::NoAutoMnemonics);
2570 const auto nCount = pMenu->GetItemCount();
2571 m_nLastId = nCount ? pMenu->GetItemId(nCount-1) : 0;
2572 }
2573 }
2574
set_active(bool active)2575 virtual void set_active(bool active) override
2576 {
2577 if (active == get_active())
2578 return;
2579 if (active)
2580 m_xMenuButton->ExecuteMenu();
2581 else
2582 m_xMenuButton->CancelMenu();
2583 }
2584
get_active() const2585 virtual bool get_active() const override
2586 {
2587 return m_xMenuButton->InPopupMode();
2588 }
2589
set_inconsistent(bool)2590 virtual void set_inconsistent(bool /*inconsistent*/) override
2591 {
2592 //not available
2593 }
2594
get_inconsistent() const2595 virtual bool get_inconsistent() const override
2596 {
2597 return false;
2598 }
2599
insert_item(int pos,const OUString & rId,const OUString & rStr,const OUString * pIconName,VirtualDevice * pImageSurface,bool bCheck)2600 virtual void insert_item(int pos, const OUString& rId, const OUString& rStr,
2601 const OUString* pIconName, VirtualDevice* pImageSurface, bool bCheck) override
2602 {
2603 m_nLastId = insert_to_menu(m_nLastId, m_xMenuButton->GetPopupMenu(), pos, rId, rStr, pIconName, pImageSurface, bCheck);
2604 }
2605
insert_separator(int pos,const OUString & rId)2606 virtual void insert_separator(int pos, const OUString& rId) override
2607 {
2608 auto nInsertPos = pos == -1 ? MENU_APPEND : pos;
2609 m_xMenuButton->GetPopupMenu()->InsertSeparator(rId.toUtf8(), nInsertPos);
2610 }
2611
set_item_sensitive(const OString & rIdent,bool bSensitive)2612 virtual void set_item_sensitive(const OString& rIdent, bool bSensitive) override
2613 {
2614 PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2615 pMenu->EnableItem(rIdent, bSensitive);
2616 }
2617
remove_item(const OString & rId)2618 virtual void remove_item(const OString& rId) override
2619 {
2620 PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2621 pMenu->RemoveItem(pMenu->GetItemPos(pMenu->GetItemId(rId)));
2622 }
2623
clear()2624 virtual void clear() override
2625 {
2626 PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2627 pMenu->Clear();
2628 }
2629
set_item_active(const OString & rIdent,bool bActive)2630 virtual void set_item_active(const OString& rIdent, bool bActive) override
2631 {
2632 PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2633 pMenu->CheckItem(rIdent, bActive);
2634 }
2635
set_item_label(const OString & rIdent,const OUString & rText)2636 virtual void set_item_label(const OString& rIdent, const OUString& rText) override
2637 {
2638 PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2639 pMenu->SetItemText(pMenu->GetItemId(rIdent), rText);
2640 }
2641
get_item_label(const OString & rIdent) const2642 virtual OUString get_item_label(const OString& rIdent) const override
2643 {
2644 PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2645 return pMenu->GetItemText(pMenu->GetItemId(rIdent));
2646 }
2647
set_item_visible(const OString & rIdent,bool bShow)2648 virtual void set_item_visible(const OString& rIdent, bool bShow) override
2649 {
2650 PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2651 pMenu->ShowItem(pMenu->GetItemId(rIdent), bShow);
2652 }
2653
set_item_help_id(const OString & rIdent,const OString & rHelpId)2654 virtual void set_item_help_id(const OString& rIdent, const OString& rHelpId) override
2655 {
2656 PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2657 pMenu->SetHelpId(pMenu->GetItemId(rIdent), rHelpId);
2658 }
2659
get_item_help_id(const OString & rIdent) const2660 virtual OString get_item_help_id(const OString& rIdent) const override
2661 {
2662 PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
2663 return pMenu->GetHelpId(pMenu->GetItemId(rIdent));
2664 }
2665
set_popover(weld::Widget * pPopover)2666 virtual void set_popover(weld::Widget* pPopover) override
2667 {
2668 SalInstanceWidget* pPopoverWidget = dynamic_cast<SalInstanceWidget*>(pPopover);
2669 m_xMenuButton->SetPopover(pPopoverWidget ? pPopoverWidget->getWidget() : nullptr);
2670 }
2671
~SalInstanceMenuButton()2672 virtual ~SalInstanceMenuButton() override
2673 {
2674 m_xMenuButton->SetSelectHdl(Link<::MenuButton*, void>());
2675 m_xMenuButton->SetActivateHdl(Link<::MenuButton*, void>());
2676 }
2677 };
2678
IMPL_LINK_NOARG(SalInstanceMenuButton,MenuSelectHdl,::MenuButton *,void)2679 IMPL_LINK_NOARG(SalInstanceMenuButton, MenuSelectHdl, ::MenuButton*, void)
2680 {
2681 signal_selected(m_xMenuButton->GetCurItemIdent());
2682 }
2683
IMPL_LINK_NOARG(SalInstanceMenuButton,ActivateHdl,::MenuButton *,void)2684 IMPL_LINK_NOARG(SalInstanceMenuButton, ActivateHdl, ::MenuButton*, void)
2685 {
2686 if (notify_events_disabled())
2687 return;
2688 signal_toggled();
2689 }
2690
2691 class SalInstanceLinkButton : public SalInstanceContainer, public virtual weld::LinkButton
2692 {
2693 private:
2694 VclPtr<FixedHyperlink> m_xButton;
2695 Link<FixedHyperlink&,void> m_aOrigClickHdl;
2696
2697 DECL_LINK(ClickHdl, FixedHyperlink&, void);
2698 public:
SalInstanceLinkButton(FixedHyperlink * pButton,SalInstanceBuilder * pBuilder,bool bTakeOwnership)2699 SalInstanceLinkButton(FixedHyperlink* pButton, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2700 : SalInstanceContainer(pButton, pBuilder, bTakeOwnership)
2701 , m_xButton(pButton)
2702 {
2703 m_aOrigClickHdl = m_xButton->GetClickHdl();
2704 m_xButton->SetClickHdl(LINK(this, SalInstanceLinkButton, ClickHdl));
2705 }
2706
set_label(const OUString & rText)2707 virtual void set_label(const OUString& rText) override
2708 {
2709 m_xButton->SetText(rText);
2710 }
2711
get_label() const2712 virtual OUString get_label() const override
2713 {
2714 return m_xButton->GetText();
2715 }
2716
set_uri(const OUString & rUri)2717 virtual void set_uri(const OUString& rUri) override
2718 {
2719 m_xButton->SetURL(rUri);
2720 }
2721
get_uri() const2722 virtual OUString get_uri() const override
2723 {
2724 return m_xButton->GetURL();
2725 }
2726
~SalInstanceLinkButton()2727 virtual ~SalInstanceLinkButton() override
2728 {
2729 m_xButton->SetClickHdl(m_aOrigClickHdl);
2730 }
2731 };
2732
IMPL_LINK(SalInstanceLinkButton,ClickHdl,FixedHyperlink &,rButton,void)2733 IMPL_LINK(SalInstanceLinkButton, ClickHdl, FixedHyperlink&, rButton, void)
2734 {
2735 bool bConsumed = signal_activate_link();
2736 if (!bConsumed)
2737 m_aOrigClickHdl.Call(rButton);
2738 }
2739
2740 class SalInstanceRadioButton : public SalInstanceButton, public virtual weld::RadioButton
2741 {
2742 private:
2743 VclPtr<::RadioButton> m_xRadioButton;
2744
2745 DECL_LINK(ToggleHdl, ::RadioButton&, void);
2746
2747 public:
SalInstanceRadioButton(::RadioButton * pButton,SalInstanceBuilder * pBuilder,bool bTakeOwnership)2748 SalInstanceRadioButton(::RadioButton* pButton, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2749 : SalInstanceButton(pButton, pBuilder, bTakeOwnership)
2750 , m_xRadioButton(pButton)
2751 {
2752 m_xRadioButton->SetToggleHdl(LINK(this, SalInstanceRadioButton, ToggleHdl));
2753 }
2754
set_active(bool active)2755 virtual void set_active(bool active) override
2756 {
2757 disable_notify_events();
2758 m_xRadioButton->Check(active);
2759 enable_notify_events();
2760 }
2761
get_active() const2762 virtual bool get_active() const override
2763 {
2764 return m_xRadioButton->IsChecked();
2765 }
2766
set_image(VirtualDevice * pDevice)2767 virtual void set_image(VirtualDevice* pDevice) override
2768 {
2769 m_xRadioButton->SetImageAlign(ImageAlign::Center);
2770 if (pDevice)
2771 m_xRadioButton->SetModeImage(createImage(*pDevice));
2772 else
2773 m_xRadioButton->SetModeImage(Image());
2774 }
2775
set_image(const css::uno::Reference<css::graphic::XGraphic> & rImage)2776 virtual void set_image(const css::uno::Reference<css::graphic::XGraphic>& rImage) override
2777 {
2778 m_xRadioButton->SetImageAlign(ImageAlign::Center);
2779 m_xRadioButton->SetModeImage(Image(rImage));
2780 }
2781
set_from_icon_name(const OUString & rIconName)2782 virtual void set_from_icon_name(const OUString& rIconName) override
2783 {
2784 m_xRadioButton->SetModeRadioImage(Image(StockImage::Yes, rIconName));
2785 }
2786
set_inconsistent(bool)2787 virtual void set_inconsistent(bool /*inconsistent*/) override
2788 {
2789 //not available
2790 }
2791
get_inconsistent() const2792 virtual bool get_inconsistent() const override
2793 {
2794 return false;
2795 }
2796
~SalInstanceRadioButton()2797 virtual ~SalInstanceRadioButton() override
2798 {
2799 m_xRadioButton->SetToggleHdl(Link<::RadioButton&, void>());
2800 }
2801 };
2802
IMPL_LINK_NOARG(SalInstanceRadioButton,ToggleHdl,::RadioButton &,void)2803 IMPL_LINK_NOARG(SalInstanceRadioButton, ToggleHdl, ::RadioButton&, void)
2804 {
2805 if (notify_events_disabled())
2806 return;
2807 signal_toggled();
2808 }
2809
2810 class SalInstanceToggleButton : public SalInstanceButton, public virtual weld::ToggleButton
2811 {
2812 private:
2813 VclPtr<PushButton> m_xToggleButton;
2814
2815 DECL_LINK(ToggleListener, VclWindowEvent&, void);
2816
2817 public:
SalInstanceToggleButton(PushButton * pButton,SalInstanceBuilder * pBuilder,bool bTakeOwnership)2818 SalInstanceToggleButton(PushButton* pButton, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2819 : SalInstanceButton(pButton, pBuilder, bTakeOwnership)
2820 , m_xToggleButton(pButton)
2821 {
2822 }
2823
connect_toggled(const Link<ToggleButton &,void> & rLink)2824 virtual void connect_toggled(const Link<ToggleButton&, void>& rLink) override
2825 {
2826 assert(!m_aToggleHdl.IsSet());
2827 m_xToggleButton->AddEventListener(LINK(this, SalInstanceToggleButton, ToggleListener));
2828 weld::ToggleButton::connect_toggled(rLink);
2829 }
2830
set_active(bool active)2831 virtual void set_active(bool active) override
2832 {
2833 disable_notify_events();
2834 m_xToggleButton->Check(active);
2835 enable_notify_events();
2836 }
2837
get_active() const2838 virtual bool get_active() const override
2839 {
2840 return m_xToggleButton->IsChecked();
2841 }
2842
set_inconsistent(bool inconsistent)2843 virtual void set_inconsistent(bool inconsistent) override
2844 {
2845 disable_notify_events();
2846 m_xToggleButton->SetState(inconsistent ? TRISTATE_INDET : TRISTATE_FALSE);
2847 enable_notify_events();
2848 }
2849
get_inconsistent() const2850 virtual bool get_inconsistent() const override
2851 {
2852 return m_xToggleButton->GetState() == TRISTATE_INDET;
2853 }
2854
~SalInstanceToggleButton()2855 virtual ~SalInstanceToggleButton() override
2856 {
2857 if (m_aToggleHdl.IsSet())
2858 m_xToggleButton->RemoveEventListener(LINK(this, SalInstanceToggleButton, ToggleListener));
2859 }
2860 };
2861
IMPL_LINK(SalInstanceToggleButton,ToggleListener,VclWindowEvent &,rEvent,void)2862 IMPL_LINK(SalInstanceToggleButton, ToggleListener, VclWindowEvent&, rEvent, void)
2863 {
2864 if (notify_events_disabled())
2865 return;
2866 if (rEvent.GetId() == VclEventId::PushbuttonToggle)
2867 signal_toggled();
2868 }
2869
2870 class SalInstanceCheckButton : public SalInstanceButton, public virtual weld::CheckButton
2871 {
2872 private:
2873 VclPtr<CheckBox> m_xCheckButton;
2874
2875 DECL_LINK(ToggleHdl, CheckBox&, void);
2876 public:
SalInstanceCheckButton(CheckBox * pButton,SalInstanceBuilder * pBuilder,bool bTakeOwnership)2877 SalInstanceCheckButton(CheckBox* pButton, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2878 : SalInstanceButton(pButton, pBuilder, bTakeOwnership)
2879 , m_xCheckButton(pButton)
2880 {
2881 m_xCheckButton->SetToggleHdl(LINK(this, SalInstanceCheckButton, ToggleHdl));
2882 }
2883
set_active(bool active)2884 virtual void set_active(bool active) override
2885 {
2886 disable_notify_events();
2887 m_xCheckButton->EnableTriState(false);
2888 m_xCheckButton->Check(active);
2889 enable_notify_events();
2890 }
2891
get_active() const2892 virtual bool get_active() const override
2893 {
2894 return m_xCheckButton->IsChecked();
2895 }
2896
set_inconsistent(bool inconsistent)2897 virtual void set_inconsistent(bool inconsistent) override
2898 {
2899 disable_notify_events();
2900 m_xCheckButton->EnableTriState(true);
2901 m_xCheckButton->SetState(inconsistent ? TRISTATE_INDET : TRISTATE_FALSE);
2902 enable_notify_events();
2903 }
2904
get_inconsistent() const2905 virtual bool get_inconsistent() const override
2906 {
2907 return m_xCheckButton->GetState() == TRISTATE_INDET;
2908 }
2909
~SalInstanceCheckButton()2910 virtual ~SalInstanceCheckButton() override
2911 {
2912 m_xCheckButton->SetToggleHdl(Link<CheckBox&, void>());
2913 }
2914 };
2915
IMPL_LINK_NOARG(SalInstanceCheckButton,ToggleHdl,CheckBox &,void)2916 IMPL_LINK_NOARG(SalInstanceCheckButton, ToggleHdl, CheckBox&, void)
2917 {
2918 if (notify_events_disabled())
2919 return;
2920 m_xCheckButton->EnableTriState(false);
2921 signal_toggled();
2922 }
2923
2924 class SalInstanceScale : public SalInstanceWidget, public virtual weld::Scale
2925 {
2926 private:
2927 VclPtr<Slider> m_xScale;
2928
2929 DECL_LINK(SlideHdl, Slider*, void);
2930 public:
SalInstanceScale(Slider * pScale,SalInstanceBuilder * pBuilder,bool bTakeOwnership)2931 SalInstanceScale(Slider* pScale, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2932 : SalInstanceWidget(pScale, pBuilder, bTakeOwnership)
2933 , m_xScale(pScale)
2934 {
2935 m_xScale->SetSlideHdl(LINK(this, SalInstanceScale, SlideHdl));
2936 }
2937
set_value(int value)2938 virtual void set_value(int value) override
2939 {
2940 m_xScale->SetThumbPos(value);
2941 }
2942
set_range(int min,int max)2943 virtual void set_range(int min, int max) override
2944 {
2945 m_xScale->SetRangeMin(min);
2946 m_xScale->SetRangeMax(max);
2947 }
2948
get_value() const2949 virtual int get_value() const override
2950 {
2951 return m_xScale->GetThumbPos();
2952 }
2953
~SalInstanceScale()2954 virtual ~SalInstanceScale() override
2955 {
2956 m_xScale->SetSlideHdl(Link<Slider*, void>());
2957 }
2958 };
2959
IMPL_LINK_NOARG(SalInstanceScale,SlideHdl,Slider *,void)2960 IMPL_LINK_NOARG(SalInstanceScale, SlideHdl, Slider*, void)
2961 {
2962 signal_value_changed();
2963 }
2964
2965 class SalInstanceSpinner : public SalInstanceWidget, public virtual weld::Spinner
2966 {
2967 private:
2968 VclPtr<Throbber> m_xThrobber;
2969
2970 public:
SalInstanceSpinner(Throbber * pThrobber,SalInstanceBuilder * pBuilder,bool bTakeOwnership)2971 SalInstanceSpinner(Throbber* pThrobber, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2972 : SalInstanceWidget(pThrobber, pBuilder, bTakeOwnership)
2973 , m_xThrobber(pThrobber)
2974 {
2975 }
2976
start()2977 virtual void start() override
2978 {
2979 m_xThrobber->start();
2980 }
2981
stop()2982 virtual void stop() override
2983 {
2984 m_xThrobber->stop();
2985 }
2986 };
2987
2988 class SalInstanceProgressBar : public SalInstanceWidget, public virtual weld::ProgressBar
2989 {
2990 private:
2991 VclPtr<::ProgressBar> m_xProgressBar;
2992
2993 public:
SalInstanceProgressBar(::ProgressBar * pProgressBar,SalInstanceBuilder * pBuilder,bool bTakeOwnership)2994 SalInstanceProgressBar(::ProgressBar* pProgressBar, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2995 : SalInstanceWidget(pProgressBar, pBuilder, bTakeOwnership)
2996 , m_xProgressBar(pProgressBar)
2997 {
2998 }
2999
set_percentage(int value)3000 virtual void set_percentage(int value) override
3001 {
3002 m_xProgressBar->SetValue(value);
3003 }
3004
get_text() const3005 virtual OUString get_text() const override
3006 {
3007 return m_xProgressBar->GetText();
3008 }
3009
set_text(const OUString & rText)3010 virtual void set_text(const OUString& rText) override
3011 {
3012 m_xProgressBar->SetText(rText);
3013 }
3014 };
3015
3016 class SalInstanceImage : public SalInstanceWidget, public virtual weld::Image
3017 {
3018 private:
3019 VclPtr<FixedImage> m_xImage;
3020
3021 public:
SalInstanceImage(FixedImage * pImage,SalInstanceBuilder * pBuilder,bool bTakeOwnership)3022 SalInstanceImage(FixedImage* pImage, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3023 : SalInstanceWidget(pImage, pBuilder, bTakeOwnership)
3024 , m_xImage(pImage)
3025 {
3026 }
3027
set_from_icon_name(const OUString & rIconName)3028 virtual void set_from_icon_name(const OUString& rIconName) override
3029 {
3030 m_xImage->SetImage(::Image(StockImage::Yes, rIconName));
3031 }
3032
set_image(VirtualDevice * pDevice)3033 virtual void set_image(VirtualDevice* pDevice) override
3034 {
3035 if (pDevice)
3036 m_xImage->SetImage(createImage(*pDevice));
3037 else
3038 m_xImage->SetImage(::Image());
3039 }
3040
set_image(const css::uno::Reference<css::graphic::XGraphic> & rImage)3041 virtual void set_image(const css::uno::Reference<css::graphic::XGraphic>& rImage) override
3042 {
3043 m_xImage->SetImage(::Image(rImage));
3044 }
3045 };
3046
3047 class SalInstanceCalendar : public SalInstanceWidget, public virtual weld::Calendar
3048 {
3049 private:
3050 VclPtr<::Calendar> m_xCalendar;
3051
3052 DECL_LINK(SelectHdl, ::Calendar*, void);
3053 DECL_LINK(ActivateHdl, ::Calendar*, void);
3054
3055 public:
SalInstanceCalendar(::Calendar * pCalendar,SalInstanceBuilder * pBuilder,bool bTakeOwnership)3056 SalInstanceCalendar(::Calendar* pCalendar, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3057 : SalInstanceWidget(pCalendar, pBuilder, bTakeOwnership)
3058 , m_xCalendar(pCalendar)
3059 {
3060 m_xCalendar->SetSelectHdl(LINK(this, SalInstanceCalendar, SelectHdl));
3061 m_xCalendar->SetActivateHdl(LINK(this, SalInstanceCalendar, ActivateHdl));
3062 }
3063
set_date(const Date & rDate)3064 virtual void set_date(const Date& rDate) override
3065 {
3066 m_xCalendar->SetCurDate(rDate);
3067 }
3068
get_date() const3069 virtual Date get_date() const override
3070 {
3071 return m_xCalendar->GetFirstSelectedDate();
3072 }
3073
~SalInstanceCalendar()3074 virtual ~SalInstanceCalendar() override
3075 {
3076 m_xCalendar->SetSelectHdl(Link<::Calendar*, void>());
3077 m_xCalendar->SetActivateHdl(Link<::Calendar*, void>());
3078 }
3079 };
3080
IMPL_LINK_NOARG(SalInstanceCalendar,SelectHdl,::Calendar *,void)3081 IMPL_LINK_NOARG(SalInstanceCalendar, SelectHdl, ::Calendar*, void)
3082 {
3083 if (notify_events_disabled())
3084 return;
3085 signal_selected();
3086 }
3087
IMPL_LINK_NOARG(SalInstanceCalendar,ActivateHdl,::Calendar *,void)3088 IMPL_LINK_NOARG(SalInstanceCalendar, ActivateHdl, ::Calendar*, void)
3089 {
3090 if (notify_events_disabled())
3091 return;
3092 signal_activated();
3093 }
3094
3095 namespace
3096 {
3097 class WeldTextFilter : public TextFilter
3098 {
3099 private:
3100 Link<OUString&, bool>& m_rInsertTextHdl;
3101 public:
WeldTextFilter(Link<OUString &,bool> & rInsertTextHdl)3102 WeldTextFilter(Link<OUString&, bool>& rInsertTextHdl)
3103 : TextFilter(OUString())
3104 , m_rInsertTextHdl(rInsertTextHdl)
3105 {
3106 }
3107
filter(const OUString & rText)3108 virtual OUString filter(const OUString &rText) override
3109 {
3110 if (!m_rInsertTextHdl.IsSet())
3111 return rText;
3112 OUString sText(rText);
3113 const bool bContinue = m_rInsertTextHdl.Call(sText);
3114 if (!bContinue)
3115 return OUString();
3116 return sText;
3117 }
3118 };
3119 }
3120
3121 class SalInstanceEntry : public SalInstanceWidget, public virtual weld::Entry
3122 {
3123 private:
3124 VclPtr<Edit> m_xEntry;
3125
3126 DECL_LINK(ChangeHdl, Edit&, void);
3127 DECL_LINK(CursorListener, VclWindowEvent&, void);
3128 DECL_LINK(ActivateHdl, Edit&, bool);
3129
3130 WeldTextFilter m_aTextFilter;
3131 public:
SalInstanceEntry(Edit * pEntry,SalInstanceBuilder * pBuilder,bool bTakeOwnership)3132 SalInstanceEntry(Edit* pEntry, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3133 : SalInstanceWidget(pEntry, pBuilder, bTakeOwnership)
3134 , m_xEntry(pEntry)
3135 , m_aTextFilter(m_aInsertTextHdl)
3136 {
3137 m_xEntry->SetModifyHdl(LINK(this, SalInstanceEntry, ChangeHdl));
3138 m_xEntry->SetActivateHdl(LINK(this, SalInstanceEntry, ActivateHdl));
3139 m_xEntry->SetTextFilter(&m_aTextFilter);
3140 }
3141
set_text(const OUString & rText)3142 virtual void set_text(const OUString& rText) override
3143 {
3144 disable_notify_events();
3145 m_xEntry->SetText(rText);
3146 enable_notify_events();
3147 }
3148
get_text() const3149 virtual OUString get_text() const override
3150 {
3151 return m_xEntry->GetText();
3152 }
3153
set_width_chars(int nChars)3154 virtual void set_width_chars(int nChars) override
3155 {
3156 m_xEntry->SetWidthInChars(nChars);
3157 }
3158
get_width_chars() const3159 virtual int get_width_chars() const override
3160 {
3161 return m_xEntry->GetWidthInChars();
3162 }
3163
set_max_length(int nChars)3164 virtual void set_max_length(int nChars) override
3165 {
3166 m_xEntry->SetMaxTextLen(nChars);
3167 }
3168
select_region(int nStartPos,int nEndPos)3169 virtual void select_region(int nStartPos, int nEndPos) override
3170 {
3171 disable_notify_events();
3172 m_xEntry->SetSelection(Selection(nStartPos, nEndPos < 0 ? SELECTION_MAX : nEndPos));
3173 enable_notify_events();
3174 }
3175
get_selection_bounds(int & rStartPos,int & rEndPos)3176 bool get_selection_bounds(int& rStartPos, int &rEndPos) override
3177 {
3178 const Selection& rSelection = m_xEntry->GetSelection();
3179 rStartPos = rSelection.Min();
3180 rEndPos = rSelection.Max();
3181 return rSelection.Len();
3182 }
3183
replace_selection(const OUString & rText)3184 virtual void replace_selection(const OUString& rText) override
3185 {
3186 m_xEntry->ReplaceSelected(rText);
3187 }
3188
set_position(int nCursorPos)3189 virtual void set_position(int nCursorPos) override
3190 {
3191 disable_notify_events();
3192 if (nCursorPos < 0)
3193 m_xEntry->SetCursorAtLast();
3194 else
3195 m_xEntry->SetSelection(Selection(nCursorPos, nCursorPos));
3196 enable_notify_events();
3197 }
3198
get_position() const3199 virtual int get_position() const override
3200 {
3201 return m_xEntry->GetSelection().Max();
3202 }
3203
set_editable(bool bEditable)3204 virtual void set_editable(bool bEditable) override
3205 {
3206 m_xEntry->SetReadOnly(!bEditable);
3207 }
3208
get_editable() const3209 virtual bool get_editable() const override
3210 {
3211 return !m_xEntry->IsReadOnly();
3212 }
3213
set_message_type(weld::EntryMessageType eType)3214 virtual void set_message_type(weld::EntryMessageType eType) override
3215 {
3216 if (eType == weld::EntryMessageType::Error)
3217 {
3218 // tdf#114603: enable setting the background to a different color;
3219 // relevant for GTK; see also #i75179#
3220 m_xEntry->SetForceControlBackground(true);
3221 m_xEntry->SetControlForeground(COL_WHITE);
3222 m_xEntry->SetControlBackground(0xff6563);
3223 }
3224 else if (eType == weld::EntryMessageType::Warning)
3225 {
3226 // tdf#114603: enable setting the background to a different color;
3227 // relevant for GTK; see also #i75179#
3228 m_xEntry->SetForceControlBackground(true);
3229 m_xEntry->SetControlForeground();
3230 m_xEntry->SetControlBackground(COL_YELLOW);
3231 }
3232 else
3233 {
3234 m_xEntry->SetForceControlBackground(false);
3235 m_xEntry->SetControlForeground();
3236 m_xEntry->SetControlBackground();
3237 }
3238 }
3239
set_font(const vcl::Font & rFont)3240 virtual void set_font(const vcl::Font& rFont) override
3241 {
3242 m_xEntry->SetPointFont(*m_xEntry, rFont);
3243 m_xEntry->Invalidate();
3244 }
3245
connect_cursor_position(const Link<Entry &,void> & rLink)3246 virtual void connect_cursor_position(const Link<Entry&, void>& rLink) override
3247 {
3248 assert(!m_aCursorPositionHdl.IsSet());
3249 m_xEntry->AddEventListener(LINK(this, SalInstanceEntry, CursorListener));
3250 weld::Entry::connect_cursor_position(rLink);
3251 }
3252
getEntry()3253 Edit& getEntry()
3254 {
3255 return *m_xEntry;
3256 }
3257
fire_signal_changed()3258 void fire_signal_changed()
3259 {
3260 signal_changed();
3261 }
3262
cut_clipboard()3263 virtual void cut_clipboard() override
3264 {
3265 m_xEntry->Cut();
3266 }
3267
copy_clipboard()3268 virtual void copy_clipboard() override
3269 {
3270 m_xEntry->Copy();
3271 }
3272
paste_clipboard()3273 virtual void paste_clipboard() override
3274 {
3275 m_xEntry->Paste();
3276 }
3277
~SalInstanceEntry()3278 virtual ~SalInstanceEntry() override
3279 {
3280 if (m_aCursorPositionHdl.IsSet())
3281 m_xEntry->RemoveEventListener(LINK(this, SalInstanceEntry, CursorListener));
3282 m_xEntry->SetTextFilter(nullptr);
3283 m_xEntry->SetActivateHdl(Link<Edit&, bool>());
3284 m_xEntry->SetModifyHdl(Link<Edit&, void>());
3285 }
3286 };
3287
IMPL_LINK_NOARG(SalInstanceEntry,ChangeHdl,Edit &,void)3288 IMPL_LINK_NOARG(SalInstanceEntry, ChangeHdl, Edit&, void)
3289 {
3290 signal_changed();
3291 }
3292
IMPL_LINK(SalInstanceEntry,CursorListener,VclWindowEvent &,rEvent,void)3293 IMPL_LINK(SalInstanceEntry, CursorListener, VclWindowEvent&, rEvent, void)
3294 {
3295 if (notify_events_disabled())
3296 return;
3297 if (rEvent.GetId() == VclEventId::EditSelectionChanged || rEvent.GetId() == VclEventId::EditCaretChanged)
3298 signal_cursor_position();
3299 }
3300
IMPL_LINK_NOARG(SalInstanceEntry,ActivateHdl,Edit &,bool)3301 IMPL_LINK_NOARG(SalInstanceEntry, ActivateHdl, Edit&, bool)
3302 {
3303 return m_aActivateHdl.Call(*this);
3304 }
3305
3306 struct SalInstanceTreeIter : public weld::TreeIter
3307 {
SalInstanceTreeIterSalInstanceTreeIter3308 SalInstanceTreeIter(const SalInstanceTreeIter* pOrig)
3309 : iter(pOrig ? pOrig->iter : nullptr)
3310 {
3311 }
SalInstanceTreeIterSalInstanceTreeIter3312 SalInstanceTreeIter(SvTreeListEntry* pIter)
3313 : iter(pIter)
3314 {
3315 }
equalSalInstanceTreeIter3316 virtual bool equal(const TreeIter& rOther) const override
3317 {
3318 return iter == static_cast<const SalInstanceTreeIter&>(rOther).iter;
3319 }
3320 SvTreeListEntry* iter;
3321 };
3322
3323 namespace
3324 {
get_toggle(SvTreeListEntry * pEntry,int col)3325 TriState get_toggle(SvTreeListEntry* pEntry, int col)
3326 {
3327 ++col; //skip dummy/expander column
3328
3329 if (static_cast<size_t>(col) == pEntry->ItemCount())
3330 return TRISTATE_FALSE;
3331
3332 assert(col >= 0 && static_cast<size_t>(col) < pEntry->ItemCount());
3333 SvLBoxItem& rItem = pEntry->GetItem(col);
3334 assert(dynamic_cast<SvLBoxButton*>(&rItem));
3335 SvLBoxButton& rToggle = static_cast<SvLBoxButton&>(rItem);
3336 if (rToggle.IsStateTristate())
3337 return TRISTATE_INDET;
3338 else if (rToggle.IsStateChecked())
3339 return TRISTATE_TRUE;
3340 return TRISTATE_FALSE;
3341 }
3342
get_text_emphasis(SvTreeListEntry * pEntry,int col)3343 bool get_text_emphasis(SvTreeListEntry* pEntry, int col)
3344 {
3345 ++col; //skip dummy/expander column
3346
3347 assert(col >= 0 && static_cast<size_t>(col) < pEntry->ItemCount());
3348 SvLBoxItem& rItem = pEntry->GetItem(col);
3349 assert(dynamic_cast<SvLBoxString*>(&rItem));
3350 return static_cast<SvLBoxString&>(rItem).IsEmphasized();
3351 }
3352 }
3353
3354 class SalInstanceTreeView;
3355
3356 static SalInstanceTreeView* g_DragSource;
3357
3358 class SalInstanceTreeView : public SalInstanceContainer, public virtual weld::TreeView
3359 {
3360 private:
3361 // owner for UserData
3362 std::vector<std::unique_ptr<OUString>> m_aUserData;
3363 VclPtr<SvTabListBox> m_xTreeView;
3364 SvLBoxButtonData m_aCheckButtonData;
3365 SvLBoxButtonData m_aRadioButtonData;
3366 bool m_bDisableCheckBoxAutoWidth;
3367 int m_nSortColumn;
3368
3369 DECL_LINK(SelectHdl, SvTreeListBox*, void);
3370 DECL_LINK(DeSelectHdl, SvTreeListBox*, void);
3371 DECL_LINK(DoubleClickHdl, SvTreeListBox*, bool);
3372 DECL_LINK(ExpandingHdl, SvTreeListBox*, bool);
3373 DECL_LINK(EndDragHdl, HeaderBar*, void);
3374 DECL_LINK(HeaderBarClickedHdl, HeaderBar*, void);
3375 DECL_LINK(ToggleHdl, SvLBoxButtonData*, void);
3376 DECL_LINK(ModelChangedHdl, SvTreeListBox*, void);
3377 DECL_LINK(StartDragHdl, SvTreeListBox*, void);
3378 DECL_STATIC_LINK(SalInstanceTreeView, FinishDragHdl, SvTreeListBox*, void);
3379 DECL_LINK(EditingEntryHdl, SvTreeListEntry*, bool);
3380 typedef std::pair<SvTreeListEntry*, OUString> IterString;
3381 DECL_LINK(EditedEntryHdl, IterString, bool);
3382 DECL_LINK(VisibleRangeChangedHdl, SvTreeListBox*, void);
3383 DECL_LINK(CompareHdl, const SvSortData&, sal_Int32);
3384 DECL_LINK(PopupMenuHdl, const CommandEvent&, bool);
3385
IsDummyEntry(SvTreeListEntry * pEntry) const3386 bool IsDummyEntry(SvTreeListEntry* pEntry) const
3387 {
3388 return m_xTreeView->GetEntryText(pEntry).trim() == "<dummy>";
3389 }
3390
3391 public:
SalInstanceTreeView(SvTabListBox * pTreeView,SalInstanceBuilder * pBuilder,bool bTakeOwnership)3392 SalInstanceTreeView(SvTabListBox* pTreeView, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3393 : SalInstanceContainer(pTreeView, pBuilder, bTakeOwnership)
3394 , m_xTreeView(pTreeView)
3395 , m_aCheckButtonData(pTreeView, false)
3396 , m_aRadioButtonData(pTreeView, true)
3397 , m_bDisableCheckBoxAutoWidth(false)
3398 , m_nSortColumn(-1)
3399 {
3400 m_xTreeView->SetNodeDefaultImages();
3401 m_xTreeView->SetSelectHdl(LINK(this, SalInstanceTreeView, SelectHdl));
3402 m_xTreeView->SetDeselectHdl(LINK(this, SalInstanceTreeView, DeSelectHdl));
3403 m_xTreeView->SetDoubleClickHdl(LINK(this, SalInstanceTreeView, DoubleClickHdl));
3404 m_xTreeView->SetExpandingHdl(LINK(this, SalInstanceTreeView, ExpandingHdl));
3405 m_xTreeView->SetPopupMenuHdl(LINK(this, SalInstanceTreeView, PopupMenuHdl));
3406 const long aTabPositions[] = { 0 };
3407 m_xTreeView->SetTabs(SAL_N_ELEMENTS(aTabPositions), aTabPositions);
3408 LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
3409
3410 if (pHeaderBox)
3411 {
3412 if (HeaderBar* pHeaderBar = pHeaderBox->GetHeaderBar())
3413 {
3414 //make the last entry fill available space
3415 pHeaderBar->SetItemSize(pHeaderBar->GetItemId(pHeaderBar->GetItemCount() - 1 ), HEADERBAR_FULLSIZE);
3416 pHeaderBar->SetEndDragHdl(LINK(this, SalInstanceTreeView, EndDragHdl));
3417 pHeaderBar->SetSelectHdl(LINK(this, SalInstanceTreeView, HeaderBarClickedHdl));
3418 }
3419 pHeaderBox->SetEditingEntryHdl(LINK(this, SalInstanceTreeView, EditingEntryHdl));
3420 pHeaderBox->SetEditedEntryHdl(LINK(this, SalInstanceTreeView, EditedEntryHdl));
3421 }
3422 else
3423 {
3424 static_cast<LclTabListBox&>(*m_xTreeView).SetModelChangedHdl(LINK(this, SalInstanceTreeView, ModelChangedHdl));
3425 static_cast<LclTabListBox&>(*m_xTreeView).SetStartDragHdl(LINK(this, SalInstanceTreeView, StartDragHdl));
3426 static_cast<LclTabListBox&>(*m_xTreeView).SetEndDragHdl(LINK(this, SalInstanceTreeView, FinishDragHdl));
3427 static_cast<LclTabListBox&>(*m_xTreeView).SetEditingEntryHdl(LINK(this, SalInstanceTreeView, EditingEntryHdl));
3428 static_cast<LclTabListBox&>(*m_xTreeView).SetEditedEntryHdl(LINK(this, SalInstanceTreeView, EditedEntryHdl));
3429 }
3430 m_aCheckButtonData.SetLink(LINK(this, SalInstanceTreeView, ToggleHdl));
3431 m_aRadioButtonData.SetLink(LINK(this, SalInstanceTreeView, ToggleHdl));
3432 }
3433
columns_autosize()3434 virtual void columns_autosize() override
3435 {
3436 std::vector<long> aWidths;
3437 m_xTreeView->getPreferredDimensions(aWidths);
3438 if (aWidths.size() > 2)
3439 {
3440 std::vector<int> aColWidths;
3441 for (size_t i = 1; i < aWidths.size() - 1; ++i)
3442 aColWidths.push_back(aWidths[i] - aWidths[i - 1]);
3443 set_column_fixed_widths(aColWidths);
3444 }
3445 }
3446
freeze()3447 virtual void freeze() override
3448 {
3449 SalInstanceWidget::freeze();
3450 m_xTreeView->SetUpdateMode(false);
3451 }
3452
thaw()3453 virtual void thaw() override
3454 {
3455 m_xTreeView->SetUpdateMode(true);
3456 SalInstanceWidget::thaw();
3457 }
3458
set_column_fixed_widths(const std::vector<int> & rWidths)3459 virtual void set_column_fixed_widths(const std::vector<int>& rWidths) override
3460 {
3461 m_bDisableCheckBoxAutoWidth = true;
3462 std::vector<long> aTabPositions;
3463 aTabPositions.push_back(0);
3464 for (size_t i = 0; i < rWidths.size(); ++i)
3465 aTabPositions.push_back(aTabPositions[i] + rWidths[i]);
3466 m_xTreeView->SetTabs(aTabPositions.size(), aTabPositions.data(), MapUnit::MapPixel);
3467 LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
3468 if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
3469 {
3470 for (size_t i = 0; i < rWidths.size(); ++i)
3471 pHeaderBar->SetItemSize(pHeaderBar->GetItemId(i), rWidths[i]);
3472 }
3473 // call Resize to recalculate based on the new tabs
3474 m_xTreeView->Resize();
3475 }
3476
set_centered_column(int nCol)3477 virtual void set_centered_column(int nCol) override
3478 {
3479 m_xTreeView->SetTabJustify(nCol, SvTabJustify::AdjustCenter);
3480 }
3481
get_column_width(int nColumn) const3482 virtual int get_column_width(int nColumn) const override
3483 {
3484 LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
3485 if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
3486 return pHeaderBar->GetItemSize(pHeaderBar->GetItemId(nColumn));
3487 // GetTab(0) gives the position of the bitmap which is automatically inserted by the TabListBox.
3488 // So the first text column's width is Tab(2)-Tab(1).
3489 auto nWidthPixel = m_xTreeView->GetLogicTab(nColumn + 2) - m_xTreeView->GetLogicTab(nColumn + 1);
3490 nWidthPixel -= SV_TAB_BORDER;
3491 return nWidthPixel;
3492 }
3493
get_column_title(int nColumn) const3494 virtual OUString get_column_title(int nColumn) const override
3495 {
3496 LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
3497 if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
3498 {
3499 return pHeaderBar->GetItemText(pHeaderBar->GetItemId(nColumn));
3500 }
3501 return OUString();
3502 }
3503
set_column_title(int nColumn,const OUString & rTitle)3504 virtual void set_column_title(int nColumn, const OUString& rTitle) override
3505 {
3506 LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
3507 if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
3508 {
3509 return pHeaderBar->SetItemText(pHeaderBar->GetItemId(nColumn), rTitle);
3510 }
3511 }
3512
show()3513 virtual void show() override
3514 {
3515 if (LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get()))
3516 pHeaderBox->GetParent()->Show();
3517 SalInstanceContainer::show();
3518 }
3519
hide()3520 virtual void hide() override
3521 {
3522 if (LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get()))
3523 pHeaderBox->GetParent()->Hide();
3524 SalInstanceContainer::hide();
3525 }
3526
insert(const weld::TreeIter * pParent,int pos,const OUString * pStr,const OUString * pId,const OUString * pIconName,VirtualDevice * pImageSurface,const OUString * pExpanderName,bool bChildrenOnDemand,weld::TreeIter * pRet)3527 virtual void insert(const weld::TreeIter* pParent, int pos, const OUString* pStr, const OUString* pId,
3528 const OUString* pIconName, VirtualDevice* pImageSurface,
3529 const OUString* pExpanderName, bool bChildrenOnDemand, weld::TreeIter* pRet) override
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 (pIconName || pImageSurface)
3546 {
3547 Image aImage(pIconName ? createImage(*pIconName) : createImage(*pImageSurface));
3548 pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(aImage, aImage, false));
3549 }
3550 else
3551 {
3552 Image aDummy;
3553 pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(aDummy, aDummy, false));
3554 }
3555 if (pStr)
3556 pEntry->AddItem(std::make_unique<SvLBoxString>(*pStr));
3557 pEntry->SetUserData(pUserData);
3558 m_xTreeView->Insert(pEntry, iter, nInsertPos);
3559
3560 if (pExpanderName)
3561 {
3562 Image aImage(createImage(*pExpanderName));
3563 m_xTreeView->SetExpandedEntryBmp(pEntry, aImage);
3564 m_xTreeView->SetCollapsedEntryBmp(pEntry, aImage);
3565 }
3566
3567 if (pRet)
3568 {
3569 SalInstanceTreeIter* pVclRetIter = static_cast<SalInstanceTreeIter*>(pRet);
3570 pVclRetIter->iter = pEntry;
3571 }
3572
3573 if (bChildrenOnDemand)
3574 {
3575 m_xTreeView->InsertEntry("<dummy>", pEntry, false, 0, nullptr);
3576 }
3577 enable_notify_events();
3578 }
3579
bulk_insert_for_each(int nSourceCount,const std::function<void (weld::TreeIter &,int nSourceIndex)> & func,const std::vector<int> * pFixedWidths)3580 virtual void bulk_insert_for_each(int nSourceCount,
3581 const std::function<void(weld::TreeIter&, int nSourceIndex)>& func,
3582 const std::vector<int>* pFixedWidths) override
3583 {
3584 freeze();
3585 clear();
3586 SalInstanceTreeIter aVclIter(static_cast<SvTreeListEntry*>(nullptr));
3587
3588 m_xTreeView->nTreeFlags |= SvTreeFlags::MANINS;
3589
3590 if (pFixedWidths)
3591 set_column_fixed_widths(*pFixedWidths);
3592
3593 Image aDummy;
3594 for (int i = 0; i < nSourceCount; ++i)
3595 {
3596 aVclIter.iter = new SvTreeListEntry;
3597 aVclIter.iter->AddItem(std::make_unique<SvLBoxContextBmp>(aDummy, aDummy, false));
3598 m_xTreeView->Insert(aVclIter.iter, nullptr, TREELIST_APPEND);
3599 func(aVclIter, i);
3600
3601 if (!pFixedWidths)
3602 continue;
3603
3604 size_t nFixedWidths = std::min(pFixedWidths->size(), aVclIter.iter->ItemCount());
3605 for (size_t j = 0; j < nFixedWidths; ++j)
3606 {
3607 SvLBoxItem& rItem = aVclIter.iter->GetItem(j);
3608 SvViewDataItem* pViewDataItem = m_xTreeView->GetViewDataItem(aVclIter.iter, &rItem);
3609 pViewDataItem->mnWidth = (*pFixedWidths)[j];
3610 }
3611 }
3612
3613 m_xTreeView->nTreeFlags &= ~SvTreeFlags::MANINS;
3614
3615 thaw();
3616 }
3617
set_font_color(int pos,const Color & rColor) const3618 virtual void set_font_color(int pos, const Color& rColor) const override
3619 {
3620 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
3621 pEntry->SetTextColor(rColor);
3622 }
3623
set_font_color(const weld::TreeIter & rIter,const Color & rColor) const3624 virtual void set_font_color(const weld::TreeIter& rIter, const Color& rColor) const override
3625 {
3626 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
3627 rVclIter.iter->SetTextColor(rColor);
3628 }
3629
remove(int pos)3630 virtual void remove(int pos) override
3631 {
3632 disable_notify_events();
3633 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
3634 m_xTreeView->RemoveEntry(pEntry);
3635 enable_notify_events();
3636 }
3637
find_text(const OUString & rText) const3638 virtual int find_text(const OUString& rText) const override
3639 {
3640 for (SvTreeListEntry* pEntry = m_xTreeView->First(); pEntry; pEntry = m_xTreeView->Next(pEntry))
3641 {
3642 if (SvTabListBox::GetEntryText(pEntry, 0) == rText)
3643 return SvTreeList::GetRelPos(pEntry);
3644 }
3645 return -1;
3646 }
3647
find_id(const OUString & rId) const3648 virtual int find_id(const OUString& rId) const override
3649 {
3650 for (SvTreeListEntry* pEntry = m_xTreeView->First(); pEntry; pEntry = m_xTreeView->Next(pEntry))
3651 {
3652 const OUString* pId = static_cast<const OUString*>(pEntry->GetUserData());
3653 if (!pId)
3654 continue;
3655 if (rId == *pId)
3656 return SvTreeList::GetRelPos(pEntry);
3657 }
3658 return -1;
3659 }
3660
swap(int pos1,int pos2)3661 virtual void swap(int pos1, int pos2) override
3662 {
3663 int min = std::min(pos1, pos2);
3664 int max = std::max(pos1, pos2);
3665 SvTreeList* pModel = m_xTreeView->GetModel();
3666 SvTreeListEntry* pEntry1 = pModel->GetEntry(nullptr, min);
3667 SvTreeListEntry* pEntry2 = pModel->GetEntry(nullptr, max);
3668 pModel->Move(pEntry1, pEntry2);
3669 }
3670
clear()3671 virtual void clear() override
3672 {
3673 disable_notify_events();
3674 m_xTreeView->Clear();
3675 m_aUserData.clear();
3676 enable_notify_events();
3677 }
3678
n_children() const3679 virtual int n_children() const override
3680 {
3681 return m_xTreeView->GetModel()->GetChildList(nullptr).size();
3682 }
3683
select(int pos)3684 virtual void select(int pos) override
3685 {
3686 assert(m_xTreeView->IsUpdateMode() && "don't select when frozen");
3687 disable_notify_events();
3688 if (pos == -1 || (pos == 0 && n_children() == 0))
3689 m_xTreeView->SelectAll(false);
3690 else
3691 {
3692 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
3693 m_xTreeView->Select(pEntry, true);
3694 m_xTreeView->MakeVisible(pEntry);
3695 }
3696 enable_notify_events();
3697 }
3698
get_cursor_index() const3699 virtual int get_cursor_index() const override
3700 {
3701 SvTreeListEntry* pEntry = m_xTreeView->GetCurEntry();
3702 if (!pEntry)
3703 return -1;
3704 return SvTreeList::GetRelPos(pEntry);
3705 }
3706
set_cursor(int pos)3707 virtual void set_cursor(int pos) override
3708 {
3709 if (pos == -1)
3710 m_xTreeView->SetCurEntry(nullptr);
3711 else
3712 {
3713 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
3714 m_xTreeView->SetCurEntry(pEntry);
3715 }
3716 }
3717
scroll_to_row(int pos)3718 virtual void scroll_to_row(int pos) override
3719 {
3720 assert(m_xTreeView->IsUpdateMode() && "don't select when frozen");
3721 disable_notify_events();
3722 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
3723 m_xTreeView->MakeVisible(pEntry);
3724 enable_notify_events();
3725 }
3726
is_selected(int pos) const3727 virtual bool is_selected(int pos) const override
3728 {
3729 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
3730 return m_xTreeView->IsSelected(pEntry);
3731 }
3732
unselect(int pos)3733 virtual void unselect(int pos) override
3734 {
3735 assert(m_xTreeView->IsUpdateMode() && "don't select when frozen");
3736 disable_notify_events();
3737 if (pos == -1)
3738 m_xTreeView->SelectAll(true);
3739 else
3740 {
3741 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
3742 m_xTreeView->Select(pEntry, false);
3743 }
3744 enable_notify_events();
3745 }
3746
get_selected_rows() const3747 virtual std::vector<int> get_selected_rows() const override
3748 {
3749 std::vector<int> aRows;
3750
3751 aRows.reserve(m_xTreeView->GetSelectionCount());
3752 for (SvTreeListEntry* pEntry = m_xTreeView->FirstSelected(); pEntry; pEntry = m_xTreeView->NextSelected(pEntry))
3753 aRows.push_back(SvTreeList::GetRelPos(pEntry));
3754
3755 return aRows;
3756 }
3757
get_text(SvTreeListEntry * pEntry,int col)3758 static OUString get_text(SvTreeListEntry* pEntry, int col)
3759 {
3760 if (col == -1)
3761 return SvTabListBox::GetEntryText(pEntry, 0);
3762
3763 ++col; //skip dummy/expander column
3764
3765 if (static_cast<size_t>(col) == pEntry->ItemCount())
3766 return OUString();
3767
3768 assert(col >= 0 && static_cast<size_t>(col) < pEntry->ItemCount());
3769 SvLBoxItem& rItem = pEntry->GetItem(col);
3770 assert(dynamic_cast<SvLBoxString*>(&rItem));
3771 return static_cast<SvLBoxString&>(rItem).GetText();
3772 }
3773
get_text(int pos,int col) const3774 virtual OUString get_text(int pos, int col) const override
3775 {
3776 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
3777 return get_text(pEntry, col);
3778 }
3779
set_text(SvTreeListEntry * pEntry,const OUString & rText,int col)3780 void set_text(SvTreeListEntry* pEntry, const OUString& rText, int col)
3781 {
3782 if (col == -1)
3783 {
3784 m_xTreeView->SetEntryText(pEntry, rText);
3785 return;
3786 }
3787
3788 ++col; //skip dummy/expander column
3789
3790 // blank out missing entries
3791 for (int i = pEntry->ItemCount(); i < col ; ++i)
3792 pEntry->AddItem(std::make_unique<SvLBoxString>(""));
3793
3794 if (static_cast<size_t>(col) == pEntry->ItemCount())
3795 {
3796 pEntry->AddItem(std::make_unique<SvLBoxString>(rText));
3797 SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry);
3798 m_xTreeView->InitViewData(pViewData, pEntry);
3799 }
3800 else
3801 {
3802 assert(col >= 0 && static_cast<size_t>(col) < pEntry->ItemCount());
3803 SvLBoxItem& rItem = pEntry->GetItem(col);
3804 assert(dynamic_cast<SvLBoxString*>(&rItem));
3805 static_cast<SvLBoxString&>(rItem).SetText(rText);
3806 }
3807 m_xTreeView->ModelHasEntryInvalidated(pEntry);
3808 }
3809
set_text(int pos,const OUString & rText,int col)3810 virtual void set_text(int pos, const OUString& rText, int col) override
3811 {
3812 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
3813 set_text(pEntry, rText, col);
3814 }
3815
set_sensitive(SvTreeListEntry * pEntry,bool bSensitive,int col)3816 void set_sensitive(SvTreeListEntry* pEntry, bool bSensitive, int col)
3817 {
3818 if (col == -1)
3819 {
3820 const sal_uInt16 nCount = pEntry->ItemCount();
3821 for (sal_uInt16 nCur = 0; nCur < nCount; ++nCur)
3822 {
3823 SvLBoxItem& rItem = pEntry->GetItem(nCur);
3824 if (rItem.GetType() == SvLBoxItemType::String)
3825 {
3826 rItem.Enable(bSensitive);
3827 m_xTreeView->ModelHasEntryInvalidated(pEntry);
3828 break;
3829 }
3830 }
3831 return;
3832 }
3833
3834 ++col; //skip dummy/expander column
3835
3836 assert(col >= 0 && static_cast<size_t>(col) < pEntry->ItemCount());
3837 SvLBoxItem& rItem = pEntry->GetItem(col);
3838 rItem.Enable(bSensitive);
3839
3840 m_xTreeView->ModelHasEntryInvalidated(pEntry);
3841 }
3842
3843 using SalInstanceWidget::set_sensitive;
3844
set_sensitive(int pos,bool bSensitive,int col)3845 virtual void set_sensitive(int pos, bool bSensitive, int col) override
3846 {
3847 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
3848 set_sensitive(pEntry, bSensitive, col);
3849 }
3850
set_sensitive(const weld::TreeIter & rIter,bool bSensitive,int col)3851 virtual void set_sensitive(const weld::TreeIter& rIter, bool bSensitive, int col) override
3852 {
3853 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
3854 set_sensitive(rVclIter.iter, bSensitive, col);
3855 }
3856
get_toggle(int pos,int col) const3857 virtual TriState get_toggle(int pos, int col) const override
3858 {
3859 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
3860 return ::get_toggle(pEntry, col);
3861 }
3862
get_toggle(const weld::TreeIter & rIter,int col) const3863 virtual TriState get_toggle(const weld::TreeIter& rIter, int col) const override
3864 {
3865 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
3866 return ::get_toggle(rVclIter.iter, col);
3867 }
3868
set_toggle(SvTreeListEntry * pEntry,TriState eState,int col)3869 void set_toggle(SvTreeListEntry* pEntry, TriState eState, int col)
3870 {
3871 bool bRadio = std::find(m_aRadioIndexes.begin(), m_aRadioIndexes.end(), col) != m_aRadioIndexes.end();
3872 ++col; //skip dummy/expander column
3873
3874 // blank out missing entries
3875 for (int i = pEntry->ItemCount(); i < col ; ++i)
3876 pEntry->AddItem(std::make_unique<SvLBoxString>(""));
3877
3878 if (static_cast<size_t>(col) == pEntry->ItemCount())
3879 {
3880 SvLBoxButtonData* pData = bRadio ? &m_aRadioButtonData : &m_aCheckButtonData;
3881
3882 // if we want to have the implicit auto-sizing of the checkbox
3883 // column we need to call EnableCheckButton and CheckBoxInserted to
3884 // let it figure out that width. But we don't want to override any
3885 // explicitly set column width, so disable this if we've set
3886 // explicit column widths
3887 if (!m_bDisableCheckBoxAutoWidth)
3888 {
3889 if (!(m_xTreeView->GetTreeFlags() & SvTreeFlags::CHKBTN))
3890 {
3891 m_xTreeView->EnableCheckButton(pData);
3892 // EnableCheckButton clobbered this, restore it
3893 pData->SetLink(LINK(this, SalInstanceTreeView, ToggleHdl));
3894 }
3895 }
3896
3897 pEntry->AddItem(std::make_unique<SvLBoxButton>(pData));
3898 SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry);
3899 m_xTreeView->InitViewData(pViewData, pEntry);
3900
3901 if (!m_bDisableCheckBoxAutoWidth)
3902 m_xTreeView->CheckBoxInserted(pEntry);
3903 }
3904
3905 assert(col >= 0 && static_cast<size_t>(col) < pEntry->ItemCount());
3906 SvLBoxItem& rItem = pEntry->GetItem(col);
3907 assert(dynamic_cast<SvLBoxButton*>(&rItem));
3908 switch (eState)
3909 {
3910 case TRISTATE_TRUE:
3911 static_cast<SvLBoxButton&>(rItem).SetStateChecked();
3912 break;
3913 case TRISTATE_FALSE:
3914 static_cast<SvLBoxButton&>(rItem).SetStateUnchecked();
3915 break;
3916 case TRISTATE_INDET:
3917 static_cast<SvLBoxButton&>(rItem).SetStateTristate();
3918 break;
3919 }
3920
3921 m_xTreeView->ModelHasEntryInvalidated(pEntry);
3922 }
3923
set_toggle(int pos,TriState eState,int col)3924 virtual void set_toggle(int pos, TriState eState, int col) override
3925 {
3926 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
3927 set_toggle(pEntry, eState, col);
3928 }
3929
set_toggle(const weld::TreeIter & rIter,TriState eState,int col)3930 virtual void set_toggle(const weld::TreeIter& rIter, TriState eState, int col) override
3931 {
3932 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
3933 set_toggle(rVclIter.iter, eState, col);
3934 }
3935
set_text_emphasis(SvTreeListEntry * pEntry,bool bOn,int col)3936 void set_text_emphasis(SvTreeListEntry* pEntry, bool bOn, int col)
3937 {
3938 ++col; //skip dummy/expander column
3939
3940 assert(col >= 0 && static_cast<size_t>(col) < pEntry->ItemCount());
3941 SvLBoxItem& rItem = pEntry->GetItem(col);
3942 assert(dynamic_cast<SvLBoxString*>(&rItem));
3943 static_cast<SvLBoxString&>(rItem).Emphasize(bOn);
3944
3945 m_xTreeView->ModelHasEntryInvalidated(pEntry);
3946 }
3947
set_text_emphasis(const weld::TreeIter & rIter,bool bOn,int col)3948 virtual void set_text_emphasis(const weld::TreeIter& rIter, bool bOn, int col) override
3949 {
3950 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
3951 set_text_emphasis(rVclIter.iter, bOn, col);
3952 }
3953
set_text_emphasis(int pos,bool bOn,int col)3954 virtual void set_text_emphasis(int pos, bool bOn, int col) override
3955 {
3956 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
3957 set_text_emphasis(pEntry, bOn, col);
3958 }
3959
get_text_emphasis(const weld::TreeIter & rIter,int col) const3960 virtual bool get_text_emphasis(const weld::TreeIter& rIter, int col) const override
3961 {
3962 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
3963 return ::get_text_emphasis(rVclIter.iter, col);
3964 }
3965
get_text_emphasis(int pos,int col) const3966 virtual bool get_text_emphasis(int pos, int col) const override
3967 {
3968 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
3969 return ::get_text_emphasis(pEntry, col);
3970 }
3971
connect_editing(const Link<const weld::TreeIter &,bool> & rStartLink,const Link<const std::pair<const weld::TreeIter &,OUString> &,bool> & rEndLink)3972 virtual void connect_editing(const Link<const weld::TreeIter&, bool>& rStartLink,
3973 const Link<const std::pair<const weld::TreeIter&, OUString>&, bool>& rEndLink) override
3974 {
3975 m_xTreeView->EnableInplaceEditing(rStartLink.IsSet() || rEndLink.IsSet());
3976 weld::TreeView::connect_editing(rStartLink, rEndLink);
3977 }
3978
start_editing(const weld::TreeIter & rIter)3979 virtual void start_editing(const weld::TreeIter& rIter) override
3980 {
3981 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
3982 m_xTreeView->EditEntry(rVclIter.iter);
3983 }
3984
end_editing()3985 virtual void end_editing() override
3986 {
3987 m_xTreeView->EndEditing();
3988 }
3989
set_image(SvTreeListEntry * pEntry,const Image & rImage,int col)3990 void set_image(SvTreeListEntry* pEntry, const Image& rImage, int col)
3991 {
3992 if (col == -1)
3993 {
3994 m_xTreeView->SetExpandedEntryBmp(pEntry, rImage);
3995 m_xTreeView->SetCollapsedEntryBmp(pEntry, rImage);
3996 return;
3997 }
3998
3999 ++col; //skip dummy/expander column
4000
4001 // blank out missing entries
4002 for (int i = pEntry->ItemCount(); i < col ; ++i)
4003 pEntry->AddItem(std::make_unique<SvLBoxString>(""));
4004
4005 if (static_cast<size_t>(col) == pEntry->ItemCount())
4006 {
4007 pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(rImage, rImage, false));
4008 SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry);
4009 m_xTreeView->InitViewData(pViewData, pEntry);
4010 }
4011 else
4012 {
4013 assert(col >= 0 && static_cast<size_t>(col) < pEntry->ItemCount());
4014 SvLBoxItem& rItem = pEntry->GetItem(col);
4015 assert(dynamic_cast<SvLBoxContextBmp*>(&rItem));
4016 static_cast<SvLBoxContextBmp&>(rItem).SetBitmap1(rImage);
4017 static_cast<SvLBoxContextBmp&>(rItem).SetBitmap2(rImage);
4018 }
4019
4020 m_xTreeView->SetEntryHeight(pEntry);
4021 m_xTreeView->ModelHasEntryInvalidated(pEntry);
4022 }
4023
set_image(int pos,const OUString & rImage,int col)4024 virtual void set_image(int pos, const OUString& rImage, int col) override
4025 {
4026 set_image(m_xTreeView->GetEntry(nullptr, pos), createImage(rImage), col);
4027 }
4028
set_image(int pos,const css::uno::Reference<css::graphic::XGraphic> & rImage,int col)4029 virtual void set_image(int pos, const css::uno::Reference<css::graphic::XGraphic>& rImage, int col) override
4030 {
4031 set_image(m_xTreeView->GetEntry(nullptr, pos), Image(rImage), col);
4032 }
4033
set_image(int pos,VirtualDevice & rImage,int col)4034 virtual void set_image(int pos, VirtualDevice& rImage, int col) override
4035 {
4036 set_image(m_xTreeView->GetEntry(nullptr, pos), createImage(rImage), col);
4037 }
4038
set_image(const weld::TreeIter & rIter,const OUString & rImage,int col)4039 virtual void set_image(const weld::TreeIter& rIter, const OUString& rImage, int col) override
4040 {
4041 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4042 set_image(rVclIter.iter, createImage(rImage), col);
4043 }
4044
set_image(const weld::TreeIter & rIter,const css::uno::Reference<css::graphic::XGraphic> & rImage,int col)4045 virtual void set_image(const weld::TreeIter& rIter, const css::uno::Reference<css::graphic::XGraphic>& rImage, int col) override
4046 {
4047 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4048 set_image(rVclIter.iter, Image(rImage), col);
4049 }
4050
set_image(const weld::TreeIter & rIter,VirtualDevice & rImage,int col)4051 virtual void set_image(const weld::TreeIter& rIter, VirtualDevice& rImage, int col) override
4052 {
4053 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4054 set_image(rVclIter.iter, createImage(rImage), col);
4055 }
4056
getEntryData(int index) const4057 const OUString* getEntryData(int index) const
4058 {
4059 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, index);
4060 return pEntry ? static_cast<const OUString*>(pEntry->GetUserData()) : nullptr;
4061 }
4062
get_id(int pos) const4063 virtual OUString get_id(int pos) const override
4064 {
4065 const OUString* pRet = getEntryData(pos);
4066 if (!pRet)
4067 return OUString();
4068 return *pRet;
4069 }
4070
set_id(SvTreeListEntry * pEntry,const OUString & rId)4071 void set_id(SvTreeListEntry* pEntry, const OUString& rId)
4072 {
4073 m_aUserData.emplace_back(std::make_unique<OUString>(rId));
4074 pEntry->SetUserData(m_aUserData.back().get());
4075 }
4076
set_id(int pos,const OUString & rId)4077 virtual void set_id(int pos, const OUString& rId) override
4078 {
4079 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4080 set_id(pEntry, rId);
4081 }
4082
get_selected_index() const4083 virtual int get_selected_index() const override
4084 {
4085 assert(m_xTreeView->IsUpdateMode() && "don't request selection when frozen");
4086 SvTreeListEntry* pEntry = m_xTreeView->FirstSelected();
4087 if (!pEntry)
4088 return -1;
4089 return SvTreeList::GetRelPos(pEntry);
4090 }
4091
get_selected_text() const4092 virtual OUString get_selected_text() const override
4093 {
4094 assert(m_xTreeView->IsUpdateMode() && "don't request selection when frozen");
4095 if (SvTreeListEntry* pEntry = m_xTreeView->FirstSelected())
4096 return m_xTreeView->GetEntryText(pEntry);
4097 return OUString();
4098 }
4099
get_selected_id() const4100 virtual OUString get_selected_id() const override
4101 {
4102 assert(m_xTreeView->IsUpdateMode() && "don't request selection when frozen");
4103 if (SvTreeListEntry* pEntry = m_xTreeView->FirstSelected())
4104 {
4105 if (const OUString* pStr = static_cast<const OUString*>(pEntry->GetUserData()))
4106 return *pStr;
4107 }
4108 return OUString();
4109 }
4110
make_iterator(const weld::TreeIter * pOrig) const4111 virtual std::unique_ptr<weld::TreeIter> make_iterator(const weld::TreeIter* pOrig) const override
4112 {
4113 return std::unique_ptr<weld::TreeIter>(new SalInstanceTreeIter(static_cast<const SalInstanceTreeIter*>(pOrig)));
4114 }
4115
copy_iterator(const weld::TreeIter & rSource,weld::TreeIter & rDest) const4116 virtual void copy_iterator(const weld::TreeIter& rSource, weld::TreeIter& rDest) const override
4117 {
4118 const SalInstanceTreeIter& rVclSource(static_cast<const SalInstanceTreeIter&>(rSource));
4119 SalInstanceTreeIter& rVclDest(static_cast<SalInstanceTreeIter&>(rDest));
4120 rVclDest.iter = rVclSource.iter;
4121 }
4122
get_selected(weld::TreeIter * pIter) const4123 virtual bool get_selected(weld::TreeIter* pIter) const override
4124 {
4125 SvTreeListEntry* pEntry = m_xTreeView->FirstSelected();
4126 auto pVclIter = static_cast<SalInstanceTreeIter*>(pIter);
4127 if (pVclIter)
4128 pVclIter->iter = pEntry;
4129 return pEntry != nullptr;
4130 }
4131
get_cursor(weld::TreeIter * pIter) const4132 virtual bool get_cursor(weld::TreeIter* pIter) const override
4133 {
4134 SvTreeListEntry* pEntry = m_xTreeView->GetCurEntry();
4135 auto pVclIter = static_cast<SalInstanceTreeIter*>(pIter);
4136 if (pVclIter)
4137 pVclIter->iter = pEntry;
4138 return pEntry != nullptr;
4139 }
4140
set_cursor(const weld::TreeIter & rIter)4141 virtual void set_cursor(const weld::TreeIter& rIter) override
4142 {
4143 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4144 disable_notify_events();
4145 m_xTreeView->SetCurEntry(rVclIter.iter);
4146 enable_notify_events();
4147 }
4148
get_iter_first(weld::TreeIter & rIter) const4149 virtual bool get_iter_first(weld::TreeIter& rIter) const override
4150 {
4151 SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
4152 rVclIter.iter = m_xTreeView->GetEntry(0);
4153 return rVclIter.iter != nullptr;
4154 }
4155
iter_next_sibling(weld::TreeIter & rIter) const4156 virtual bool iter_next_sibling(weld::TreeIter& rIter) const override
4157 {
4158 SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
4159 rVclIter.iter = rVclIter.iter->NextSibling();
4160 return rVclIter.iter != nullptr;
4161 }
4162
iter_next(weld::TreeIter & rIter) const4163 virtual bool iter_next(weld::TreeIter& rIter) const override
4164 {
4165 SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
4166 rVclIter.iter = m_xTreeView->Next(rVclIter.iter);
4167 if (rVclIter.iter && IsDummyEntry(rVclIter.iter))
4168 return iter_next(rVclIter);
4169 return rVclIter.iter != nullptr;
4170 }
4171
iter_children(weld::TreeIter & rIter) const4172 virtual bool iter_children(weld::TreeIter& rIter) const override
4173 {
4174 SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
4175 rVclIter.iter = m_xTreeView->FirstChild(rVclIter.iter);
4176 bool bRet = rVclIter.iter != nullptr;
4177 if (bRet)
4178 {
4179 //on-demand dummy entry doesn't count
4180 return !IsDummyEntry(rVclIter.iter);
4181 }
4182 return bRet;
4183 }
4184
iter_parent(weld::TreeIter & rIter) const4185 virtual bool iter_parent(weld::TreeIter& rIter) const override
4186 {
4187 SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
4188 rVclIter.iter = m_xTreeView->GetParent(rVclIter.iter);
4189 return rVclIter.iter != nullptr;
4190 }
4191
remove(const weld::TreeIter & rIter)4192 virtual void remove(const weld::TreeIter& rIter) override
4193 {
4194 disable_notify_events();
4195 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4196 m_xTreeView->RemoveEntry(rVclIter.iter);
4197 enable_notify_events();
4198 }
4199
select(const weld::TreeIter & rIter)4200 virtual void select(const weld::TreeIter& rIter) override
4201 {
4202 assert(m_xTreeView->IsUpdateMode() && "don't select when frozen");
4203 disable_notify_events();
4204 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4205 m_xTreeView->Select(rVclIter.iter, true);
4206 enable_notify_events();
4207 }
4208
scroll_to_row(const weld::TreeIter & rIter)4209 virtual void scroll_to_row(const weld::TreeIter& rIter) override
4210 {
4211 assert(m_xTreeView->IsUpdateMode() && "don't select when frozen");
4212 disable_notify_events();
4213 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4214 m_xTreeView->MakeVisible(rVclIter.iter);
4215 enable_notify_events();
4216 }
4217
unselect(const weld::TreeIter & rIter)4218 virtual void unselect(const weld::TreeIter& rIter) override
4219 {
4220 assert(m_xTreeView->IsUpdateMode() && "don't unselect when frozen");
4221 disable_notify_events();
4222 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4223 m_xTreeView->Select(rVclIter.iter, false);
4224 enable_notify_events();
4225 }
4226
get_iter_depth(const weld::TreeIter & rIter) const4227 virtual int get_iter_depth(const weld::TreeIter& rIter) const override
4228 {
4229 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4230 return m_xTreeView->GetModel()->GetDepth(rVclIter.iter);
4231 }
4232
iter_has_child(const weld::TreeIter & rIter) const4233 virtual bool iter_has_child(const weld::TreeIter& rIter) const override
4234 {
4235 weld::TreeIter& rNonConstIter = const_cast<weld::TreeIter&>(rIter);
4236 SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rNonConstIter);
4237 SvTreeListEntry* restore(rVclIter.iter);
4238 bool ret = iter_children(rNonConstIter);
4239 rVclIter.iter = restore;
4240 return ret;
4241 }
4242
get_row_expanded(const weld::TreeIter & rIter) const4243 virtual bool get_row_expanded(const weld::TreeIter& rIter) const override
4244 {
4245 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4246 return m_xTreeView->IsExpanded(rVclIter.iter);
4247 }
4248
expand_row(const weld::TreeIter & rIter)4249 virtual void expand_row(const weld::TreeIter& rIter) override
4250 {
4251 assert(m_xTreeView->IsUpdateMode() && "don't expand when frozen");
4252 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4253 if (!m_xTreeView->IsExpanded(rVclIter.iter) && signal_expanding(rIter))
4254 m_xTreeView->Expand(rVclIter.iter);
4255 }
4256
collapse_row(const weld::TreeIter & rIter)4257 virtual void collapse_row(const weld::TreeIter& rIter) override
4258 {
4259 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4260 if (m_xTreeView->IsExpanded(rVclIter.iter))
4261 m_xTreeView->Collapse(rVclIter.iter);
4262 }
4263
get_text(const weld::TreeIter & rIter,int col) const4264 virtual OUString get_text(const weld::TreeIter& rIter, int col) const override
4265 {
4266 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4267 return get_text(rVclIter.iter, col);
4268 }
4269
set_text(const weld::TreeIter & rIter,const OUString & rText,int col)4270 virtual void set_text(const weld::TreeIter& rIter, const OUString& rText, int col) override
4271 {
4272 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4273 set_text(rVclIter.iter, rText, col);
4274 }
4275
get_id(const weld::TreeIter & rIter) const4276 virtual OUString get_id(const weld::TreeIter& rIter) const override
4277 {
4278 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4279 const OUString* pStr = static_cast<const OUString*>(rVclIter.iter->GetUserData());
4280 if (pStr)
4281 return *pStr;
4282 return OUString();
4283 }
4284
set_id(const weld::TreeIter & rIter,const OUString & rId)4285 virtual void set_id(const weld::TreeIter& rIter, const OUString& rId) override
4286 {
4287 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4288 set_id(rVclIter.iter, rId);
4289 }
4290
set_selection_mode(SelectionMode eMode)4291 virtual void set_selection_mode(SelectionMode eMode) override
4292 {
4293 m_xTreeView->SetSelectionMode(eMode);
4294 }
4295
all_foreach(const std::function<bool (weld::TreeIter &)> & func)4296 virtual void all_foreach(const std::function<bool(weld::TreeIter&)>& func) override
4297 {
4298 SalInstanceTreeIter aVclIter(m_xTreeView->First());
4299 while (aVclIter.iter)
4300 {
4301 if (func(aVclIter))
4302 return;
4303 aVclIter.iter = m_xTreeView->Next(aVclIter.iter);
4304 }
4305 }
4306
selected_foreach(const std::function<bool (weld::TreeIter &)> & func)4307 virtual void selected_foreach(const std::function<bool(weld::TreeIter&)>& func) override
4308 {
4309 SalInstanceTreeIter aVclIter(m_xTreeView->FirstSelected());
4310 while (aVclIter.iter)
4311 {
4312 if (func(aVclIter))
4313 return;
4314 aVclIter.iter = m_xTreeView->NextSelected(aVclIter.iter);
4315 }
4316 }
4317
visible_foreach(const std::function<bool (weld::TreeIter &)> & func)4318 virtual void visible_foreach(const std::function<bool(weld::TreeIter&)>& func) override
4319 {
4320 SalInstanceTreeIter aVclIter(m_xTreeView->GetFirstEntryInView());
4321 while (aVclIter.iter)
4322 {
4323 if (func(aVclIter))
4324 return;
4325 aVclIter.iter = m_xTreeView->GetNextEntryInView(aVclIter.iter);
4326 }
4327 }
4328
connect_visible_range_changed(const Link<weld::TreeView &,void> & rLink)4329 virtual void connect_visible_range_changed(const Link<weld::TreeView&, void>& rLink) override
4330 {
4331 weld::TreeView::connect_visible_range_changed(rLink);
4332 m_xTreeView->SetScrolledHdl(LINK(this, SalInstanceTreeView, VisibleRangeChangedHdl));
4333 }
4334
remove_selection()4335 virtual void remove_selection() override
4336 {
4337 disable_notify_events();
4338 SvTreeListEntry* pSelected = m_xTreeView->FirstSelected();
4339 while (pSelected)
4340 {
4341 SvTreeListEntry* pNextSelected = m_xTreeView->NextSelected(pSelected);
4342 m_xTreeView->RemoveEntry(pSelected);
4343 pSelected = pNextSelected;
4344 }
4345 enable_notify_events();
4346 }
4347
is_selected(const weld::TreeIter & rIter) const4348 virtual bool is_selected(const weld::TreeIter& rIter) const override
4349 {
4350 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4351 return m_xTreeView->IsSelected(rVclIter.iter);
4352 }
4353
get_iter_index_in_parent(const weld::TreeIter & rIter) const4354 virtual int get_iter_index_in_parent(const weld::TreeIter& rIter) const override
4355 {
4356 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4357 return SvTreeList::GetRelPos(rVclIter.iter);
4358 }
4359
iter_compare(const weld::TreeIter & a,const weld::TreeIter & b) const4360 virtual int iter_compare(const weld::TreeIter& a, const weld::TreeIter& b) const override
4361 {
4362 const SalInstanceTreeIter& rVclIterA = static_cast<const SalInstanceTreeIter&>(a);
4363 const SalInstanceTreeIter& rVclIterB = static_cast<const SalInstanceTreeIter&>(b);
4364 const SvTreeList* pModel = m_xTreeView->GetModel();
4365 auto nAbsPosA = pModel->GetAbsPos(rVclIterA.iter);
4366 auto nAbsPosB = pModel->GetAbsPos(rVclIterB.iter);
4367 if (nAbsPosA < nAbsPosB)
4368 return -1;
4369 if (nAbsPosA > nAbsPosB)
4370 return 1;
4371 return 0;
4372 }
4373
move_subtree(weld::TreeIter & rNode,const weld::TreeIter * pNewParent,int nIndexInNewParent)4374 virtual void move_subtree(weld::TreeIter& rNode, const weld::TreeIter* pNewParent, int nIndexInNewParent) override
4375 {
4376 SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rNode);
4377 const SalInstanceTreeIter* pVclParentIter = static_cast<const SalInstanceTreeIter*>(pNewParent);
4378 m_xTreeView->GetModel()->Move(rVclIter.iter, pVclParentIter ? pVclParentIter->iter : nullptr, nIndexInNewParent);
4379 }
4380
count_selected_rows() const4381 virtual int count_selected_rows() const override
4382 {
4383 return m_xTreeView->GetSelectionCount();
4384 }
4385
get_height_rows(int nRows) const4386 virtual int get_height_rows(int nRows) const override
4387 {
4388 return m_xTreeView->GetEntryHeight() * nRows;
4389 }
4390
make_sorted()4391 virtual void make_sorted() override
4392 {
4393 assert(m_xTreeView->IsUpdateMode() && "don't sort when frozen");
4394 m_xTreeView->SetStyle(m_xTreeView->GetStyle() | WB_SORT);
4395 m_xTreeView->GetModel()->SetCompareHdl(LINK(this, SalInstanceTreeView, CompareHdl));
4396 set_sort_order(true);
4397 }
4398
set_sort_func(const std::function<int (const weld::TreeIter &,const weld::TreeIter &)> & func)4399 virtual void set_sort_func(const std::function<int(const weld::TreeIter&, const weld::TreeIter&)>& func) override
4400 {
4401 weld::TreeView::set_sort_func(func);
4402 SvTreeList* pListModel = m_xTreeView->GetModel();
4403 pListModel->Resort();
4404 }
4405
make_unsorted()4406 virtual void make_unsorted() override
4407 {
4408 m_xTreeView->SetStyle(m_xTreeView->GetStyle() & ~WB_SORT);
4409 }
4410
set_sort_order(bool bAscending)4411 virtual void set_sort_order(bool bAscending) override
4412 {
4413 SvTreeList* pListModel = m_xTreeView->GetModel();
4414 pListModel->SetSortMode(bAscending ? SortAscending : SortDescending);
4415 pListModel->Resort();
4416 }
4417
get_sort_order() const4418 virtual bool get_sort_order() const override
4419 {
4420 return m_xTreeView->GetModel()->GetSortMode() == SortAscending;
4421 }
4422
set_sort_indicator(TriState eState,int col)4423 virtual void set_sort_indicator(TriState eState, int col) override
4424 {
4425 if (col == -1)
4426 col = 0;
4427
4428 LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
4429 if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
4430 {
4431 sal_uInt16 nTextId = pHeaderBar->GetItemId(col);
4432 HeaderBarItemBits nBits = pHeaderBar->GetItemBits(nTextId);
4433 nBits &= ~HeaderBarItemBits::UPARROW;
4434 nBits &= ~HeaderBarItemBits::DOWNARROW;
4435 if (eState != TRISTATE_INDET)
4436 {
4437 if (eState == TRISTATE_TRUE)
4438 nBits |= HeaderBarItemBits::DOWNARROW;
4439 else
4440 nBits |= HeaderBarItemBits::UPARROW;
4441 }
4442 pHeaderBar->SetItemBits(nTextId, nBits);
4443 }
4444 }
4445
get_sort_indicator(int col) const4446 virtual TriState get_sort_indicator(int col) const override
4447 {
4448 if (col == -1)
4449 col = 0;
4450
4451 LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
4452 if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
4453 {
4454 sal_uInt16 nTextId = pHeaderBar->GetItemId(col);
4455 HeaderBarItemBits nBits = pHeaderBar->GetItemBits(nTextId);
4456 if (nBits & HeaderBarItemBits::DOWNARROW)
4457 return TRISTATE_TRUE;
4458 if (nBits & HeaderBarItemBits::UPARROW)
4459 return TRISTATE_FALSE;
4460 }
4461
4462 return TRISTATE_INDET;
4463 }
4464
get_sort_column() const4465 virtual int get_sort_column() const override
4466 {
4467 return m_nSortColumn;
4468 }
4469
set_sort_column(int nColumn)4470 virtual void set_sort_column(int nColumn) override
4471 {
4472 if (nColumn == -1)
4473 {
4474 make_unsorted();
4475 m_nSortColumn = -1;
4476 return;
4477 }
4478
4479 if (nColumn != m_nSortColumn)
4480 {
4481 m_nSortColumn = nColumn;
4482 m_xTreeView->GetModel()->Resort();
4483 }
4484 }
4485
getTreeView()4486 SvTabListBox& getTreeView()
4487 {
4488 return *m_xTreeView;
4489 }
4490
get_dest_row_at_pos(const Point & rPos,weld::TreeIter * pResult)4491 virtual bool get_dest_row_at_pos(const Point &rPos, weld::TreeIter* pResult) override
4492 {
4493 SvTreeListEntry* pTarget = m_xTreeView->GetDropTarget(rPos);
4494
4495 if (pTarget && pResult)
4496 {
4497 SalInstanceTreeIter& rSalIter = static_cast<SalInstanceTreeIter&>(*pResult);
4498 rSalIter.iter = pTarget;
4499 }
4500
4501 return pTarget != nullptr;
4502 }
4503
get_drag_source() const4504 virtual TreeView* get_drag_source() const override
4505 {
4506 return g_DragSource;
4507 }
4508
~SalInstanceTreeView()4509 virtual ~SalInstanceTreeView() override
4510 {
4511 LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
4512 if (pHeaderBox)
4513 {
4514 if (HeaderBar* pHeaderBar = pHeaderBox->GetHeaderBar())
4515 {
4516 pHeaderBar->SetSelectHdl(Link<HeaderBar*, void>());
4517 pHeaderBar->SetEndDragHdl(Link<HeaderBar*, void>());
4518 }
4519 }
4520 else
4521 {
4522 static_cast<LclTabListBox&>(*m_xTreeView).SetEndDragHdl(Link<SvTreeListBox*, void>());
4523 static_cast<LclTabListBox&>(*m_xTreeView).SetStartDragHdl(Link<SvTreeListBox*, void>());
4524 static_cast<LclTabListBox&>(*m_xTreeView).SetModelChangedHdl(Link<SvTreeListBox*, void>());
4525 }
4526 m_xTreeView->SetPopupMenuHdl(Link<const CommandEvent&, bool>());
4527 m_xTreeView->SetExpandingHdl(Link<SvTreeListBox*, bool>());
4528 m_xTreeView->SetDoubleClickHdl(Link<SvTreeListBox*, bool>());
4529 m_xTreeView->SetSelectHdl(Link<SvTreeListBox*, void>());
4530 m_xTreeView->SetDeselectHdl(Link<SvTreeListBox*, void>());
4531 m_xTreeView->SetScrolledHdl(Link<SvTreeListBox*, void>());
4532 }
4533 };
4534
IMPL_LINK(SalInstanceTreeView,CompareHdl,const SvSortData &,rSortData,sal_Int32)4535 IMPL_LINK(SalInstanceTreeView, CompareHdl, const SvSortData&, rSortData, sal_Int32)
4536 {
4537 const SvTreeListEntry* pLHS = rSortData.pLeft;
4538 const SvTreeListEntry* pRHS = rSortData.pRight;
4539 assert(pLHS && pRHS);
4540
4541 if (m_aCustomSort)
4542 return m_aCustomSort(SalInstanceTreeIter(const_cast<SvTreeListEntry*>(pLHS)),
4543 SalInstanceTreeIter(const_cast<SvTreeListEntry*>(pRHS)));
4544
4545 const SvLBoxString* pLeftTextItem;
4546 const SvLBoxString* pRightTextItem;
4547
4548 if (m_nSortColumn != -1)
4549 {
4550 size_t col = m_nSortColumn;
4551
4552 ++col; //skip dummy/expander column
4553
4554 if (col < pLHS->ItemCount())
4555 {
4556 const SvLBoxString& rLeftTextItem = static_cast<const SvLBoxString&>(pLHS->GetItem(col));
4557 pLeftTextItem = &rLeftTextItem;
4558 }
4559 else
4560 pLeftTextItem = nullptr;
4561 if (col < pRHS->ItemCount())
4562 {
4563 const SvLBoxString& rRightTextItem = static_cast<const SvLBoxString&>(pRHS->GetItem(col));
4564 pRightTextItem = &rRightTextItem;
4565 }
4566 else
4567 pRightTextItem = nullptr;
4568 }
4569 else
4570 {
4571 pLeftTextItem = static_cast<const SvLBoxString*>(pLHS->GetFirstItem(SvLBoxItemType::String));
4572 pRightTextItem = static_cast<const SvLBoxString*>(pRHS->GetFirstItem(SvLBoxItemType::String));
4573 }
4574
4575 return m_xTreeView->DefaultCompare(pLeftTextItem, pRightTextItem);
4576 }
4577
IMPL_LINK_NOARG(SalInstanceTreeView,VisibleRangeChangedHdl,SvTreeListBox *,void)4578 IMPL_LINK_NOARG(SalInstanceTreeView, VisibleRangeChangedHdl, SvTreeListBox*, void)
4579 {
4580 if (notify_events_disabled())
4581 return;
4582 signal_visible_range_changed();
4583 }
4584
IMPL_LINK_NOARG(SalInstanceTreeView,ModelChangedHdl,SvTreeListBox *,void)4585 IMPL_LINK_NOARG(SalInstanceTreeView, ModelChangedHdl, SvTreeListBox*, void)
4586 {
4587 if (notify_events_disabled())
4588 return;
4589 signal_model_changed();
4590 }
4591
IMPL_LINK_NOARG(SalInstanceTreeView,StartDragHdl,SvTreeListBox *,void)4592 IMPL_LINK_NOARG(SalInstanceTreeView, StartDragHdl, SvTreeListBox*, void)
4593 {
4594 g_DragSource = this;
4595 }
4596
IMPL_STATIC_LINK_NOARG(SalInstanceTreeView,FinishDragHdl,SvTreeListBox *,void)4597 IMPL_STATIC_LINK_NOARG(SalInstanceTreeView, FinishDragHdl, SvTreeListBox*, void)
4598 {
4599 g_DragSource = nullptr;
4600 }
4601
IMPL_LINK(SalInstanceTreeView,ToggleHdl,SvLBoxButtonData *,pData,void)4602 IMPL_LINK(SalInstanceTreeView, ToggleHdl, SvLBoxButtonData*, pData, void)
4603 {
4604 SvTreeListEntry* pEntry = pData->GetActEntry();
4605 SvLBoxButton* pBox = pData->GetActBox();
4606
4607 // tdf#122874 Select the row, calling SelectHdl, before handling
4608 // the toggle
4609 if (!m_xTreeView->IsSelected(pEntry))
4610 {
4611 m_xTreeView->SelectAll(false);
4612 m_xTreeView->Select(pEntry, true);
4613 }
4614
4615 // toggled signal handlers can query get_cursor to get which
4616 // node was clicked
4617 m_xTreeView->pImpl->m_pCursor = pEntry;
4618
4619 for (int i = 1, nCount = pEntry->ItemCount(); i < nCount; ++i)
4620 {
4621 SvLBoxItem& rItem = pEntry->GetItem(i);
4622 if (&rItem == pBox)
4623 {
4624 int nRow = SvTreeList::GetRelPos(pEntry);
4625 int nCol = i - 1; // less dummy/expander column
4626 signal_toggled(std::make_pair(nRow, nCol));
4627 break;
4628 }
4629 }
4630 }
4631
IMPL_LINK_NOARG(SalInstanceTreeView,SelectHdl,SvTreeListBox *,void)4632 IMPL_LINK_NOARG(SalInstanceTreeView, SelectHdl, SvTreeListBox*, void)
4633 {
4634 if (notify_events_disabled())
4635 return;
4636 signal_changed();
4637 }
4638
IMPL_LINK_NOARG(SalInstanceTreeView,DeSelectHdl,SvTreeListBox *,void)4639 IMPL_LINK_NOARG(SalInstanceTreeView, DeSelectHdl, SvTreeListBox*, void)
4640 {
4641 if (notify_events_disabled())
4642 return;
4643 if (m_xTreeView->GetSelectionMode() == SelectionMode::Single)
4644 return;
4645 signal_changed();
4646 }
4647
IMPL_LINK_NOARG(SalInstanceTreeView,DoubleClickHdl,SvTreeListBox *,bool)4648 IMPL_LINK_NOARG(SalInstanceTreeView, DoubleClickHdl, SvTreeListBox*, bool)
4649 {
4650 if (notify_events_disabled())
4651 return false;
4652 return !signal_row_activated();
4653 }
4654
IMPL_LINK(SalInstanceTreeView,EndDragHdl,HeaderBar *,pHeaderBar,void)4655 IMPL_LINK(SalInstanceTreeView, EndDragHdl, HeaderBar*, pHeaderBar, void)
4656 {
4657 std::vector<long> aTabPositions;
4658 aTabPositions.push_back(0);
4659 for (int i = 0; i < pHeaderBar->GetItemCount() - 1; ++i)
4660 aTabPositions.push_back(aTabPositions[i] + pHeaderBar->GetItemSize(pHeaderBar->GetItemId(i)));
4661 m_xTreeView->SetTabs(aTabPositions.size(), aTabPositions.data(), MapUnit::MapPixel);
4662 }
4663
IMPL_LINK(SalInstanceTreeView,HeaderBarClickedHdl,HeaderBar *,pHeaderBar,void)4664 IMPL_LINK(SalInstanceTreeView, HeaderBarClickedHdl, HeaderBar*, pHeaderBar, void)
4665 {
4666 sal_uInt16 nId = pHeaderBar->GetCurItemId();
4667 if (!(pHeaderBar->GetItemBits(nId) & HeaderBarItemBits::CLICKABLE))
4668 return;
4669 signal_column_clicked(pHeaderBar->GetItemPos(nId));
4670 }
4671
IMPL_LINK_NOARG(SalInstanceTreeView,ExpandingHdl,SvTreeListBox *,bool)4672 IMPL_LINK_NOARG(SalInstanceTreeView, ExpandingHdl, SvTreeListBox*, bool)
4673 {
4674 SvTreeListEntry* pEntry = m_xTreeView->GetHdlEntry();
4675 if (m_xTreeView->IsExpanded(pEntry))
4676 {
4677 //collapsing;
4678 return true;
4679 }
4680
4681 // if there's a preexisting placeholder child, required to make this
4682 // potentially expandable in the first place, now we remove it
4683 bool bPlaceHolder = false;
4684 if (pEntry->HasChildren())
4685 {
4686 auto pChild = m_xTreeView->FirstChild(pEntry);
4687 assert(pChild);
4688 if (IsDummyEntry(pChild))
4689 {
4690 m_xTreeView->RemoveEntry(pChild);
4691 bPlaceHolder = true;
4692 }
4693 }
4694
4695 SalInstanceTreeIter aIter(pEntry);
4696 bool bRet = signal_expanding(aIter);
4697
4698 //expand disallowed, restore placeholder
4699 if (!bRet && bPlaceHolder)
4700 {
4701 m_xTreeView->InsertEntry("<dummy>", pEntry, false, 0, nullptr);
4702 }
4703
4704 return bRet;
4705 }
4706
IMPL_LINK(SalInstanceTreeView,PopupMenuHdl,const CommandEvent &,rEvent,bool)4707 IMPL_LINK(SalInstanceTreeView, PopupMenuHdl, const CommandEvent&, rEvent, bool)
4708 {
4709 return m_aPopupMenuHdl.Call(rEvent);
4710 }
4711
IMPL_LINK(SalInstanceTreeView,EditingEntryHdl,SvTreeListEntry *,pEntry,bool)4712 IMPL_LINK(SalInstanceTreeView, EditingEntryHdl, SvTreeListEntry*, pEntry, bool)
4713 {
4714 return signal_editing_started(SalInstanceTreeIter(pEntry));
4715 }
4716
IMPL_LINK(SalInstanceTreeView,EditedEntryHdl,IterString,rIterString,bool)4717 IMPL_LINK(SalInstanceTreeView, EditedEntryHdl, IterString, rIterString, bool)
4718 {
4719 return signal_editing_done(std::pair<const weld::TreeIter&, OUString>(SalInstanceTreeIter(rIterString.first), rIterString.second));
4720 }
4721
4722 class SalInstanceIconView : public SalInstanceContainer, public virtual weld::IconView
4723 {
4724 private:
4725 // owner for UserData
4726 std::vector<std::unique_ptr<OUString>> m_aUserData;
4727 VclPtr<::IconView> m_xIconView;
4728
4729 DECL_LINK(SelectHdl, SvTreeListBox*, void);
4730 DECL_LINK(DeSelectHdl, SvTreeListBox*, void);
4731 DECL_LINK(DoubleClickHdl, SvTreeListBox*, bool);
4732
4733 public:
SalInstanceIconView(::IconView * pIconView,SalInstanceBuilder * pBuilder,bool bTakeOwnership)4734 SalInstanceIconView(::IconView* pIconView, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
4735 : SalInstanceContainer(pIconView, pBuilder, bTakeOwnership)
4736 , m_xIconView(pIconView)
4737 {
4738 m_xIconView->SetSelectHdl(LINK(this, SalInstanceIconView, SelectHdl));
4739 m_xIconView->SetDeselectHdl(LINK(this, SalInstanceIconView, DeSelectHdl));
4740 m_xIconView->SetDoubleClickHdl(LINK(this, SalInstanceIconView, DoubleClickHdl));
4741 }
4742
freeze()4743 virtual void freeze() override
4744 {
4745 SalInstanceWidget::freeze();
4746 m_xIconView->SetUpdateMode(false);
4747 }
4748
thaw()4749 virtual void thaw() override
4750 {
4751 m_xIconView->SetUpdateMode(true);
4752 SalInstanceWidget::thaw();
4753 }
4754
insert(int pos,const OUString * pStr,const OUString * pId,const OUString * pIconName,weld::TreeIter * pRet)4755 virtual void insert(int pos, const OUString* pStr, const OUString* pId,
4756 const OUString* pIconName, weld::TreeIter* pRet) override
4757 {
4758 disable_notify_events();
4759 auto nInsertPos = pos == -1 ? TREELIST_APPEND : pos;
4760 void* pUserData;
4761 if (pId)
4762 {
4763 m_aUserData.emplace_back(std::make_unique<OUString>(*pId));
4764 pUserData = m_aUserData.back().get();
4765 }
4766 else
4767 pUserData = nullptr;
4768
4769 SvTreeListEntry* pEntry = new SvTreeListEntry;
4770 if (pIconName)
4771 {
4772 Image aImage(createImage(*pIconName));
4773 pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(aImage, aImage, false));
4774 }
4775 else
4776 {
4777 Image aDummy;
4778 pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(aDummy, aDummy, false));
4779 }
4780 if (pStr)
4781 pEntry->AddItem(std::make_unique<SvLBoxString>(*pStr));
4782 pEntry->SetUserData(pUserData);
4783 m_xIconView->Insert(pEntry, nullptr, nInsertPos);
4784
4785 if (pRet)
4786 {
4787 SalInstanceTreeIter* pVclRetIter = static_cast<SalInstanceTreeIter*>(pRet);
4788 pVclRetIter->iter = pEntry;
4789 }
4790
4791 enable_notify_events();
4792 }
4793
get_selected_id() const4794 virtual OUString get_selected_id() const override
4795 {
4796 assert(m_xIconView->IsUpdateMode() && "don't request selection when frozen");
4797 if (SvTreeListEntry* pEntry = m_xIconView->FirstSelected())
4798 {
4799 if (const OUString* pStr = static_cast<const OUString*>(pEntry->GetUserData()))
4800 return *pStr;
4801 }
4802 return OUString();
4803 }
4804
get_selected_text() const4805 virtual OUString get_selected_text() const override
4806 {
4807 assert(m_xIconView->IsUpdateMode() && "don't request selection when frozen");
4808 if (SvTreeListEntry* pEntry = m_xIconView->FirstSelected())
4809 return m_xIconView->GetEntryText(pEntry);
4810 return OUString();
4811 }
4812
count_selected_items() const4813 virtual int count_selected_items() const override
4814 {
4815 return m_xIconView->GetSelectionCount();
4816 }
4817
select(int pos)4818 virtual void select(int pos) override
4819 {
4820 assert(m_xIconView->IsUpdateMode() && "don't select when frozen");
4821 disable_notify_events();
4822 if (pos == -1 || (pos == 0 && n_children() == 0))
4823 m_xIconView->SelectAll(false);
4824 else
4825 {
4826 SvTreeListEntry* pEntry = m_xIconView->GetEntry(nullptr, pos);
4827 m_xIconView->Select(pEntry, true);
4828 m_xIconView->MakeVisible(pEntry);
4829 }
4830 enable_notify_events();
4831 }
4832
unselect(int pos)4833 virtual void unselect(int pos) override
4834 {
4835 assert(m_xIconView->IsUpdateMode() && "don't select when frozen");
4836 disable_notify_events();
4837 if (pos == -1)
4838 m_xIconView->SelectAll(true);
4839 else
4840 {
4841 SvTreeListEntry* pEntry = m_xIconView->GetEntry(nullptr, pos);
4842 m_xIconView->Select(pEntry, false);
4843 }
4844 enable_notify_events();
4845 }
4846
n_children() const4847 virtual int n_children() const override
4848 {
4849 return m_xIconView->GetModel()->GetChildList(nullptr).size();
4850 }
4851
make_iterator(const weld::TreeIter * pOrig) const4852 virtual std::unique_ptr<weld::TreeIter> make_iterator(const weld::TreeIter* pOrig) const override
4853 {
4854 return std::unique_ptr<weld::TreeIter>(new SalInstanceTreeIter(static_cast<const SalInstanceTreeIter*>(pOrig)));
4855 }
4856
get_selected(weld::TreeIter * pIter) const4857 virtual bool get_selected(weld::TreeIter* pIter) const override
4858 {
4859 SvTreeListEntry* pEntry = m_xIconView->FirstSelected();
4860 auto pVclIter = static_cast<SalInstanceTreeIter*>(pIter);
4861 if (pVclIter)
4862 pVclIter->iter = pEntry;
4863 return pEntry != nullptr;
4864 }
4865
get_cursor(weld::TreeIter * pIter) const4866 virtual bool get_cursor(weld::TreeIter* pIter) const override
4867 {
4868 SvTreeListEntry* pEntry = m_xIconView->GetCurEntry();
4869 auto pVclIter = static_cast<SalInstanceTreeIter*>(pIter);
4870 if (pVclIter)
4871 pVclIter->iter = pEntry;
4872 return pEntry != nullptr;
4873 }
4874
set_cursor(const weld::TreeIter & rIter)4875 virtual void set_cursor(const weld::TreeIter& rIter) override
4876 {
4877 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4878 disable_notify_events();
4879 m_xIconView->SetCurEntry(rVclIter.iter);
4880 enable_notify_events();
4881 }
4882
get_iter_first(weld::TreeIter & rIter) const4883 virtual bool get_iter_first(weld::TreeIter& rIter) const override
4884 {
4885 SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
4886 rVclIter.iter = m_xIconView->GetEntry(0);
4887 return rVclIter.iter != nullptr;
4888 }
4889
scroll_to_item(const weld::TreeIter & rIter)4890 virtual void scroll_to_item(const weld::TreeIter& rIter) override
4891 {
4892 assert(m_xIconView->IsUpdateMode() && "don't select when frozen");
4893 disable_notify_events();
4894 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4895 m_xIconView->MakeVisible(rVclIter.iter);
4896 enable_notify_events();
4897 }
4898
selected_foreach(const std::function<bool (weld::TreeIter &)> & func)4899 virtual void selected_foreach(const std::function<bool(weld::TreeIter&)>& func) override
4900 {
4901 SalInstanceTreeIter aVclIter(m_xIconView->FirstSelected());
4902 while (aVclIter.iter)
4903 {
4904 if (func(aVclIter))
4905 return;
4906 aVclIter.iter = m_xIconView->NextSelected(aVclIter.iter);
4907 }
4908 }
4909
get_id(const weld::TreeIter & rIter) const4910 virtual OUString get_id(const weld::TreeIter& rIter) const override
4911 {
4912 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4913 const OUString* pStr = static_cast<const OUString*>(rVclIter.iter->GetUserData());
4914 if (pStr)
4915 return *pStr;
4916 return OUString();
4917 }
4918
clear()4919 virtual void clear() override
4920 {
4921 disable_notify_events();
4922 m_xIconView->Clear();
4923 m_aUserData.clear();
4924 enable_notify_events();
4925 }
4926
~SalInstanceIconView()4927 virtual ~SalInstanceIconView() override
4928 {
4929 m_xIconView->SetDoubleClickHdl(Link<SvTreeListBox*, bool>());
4930 m_xIconView->SetSelectHdl(Link<SvTreeListBox*, void>());
4931 m_xIconView->SetDeselectHdl(Link<SvTreeListBox*, void>());
4932 }
4933 };
4934
IMPL_LINK_NOARG(SalInstanceIconView,SelectHdl,SvTreeListBox *,void)4935 IMPL_LINK_NOARG(SalInstanceIconView, SelectHdl, SvTreeListBox*, void)
4936 {
4937 if (notify_events_disabled())
4938 return;
4939 signal_selection_changed();
4940 }
4941
IMPL_LINK_NOARG(SalInstanceIconView,DeSelectHdl,SvTreeListBox *,void)4942 IMPL_LINK_NOARG(SalInstanceIconView, DeSelectHdl, SvTreeListBox*, void)
4943 {
4944 if (notify_events_disabled())
4945 return;
4946 if (m_xIconView->GetSelectionMode() == SelectionMode::Single)
4947 return;
4948 signal_selection_changed();
4949 }
4950
IMPL_LINK_NOARG(SalInstanceIconView,DoubleClickHdl,SvTreeListBox *,bool)4951 IMPL_LINK_NOARG(SalInstanceIconView, DoubleClickHdl, SvTreeListBox*, bool)
4952 {
4953 if (notify_events_disabled())
4954 return false;
4955 return !signal_item_activated();
4956 }
4957
4958 class SalInstanceSpinButton : public SalInstanceEntry, public virtual weld::SpinButton
4959 {
4960 private:
4961 VclPtr<FormattedField> m_xButton;
4962
4963 DECL_LINK(UpDownHdl, SpinField&, void);
4964 DECL_LINK(LoseFocusHdl, Control&, void);
4965 DECL_LINK(OutputHdl, Edit&, bool);
4966 DECL_LINK(InputHdl, sal_Int64*, TriState);
4967 DECL_LINK(ActivateHdl, Edit&, bool);
4968
toField(int nValue) const4969 double toField(int nValue) const
4970 {
4971 return static_cast<double>(nValue) / Power10(get_digits());
4972 }
4973
fromField(double fValue) const4974 int fromField(double fValue) const
4975 {
4976 return FRound(fValue * Power10(get_digits()));
4977 }
4978
4979 public:
SalInstanceSpinButton(FormattedField * pButton,SalInstanceBuilder * pBuilder,bool bTakeOwnership)4980 SalInstanceSpinButton(FormattedField* pButton, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
4981 : SalInstanceEntry(pButton, pBuilder, bTakeOwnership)
4982 , m_xButton(pButton)
4983 {
4984 m_xButton->SetThousandsSep(false); //off by default, MetricSpinButton enables it
4985 m_xButton->SetUpHdl(LINK(this, SalInstanceSpinButton, UpDownHdl));
4986 m_xButton->SetDownHdl(LINK(this, SalInstanceSpinButton, UpDownHdl));
4987 m_xButton->SetLoseFocusHdl(LINK(this, SalInstanceSpinButton, LoseFocusHdl));
4988 m_xButton->SetOutputHdl(LINK(this, SalInstanceSpinButton, OutputHdl));
4989 m_xButton->SetInputHdl(LINK(this, SalInstanceSpinButton, InputHdl));
4990 if (Edit* pEdit = m_xButton->GetSubEdit())
4991 pEdit->SetActivateHdl(LINK(this, SalInstanceSpinButton, ActivateHdl));
4992 else
4993 m_xButton->SetActivateHdl(LINK(this, SalInstanceSpinButton, ActivateHdl));
4994 }
4995
get_value() const4996 virtual int get_value() const override
4997 {
4998 return fromField(m_xButton->GetValue());
4999 }
5000
set_value(int value)5001 virtual void set_value(int value) override
5002 {
5003 m_xButton->SetValue(toField(value));
5004 }
5005
set_range(int min,int max)5006 virtual void set_range(int min, int max) override
5007 {
5008 m_xButton->SetMinValue(toField(min));
5009 m_xButton->SetMaxValue(toField(max));
5010 }
5011
get_range(int & min,int & max) const5012 virtual void get_range(int& min, int& max) const override
5013 {
5014 min = fromField(m_xButton->GetMinValue());
5015 max = fromField(m_xButton->GetMaxValue());
5016 }
5017
set_increments(int step,int)5018 virtual void set_increments(int step, int /*page*/) override
5019 {
5020 m_xButton->SetSpinSize(toField(step));
5021 }
5022
get_increments(int & step,int & page) const5023 virtual void get_increments(int& step, int& page) const override
5024 {
5025 step = fromField(m_xButton->GetSpinSize());
5026 page = fromField(m_xButton->GetSpinSize());
5027 }
5028
set_digits(unsigned int digits)5029 virtual void set_digits(unsigned int digits) override
5030 {
5031 m_xButton->SetDecimalDigits(digits);
5032 }
5033
5034 //so with hh::mm::ss, incrementing mm will not reset ss
DisableRemainderFactor()5035 void DisableRemainderFactor()
5036 {
5037 m_xButton->DisableRemainderFactor();
5038 }
5039
5040 //off by default for direct SpinButtons, MetricSpinButton enables it
SetUseThousandSep()5041 void SetUseThousandSep()
5042 {
5043 m_xButton->SetThousandsSep(true);
5044 }
5045
get_digits() const5046 virtual unsigned int get_digits() const override
5047 {
5048 return m_xButton->GetDecimalDigits();
5049 }
5050
~SalInstanceSpinButton()5051 virtual ~SalInstanceSpinButton() override
5052 {
5053 if (Edit* pEdit = m_xButton->GetSubEdit())
5054 pEdit->SetActivateHdl(Link<Edit&, bool>());
5055 else
5056 m_xButton->SetActivateHdl(Link<Edit&, bool>());
5057 m_xButton->SetInputHdl(Link<sal_Int64*, TriState>());
5058 m_xButton->SetOutputHdl(Link<Edit&, bool>());
5059 m_xButton->SetLoseFocusHdl(Link<Control&, void>());
5060 m_xButton->SetDownHdl(Link<SpinField&, void>());
5061 m_xButton->SetUpHdl(Link<SpinField&, void>());
5062 }
5063 };
5064
IMPL_LINK_NOARG(SalInstanceSpinButton,ActivateHdl,Edit &,bool)5065 IMPL_LINK_NOARG(SalInstanceSpinButton, ActivateHdl, Edit&, bool)
5066 {
5067 // tdf#122348 return pressed to end dialog
5068 signal_value_changed();
5069 return false;
5070 }
5071
IMPL_LINK_NOARG(SalInstanceSpinButton,UpDownHdl,SpinField &,void)5072 IMPL_LINK_NOARG(SalInstanceSpinButton, UpDownHdl, SpinField&, void)
5073 {
5074 signal_value_changed();
5075 }
5076
IMPL_LINK_NOARG(SalInstanceSpinButton,LoseFocusHdl,Control &,void)5077 IMPL_LINK_NOARG(SalInstanceSpinButton, LoseFocusHdl, Control&, void)
5078 {
5079 signal_value_changed();
5080 }
5081
IMPL_LINK_NOARG(SalInstanceSpinButton,OutputHdl,Edit &,bool)5082 IMPL_LINK_NOARG(SalInstanceSpinButton, OutputHdl, Edit&, bool)
5083 {
5084 return signal_output();
5085 }
5086
IMPL_LINK(SalInstanceSpinButton,InputHdl,sal_Int64 *,pResult,TriState)5087 IMPL_LINK(SalInstanceSpinButton, InputHdl, sal_Int64*, pResult, TriState)
5088 {
5089 int nResult;
5090 TriState eRet = signal_input(&nResult);
5091 if (eRet == TRISTATE_TRUE)
5092 *pResult = nResult;
5093 return eRet;
5094 }
5095
5096 class SalInstanceFormattedSpinButton : public SalInstanceEntry, public virtual weld::FormattedSpinButton
5097 {
5098 private:
5099 VclPtr<FormattedField> m_xButton;
5100
5101 public:
SalInstanceFormattedSpinButton(FormattedField * pButton,SalInstanceBuilder * pBuilder,bool bTakeOwnership)5102 SalInstanceFormattedSpinButton(FormattedField* pButton, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
5103 : SalInstanceEntry(pButton, pBuilder, bTakeOwnership)
5104 , m_xButton(pButton)
5105 {
5106 // #i6278# allow more decimal places than the output format. As
5107 // the numbers shown in the edit fields are used for input, it makes more
5108 // sense to display the values in the input format rather than the output
5109 // format.
5110 m_xButton->UseInputStringForFormatting();
5111 }
5112
get_value() const5113 virtual double get_value() const override
5114 {
5115 return m_xButton->GetValue();
5116 }
5117
set_value(double value)5118 virtual void set_value(double value) override
5119 {
5120 m_xButton->SetValue(value);
5121 }
5122
set_range(double min,double max)5123 virtual void set_range(double min, double max) override
5124 {
5125 m_xButton->SetMinValue(min);
5126 m_xButton->SetMaxValue(max);
5127 }
5128
get_range(double & min,double & max) const5129 virtual void get_range(double& min, double& max) const override
5130 {
5131 min = m_xButton->GetMinValue();
5132 max = m_xButton->GetMaxValue();
5133 }
5134
set_formatter(SvNumberFormatter * pFormatter)5135 virtual void set_formatter(SvNumberFormatter* pFormatter) override
5136 {
5137 m_xButton->SetFormatter(pFormatter);
5138 }
5139
get_format_key() const5140 virtual sal_Int32 get_format_key() const override
5141 {
5142 return m_xButton->GetFormatKey();
5143 }
5144
set_format_key(sal_Int32 nFormatKey)5145 virtual void set_format_key(sal_Int32 nFormatKey) override
5146 {
5147 m_xButton->SetFormatKey(nFormatKey);
5148 }
5149 };
5150
5151 class SalInstanceLabel : public SalInstanceWidget, public virtual weld::Label
5152 {
5153 private:
5154 // Control instead of FixedText so we can also use this for
5155 // SelectableFixedText which is derived from Edit. We just typically need
5156 // [G|S]etText which exists in their shared baseclass
5157 VclPtr<Control> m_xLabel;
5158 public:
SalInstanceLabel(Control * pLabel,SalInstanceBuilder * pBuilder,bool bTakeOwnership)5159 SalInstanceLabel(Control* pLabel, SalInstanceBuilder *pBuilder, bool bTakeOwnership)
5160 : SalInstanceWidget(pLabel, pBuilder, bTakeOwnership)
5161 , m_xLabel(pLabel)
5162 {
5163 }
5164
set_label(const OUString & rText)5165 virtual void set_label(const OUString& rText) override
5166 {
5167 m_xLabel->SetText(rText);
5168 }
5169
get_label() const5170 virtual OUString get_label() const override
5171 {
5172 return m_xLabel->GetText();
5173 }
5174
set_mnemonic_widget(Widget * pTarget)5175 virtual void set_mnemonic_widget(Widget* pTarget) override
5176 {
5177 FixedText* pLabel = dynamic_cast<FixedText*>(m_xLabel.get());
5178 assert(pLabel && "can't use set_mnemonic_widget on SelectableFixedText");
5179 SalInstanceWidget* pTargetWidget = dynamic_cast<SalInstanceWidget*>(pTarget);
5180 pLabel->set_mnemonic_widget(pTargetWidget ? pTargetWidget->getWidget() : nullptr);
5181 }
5182
set_message_type(weld::EntryMessageType eType)5183 virtual void set_message_type(weld::EntryMessageType eType) override
5184 {
5185 if (eType == weld::EntryMessageType::Error)
5186 m_xLabel->SetControlBackground(m_xLabel->GetSettings().GetStyleSettings().GetHighlightColor());
5187 else if (eType == weld::EntryMessageType::Warning)
5188 m_xLabel->SetControlBackground(COL_YELLOW);
5189 else
5190 m_xLabel->SetControlBackground();
5191 }
5192
set_font(const vcl::Font & rFont)5193 virtual void set_font(const vcl::Font& rFont) override
5194 {
5195 m_xLabel->SetPointFont(*m_xLabel, rFont);
5196 m_xLabel->Invalidate();
5197 }
5198 };
5199
weld_label_widget() const5200 std::unique_ptr<weld::Label> SalInstanceFrame::weld_label_widget() const
5201 {
5202 FixedText* pLabel = dynamic_cast<FixedText*>(m_xFrame->get_label_widget());
5203 if (!pLabel)
5204 return nullptr;
5205 return std::make_unique<SalInstanceLabel>(pLabel, m_pBuilder, false);
5206 }
5207
5208 class SalInstanceTextView : public SalInstanceContainer, public virtual weld::TextView
5209 {
5210 private:
5211 VclPtr<VclMultiLineEdit> m_xTextView;
5212 Link<ScrollBar*,void> m_aOrigVScrollHdl;
5213
5214 DECL_LINK(ChangeHdl, Edit&, void);
5215 DECL_LINK(VscrollHdl, ScrollBar*, void);
5216 DECL_LINK(CursorListener, VclWindowEvent&, void);
5217 public:
SalInstanceTextView(VclMultiLineEdit * pTextView,SalInstanceBuilder * pBuilder,bool bTakeOwnership)5218 SalInstanceTextView(VclMultiLineEdit* pTextView, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
5219 : SalInstanceContainer(pTextView, pBuilder, bTakeOwnership)
5220 , m_xTextView(pTextView)
5221 {
5222 m_xTextView->SetModifyHdl(LINK(this, SalInstanceTextView, ChangeHdl));
5223 ScrollBar& rVertScrollBar = m_xTextView->GetVScrollBar();
5224 m_aOrigVScrollHdl = rVertScrollBar.GetScrollHdl();
5225 rVertScrollBar.SetScrollHdl(LINK(this, SalInstanceTextView, VscrollHdl));
5226 }
5227
set_text(const OUString & rText)5228 virtual void set_text(const OUString& rText) override
5229 {
5230 disable_notify_events();
5231 m_xTextView->SetText(rText);
5232 enable_notify_events();
5233 }
5234
replace_selection(const OUString & rText)5235 virtual void replace_selection(const OUString& rText) override
5236 {
5237 disable_notify_events();
5238 m_xTextView->ReplaceSelected(rText);
5239 enable_notify_events();
5240 }
5241
get_text() const5242 virtual OUString get_text() const override
5243 {
5244 return m_xTextView->GetText();
5245 }
5246
get_selection_bounds(int & rStartPos,int & rEndPos)5247 bool get_selection_bounds(int& rStartPos, int &rEndPos) override
5248 {
5249 const Selection& rSelection = m_xTextView->GetSelection();
5250 rStartPos = rSelection.Min();
5251 rEndPos = rSelection.Max();
5252 return rSelection.Len();
5253 }
5254
select_region(int nStartPos,int nEndPos)5255 virtual void select_region(int nStartPos, int nEndPos) override
5256 {
5257 disable_notify_events();
5258 m_xTextView->SetSelection(Selection(nStartPos, nEndPos < 0 ? SELECTION_MAX : nEndPos));
5259 enable_notify_events();
5260 }
5261
set_editable(bool bEditable)5262 virtual void set_editable(bool bEditable) override
5263 {
5264 m_xTextView->SetReadOnly(!bEditable);
5265 }
5266
set_monospace(bool bMonospace)5267 virtual void set_monospace(bool bMonospace) override
5268 {
5269 vcl::Font aOrigFont = m_xTextView->GetControlFont();
5270 vcl::Font aFont;
5271 if (bMonospace)
5272 aFont = OutputDevice::GetDefaultFont(DefaultFontType::UI_FIXED, LANGUAGE_DONTKNOW, GetDefaultFontFlags::OnlyOne, m_xTextView);
5273 else
5274 aFont = Application::GetSettings().GetStyleSettings().GetFieldFont();
5275 aFont.SetFontHeight(aOrigFont.GetFontHeight());
5276 m_xTextView->SetFont(aFont);
5277 m_xTextView->SetControlFont(aFont);
5278 }
5279
connect_cursor_position(const Link<TextView &,void> & rLink)5280 virtual void connect_cursor_position(const Link<TextView&, void>& rLink) override
5281 {
5282 assert(!m_aCursorPositionHdl.IsSet());
5283 m_xTextView->AddEventListener(LINK(this, SalInstanceTextView, CursorListener));
5284 weld::TextView::connect_cursor_position(rLink);
5285 }
5286
vadjustment_get_value() const5287 virtual int vadjustment_get_value() const override
5288 {
5289 ScrollBar& rVertScrollBar = m_xTextView->GetVScrollBar();
5290 return rVertScrollBar.GetThumbPos();
5291 }
5292
vadjustment_set_value(int value)5293 virtual void vadjustment_set_value(int value) override
5294 {
5295 ScrollBar& rVertScrollBar = m_xTextView->GetVScrollBar();
5296 rVertScrollBar.SetThumbPos(value);
5297 m_aOrigVScrollHdl.Call(&rVertScrollBar);
5298 }
5299
vadjustment_get_upper() const5300 virtual int vadjustment_get_upper() const override
5301 {
5302 ScrollBar& rVertScrollBar = m_xTextView->GetVScrollBar();
5303 return rVertScrollBar.GetRangeMax();
5304 }
5305
vadjustment_get_lower() const5306 virtual int vadjustment_get_lower() const override
5307 {
5308 ScrollBar& rVertScrollBar = m_xTextView->GetVScrollBar();
5309 return rVertScrollBar.GetRangeMin();
5310 }
5311
vadjustment_get_page_size() const5312 virtual int vadjustment_get_page_size() const override
5313 {
5314 ScrollBar& rVertScrollBar = m_xTextView->GetVScrollBar();
5315 return rVertScrollBar.GetVisibleSize();
5316 }
5317
~SalInstanceTextView()5318 virtual ~SalInstanceTextView() override
5319 {
5320 if (!m_xTextView->IsDisposed())
5321 {
5322 if (m_aCursorPositionHdl.IsSet())
5323 m_xTextView->RemoveEventListener(LINK(this, SalInstanceTextView, CursorListener));
5324 m_xTextView->SetModifyHdl(Link<Edit&, void>());
5325 ScrollBar& rVertScrollBar = m_xTextView->GetVScrollBar();
5326 rVertScrollBar.SetScrollHdl(m_aOrigVScrollHdl);
5327 }
5328 }
5329 };
5330
IMPL_LINK(SalInstanceTextView,VscrollHdl,ScrollBar *,pScrollBar,void)5331 IMPL_LINK(SalInstanceTextView, VscrollHdl, ScrollBar*, pScrollBar, void)
5332 {
5333 signal_vadjustment_changed();
5334 m_aOrigVScrollHdl.Call(pScrollBar);
5335 }
5336
IMPL_LINK_NOARG(SalInstanceTextView,ChangeHdl,Edit &,void)5337 IMPL_LINK_NOARG(SalInstanceTextView, ChangeHdl, Edit&, void)
5338 {
5339 signal_changed();
5340 }
5341
IMPL_LINK(SalInstanceTextView,CursorListener,VclWindowEvent &,rEvent,void)5342 IMPL_LINK(SalInstanceTextView, CursorListener, VclWindowEvent&, rEvent, void)
5343 {
5344 if (notify_events_disabled())
5345 return;
5346 if (rEvent.GetId() == VclEventId::EditSelectionChanged || rEvent.GetId() == VclEventId::EditCaretChanged)
5347 signal_cursor_position();
5348 }
5349
5350 class SalInstanceExpander : public SalInstanceContainer, public virtual weld::Expander
5351 {
5352 private:
5353 VclPtr<VclExpander> m_xExpander;
5354
5355 DECL_LINK(ExpandedHdl, VclExpander&, void);
5356
5357 public:
SalInstanceExpander(VclExpander * pExpander,SalInstanceBuilder * pBuilder,bool bTakeOwnership)5358 SalInstanceExpander(VclExpander* pExpander, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
5359 : SalInstanceContainer(pExpander, pBuilder, bTakeOwnership)
5360 , m_xExpander(pExpander)
5361 {
5362 m_xExpander->SetExpandedHdl(LINK(this, SalInstanceExpander, ExpandedHdl));
5363 }
5364
get_expanded() const5365 virtual bool get_expanded() const override
5366 {
5367 return m_xExpander->get_expanded();
5368 }
5369
set_expanded(bool bExpand)5370 virtual void set_expanded(bool bExpand) override
5371 {
5372 m_xExpander->set_expanded(bExpand);
5373 }
5374
~SalInstanceExpander()5375 virtual ~SalInstanceExpander() override
5376 {
5377 m_xExpander->SetExpandedHdl(Link<VclExpander&, void>());
5378 }
5379 };
5380
IMPL_LINK_NOARG(SalInstanceExpander,ExpandedHdl,VclExpander &,void)5381 IMPL_LINK_NOARG(SalInstanceExpander, ExpandedHdl, VclExpander&, void)
5382 {
5383 signal_expanded();
5384 }
5385
5386 class SalInstanceDrawingArea : public SalInstanceWidget, public virtual weld::DrawingArea
5387 {
5388 private:
5389 VclPtr<VclDrawingArea> m_xDrawingArea;
5390
5391 typedef std::pair<vcl::RenderContext&, const tools::Rectangle&> target_and_area;
5392 DECL_LINK(PaintHdl, target_and_area, void);
5393 DECL_LINK(ResizeHdl, const Size&, void);
5394 DECL_LINK(MousePressHdl, const MouseEvent&, bool);
5395 DECL_LINK(MouseMoveHdl, const MouseEvent&, bool);
5396 DECL_LINK(MouseReleaseHdl, const MouseEvent&, bool);
5397 DECL_LINK(KeyPressHdl, const KeyEvent&, bool);
5398 DECL_LINK(KeyReleaseHdl, const KeyEvent&, bool);
5399 DECL_LINK(StyleUpdatedHdl, VclDrawingArea&, void);
5400 DECL_LINK(CommandHdl, const CommandEvent&, bool);
5401 DECL_LINK(QueryTooltipHdl, tools::Rectangle&, OUString);
5402
5403 // SalInstanceWidget has a generic listener for all these
5404 // events, ignore the ones we have specializations for
5405 // in VclDrawingArea
HandleEventListener(VclWindowEvent & rEvent)5406 virtual void HandleEventListener(VclWindowEvent& rEvent) override
5407 {
5408 if (rEvent.GetId() == VclEventId::WindowResize)
5409 return;
5410 SalInstanceWidget::HandleEventListener(rEvent);
5411 }
5412
HandleMouseEventListener(VclSimpleEvent & rEvent)5413 virtual void HandleMouseEventListener(VclSimpleEvent& rEvent) override
5414 {
5415 if (rEvent.GetId() == VclEventId::WindowMouseButtonDown ||
5416 rEvent.GetId() == VclEventId::WindowMouseButtonUp ||
5417 rEvent.GetId() == VclEventId::WindowMouseMove)
5418 {
5419 return;
5420 }
5421 SalInstanceWidget::HandleMouseEventListener(rEvent);
5422 }
5423
5424
HandleKeyEventListener(VclWindowEvent &)5425 virtual bool HandleKeyEventListener(VclWindowEvent& /*rEvent*/) override
5426 {
5427 return false;
5428 }
5429
5430 public:
SalInstanceDrawingArea(VclDrawingArea * pDrawingArea,SalInstanceBuilder * pBuilder,const a11yref & rAlly,FactoryFunction pUITestFactoryFunction,void * pUserData,bool bTakeOwnership)5431 SalInstanceDrawingArea(VclDrawingArea* pDrawingArea, SalInstanceBuilder* pBuilder, const a11yref& rAlly,
5432 FactoryFunction pUITestFactoryFunction, void* pUserData, bool bTakeOwnership)
5433 : SalInstanceWidget(pDrawingArea, pBuilder, bTakeOwnership)
5434 , m_xDrawingArea(pDrawingArea)
5435 {
5436 m_xDrawingArea->SetAccessible(rAlly);
5437 m_xDrawingArea->SetUITestFactory(std::move(pUITestFactoryFunction), pUserData);
5438 m_xDrawingArea->SetPaintHdl(LINK(this, SalInstanceDrawingArea, PaintHdl));
5439 m_xDrawingArea->SetResizeHdl(LINK(this, SalInstanceDrawingArea, ResizeHdl));
5440 m_xDrawingArea->SetMousePressHdl(LINK(this, SalInstanceDrawingArea, MousePressHdl));
5441 m_xDrawingArea->SetMouseMoveHdl(LINK(this, SalInstanceDrawingArea, MouseMoveHdl));
5442 m_xDrawingArea->SetMouseReleaseHdl(LINK(this, SalInstanceDrawingArea, MouseReleaseHdl));
5443 m_xDrawingArea->SetKeyPressHdl(LINK(this, SalInstanceDrawingArea, KeyPressHdl));
5444 m_xDrawingArea->SetKeyReleaseHdl(LINK(this, SalInstanceDrawingArea, KeyReleaseHdl));
5445 m_xDrawingArea->SetStyleUpdatedHdl(LINK(this, SalInstanceDrawingArea, StyleUpdatedHdl));
5446 m_xDrawingArea->SetCommandHdl(LINK(this, SalInstanceDrawingArea, CommandHdl));
5447 m_xDrawingArea->SetQueryTooltipHdl(LINK(this, SalInstanceDrawingArea, QueryTooltipHdl));
5448 }
5449
queue_draw()5450 virtual void queue_draw() override
5451 {
5452 m_xDrawingArea->Invalidate();
5453 }
5454
queue_draw_area(int x,int y,int width,int height)5455 virtual void queue_draw_area(int x, int y, int width, int height) override
5456 {
5457 m_xDrawingArea->Invalidate(tools::Rectangle(Point(x, y), Size(width, height)));
5458 }
5459
queue_resize()5460 virtual void queue_resize() override
5461 {
5462 m_xDrawingArea->queue_resize();
5463 }
5464
connect_size_allocate(const Link<const Size &,void> & rLink)5465 virtual void connect_size_allocate(const Link<const Size&, void>& rLink) override
5466 {
5467 weld::Widget::connect_size_allocate(rLink);
5468 }
5469
connect_key_press(const Link<const KeyEvent &,bool> & rLink)5470 virtual void connect_key_press(const Link<const KeyEvent&, bool>& rLink) override
5471 {
5472 weld::Widget::connect_key_press(rLink);
5473 }
5474
connect_key_release(const Link<const KeyEvent &,bool> & rLink)5475 virtual void connect_key_release(const Link<const KeyEvent&, bool>& rLink) override
5476 {
5477 weld::Widget::connect_key_release(rLink);
5478 }
5479
set_cursor(PointerStyle ePointerStyle)5480 virtual void set_cursor(PointerStyle ePointerStyle) override
5481 {
5482 m_xDrawingArea->SetPointer(ePointerStyle);
5483 }
5484
get_accessible_parent()5485 virtual a11yref get_accessible_parent() override
5486 {
5487 vcl::Window* pParent = m_xDrawingArea->GetParent();
5488 if (pParent)
5489 return pParent->GetAccessible();
5490 return css::uno::Reference<css::accessibility::XAccessible>();
5491 }
5492
get_accessible_relation_set()5493 virtual a11yrelationset get_accessible_relation_set() override
5494 {
5495 utl::AccessibleRelationSetHelper* pRelationSetHelper = new utl::AccessibleRelationSetHelper;
5496 css::uno::Reference< css::accessibility::XAccessibleRelationSet > xSet = pRelationSetHelper;
5497 vcl::Window* pWindow = m_xDrawingArea.get();
5498 if (pWindow)
5499 {
5500 vcl::Window *pLabeledBy = pWindow->GetAccessibleRelationLabeledBy();
5501 if (pLabeledBy && pLabeledBy != pWindow)
5502 {
5503 css::uno::Sequence<css::uno::Reference<css::uno::XInterface>> aSequence { pLabeledBy->GetAccessible() };
5504 pRelationSetHelper->AddRelation( css::accessibility::AccessibleRelation( css::accessibility::AccessibleRelationType::LABELED_BY, aSequence ) );
5505 }
5506 vcl::Window* pMemberOf = pWindow->GetAccessibleRelationMemberOf();
5507 if (pMemberOf && pMemberOf != pWindow)
5508 {
5509 css::uno::Sequence<css::uno::Reference<css::uno::XInterface>> aSequence { pMemberOf->GetAccessible() };
5510 pRelationSetHelper->AddRelation( css::accessibility::AccessibleRelation( css::accessibility::AccessibleRelationType::MEMBER_OF, aSequence ) );
5511 }
5512 }
5513 return xSet;
5514 }
5515
get_accessible_location()5516 virtual Point get_accessible_location() override
5517 {
5518 return m_xDrawingArea->OutputToAbsoluteScreenPixel(Point());
5519 }
5520
~SalInstanceDrawingArea()5521 virtual ~SalInstanceDrawingArea() override
5522 {
5523 m_xDrawingArea->SetQueryTooltipHdl(Link<tools::Rectangle&, OUString>());
5524 m_xDrawingArea->SetCommandHdl(Link<const CommandEvent&, bool>());
5525 m_xDrawingArea->SetStyleUpdatedHdl(Link<VclDrawingArea&, void>());
5526 m_xDrawingArea->SetMousePressHdl(Link<const MouseEvent&, bool>());
5527 m_xDrawingArea->SetMouseMoveHdl(Link<const MouseEvent&, bool>());
5528 m_xDrawingArea->SetMouseReleaseHdl(Link<const MouseEvent&, bool>());
5529 m_xDrawingArea->SetKeyPressHdl(Link<const KeyEvent&, bool>());
5530 m_xDrawingArea->SetKeyReleaseHdl(Link<const KeyEvent&, bool>());
5531 m_xDrawingArea->SetResizeHdl(Link<const Size&, void>());
5532 m_xDrawingArea->SetPaintHdl(Link<std::pair<vcl::RenderContext&, const tools::Rectangle&>, void>());
5533 }
5534
get_ref_device()5535 virtual OutputDevice& get_ref_device() override
5536 {
5537 return *m_xDrawingArea;
5538 }
5539 };
5540
IMPL_LINK(SalInstanceDrawingArea,PaintHdl,target_and_area,aPayload,void)5541 IMPL_LINK(SalInstanceDrawingArea, PaintHdl, target_and_area, aPayload, void)
5542 {
5543 m_aDrawHdl.Call(aPayload);
5544 tools::Rectangle aFocusRect(m_aGetFocusRectHdl.Call(*this));
5545 if (!aFocusRect.IsEmpty())
5546 DrawFocusRect(aPayload.first, aFocusRect);
5547 }
5548
IMPL_LINK(SalInstanceDrawingArea,ResizeHdl,const Size &,rSize,void)5549 IMPL_LINK(SalInstanceDrawingArea, ResizeHdl, const Size&, rSize, void)
5550 {
5551 m_aSizeAllocateHdl.Call(rSize);
5552 }
5553
IMPL_LINK(SalInstanceDrawingArea,MousePressHdl,const MouseEvent &,rEvent,bool)5554 IMPL_LINK(SalInstanceDrawingArea, MousePressHdl, const MouseEvent&, rEvent, bool)
5555 {
5556 return m_aMousePressHdl.Call(rEvent);
5557 }
5558
IMPL_LINK(SalInstanceDrawingArea,MouseMoveHdl,const MouseEvent &,rEvent,bool)5559 IMPL_LINK(SalInstanceDrawingArea, MouseMoveHdl, const MouseEvent&, rEvent, bool)
5560 {
5561 return m_aMouseMotionHdl.Call(rEvent);
5562 }
5563
IMPL_LINK(SalInstanceDrawingArea,MouseReleaseHdl,const MouseEvent &,rEvent,bool)5564 IMPL_LINK(SalInstanceDrawingArea, MouseReleaseHdl, const MouseEvent&, rEvent, bool)
5565 {
5566 return m_aMouseReleaseHdl.Call(rEvent);
5567 }
5568
IMPL_LINK(SalInstanceDrawingArea,KeyPressHdl,const KeyEvent &,rEvent,bool)5569 IMPL_LINK(SalInstanceDrawingArea, KeyPressHdl, const KeyEvent&, rEvent, bool)
5570 {
5571 return m_aKeyPressHdl.Call(rEvent);
5572 }
5573
IMPL_LINK(SalInstanceDrawingArea,KeyReleaseHdl,const KeyEvent &,rEvent,bool)5574 IMPL_LINK(SalInstanceDrawingArea, KeyReleaseHdl, const KeyEvent&, rEvent, bool)
5575 {
5576 return m_aKeyReleaseHdl.Call(rEvent);
5577 }
5578
IMPL_LINK_NOARG(SalInstanceDrawingArea,StyleUpdatedHdl,VclDrawingArea &,void)5579 IMPL_LINK_NOARG(SalInstanceDrawingArea, StyleUpdatedHdl, VclDrawingArea&, void)
5580 {
5581 m_aStyleUpdatedHdl.Call(*this);
5582 }
5583
IMPL_LINK(SalInstanceDrawingArea,CommandHdl,const CommandEvent &,rEvent,bool)5584 IMPL_LINK(SalInstanceDrawingArea, CommandHdl, const CommandEvent&, rEvent, bool)
5585 {
5586 return m_aCommandHdl.Call(rEvent);
5587 }
5588
IMPL_LINK(SalInstanceDrawingArea,QueryTooltipHdl,tools::Rectangle &,rHelpArea,OUString)5589 IMPL_LINK(SalInstanceDrawingArea, QueryTooltipHdl, tools::Rectangle&, rHelpArea, OUString)
5590 {
5591 return m_aQueryTooltipHdl.Call(rHelpArea);
5592 }
5593
5594 //ComboBox and ListBox have similar apis, ComboBoxes in LibreOffice have an edit box and ListBoxes
5595 //don't. This distinction isn't there in Gtk. Use a template to sort this problem out.
5596 template <class vcl_type>
5597 class SalInstanceComboBox : public SalInstanceContainer, public virtual weld::ComboBox
5598 {
5599 protected:
5600 // owner for ListBox/ComboBox UserData
5601 std::vector<std::unique_ptr<OUString>> m_aUserData;
5602 VclPtr<vcl_type> m_xComboBox;
5603
5604 public:
SalInstanceComboBox(vcl_type * pComboBox,SalInstanceBuilder * pBuilder,bool bTakeOwnership)5605 SalInstanceComboBox(vcl_type* pComboBox, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
5606 : SalInstanceContainer(pComboBox, pBuilder, bTakeOwnership)
5607 , m_xComboBox(pComboBox)
5608 {
5609 }
5610
get_active() const5611 virtual int get_active() const override
5612 {
5613 const sal_Int32 nRet = m_xComboBox->GetSelectedEntryPos();
5614 if (nRet == LISTBOX_ENTRY_NOTFOUND)
5615 return -1;
5616 return nRet;
5617 }
5618
getEntryData(int index) const5619 const OUString* getEntryData(int index) const
5620 {
5621 return static_cast<const OUString*>(m_xComboBox->GetEntryData(index));
5622 }
5623
5624 // ComboBoxes are comprised of multiple subwidgets, consider the lot as
5625 // one thing for focus
has_focus() const5626 virtual bool has_focus() const override
5627 {
5628 return m_xWidget->HasChildPathFocus();
5629 }
5630
get_active_id() const5631 virtual OUString get_active_id() const override
5632 {
5633 sal_Int32 nPos = m_xComboBox->GetSelectedEntryPos();
5634 const OUString* pRet;
5635 if (nPos != LISTBOX_ENTRY_NOTFOUND)
5636 pRet = getEntryData(m_xComboBox->GetSelectedEntryPos());
5637 else
5638 pRet = nullptr;
5639 if (!pRet)
5640 return OUString();
5641 return *pRet;
5642 }
5643
set_active_id(const OUString & rStr)5644 virtual void set_active_id(const OUString& rStr) override
5645 {
5646 for (int i = 0; i < get_count(); ++i)
5647 {
5648 const OUString* pId = getEntryData(i);
5649 if (!pId)
5650 continue;
5651 if (*pId == rStr)
5652 m_xComboBox->SelectEntryPos(i);
5653 }
5654 }
5655
set_active(int pos)5656 virtual void set_active(int pos) override
5657 {
5658 if (pos == -1)
5659 {
5660 m_xComboBox->SetNoSelection();
5661 return;
5662 }
5663 m_xComboBox->SelectEntryPos(pos);
5664 }
5665
get_text(int pos) const5666 virtual OUString get_text(int pos) const override
5667 {
5668 return m_xComboBox->GetEntry(pos);
5669 }
5670
get_id(int pos) const5671 virtual OUString get_id(int pos) const override
5672 {
5673 const OUString* pRet = getEntryData(pos);
5674 if (!pRet)
5675 return OUString();
5676 return *pRet;
5677 }
5678
set_id(int row,const OUString & rId)5679 virtual void set_id(int row, const OUString& rId) override
5680 {
5681 m_aUserData.emplace_back(std::make_unique<OUString>(rId));
5682 m_xComboBox->SetEntryData(row, m_aUserData.back().get());
5683 }
5684
insert_vector(const std::vector<weld::ComboBoxEntry> & rItems,bool bKeepExisting)5685 virtual void insert_vector(const std::vector<weld::ComboBoxEntry>& rItems, bool bKeepExisting) override
5686 {
5687 freeze();
5688 if (!bKeepExisting)
5689 clear();
5690 for (const auto& rItem : rItems)
5691 {
5692 insert(-1, rItem.sString, rItem.sId.isEmpty() ? nullptr : &rItem.sId,
5693 rItem.sImage.isEmpty() ? nullptr : &rItem.sImage, nullptr);
5694 }
5695 thaw();
5696 }
5697
get_count() const5698 virtual int get_count() const override
5699 {
5700 return m_xComboBox->GetEntryCount();
5701 }
5702
find_text(const OUString & rStr) const5703 virtual int find_text(const OUString& rStr) const override
5704 {
5705 const sal_Int32 nRet = m_xComboBox->GetEntryPos(rStr);
5706 if (nRet == LISTBOX_ENTRY_NOTFOUND)
5707 return -1;
5708 return nRet;
5709 }
5710
find_id(const OUString & rStr) const5711 virtual int find_id(const OUString& rStr) const override
5712 {
5713 for (int i = 0; i < get_count(); ++i)
5714 {
5715 const OUString* pId = getEntryData(i);
5716 if (!pId)
5717 continue;
5718 if (*pId == rStr)
5719 return i;
5720 }
5721 return -1;
5722 }
5723
clear()5724 virtual void clear() override
5725 {
5726 m_xComboBox->Clear();
5727 m_aUserData.clear();
5728 }
5729
make_sorted()5730 virtual void make_sorted() override
5731 {
5732 m_xComboBox->SetStyle(m_xComboBox->GetStyle() | WB_SORT);
5733 }
5734
get_popup_shown() const5735 virtual bool get_popup_shown() const override
5736 {
5737 return m_xComboBox->IsInDropDown();
5738 }
5739
connect_popup_toggled(const Link<ComboBox &,void> & rLink)5740 virtual void connect_popup_toggled(const Link<ComboBox&, void>& rLink) override
5741 {
5742 weld::ComboBox::connect_popup_toggled(rLink);
5743 ensure_event_listener();
5744 }
5745
HandleEventListener(VclWindowEvent & rEvent)5746 virtual void HandleEventListener(VclWindowEvent& rEvent) override
5747 {
5748 if (rEvent.GetId() == VclEventId::DropdownPreOpen ||
5749 rEvent.GetId() == VclEventId::DropdownClose)
5750 {
5751 signal_popup_toggled();
5752 return;
5753 }
5754 SalInstanceContainer::HandleEventListener(rEvent);
5755 }
5756 };
5757
5758 class SalInstanceComboBoxWithoutEdit : public SalInstanceComboBox<ListBox>
5759 {
5760 private:
5761 DECL_LINK(SelectHdl, ListBox&, void);
5762
5763 public:
SalInstanceComboBoxWithoutEdit(ListBox * pListBox,SalInstanceBuilder * pBuilder,bool bTakeOwnership)5764 SalInstanceComboBoxWithoutEdit(ListBox* pListBox, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
5765 : SalInstanceComboBox<ListBox>(pListBox, pBuilder, bTakeOwnership)
5766 {
5767 m_xComboBox->SetSelectHdl(LINK(this, SalInstanceComboBoxWithoutEdit, SelectHdl));
5768 }
5769
get_active_text() const5770 virtual OUString get_active_text() const override
5771 {
5772 return m_xComboBox->GetSelectedEntry();
5773 }
5774
remove(int pos)5775 virtual void remove(int pos) override
5776 {
5777 m_xComboBox->RemoveEntry(pos);
5778 }
5779
insert(int pos,const OUString & rStr,const OUString * pId,const OUString * pIconName,VirtualDevice * pImageSurface)5780 virtual void insert(int pos, const OUString& rStr, const OUString* pId, const OUString* pIconName, VirtualDevice* pImageSurface) override
5781 {
5782 auto nInsertPos = pos == -1 ? COMBOBOX_APPEND : pos;
5783 sal_Int32 nInsertedAt;
5784 if (!pIconName && !pImageSurface)
5785 nInsertedAt = m_xComboBox->InsertEntry(rStr, nInsertPos);
5786 else if (pIconName)
5787 nInsertedAt = m_xComboBox->InsertEntry(rStr, createImage(*pIconName), nInsertPos);
5788 else
5789 nInsertedAt = m_xComboBox->InsertEntry(rStr, createImage(*pImageSurface), nInsertPos);
5790 if (pId)
5791 {
5792 m_aUserData.emplace_back(std::make_unique<OUString>(*pId));
5793 m_xComboBox->SetEntryData(nInsertedAt, m_aUserData.back().get());
5794 }
5795 }
5796
insert_separator(int pos,const OUString &)5797 virtual void insert_separator(int pos, const OUString& /*rId*/) override
5798 {
5799 auto nInsertPos = pos == -1 ? m_xComboBox->GetEntryCount() : pos;
5800 m_xComboBox->AddSeparator(nInsertPos - 1);
5801 }
5802
has_entry() const5803 virtual bool has_entry() const override
5804 {
5805 return false;
5806 }
5807
set_entry_message_type(weld::EntryMessageType)5808 virtual void set_entry_message_type(weld::EntryMessageType /*eType*/) override
5809 {
5810 assert(false);
5811 }
5812
set_entry_text(const OUString &)5813 virtual void set_entry_text(const OUString& /*rText*/) override
5814 {
5815 assert(false);
5816 }
5817
select_entry_region(int,int)5818 virtual void select_entry_region(int /*nStartPos*/, int /*nEndPos*/) override
5819 {
5820 assert(false);
5821 }
5822
get_entry_selection_bounds(int &,int &)5823 virtual bool get_entry_selection_bounds(int& /*rStartPos*/, int& /*rEndPos*/) override
5824 {
5825 assert(false);
5826 return false;
5827 }
5828
set_entry_width_chars(int)5829 virtual void set_entry_width_chars(int /*nChars*/) override
5830 {
5831 assert(false);
5832 }
5833
set_entry_max_length(int)5834 virtual void set_entry_max_length(int /*nChars*/) override
5835 {
5836 assert(false);
5837 }
5838
set_entry_completion(bool,bool)5839 virtual void set_entry_completion(bool, bool) override
5840 {
5841 assert(false);
5842 }
5843
~SalInstanceComboBoxWithoutEdit()5844 virtual ~SalInstanceComboBoxWithoutEdit() override
5845 {
5846 m_xComboBox->SetSelectHdl(Link<ListBox&, void>());
5847 }
5848 };
5849
IMPL_LINK_NOARG(SalInstanceComboBoxWithoutEdit,SelectHdl,ListBox &,void)5850 IMPL_LINK_NOARG(SalInstanceComboBoxWithoutEdit, SelectHdl, ListBox&, void)
5851 {
5852 return signal_changed();
5853 }
5854
5855 class SalInstanceComboBoxWithEdit : public SalInstanceComboBox<ComboBox>
5856 {
5857 private:
5858 DECL_LINK(ChangeHdl, Edit&, void);
5859 DECL_LINK(EntryActivateHdl, Edit&, bool);
5860 WeldTextFilter m_aTextFilter;
5861 public:
SalInstanceComboBoxWithEdit(::ComboBox * pComboBox,SalInstanceBuilder * pBuilder,bool bTakeOwnership)5862 SalInstanceComboBoxWithEdit(::ComboBox* pComboBox, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
5863 : SalInstanceComboBox<::ComboBox>(pComboBox, pBuilder, bTakeOwnership)
5864 , m_aTextFilter(m_aEntryInsertTextHdl)
5865 {
5866 m_xComboBox->SetModifyHdl(LINK(this, SalInstanceComboBoxWithEdit, ChangeHdl));
5867 m_xComboBox->SetEntryActivateHdl(LINK(this, SalInstanceComboBoxWithEdit, EntryActivateHdl));
5868 m_xComboBox->SetTextFilter(&m_aTextFilter);
5869 }
5870
has_entry() const5871 virtual bool has_entry() const override
5872 {
5873 return true;
5874 }
5875
set_entry_message_type(weld::EntryMessageType eType)5876 virtual void set_entry_message_type(weld::EntryMessageType eType) override
5877 {
5878 if (eType == weld::EntryMessageType::Error)
5879 m_xComboBox->SetControlForeground(Color(0xf0, 0, 0));
5880 else if (eType == weld::EntryMessageType::Warning)
5881 m_xComboBox->SetControlForeground(COL_YELLOW);
5882 else
5883 m_xComboBox->SetControlForeground();
5884 }
5885
get_active_text() const5886 virtual OUString get_active_text() const override
5887 {
5888 return m_xComboBox->GetText();
5889 }
5890
remove(int pos)5891 virtual void remove(int pos) override
5892 {
5893 m_xComboBox->RemoveEntryAt(pos);
5894 }
5895
insert(int pos,const OUString & rStr,const OUString * pId,const OUString * pIconName,VirtualDevice * pImageSurface)5896 virtual void insert(int pos, const OUString& rStr, const OUString* pId, const OUString* pIconName, VirtualDevice* pImageSurface) override
5897 {
5898 auto nInsertPos = pos == -1 ? COMBOBOX_APPEND : pos;
5899 sal_Int32 nInsertedAt;
5900 if (!pIconName && !pImageSurface)
5901 nInsertedAt = m_xComboBox->InsertEntry(rStr, nInsertPos);
5902 else if (pIconName)
5903 nInsertedAt = m_xComboBox->InsertEntryWithImage(rStr, createImage(*pIconName), nInsertPos);
5904 else
5905 nInsertedAt = m_xComboBox->InsertEntryWithImage(rStr, createImage(*pImageSurface), nInsertPos);
5906 if (pId)
5907 {
5908 m_aUserData.emplace_back(std::make_unique<OUString>(*pId));
5909 m_xComboBox->SetEntryData(nInsertedAt, m_aUserData.back().get());
5910 }
5911 }
5912
insert_separator(int pos,const OUString &)5913 virtual void insert_separator(int pos, const OUString& /*rId*/) override
5914 {
5915 auto nInsertPos = pos == -1 ? m_xComboBox->GetEntryCount() : pos;
5916 m_xComboBox->AddSeparator(nInsertPos - 1);
5917 }
5918
set_entry_text(const OUString & rText)5919 virtual void set_entry_text(const OUString& rText) override
5920 {
5921 m_xComboBox->SetText(rText);
5922 }
5923
set_entry_width_chars(int nChars)5924 virtual void set_entry_width_chars(int nChars) override
5925 {
5926 m_xComboBox->SetWidthInChars(nChars);
5927 }
5928
set_entry_max_length(int nChars)5929 virtual void set_entry_max_length(int nChars) override
5930 {
5931 m_xComboBox->SetMaxTextLen(nChars);
5932 }
5933
set_entry_completion(bool bEnable,bool bCaseSensitive)5934 virtual void set_entry_completion(bool bEnable, bool bCaseSensitive) override
5935 {
5936 m_xComboBox->EnableAutocomplete(bEnable, bCaseSensitive);
5937 }
5938
select_entry_region(int nStartPos,int nEndPos)5939 virtual void select_entry_region(int nStartPos, int nEndPos) override
5940 {
5941 m_xComboBox->SetSelection(Selection(nStartPos, nEndPos < 0 ? SELECTION_MAX : nEndPos));
5942 }
5943
get_entry_selection_bounds(int & rStartPos,int & rEndPos)5944 virtual bool get_entry_selection_bounds(int& rStartPos, int& rEndPos) override
5945 {
5946 const Selection& rSelection = m_xComboBox->GetSelection();
5947 rStartPos = rSelection.Min();
5948 rEndPos = rSelection.Max();
5949 return rSelection.Len();
5950 }
5951
~SalInstanceComboBoxWithEdit()5952 virtual ~SalInstanceComboBoxWithEdit() override
5953 {
5954 m_xComboBox->SetTextFilter(nullptr);
5955 m_xComboBox->SetEntryActivateHdl(Link<Edit&, bool>());
5956 m_xComboBox->SetModifyHdl(Link<Edit&, void>());
5957 }
5958 };
5959
IMPL_LINK_NOARG(SalInstanceComboBoxWithEdit,ChangeHdl,Edit &,void)5960 IMPL_LINK_NOARG(SalInstanceComboBoxWithEdit, ChangeHdl, Edit&, void)
5961 {
5962 signal_changed();
5963 }
5964
IMPL_LINK_NOARG(SalInstanceComboBoxWithEdit,EntryActivateHdl,Edit &,bool)5965 IMPL_LINK_NOARG(SalInstanceComboBoxWithEdit, EntryActivateHdl, Edit&, bool)
5966 {
5967 return m_aEntryActivateHdl.Call(*this);
5968 }
5969
5970 class SalInstanceEntryTreeView : public SalInstanceContainer, public virtual weld::EntryTreeView
5971 {
5972 private:
5973 DECL_LINK(AutocompleteHdl, Edit&, void);
5974 DECL_LINK(KeyPressListener, VclWindowEvent&, void);
5975 SalInstanceEntry* m_pEntry;
5976 SalInstanceTreeView* m_pTreeView;
5977 public:
SalInstanceEntryTreeView(vcl::Window * pContainer,SalInstanceBuilder * pBuilder,bool bTakeOwnership,std::unique_ptr<weld::Entry> xEntry,std::unique_ptr<weld::TreeView> xTreeView)5978 SalInstanceEntryTreeView(vcl::Window *pContainer, SalInstanceBuilder* pBuilder, bool bTakeOwnership,
5979 std::unique_ptr<weld::Entry> xEntry, std::unique_ptr<weld::TreeView> xTreeView)
5980 : EntryTreeView(std::move(xEntry), std::move(xTreeView))
5981 , SalInstanceContainer(pContainer, pBuilder, bTakeOwnership)
5982 , m_pEntry(dynamic_cast<SalInstanceEntry*>(m_xEntry.get()))
5983 , m_pTreeView(dynamic_cast<SalInstanceTreeView*>(m_xTreeView.get()))
5984 {
5985 assert(m_pEntry && m_pTreeView);
5986
5987 Edit& rEntry = m_pEntry->getEntry();
5988 rEntry.SetAutocompleteHdl(LINK(this, SalInstanceEntryTreeView, AutocompleteHdl));
5989 rEntry.AddEventListener(LINK(this, SalInstanceEntryTreeView, KeyPressListener));
5990 }
5991
insert_separator(int,const OUString &)5992 virtual void insert_separator(int /*pos*/, const OUString& /*rId*/) override
5993 {
5994 assert(false);
5995 }
5996
make_sorted()5997 virtual void make_sorted() override
5998 {
5999 vcl::Window *pTreeView = m_pTreeView->getWidget();
6000 pTreeView->SetStyle(pTreeView->GetStyle() | WB_SORT);
6001 }
6002
set_entry_completion(bool bEnable,bool)6003 virtual void set_entry_completion(bool bEnable, bool /*bCaseSensitive*/) override
6004 {
6005 assert(!bEnable && "not implemented yet"); (void) bEnable;
6006 Edit& rEntry = m_pEntry->getEntry();
6007 rEntry.SetAutocompleteHdl(Link<Edit&, void>());
6008 }
6009
grab_focus()6010 virtual void grab_focus() override { m_xEntry->grab_focus(); }
6011
connect_focus_in(const Link<Widget &,void> & rLink)6012 virtual void connect_focus_in(const Link<Widget&, void>& rLink) override
6013 {
6014 m_xEntry->connect_focus_in(rLink);
6015 }
6016
connect_focus_out(const Link<Widget &,void> & rLink)6017 virtual void connect_focus_out(const Link<Widget&, void>& rLink) override
6018 {
6019 m_xEntry->connect_focus_out(rLink);
6020 }
6021
~SalInstanceEntryTreeView()6022 virtual ~SalInstanceEntryTreeView() override
6023 {
6024 Edit& rEntry = m_pEntry->getEntry();
6025 rEntry.RemoveEventListener(LINK(this, SalInstanceEntryTreeView, KeyPressListener));
6026 rEntry.SetAutocompleteHdl(Link<Edit&, void>());
6027 }
6028 };
6029
IMPL_LINK(SalInstanceEntryTreeView,KeyPressListener,VclWindowEvent &,rEvent,void)6030 IMPL_LINK(SalInstanceEntryTreeView, KeyPressListener, VclWindowEvent&, rEvent, void)
6031 {
6032 if (rEvent.GetId() != VclEventId::WindowKeyInput)
6033 return;
6034 const KeyEvent& rKeyEvent = *static_cast<KeyEvent*>(rEvent.GetData());
6035 sal_uInt16 nKeyCode = rKeyEvent.GetKeyCode().GetCode();
6036 if (nKeyCode == KEY_UP || nKeyCode == KEY_DOWN || nKeyCode == KEY_PAGEUP || nKeyCode == KEY_PAGEDOWN)
6037 {
6038 m_pTreeView->disable_notify_events();
6039 auto& rListBox = m_pTreeView->getTreeView();
6040 if (!rListBox.FirstSelected())
6041 {
6042 if (SvTreeListEntry* pEntry = rListBox.First())
6043 rListBox.Select(pEntry, true);
6044 }
6045 else
6046 rListBox.KeyInput(rKeyEvent);
6047 m_xEntry->set_text(m_xTreeView->get_selected_text());
6048 m_xEntry->select_region(0, -1);
6049 m_pTreeView->enable_notify_events();
6050 m_pEntry->fire_signal_changed();
6051 }
6052 }
6053
IMPL_LINK(SalInstanceEntryTreeView,AutocompleteHdl,Edit &,rEdit,void)6054 IMPL_LINK(SalInstanceEntryTreeView, AutocompleteHdl, Edit&, rEdit, void)
6055 {
6056 Selection aSel = rEdit.GetSelection();
6057
6058 OUString aFullText = rEdit.GetText();
6059 OUString aStartText = aFullText.copy(0, static_cast<sal_Int32>(aSel.Max()));
6060
6061 int nPos = -1;
6062 int nCount = m_xTreeView->n_children();
6063 for (int i = 0; i < nCount; ++i)
6064 {
6065 if (m_xTreeView->get_text(i).startsWithIgnoreAsciiCase(aStartText))
6066 {
6067 nPos = i;
6068 break;
6069 }
6070 }
6071
6072 m_xTreeView->select(nPos);
6073
6074 if (nPos != -1)
6075 {
6076 OUString aText = m_xTreeView->get_text(nPos);
6077 Selection aSelection(aText.getLength(), aStartText.getLength());
6078 rEdit.SetText(aText, aSelection);
6079 }
6080 }
6081
6082 class SalInstanceBuilder : public weld::Builder
6083 {
6084 private:
6085 std::unique_ptr<VclBuilder> m_xBuilder;
6086 VclPtr<vcl::Window> m_aOwnedToplevel;
6087 public:
SalInstanceBuilder(vcl::Window * pParent,const OUString & rUIRoot,const OUString & rUIFile)6088 SalInstanceBuilder(vcl::Window* pParent, const OUString& rUIRoot, const OUString& rUIFile)
6089 : weld::Builder(rUIFile)
6090 , m_xBuilder(new VclBuilder(pParent, rUIRoot, rUIFile, OString(), css::uno::Reference<css::frame::XFrame>(), false))
6091 {
6092 }
6093
get_builder() const6094 VclBuilder& get_builder() const
6095 {
6096 return *m_xBuilder;
6097 }
6098
weld_message_dialog(const OString & id,bool bTakeOwnership)6099 virtual std::unique_ptr<weld::MessageDialog> weld_message_dialog(const OString &id, bool bTakeOwnership) override
6100 {
6101 MessageDialog* pMessageDialog = m_xBuilder->get<MessageDialog>(id);
6102 std::unique_ptr<weld::MessageDialog> pRet(pMessageDialog ? new SalInstanceMessageDialog(pMessageDialog, this, false) : nullptr);
6103 if (bTakeOwnership && pMessageDialog)
6104 {
6105 assert(!m_aOwnedToplevel && "only one toplevel per .ui allowed");
6106 m_aOwnedToplevel.set(pMessageDialog);
6107 m_xBuilder->drop_ownership(pMessageDialog);
6108 }
6109 return pRet;
6110 }
6111
weld_about_dialog(const OString & id,bool bTakeOwnership)6112 virtual std::unique_ptr<weld::AboutDialog> weld_about_dialog(const OString &id, bool bTakeOwnership) override
6113 {
6114 vcl::AboutDialog* pAboutDialog = m_xBuilder->get<vcl::AboutDialog>(id);
6115 std::unique_ptr<weld::AboutDialog> pRet(pAboutDialog ? new SalInstanceAboutDialog(pAboutDialog, this, false) : nullptr);
6116 if (bTakeOwnership && pAboutDialog)
6117 {
6118 assert(!m_aOwnedToplevel && "only one toplevel per .ui allowed");
6119 m_aOwnedToplevel.set(pAboutDialog);
6120 m_xBuilder->drop_ownership(pAboutDialog);
6121 }
6122 return pRet;
6123 }
6124
weld_dialog(const OString & id,bool bTakeOwnership)6125 virtual std::unique_ptr<weld::Dialog> weld_dialog(const OString &id, bool bTakeOwnership) override
6126 {
6127 Dialog* pDialog = m_xBuilder->get<Dialog>(id);
6128 std::unique_ptr<weld::Dialog> pRet(pDialog ? new SalInstanceDialog(pDialog, this, false) : nullptr);
6129 if (bTakeOwnership && pDialog)
6130 {
6131 assert(!m_aOwnedToplevel && "only one toplevel per .ui allowed");
6132 m_aOwnedToplevel.set(pDialog);
6133 m_xBuilder->drop_ownership(pDialog);
6134 }
6135 return pRet;
6136 }
6137
weld_assistant(const OString & id,bool bTakeOwnership)6138 virtual std::unique_ptr<weld::Assistant> weld_assistant(const OString &id, bool bTakeOwnership) override
6139 {
6140 vcl::RoadmapWizard* pDialog = m_xBuilder->get<vcl::RoadmapWizard>(id);
6141 std::unique_ptr<weld::Assistant> pRet(pDialog ? new SalInstanceAssistant(pDialog, this, false) : nullptr);
6142 if (bTakeOwnership && pDialog)
6143 {
6144 assert(!m_aOwnedToplevel && "only one toplevel per .ui allowed");
6145 m_aOwnedToplevel.set(pDialog);
6146 m_xBuilder->drop_ownership(pDialog);
6147 }
6148 return pRet;
6149 }
6150
create_screenshot_window()6151 virtual std::unique_ptr<weld::Window> create_screenshot_window() override
6152 {
6153 assert(!m_aOwnedToplevel && "only one toplevel per .ui allowed");
6154
6155 vcl::Window *pRoot = m_xBuilder->get_widget_root();
6156 if (SystemWindow *pWindow = dynamic_cast<SystemWindow*>(pRoot))
6157 {
6158 std::unique_ptr<weld::Window> xRet(new SalInstanceWindow(pWindow, this, false));
6159 m_aOwnedToplevel.set(pWindow);
6160 m_xBuilder->drop_ownership(pWindow);
6161 return xRet;
6162 }
6163
6164 VclPtrInstance<Dialog> xDialog(nullptr, WB_HIDE | WB_STDDIALOG | WB_SIZEABLE | WB_CLOSEABLE, Dialog::InitFlag::NoParent);
6165 xDialog->SetText(utl::ConfigManager::getProductName());
6166
6167 auto xContentArea = VclPtr<VclVBox>::Create(xDialog, false, 12);
6168 pRoot->SetParent(xContentArea);
6169 assert(pRoot == xContentArea->GetWindow(GetWindowType::FirstChild));
6170 xContentArea->Show();
6171 pRoot->Show();
6172 xDialog->SetHelpId(pRoot->GetHelpId());
6173
6174 m_aOwnedToplevel.set(xDialog);
6175
6176 return std::unique_ptr<weld::Dialog>(new SalInstanceDialog(xDialog, this, false));
6177 }
6178
weld_window(const OString & id,bool bTakeOwnership)6179 virtual std::unique_ptr<weld::Window> weld_window(const OString &id, bool bTakeOwnership) override
6180 {
6181 SystemWindow* pWindow = m_xBuilder->get<SystemWindow>(id);
6182 return pWindow ? std::make_unique<SalInstanceWindow>(pWindow, this, bTakeOwnership) : nullptr;
6183 }
6184
weld_widget(const OString & id,bool bTakeOwnership)6185 virtual std::unique_ptr<weld::Widget> weld_widget(const OString &id, bool bTakeOwnership) override
6186 {
6187 vcl::Window* pWidget = m_xBuilder->get<vcl::Window>(id);
6188 return pWidget ? std::make_unique<SalInstanceWidget>(pWidget, this, bTakeOwnership) : nullptr;
6189 }
6190
weld_container(const OString & id,bool bTakeOwnership)6191 virtual std::unique_ptr<weld::Container> weld_container(const OString &id, bool bTakeOwnership) override
6192 {
6193 vcl::Window* pContainer = m_xBuilder->get<vcl::Window>(id);
6194 return pContainer ? std::make_unique<SalInstanceContainer>(pContainer, this, bTakeOwnership) : nullptr;
6195 }
6196
weld_box(const OString & id,bool bTakeOwnership)6197 virtual std::unique_ptr<weld::Box> weld_box(const OString &id, bool bTakeOwnership) override
6198 {
6199 vcl::Window* pContainer = m_xBuilder->get<vcl::Window>(id);
6200 return pContainer ? std::make_unique<SalInstanceBox>(pContainer, this, bTakeOwnership) : nullptr;
6201 }
6202
weld_frame(const OString & id,bool bTakeOwnership)6203 virtual std::unique_ptr<weld::Frame> weld_frame(const OString &id, bool bTakeOwnership) override
6204 {
6205 VclFrame* pFrame = m_xBuilder->get<VclFrame>(id);
6206 std::unique_ptr<weld::Frame> pRet(pFrame ? new SalInstanceFrame(pFrame, this, false) : nullptr);
6207 if (bTakeOwnership && pFrame)
6208 {
6209 assert(!m_aOwnedToplevel && "only one toplevel per .ui allowed");
6210 m_aOwnedToplevel.set(pFrame);
6211 m_xBuilder->drop_ownership(pFrame);
6212 }
6213 return pRet;
6214 }
6215
weld_scrolled_window(const OString & id,bool bTakeOwnership)6216 virtual std::unique_ptr<weld::ScrolledWindow> weld_scrolled_window(const OString &id, bool bTakeOwnership) override
6217 {
6218 VclScrolledWindow* pScrolledWindow = m_xBuilder->get<VclScrolledWindow>(id);
6219 return pScrolledWindow ? std::make_unique<SalInstanceScrolledWindow>(pScrolledWindow, this, bTakeOwnership) : nullptr;
6220 }
6221
weld_notebook(const OString & id,bool bTakeOwnership)6222 virtual std::unique_ptr<weld::Notebook> weld_notebook(const OString &id, bool bTakeOwnership) override
6223 {
6224 vcl::Window* pNotebook = m_xBuilder->get<vcl::Window>(id);
6225 if (!pNotebook)
6226 return nullptr;
6227 if (pNotebook->GetType() == WindowType::TABCONTROL)
6228 return std::make_unique<SalInstanceNotebook>(static_cast<TabControl*>(pNotebook), this, bTakeOwnership);
6229 if (pNotebook->GetType() == WindowType::VERTICALTABCONTROL)
6230 return std::make_unique<SalInstanceVerticalNotebook>(static_cast<VerticalTabControl*>(pNotebook), this, bTakeOwnership);
6231 return nullptr;
6232 }
6233
weld_button(const OString & id,bool bTakeOwnership)6234 virtual std::unique_ptr<weld::Button> weld_button(const OString &id, bool bTakeOwnership) override
6235 {
6236 Button* pButton = m_xBuilder->get<Button>(id);
6237 return pButton ? std::make_unique<SalInstanceButton>(pButton, this, bTakeOwnership) : nullptr;
6238 }
6239
weld_menu_button(const OString & id,bool bTakeOwnership)6240 virtual std::unique_ptr<weld::MenuButton> weld_menu_button(const OString &id, bool bTakeOwnership) override
6241 {
6242 MenuButton* pButton = m_xBuilder->get<MenuButton>(id);
6243 return pButton ? std::make_unique<SalInstanceMenuButton>(pButton, this, bTakeOwnership) : nullptr;
6244 }
6245
weld_link_button(const OString & id,bool bTakeOwnership)6246 virtual std::unique_ptr<weld::LinkButton> weld_link_button(const OString &id, bool bTakeOwnership) override
6247 {
6248 FixedHyperlink* pButton = m_xBuilder->get<FixedHyperlink>(id);
6249 return pButton ? std::make_unique<SalInstanceLinkButton>(pButton, this, bTakeOwnership) : nullptr;
6250 }
6251
weld_toggle_button(const OString & id,bool bTakeOwnership)6252 virtual std::unique_ptr<weld::ToggleButton> weld_toggle_button(const OString &id, bool bTakeOwnership) override
6253 {
6254 PushButton* pToggleButton = m_xBuilder->get<PushButton>(id);
6255 return pToggleButton ? std::make_unique<SalInstanceToggleButton>(pToggleButton, this, bTakeOwnership) : nullptr;
6256 }
6257
weld_radio_button(const OString & id,bool bTakeOwnership)6258 virtual std::unique_ptr<weld::RadioButton> weld_radio_button(const OString &id, bool bTakeOwnership) override
6259 {
6260 RadioButton* pRadioButton = m_xBuilder->get<RadioButton>(id);
6261 return pRadioButton ? std::make_unique<SalInstanceRadioButton>(pRadioButton, this, bTakeOwnership) : nullptr;
6262 }
6263
weld_check_button(const OString & id,bool bTakeOwnership)6264 virtual std::unique_ptr<weld::CheckButton> weld_check_button(const OString &id, bool bTakeOwnership) override
6265 {
6266 CheckBox* pCheckButton = m_xBuilder->get<CheckBox>(id);
6267 return pCheckButton ? std::make_unique<SalInstanceCheckButton>(pCheckButton, this, bTakeOwnership) : nullptr;
6268 }
6269
weld_scale(const OString & id,bool bTakeOwnership)6270 virtual std::unique_ptr<weld::Scale> weld_scale(const OString &id, bool bTakeOwnership) override
6271 {
6272 Slider* pSlider = m_xBuilder->get<Slider>(id);
6273 return pSlider ? std::make_unique<SalInstanceScale>(pSlider, this, bTakeOwnership) : nullptr;
6274 }
6275
weld_progress_bar(const OString & id,bool bTakeOwnership)6276 virtual std::unique_ptr<weld::ProgressBar> weld_progress_bar(const OString &id, bool bTakeOwnership) override
6277 {
6278 ::ProgressBar* pProgress = m_xBuilder->get<::ProgressBar>(id);
6279 return pProgress ? std::make_unique<SalInstanceProgressBar>(pProgress, this, bTakeOwnership) : nullptr;
6280 }
6281
weld_spinner(const OString & id,bool bTakeOwnership)6282 virtual std::unique_ptr<weld::Spinner> weld_spinner(const OString &id, bool bTakeOwnership) override
6283 {
6284 Throbber* pThrobber = m_xBuilder->get<Throbber>(id);
6285 return pThrobber ? std::make_unique<SalInstanceSpinner>(pThrobber, this, bTakeOwnership) : nullptr;
6286 }
6287
weld_image(const OString & id,bool bTakeOwnership)6288 virtual std::unique_ptr<weld::Image> weld_image(const OString &id, bool bTakeOwnership) override
6289 {
6290 FixedImage* pImage = m_xBuilder->get<FixedImage>(id);
6291 return pImage ? std::make_unique<SalInstanceImage>(pImage, this, bTakeOwnership) : nullptr;
6292 }
6293
weld_calendar(const OString & id,bool bTakeOwnership)6294 virtual std::unique_ptr<weld::Calendar> weld_calendar(const OString &id, bool bTakeOwnership) override
6295 {
6296 Calendar* pCalendar = m_xBuilder->get<Calendar>(id);
6297 return pCalendar ? std::make_unique<SalInstanceCalendar>(pCalendar, this, bTakeOwnership) : nullptr;
6298 }
6299
weld_entry(const OString & id,bool bTakeOwnership)6300 virtual std::unique_ptr<weld::Entry> weld_entry(const OString &id, bool bTakeOwnership) override
6301 {
6302 Edit* pEntry = m_xBuilder->get<Edit>(id);
6303 return pEntry ? std::make_unique<SalInstanceEntry>(pEntry, this, bTakeOwnership) : nullptr;
6304 }
6305
weld_spin_button(const OString & id,bool bTakeOwnership)6306 virtual std::unique_ptr<weld::SpinButton> weld_spin_button(const OString &id, bool bTakeOwnership) override
6307 {
6308 FormattedField* pSpinButton = m_xBuilder->get<FormattedField>(id);
6309 return pSpinButton ? std::make_unique<SalInstanceSpinButton>(pSpinButton, this, bTakeOwnership) : nullptr;
6310 }
6311
weld_metric_spin_button(const OString & id,FieldUnit eUnit,bool bTakeOwnership)6312 virtual std::unique_ptr<weld::MetricSpinButton> weld_metric_spin_button(const OString& id, FieldUnit eUnit,
6313 bool bTakeOwnership) override
6314 {
6315 std::unique_ptr<weld::SpinButton> xButton(weld_spin_button(id, bTakeOwnership));
6316 if (xButton)
6317 {
6318 SalInstanceSpinButton& rButton = dynamic_cast<SalInstanceSpinButton&>(*xButton);
6319 rButton.SetUseThousandSep();
6320 }
6321 return std::make_unique<weld::MetricSpinButton>(std::move(xButton), eUnit);
6322 }
6323
weld_formatted_spin_button(const OString & id,bool bTakeOwnership)6324 virtual std::unique_ptr<weld::FormattedSpinButton> weld_formatted_spin_button(const OString& id,
6325 bool bTakeOwnership) override
6326 {
6327 FormattedField* pSpinButton = m_xBuilder->get<FormattedField>(id);
6328 return pSpinButton ? std::make_unique<SalInstanceFormattedSpinButton>(pSpinButton, this, bTakeOwnership) : nullptr;
6329 }
6330
weld_time_spin_button(const OString & id,TimeFieldFormat eFormat,bool bTakeOwnership)6331 virtual std::unique_ptr<weld::TimeSpinButton> weld_time_spin_button(const OString& id, TimeFieldFormat eFormat,
6332 bool bTakeOwnership) override
6333 {
6334 std::unique_ptr<weld::TimeSpinButton> pRet(new weld::TimeSpinButton(weld_spin_button(id, bTakeOwnership), eFormat));
6335 SalInstanceSpinButton& rButton = dynamic_cast<SalInstanceSpinButton&>(pRet->get_widget());
6336 rButton.DisableRemainderFactor(); //so with hh::mm::ss, incrementing mm will not reset ss
6337 return pRet;
6338 }
6339
weld_combo_box(const OString & id,bool bTakeOwnership)6340 virtual std::unique_ptr<weld::ComboBox> weld_combo_box(const OString &id, bool bTakeOwnership) override
6341 {
6342 vcl::Window* pWidget = m_xBuilder->get<vcl::Window>(id);
6343 ::ComboBox* pComboBox = dynamic_cast<::ComboBox*>(pWidget);
6344 if (pComboBox)
6345 return std::make_unique<SalInstanceComboBoxWithEdit>(pComboBox, this, bTakeOwnership);
6346 ListBox* pListBox = dynamic_cast<ListBox*>(pWidget);
6347 return pListBox ? std::make_unique<SalInstanceComboBoxWithoutEdit>(pListBox, this, bTakeOwnership) : nullptr;
6348 }
6349
weld_entry_tree_view(const OString & containerid,const OString & entryid,const OString & treeviewid,bool bTakeOwnership)6350 virtual std::unique_ptr<weld::EntryTreeView> weld_entry_tree_view(const OString& containerid, const OString& entryid, const OString& treeviewid, bool bTakeOwnership) override
6351 {
6352 vcl::Window* pContainer = m_xBuilder->get<vcl::Window>(containerid);
6353 return pContainer ? std::make_unique<SalInstanceEntryTreeView>(pContainer, this, bTakeOwnership,
6354 weld_entry(entryid, bTakeOwnership),
6355 weld_tree_view(treeviewid, bTakeOwnership)) : nullptr;
6356 }
6357
weld_tree_view(const OString & id,bool bTakeOwnership)6358 virtual std::unique_ptr<weld::TreeView> weld_tree_view(const OString &id, bool bTakeOwnership) override
6359 {
6360 SvTabListBox* pTreeView = m_xBuilder->get<SvTabListBox>(id);
6361 return pTreeView ? std::make_unique<SalInstanceTreeView>(pTreeView, this, bTakeOwnership) : nullptr;
6362 }
6363
weld_icon_view(const OString & id,bool bTakeOwnership)6364 virtual std::unique_ptr<weld::IconView> weld_icon_view(const OString &id, bool bTakeOwnership) override
6365 {
6366 IconView* pIconView = m_xBuilder->get<IconView>(id);
6367 return pIconView ? std::make_unique<SalInstanceIconView>(pIconView, this, bTakeOwnership) : nullptr;
6368 }
6369
weld_label(const OString & id,bool bTakeOwnership)6370 virtual std::unique_ptr<weld::Label> weld_label(const OString &id, bool bTakeOwnership) override
6371 {
6372 Control* pLabel = m_xBuilder->get<Control>(id);
6373 return pLabel ? std::make_unique<SalInstanceLabel>(pLabel, this, bTakeOwnership) : nullptr;
6374 }
6375
weld_text_view(const OString & id,bool bTakeOwnership)6376 virtual std::unique_ptr<weld::TextView> weld_text_view(const OString &id, bool bTakeOwnership) override
6377 {
6378 VclMultiLineEdit* pTextView = m_xBuilder->get<VclMultiLineEdit>(id);
6379 return pTextView ? std::make_unique<SalInstanceTextView>(pTextView, this, bTakeOwnership) : nullptr;
6380 }
6381
weld_expander(const OString & id,bool bTakeOwnership)6382 virtual std::unique_ptr<weld::Expander> weld_expander(const OString &id, bool bTakeOwnership) override
6383 {
6384 VclExpander* pExpander = m_xBuilder->get<VclExpander>(id);
6385 return pExpander ? std::make_unique<SalInstanceExpander>(pExpander, this, bTakeOwnership) : nullptr;
6386 }
6387
weld_drawing_area(const OString & id,const a11yref & rA11yImpl,FactoryFunction pUITestFactoryFunction,void * pUserData,bool bTakeOwnership)6388 virtual std::unique_ptr<weld::DrawingArea> weld_drawing_area(const OString &id, const a11yref& rA11yImpl,
6389 FactoryFunction pUITestFactoryFunction, void* pUserData, bool bTakeOwnership) override
6390 {
6391 VclDrawingArea* pDrawingArea = m_xBuilder->get<VclDrawingArea>(id);
6392 return pDrawingArea ? std::make_unique<SalInstanceDrawingArea>(pDrawingArea, this, rA11yImpl,
6393 pUITestFactoryFunction, pUserData, bTakeOwnership) : nullptr;
6394 }
6395
weld_menu(const OString & id,bool bTakeOwnership)6396 virtual std::unique_ptr<weld::Menu> weld_menu(const OString &id, bool bTakeOwnership) override
6397 {
6398 PopupMenu* pMenu = m_xBuilder->get_menu(id);
6399 return pMenu ? std::make_unique<SalInstanceMenu>(pMenu, bTakeOwnership) : nullptr;
6400 }
6401
weld_toolbar(const OString & id,bool bTakeOwnership)6402 virtual std::unique_ptr<weld::Toolbar> weld_toolbar(const OString &id, bool bTakeOwnership) override
6403 {
6404 ToolBox* pToolBox = m_xBuilder->get<ToolBox>(id);
6405 return pToolBox ? std::make_unique<SalInstanceToolbar>(pToolBox, this, bTakeOwnership) : nullptr;
6406 }
6407
create_size_group()6408 virtual std::unique_ptr<weld::SizeGroup> create_size_group() override
6409 {
6410 return std::make_unique<SalInstanceSizeGroup>();
6411 }
6412
get_current_page_help_id() const6413 OString get_current_page_help_id() const
6414 {
6415 TabControl *pCtrl = get_builder().get<TabControl>("tabcontrol");
6416 TabPage* pTabPage = pCtrl ? pCtrl->GetTabPage(pCtrl->GetCurPageId()) : nullptr;
6417 vcl::Window *pTabChild = pTabPage ? pTabPage->GetWindow(GetWindowType::FirstChild) : nullptr;
6418 pTabChild = pTabChild ? pTabChild->GetWindow(GetWindowType::FirstChild) : nullptr;
6419 if (pTabChild)
6420 return pTabChild->GetHelpId();
6421 return OString();
6422 }
6423
~SalInstanceBuilder()6424 virtual ~SalInstanceBuilder() override
6425 {
6426 if (VclBuilderContainer* pOwnedToplevel = dynamic_cast<VclBuilderContainer*>(m_aOwnedToplevel.get()))
6427 pOwnedToplevel->m_pUIBuilder = std::move(m_xBuilder);
6428 else
6429 m_xBuilder.reset();
6430 m_aOwnedToplevel.disposeAndClear();
6431 }
6432 };
6433
CreateBuilder(weld::Widget * pParent,const OUString & rUIRoot,const OUString & rUIFile)6434 weld::Builder* SalInstance::CreateBuilder(weld::Widget* pParent, const OUString& rUIRoot, const OUString& rUIFile)
6435 {
6436 SalInstanceWidget* pParentInstance = dynamic_cast<SalInstanceWidget*>(pParent);
6437 vcl::Window* pParentWidget = pParentInstance ? pParentInstance->getWidget() : nullptr;
6438 return new SalInstanceBuilder(pParentWidget, rUIRoot, rUIFile);
6439 }
6440
CreateInterimBuilder(vcl::Window * pParent,const OUString & rUIRoot,const OUString & rUIFile)6441 weld::Builder* SalInstance::CreateInterimBuilder(vcl::Window* pParent, const OUString& rUIRoot, const OUString& rUIFile)
6442 {
6443 return new SalInstanceBuilder(pParent, rUIRoot, rUIFile);
6444 }
6445
CreateInterimBuilder(weld::Widget * pParent,const OUString & rUIFile)6446 weld::Builder* Application::CreateInterimBuilder(weld::Widget* pParent, const OUString &rUIFile)
6447 {
6448 SalInstanceWidget* pParentInstance = dynamic_cast<SalInstanceWidget*>(pParent);
6449 vcl::Window* pParentWidget = pParentInstance ? pParentInstance->getWidget() : nullptr;
6450 return Application::CreateInterimBuilder(pParentWidget, rUIFile);
6451 }
6452
help()6453 void SalInstanceWindow::help()
6454 {
6455 //show help for widget with keyboard focus
6456 vcl::Window* pWidget = ImplGetSVData()->maWinData.mpFocusWin;
6457 if (!pWidget)
6458 pWidget = m_xWindow;
6459 OString sHelpId = pWidget->GetHelpId();
6460 while (sHelpId.isEmpty())
6461 {
6462 pWidget = pWidget->GetParent();
6463 if (!pWidget)
6464 break;
6465 sHelpId = pWidget->GetHelpId();
6466 }
6467 std::unique_ptr<weld::Widget> xTemp(pWidget != m_xWindow ? new SalInstanceWidget(pWidget, m_pBuilder, false) : nullptr);
6468 weld::Widget* pSource = xTemp ? xTemp.get() : this;
6469 bool bRunNormalHelpRequest = !m_aHelpRequestHdl.IsSet() || m_aHelpRequestHdl.Call(*pSource);
6470 Help* pHelp = bRunNormalHelpRequest ? Application::GetHelp() : nullptr;
6471 if (pHelp)
6472 {
6473 // tdf#126007, there's a nice fallback route for offline help where
6474 // the current page of a notebook will get checked when the help
6475 // button is pressed and there was no help for the dialog found.
6476 //
6477 // But for online help that route doesn't get taken, so bodge this here
6478 // by using the page help id if available and if the help button itself
6479 // was the original id
6480 if (m_pBuilder && sHelpId.endsWith("/help"))
6481 {
6482 OString sPageId = m_pBuilder->get_current_page_help_id();
6483 if (!sPageId.isEmpty())
6484 sHelpId = sPageId;
6485 else
6486 {
6487 // tdf#129068 likewise the help for the wrapping dialog is less
6488 // helpful than the help for the content area could be
6489 vcl::Window *pContentArea = nullptr;
6490 if (::Dialog* pDialog = dynamic_cast<::Dialog*>(m_xWindow.get()))
6491 pContentArea = pDialog->get_content_area();
6492 if (pContentArea)
6493 {
6494 vcl::Window* pContentWidget = pContentArea->GetWindow(GetWindowType::LastChild);
6495 if (pContentWidget)
6496 sHelpId = pContentWidget->GetHelpId();
6497 }
6498 }
6499 }
6500 pHelp->Start(OStringToOUString(sHelpId, RTL_TEXTENCODING_UTF8), pSource);
6501 }
6502 }
6503
6504 //iterate upwards through the hierarchy from this widgets through its parents
6505 //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)6506 void SalInstanceWidget::help_hierarchy_foreach(const std::function<bool(const OString&)>& func)
6507 {
6508 vcl::Window* pParent = m_xWidget;
6509 while ((pParent = pParent->GetParent()))
6510 {
6511 if (func(pParent->GetHelpId()))
6512 return;
6513 }
6514 }
6515
CreateMessageDialog(weld::Widget * pParent,VclMessageType eMessageType,VclButtonsType eButtonsType,const OUString & rPrimaryMessage)6516 weld::MessageDialog* SalInstance::CreateMessageDialog(weld::Widget* pParent, VclMessageType eMessageType, VclButtonsType eButtonsType, const OUString& rPrimaryMessage)
6517 {
6518 SalInstanceWidget* pParentInstance = dynamic_cast<SalInstanceWidget*>(pParent);
6519 SystemWindow* pParentWidget = pParentInstance ? pParentInstance->getSystemWindow() : nullptr;
6520 VclPtrInstance<MessageDialog> xMessageDialog(pParentWidget, rPrimaryMessage, eMessageType, eButtonsType);
6521 return new SalInstanceMessageDialog(xMessageDialog, nullptr, true);
6522 }
6523
GetFrameWeld(const css::uno::Reference<css::awt::XWindow> & rWindow)6524 weld::Window* SalInstance::GetFrameWeld(const css::uno::Reference<css::awt::XWindow>& rWindow)
6525 {
6526 UnoWrapperBase* pWrapper = UnoWrapperBase::GetUnoWrapper();
6527 if (!pWrapper)
6528 return nullptr;
6529 VclPtr<vcl::Window> xWindow = pWrapper->GetWindow(rWindow);
6530 if (!xWindow)
6531 return nullptr;
6532 return xWindow->GetFrameWeld();
6533 }
6534
GetFrameWeld() const6535 weld::Window* SalFrame::GetFrameWeld() const
6536 {
6537 if (!m_xFrameWeld)
6538 {
6539 vcl::Window* pWindow = GetWindow();
6540 pWindow = pWindow ? pWindow->ImplGetWindow() : nullptr;
6541 assert(!pWindow || (pWindow->IsSystemWindow() || pWindow->IsDockingWindow()));
6542 if (pWindow)
6543 m_xFrameWeld.reset(new SalInstanceWindow(pWindow, nullptr, false));
6544 }
6545 return m_xFrameWeld.get();
6546 }
6547
6548 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
6549