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