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