LibreOffice Module vcl (master) 1
salvtables.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <sal/config.h>
21
22#include <limits>
23#include <string_view>
24
25#include <com/sun/star/accessibility/AccessibleRelationType.hpp>
26#include <com/sun/star/awt/XWindow.hpp>
27#include <com/sun/star/awt/XWindowPeer.hpp>
28#include <o3tl/safeint.hxx>
30#include <o3tl/string_view.hxx>
31#include <officecfg/Office/Common.hxx>
32#include <salframe.hxx>
33#include <salinst.hxx>
34#include <salvd.hxx>
35#include <salprn.hxx>
36#include <saltimer.hxx>
37#include <salsession.hxx>
38#include <salsys.hxx>
39#include <salbmp.hxx>
40#include <salobj.hxx>
41#include <salmenu.hxx>
42#include <strings.hrc>
43#include <svdata.hxx>
44#include <svimpbox.hxx>
45#include <messagedialog.hxx>
46#include <treeglue.hxx>
49#include <utility>
50#include <tools/helpers.hxx>
51#include <vcl/abstdlg.hxx>
52#include <vcl/builder.hxx>
55#include <vcl/toolkit/fixed.hxx>
58#include <vcl/headbar.hxx>
60#include <vcl/layout.hxx>
63#include <vcl/ptrstyle.hxx>
64#include <slider.hxx>
65#include <vcl/sysdata.hxx>
68#include <vcl/tabctrl.hxx>
69#include <vcl/tabpage.hxx>
70#include <vcl/toolbox.hxx>
74#include <vcl/weld.hxx>
75#include <vcl/weldutils.hxx>
78#include <vcl/virdev.hxx>
79#include <bitmaps.hlst>
80#include <calendar.hxx>
81#include <menutogglebutton.hxx>
82#include <verticaltabctrl.hxx>
83#include <window.h>
84#include <wizdlg.hxx>
85#include <salvtables.hxx>
86#include <comphelper/lok.hxx>
87
89 : m_pWindow(nullptr)
90 , m_pProc(nullptr)
91{
92}
93
94// this file contains the virtual destructors of the sal interface
95// compilers usually put their vtables where the destructor is
96
98
100{
101 m_pWindow = pWindow;
102 m_pProc = pProc;
103}
104
105// default to full-frame flushes
106// on ports where partial-flushes are much cheaper this method should be overridden
108
109void SalFrame::SetRepresentedURL(const OUString&)
110{
111 // currently this is Mac only functionality
112}
113
115 tools::Long nHeight, sal_uInt16 nFlags)
116{
117 // assuming the 4 integers normally don't have more than 4 digits, but might be negative
118 OUStringBuffer aBuffer(4 * 5 + 5);
119 if (nFlags & SAL_FRAME_POSSIZE_WIDTH)
120 aBuffer << nWidth << "x";
121 else
122 aBuffer << "?x";
123 if (nFlags & SAL_FRAME_POSSIZE_HEIGHT)
124 aBuffer << nHeight << "@(";
125 else
126 aBuffer << "?@(";
127 if (nFlags & SAL_FRAME_POSSIZE_X)
128 aBuffer << nX << ",";
129 else
130 aBuffer << "?,";
131 if (nFlags & SAL_FRAME_POSSIZE_Y)
132 aBuffer << nY << ")";
133 else
134 aBuffer << "?)";
135 return aBuffer.makeStringAndClear();
136}
137
138SalInstance::SalInstance(std::unique_ptr<comphelper::SolarMutex> pMutex)
139 : m_pYieldMutex(std::move(pMutex))
140{
141}
142
144
146
147sal_uInt32 SalInstance::ReleaseYieldMutexAll() { return m_pYieldMutex->release(true); }
148
149void SalInstance::AcquireYieldMutex(sal_uInt32 nCount) { m_pYieldMutex->acquire(nCount); }
150
151std::unique_ptr<SalSession> SalInstance::CreateSalSession() { return nullptr; }
152
154{
155 assert(!m_bSupportsOpenGL);
156 std::abort();
157}
158
159std::unique_ptr<SalMenu> SalInstance::CreateMenu(bool, Menu*)
160{
161 // default: no native menus
162 return nullptr;
163}
164
165std::unique_ptr<SalMenuItem> SalInstance::CreateMenuItem(const SalItemParams&) { return nullptr; }
166
167bool SalInstance::CallEventCallback(void const* pEvent, int nBytes)
168{
169 return m_pEventInst.is() && m_pEventInst->dispatchEvent(pEvent, nBytes);
170}
171
173{
174 // can't run on system event loop without implementing DoExecute and DoQuit
176 std::abort();
177 return false;
178}
179
181{
183 std::abort();
184}
185
186SalTimer::~SalTimer() COVERITY_NOEXCEPT_FALSE {}
187
189{
190 if (ImplSVData* pSVData = ImplGetSVData())
191 {
192 auto& rCache = pSVData->maGDIData.maScaleCache;
193
194 rCache.remove_if([this](const lru_scale_cache::key_value_pair_t& rKeyValuePair) {
195 return rKeyValuePair.first.mpBitmap == this;
196 });
197 }
198}
199
201
203
205
206bool SalPrinter::StartJob(const OUString*, const OUString&, const OUString&, ImplJobSetup*,
208{
209 return false;
210}
211
213
215
217
219
221{
222 return false;
223}
224
226
227bool SalMenu::AddMenuBarButton(const SalMenuButtonItem&) { return false; }
228
230
232{
233 return tools::Rectangle();
234}
235
236int SalMenu::GetMenuBarHeight() const { return 0; }
237
239
241
243
245{
246private:
253
254 void SetFlash()
255 {
256 Color aColor(Application::GetSettings().GetStyleSettings().GetHighlightColor());
258 }
259
261 {
264 else
266 }
267
268 void Flash()
269 {
270 constexpr int FlashesWanted = 1;
271
272 if (m_nFlashCount % 2 == 0)
273 ClearFlash();
274 else
275 SetFlash();
276
277 if (m_nFlashCount == FlashesWanted * 2)
278 return;
279
281
283 }
284
285 DECL_LINK(FlashTimeout, Timer*, void);
286
287public:
289 : m_xWidget(std::move(xWidget))
290 , m_aFlashTimer("SalFlashAttention")
292 , m_nFlashCount(1)
293 {
296 }
297
298 void Start()
299 {
304 }
305
307};
308
309IMPL_LINK_NOARG(SalFlashAttention, FlashTimeout, Timer*, void) { Flash(); }
310
312{
313 if (!m_bEventListener)
314 {
315 m_xWidget->AddEventListener(LINK(this, SalInstanceWidget, EventListener));
316 m_bEventListener = true;
317 }
318}
319
320// we want the ability to mark key events as handled, so use this variant
321// for those, we get all keystrokes in this case, so we will need to filter
322// them later
324{
326 {
327 Application::AddKeyListener(LINK(this, SalInstanceWidget, KeyEventListener));
328 m_bKeyEventListener = true;
329 }
330}
331
332// we want the ability to know about mouse events that happen in our children
333// so use this variant, we will need to filter them later
335{
337 {
338 m_xWidget->AddChildEventListener(LINK(this, SalInstanceWidget, MouseEventListener));
340 }
341}
342
344{
348 {
349 // turn off WB_CLIPCHILDREN otherwise the bg won't extend "under"
350 // transparent children of the widget e.g. expander in sidebar panel header
352 // and toggle mbClipChildren on instead otherwise the bg won't fill e.g.
353 // deck titlebar header when its width is stretched
355 pImpl->mbClipChildren = true;
356 }
357}
358
360 bool bTakeOwnership)
361 : m_xWidget(pWidget)
362 , m_pBuilder(pBuilder)
363 , m_bTakeOwnership(bTakeOwnership)
364 , m_bEventListener(false)
365 , m_bKeyEventListener(false)
366 , m_bMouseEventListener(false)
367 , m_nBlockNotify(0)
368 , m_nFreezeCount(0)
369{
370}
371
372void SalInstanceWidget::set_sensitive(bool sensitive) { m_xWidget->Enable(sensitive); }
373
375
377
379
381{
382 auto nStyle = m_xWidget->GetStyle() & ~(WB_TABSTOP | WB_NOTABSTOP);
383 if (bCanFocus)
384 nStyle |= WB_TABSTOP;
385 else
386 nStyle |= WB_NOTABSTOP;
387 m_xWidget->SetStyle(nStyle);
388}
389
391{
392 if (has_focus())
393 return;
395}
396
398
400
402
404
406
407void SalInstanceWidget::set_size_request(int nWidth, int nHeight)
408{
411}
412
414{
416}
417
419
421{
423}
424
426
427Size SalInstanceWidget::get_pixel_size(const OUString& rText) const
428{
429 //TODO, or do I want GetTextBoundRect ?, just using width at the moment anyway
431}
432
434
435OString SalInstanceWidget::get_buildable_name() const { return m_xWidget->get_id().toUtf8(); }
436
438{
439 return m_xWidget->set_id(OUString::fromUtf8(rId));
440}
441
442void SalInstanceWidget::set_help_id(const OString& rId) { return m_xWidget->SetHelpId(rId); }
443
445
447{
449}
450
452
454
456{
458}
459
461
462void SalInstanceWidget::set_hexpand(bool bExpand) { m_xWidget->set_hexpand(bExpand); }
463
465
466void SalInstanceWidget::set_vexpand(bool bExpand) { m_xWidget->set_vexpand(bExpand); }
467
469
471
473
475
477
479
481
483
485
486void SalInstanceWidget::set_accessible_name(const OUString& rName)
487{
489}
490
491void SalInstanceWidget::set_accessible_description(const OUString& rDescription)
492{
493 m_xWidget->SetAccessibleDescription(rDescription);
494}
495
497
499{
501}
502
504{
506 pOldLabel->SetAccessibleRelationLabelFor(nullptr);
507 vcl::Window* pA11yLabel
508 = pLabel ? dynamic_cast<SalInstanceWidget&>(*pLabel).getWidget() : nullptr;
510 if (pA11yLabel)
512}
513
514void SalInstanceWidget::set_tooltip_text(const OUString& rTip)
515{
517}
518
520
522{
523 vcl::Cursor* pCursor = static_cast<vcl::Cursor*>(pData);
524 if (!pCursor)
525 return;
526
527 m_xWidget->SetCursor(pCursor);
528}
529
531{
534}
535
537{
538 m_xWidget->SetMnemonicActivateHdl(LINK(this, SalInstanceWidget, MnemonicActivateHdl));
540}
541
543{
546}
547
549{
552}
553
555{
558}
559
561{
564}
565
567{
570}
571
573{
576}
577
579{
582}
583
584bool SalInstanceWidget::get_extents_relative_to(const Widget& rRelative, int& x, int& y, int& width,
585 int& height) const
586{
588 dynamic_cast<const SalInstanceWidget&>(rRelative).getWidget()));
589 x = aRect.Left();
590 y = aRect.Top();
591 width = aRect.GetWidth();
592 height = aRect.GetHeight();
593 return true;
594}
595
597
599
601
603
605
607{
608 if (m_nFreezeCount == 0)
609 m_xWidget->SetUpdateMode(false);
611}
612
614{
616 if (m_nFreezeCount == 0)
618}
619
621{
622 if (!m_xWidget)
623 {
624 return;
625 }
626
627 if (bBusy)
629 else
631}
632
634
636{
637 if (m_aMnemonicActivateHdl.IsSet())
640 m_xWidget->RemoveChildEventListener(LINK(this, SalInstanceWidget, MouseEventListener));
642 Application::RemoveKeyListener(LINK(this, SalInstanceWidget, KeyEventListener));
644 m_xWidget->RemoveEventListener(LINK(this, SalInstanceWidget, EventListener));
647}
648
650
652
654
656
657OUString SalInstanceWidget::strip_mnemonic(const OUString& rLabel) const
658{
659 return rLabel.replaceFirst("~", "");
660}
661
663{
664 // create with (annoying) separate alpha layer that LibreOffice itself uses
667}
668
670{
672 m_xFlashAttention->Start();
673}
674
675css::uno::Reference<css::datatransfer::dnd::XDropTarget> SalInstanceWidget::get_drop_target()
676{
677 return m_xWidget->GetDropTarget();
678}
679
680css::uno::Reference<css::datatransfer::clipboard::XClipboard>
682{
683 return m_xWidget->GetClipboard();
684}
685
687{
689}
690
692{
693 m_xWidget->DumpAsPropertyTree(rJsonWriter);
694}
695
697{
699}
700
702{
704}
705
707{
710}
711
713{
715}
716
718
720{
721 if (rEvent.GetId() == VclEventId::WindowGetFocus)
722 m_aFocusInHdl.Call(*this);
723 else if (rEvent.GetId() == VclEventId::WindowLoseFocus)
724 m_aFocusOutHdl.Call(*this);
725 else if (rEvent.GetId() == VclEventId::WindowResize)
727}
728
729namespace
730{
731MouseEvent TransformEvent(const MouseEvent& rEvent, const vcl::Window* pParent,
732 const vcl::Window* pChild)
733{
734 return MouseEvent(
735 pParent->ScreenToOutputPixel(pChild->OutputToScreenPixel(rEvent.GetPosPixel())),
736 rEvent.GetClicks(), rEvent.GetMode(), rEvent.GetButtons(), rEvent.GetModifier());
737}
738}
739
741{
742 if (rWinEvent.GetId() == VclEventId::WindowMouseButtonDown)
743 {
744 if (m_xWidget == rWinEvent.GetWindow())
745 {
746 const MouseEvent* pMouseEvent = static_cast<const MouseEvent*>(rWinEvent.GetData());
747 m_aMousePressHdl.Call(*pMouseEvent);
748 }
749 else if (m_xWidget->ImplIsChild(rWinEvent.GetWindow()))
750 {
751 const MouseEvent* pMouseEvent = static_cast<const MouseEvent*>(rWinEvent.GetData());
752 const MouseEvent aTransformedEvent(
753 TransformEvent(*pMouseEvent, m_xWidget, rWinEvent.GetWindow()));
754 m_aMousePressHdl.Call(aTransformedEvent);
755 }
756 }
757 else if (rWinEvent.GetId() == VclEventId::WindowMouseButtonUp)
758 {
759 if (m_xWidget == rWinEvent.GetWindow())
760 {
761 const MouseEvent* pMouseEvent = static_cast<const MouseEvent*>(rWinEvent.GetData());
762 m_aMouseReleaseHdl.Call(*pMouseEvent);
763 }
764 else if (m_xWidget->ImplIsChild(rWinEvent.GetWindow()))
765 {
766 const MouseEvent* pMouseEvent = static_cast<const MouseEvent*>(rWinEvent.GetData());
767 const MouseEvent aTransformedEvent(
768 TransformEvent(*pMouseEvent, m_xWidget, rWinEvent.GetWindow()));
769 m_aMouseReleaseHdl.Call(aTransformedEvent);
770 }
771 }
772 else if (rWinEvent.GetId() == VclEventId::WindowMouseMove)
773 {
774 if (m_xWidget == rWinEvent.GetWindow())
775 {
776 const MouseEvent* pMouseEvent = static_cast<const MouseEvent*>(rWinEvent.GetData());
777 m_aMouseMotionHdl.Call(*pMouseEvent);
778 }
779 else if (m_xWidget->ImplIsChild(rWinEvent.GetWindow()))
780 {
781 const MouseEvent* pMouseEvent = static_cast<const MouseEvent*>(rWinEvent.GetData());
782 const MouseEvent aTransformedEvent(
783 TransformEvent(*pMouseEvent, m_xWidget, rWinEvent.GetWindow()));
784 m_aMouseMotionHdl.Call(aTransformedEvent);
785 }
786 }
787}
788
790{
791 // we get all key events here, ignore them unless we have focus
793 return false;
794 if (rEvent.GetId() == VclEventId::WindowKeyInput)
795 {
796 const KeyEvent* pKeyEvent = static_cast<const KeyEvent*>(rEvent.GetData());
797 return m_aKeyPressHdl.Call(*pKeyEvent);
798 }
799 else if (rEvent.GetId() == VclEventId::WindowKeyUp)
800 {
801 const KeyEvent* pKeyEvent = static_cast<const KeyEvent*>(rEvent.GetData());
802 return m_aKeyReleaseHdl.Call(*pKeyEvent);
803 }
804 return false;
805}
806
807IMPL_LINK(SalInstanceWidget, EventListener, VclWindowEvent&, rEvent, void)
808{
809 HandleEventListener(rEvent);
810}
811
812IMPL_LINK(SalInstanceWidget, KeyEventListener, VclWindowEvent&, rEvent, bool)
813{
814 return HandleKeyEventListener(rEvent);
815}
816
817IMPL_LINK(SalInstanceWidget, MouseEventListener, VclWindowEvent&, rEvent, void)
818{
819 HandleMouseEventListener(rEvent);
820}
821
822IMPL_LINK_NOARG(SalInstanceWidget, MnemonicActivateHdl, vcl::Window&, bool)
823{
824 return m_aMnemonicActivateHdl.Call(*this);
825}
826
827namespace
828{
829Image createImage(const OUString& rImage)
830{
831 if (rImage.isEmpty())
832 return Image();
833 if (rImage.lastIndexOf('.') != rImage.getLength() - 4)
834 {
835 assert((rImage == "dialog-warning" || rImage == "dialog-error"
836 || rImage == "dialog-information")
837 && "unknown stock image");
838 if (rImage == "dialog-warning")
839 return Image(StockImage::Yes, IMG_WARN);
840 else if (rImage == "dialog-error")
841 return Image(StockImage::Yes, IMG_ERROR);
842 else if (rImage == "dialog-information")
843 return Image(StockImage::Yes, IMG_INFO);
844 }
845 return Image(StockImage::Yes, rImage);
846}
847
848Image createImage(const VirtualDevice& rDevice)
849{
850 return Image(rDevice.GetBitmapEx(Point(), rDevice.GetOutputSizePixel()));
851}
852
853sal_uInt16 insert_to_menu(sal_uInt16 nLastId, PopupMenu* pMenu, int pos, std::u16string_view rId,
854 const OUString& rStr, const OUString* pIconName,
855 const VirtualDevice* pImageSurface,
856 const css::uno::Reference<css::graphic::XGraphic>& rImage,
857 TriState eCheckRadioFalse)
858{
859 const sal_uInt16 nNewid = nLastId + 1;
860
861 MenuItemBits nBits;
862 if (eCheckRadioFalse == TRISTATE_TRUE)
864 else if (eCheckRadioFalse == TRISTATE_FALSE)
866 else
867 nBits = MenuItemBits::NONE;
868
869 pMenu->InsertItem(nNewid, rStr, nBits, OUStringToOString(rId, RTL_TEXTENCODING_UTF8),
870 pos == -1 ? MENU_APPEND : pos);
871 if (pIconName)
872 {
873 pMenu->SetItemImage(nNewid, createImage(*pIconName));
874 }
875 else if (pImageSurface)
876 {
877 pMenu->SetItemImage(nNewid, createImage(*pImageSurface));
878 }
879 else if (rImage)
880 {
881 pMenu->SetItemImage(nNewid, Image(rImage));
882 }
883 return nNewid;
884}
885}
886
887SalInstanceMenu::SalInstanceMenu(PopupMenu* pMenu, bool bTakeOwnership)
888 : m_xMenu(pMenu)
889 , m_bTakeOwnership(bTakeOwnership)
890{
891 const auto nCount = m_xMenu->GetItemCount();
892 m_nLastId = nCount ? pMenu->GetItemId(nCount - 1) : 0;
893 m_xMenu->SetSelectHdl(LINK(this, SalInstanceMenu, SelectMenuHdl));
894}
896 weld::Placement ePlace)
897{
898 SalInstanceWidget* pVclWidget = dynamic_cast<SalInstanceWidget*>(pParent);
899 assert(pVclWidget);
901 if (ePlace == weld::Placement::Under)
902 eFlags = eFlags | PopupMenuFlags::ExecuteDown;
903 else
904 eFlags = eFlags | PopupMenuFlags::ExecuteRight;
905 m_xMenu->Execute(pVclWidget->getWidget(), rRect, eFlags);
906 return m_xMenu->GetCurItemIdent();
907}
908void SalInstanceMenu::set_sensitive(const OString& rIdent, bool bSensitive)
909{
910 m_xMenu->EnableItem(rIdent, bSensitive);
911}
912bool SalInstanceMenu::get_sensitive(const OString& rIdent) const
913{
914 return m_xMenu->IsItemEnabled(m_xMenu->GetItemId(rIdent));
915}
916void SalInstanceMenu::set_active(const OString& rIdent, bool bActive)
917{
918 m_xMenu->CheckItem(rIdent, bActive);
919}
920bool SalInstanceMenu::get_active(const OString& rIdent) const
921{
922 return m_xMenu->IsItemChecked(m_xMenu->GetItemId(rIdent));
923}
924void SalInstanceMenu::set_label(const OString& rIdent, const OUString& rLabel)
925{
926 m_xMenu->SetItemText(m_xMenu->GetItemId(rIdent), rLabel);
927}
928OUString SalInstanceMenu::get_label(const OString& rIdent) const
929{
930 return m_xMenu->GetItemText(m_xMenu->GetItemId(rIdent));
931}
932void SalInstanceMenu::set_visible(const OString& rIdent, bool bShow)
933{
934 m_xMenu->ShowItem(m_xMenu->GetItemId(rIdent), bShow);
935}
937void SalInstanceMenu::insert(int pos, const OUString& rId, const OUString& rStr,
938 const OUString* pIconName, VirtualDevice* pImageSurface,
939 const css::uno::Reference<css::graphic::XGraphic>& rImage,
940 TriState eCheckRadioFalse)
941{
942 m_nLastId = insert_to_menu(m_nLastId, m_xMenu, pos, rId, rStr, pIconName, pImageSurface, rImage,
943 eCheckRadioFalse);
944}
945void SalInstanceMenu::insert_separator(int pos, const OUString& rId)
946{
947 auto nInsertPos = pos == -1 ? MENU_APPEND : pos;
948 m_xMenu->InsertSeparator(rId.toUtf8(), nInsertPos);
949}
950void SalInstanceMenu::remove(const OString& rId)
951{
953}
955OString SalInstanceMenu::get_id(int pos) const
956{
958}
961{
965}
966
968{
969 signal_activate(m_xMenu->GetCurItemIdent());
970 /* tdf#131333 Menu::Select depends on a false here to allow
971 propagating a submens's selected id to its parent menu to become its
972 selected id.
973
974 without this, while gen menus already have propagated this to its parent
975 in MenuFloatingWindow::EndExecute, SalMenus as used under kf5/macOS
976 won't propagate the selected id
977 */
978 return false;
979}
980
982 bool bTakeOwnership)
983 : SalInstanceWidget(pToolBox, pBuilder, bTakeOwnership)
984 , m_xToolBox(pToolBox)
985{
988}
989
990void SalInstanceToolbar::set_item_sensitive(const OString& rIdent, bool bSensitive)
991{
992 m_xToolBox->EnableItem(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), bSensitive);
993}
994
995bool SalInstanceToolbar::get_item_sensitive(const OString& rIdent) const
996{
997 return m_xToolBox->IsItemEnabled(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)));
998}
999
1000void SalInstanceToolbar::set_item_visible(const OString& rIdent, bool bVisible)
1001{
1002 m_xToolBox->ShowItem(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), bVisible);
1003}
1004
1005void SalInstanceToolbar::set_item_help_id(const OString& rIdent, const OString& rHelpId)
1006{
1007 m_xToolBox->SetHelpId(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), rHelpId);
1008}
1009
1010bool SalInstanceToolbar::get_item_visible(const OString& rIdent) const
1011{
1012 return m_xToolBox->IsItemVisible(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)));
1013}
1014
1015void SalInstanceToolbar::set_item_active(const OString& rIdent, bool bActive)
1016{
1017 ToolBoxItemId nItemId = m_xToolBox->GetItemId(OUString::fromUtf8(rIdent));
1018 m_xToolBox->CheckItem(nItemId, bActive);
1019}
1020
1021bool SalInstanceToolbar::get_item_active(const OString& rIdent) const
1022{
1023 return m_xToolBox->IsItemChecked(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)));
1024}
1025
1026void SalInstanceToolbar::set_menu_item_active(const OString& rIdent, bool bActive)
1027{
1028 ToolBoxItemId nItemId = m_xToolBox->GetItemId(OUString::fromUtf8(rIdent));
1030
1031 if (bActive)
1032 {
1033 m_sStartShowIdent = m_xToolBox->GetItemCommand(nItemId).toUtf8();
1035 }
1036
1037 auto pFloat = m_aFloats[nItemId];
1038 if (pFloat)
1039 {
1040 if (bActive)
1043 else
1045 }
1046 auto pPopup = m_aMenus[nItemId];
1047 if (pPopup)
1048 {
1049 if (bActive)
1050 {
1051 tools::Rectangle aRect = m_xToolBox->GetItemRect(nItemId);
1052 pPopup->Execute(m_xToolBox, aRect, PopupMenuFlags::ExecuteDown);
1053 }
1054 else
1055 pPopup->EndExecute();
1056 }
1057
1058 m_sStartShowIdent.clear();
1059}
1060
1061bool SalInstanceToolbar::get_menu_item_active(const OString& rIdent) const
1062{
1063 ToolBoxItemId nItemId = m_xToolBox->GetItemId(OUString::fromUtf8(rIdent));
1065
1066 if (rIdent == m_sStartShowIdent)
1067 return true;
1068
1069 auto aFloat = m_aFloats.find(nItemId);
1070 if (aFloat != m_aFloats.end())
1071 {
1072 return vcl::Window::GetDockingManager()->IsInPopupMode(aFloat->second);
1073 }
1074
1075 auto aPopup = m_aMenus.find(nItemId);
1076 if (aPopup != m_aMenus.end())
1077 {
1078 return PopupMenu::GetActivePopupMenu() == aPopup->second;
1079 }
1080
1081 return false;
1082}
1083
1084void SalInstanceToolbar::set_item_popover(const OString& rIdent, weld::Widget* pPopover)
1085{
1086 SalInstanceWidget* pPopoverWidget = dynamic_cast<SalInstanceWidget*>(pPopover);
1087
1088 vcl::Window* pFloat = pPopoverWidget ? pPopoverWidget->getWidget() : nullptr;
1089 if (pFloat)
1090 {
1091 pFloat->AddEventListener(LINK(this, SalInstanceToolbar, MenuToggleListener));
1092 pFloat->EnableDocking();
1093 }
1094
1095 ToolBoxItemId nId = m_xToolBox->GetItemId(OUString::fromUtf8(rIdent));
1096 auto xOldFloat = m_aFloats[nId];
1097 if (xOldFloat)
1098 {
1099 xOldFloat->RemoveEventListener(LINK(this, SalInstanceToolbar, MenuToggleListener));
1100 }
1101 m_aFloats[nId] = pFloat;
1102 m_aMenus[nId] = nullptr;
1103}
1104
1105void SalInstanceToolbar::set_item_menu(const OString& rIdent, weld::Menu* pMenu)
1106{
1107 SalInstanceMenu* pInstanceMenu = dynamic_cast<SalInstanceMenu*>(pMenu);
1108
1109 PopupMenu* pPopup = pInstanceMenu ? pInstanceMenu->getMenu() : nullptr;
1110
1111 ToolBoxItemId nId = m_xToolBox->GetItemId(OUString::fromUtf8(rIdent));
1112 m_aMenus[nId] = pPopup;
1113 m_aFloats[nId] = nullptr;
1114}
1115
1116void SalInstanceToolbar::insert_item(int pos, const OUString& rId)
1117{
1120}
1121
1122void SalInstanceToolbar::insert_separator(int pos, const OUString& /*rId*/)
1123{
1124 auto nInsertPos = pos == -1 ? ToolBox::APPEND : pos;
1125 m_xToolBox->InsertSeparator(nInsertPos, 5);
1126}
1127
1129
1130OString SalInstanceToolbar::get_item_ident(int nIndex) const
1131{
1133}
1134
1135void SalInstanceToolbar::set_item_ident(int nIndex, const OString& rIdent)
1136{
1137 return m_xToolBox->SetItemCommand(m_xToolBox->GetItemId(nIndex), OUString::fromUtf8(rIdent));
1138}
1139
1140void SalInstanceToolbar::set_item_label(int nIndex, const OUString& rLabel)
1141{
1143}
1144
1145OUString SalInstanceToolbar::get_item_label(const OString& rIdent) const
1146{
1147 return m_xToolBox->GetItemText(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)));
1148}
1149
1150void SalInstanceToolbar::set_item_label(const OString& rIdent, const OUString& rLabel)
1151{
1152 m_xToolBox->SetItemText(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), rLabel);
1153}
1154
1155void SalInstanceToolbar::set_item_icon_name(const OString& rIdent, const OUString& rIconName)
1156{
1157 m_xToolBox->SetItemImage(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)),
1158 Image(StockImage::Yes, rIconName));
1159}
1160
1161void SalInstanceToolbar::set_item_image_mirrored(const OString& rIdent, bool bMirrored)
1162{
1163 m_xToolBox->SetItemImageMirrorMode(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)),
1164 bMirrored);
1165}
1166
1167void SalInstanceToolbar::set_item_image(const OString& rIdent,
1168 const css::uno::Reference<css::graphic::XGraphic>& rIcon)
1169{
1170 m_xToolBox->SetItemImage(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), Image(rIcon));
1171}
1172
1173void SalInstanceToolbar::set_item_image(const OString& rIdent, VirtualDevice* pDevice)
1174{
1175 if (pDevice)
1176 m_xToolBox->SetItemImage(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)),
1177 createImage(*pDevice));
1178 else
1179 m_xToolBox->SetItemImage(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), Image());
1180}
1181
1183 const css::uno::Reference<css::graphic::XGraphic>& rIcon)
1184{
1186}
1187
1188void SalInstanceToolbar::set_item_tooltip_text(int nIndex, const OUString& rTip)
1189{
1191}
1192
1193void SalInstanceToolbar::set_item_tooltip_text(const OString& rIdent, const OUString& rTip)
1194{
1195 m_xToolBox->SetQuickHelpText(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)), rTip);
1196}
1197
1198OUString SalInstanceToolbar::get_item_tooltip_text(const OString& rIdent) const
1199{
1200 return m_xToolBox->GetQuickHelpText(m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)));
1201}
1202
1204
1206{
1208 switch (eType)
1209 {
1211 eButtonSize = ToolBoxButtonSize::Small;
1212 break;
1214 eButtonSize = ToolBoxButtonSize::Large;
1215 break;
1217 eButtonSize = ToolBoxButtonSize::Size32;
1218 break;
1219 }
1220 if (m_xToolBox->GetToolboxButtonSize() != eButtonSize)
1221 {
1222 m_xToolBox->SetToolboxButtonSize(eButtonSize);
1224 }
1225}
1226
1228
1229int SalInstanceToolbar::get_drop_index(const Point& rPoint) const
1230{
1231 auto nRet = m_xToolBox->GetItemPos(rPoint);
1232 if (nRet == ToolBox::ITEM_NOTFOUND)
1233 return 0;
1234 return nRet;
1235}
1236
1238{
1241}
1242
1244{
1245 ToolBoxItemId nItemId = m_xToolBox->GetCurItemId();
1246 signal_clicked(m_xToolBox->GetItemCommand(nItemId).toUtf8());
1247}
1248
1250{
1251 ToolBoxItemId nItemId = m_xToolBox->GetCurItemId();
1252 set_menu_item_active(m_xToolBox->GetItemCommand(nItemId).toUtf8(), true);
1253}
1254
1255IMPL_LINK(SalInstanceToolbar, MenuToggleListener, VclWindowEvent&, rEvent, void)
1256{
1257 if (rEvent.GetId() == VclEventId::WindowEndPopupMode)
1258 {
1259 for (const auto& rFloat : m_aFloats)
1260 {
1261 if (rEvent.GetWindow() == rFloat.second)
1262 {
1263 ToolBoxItemId nItemId = rFloat.first;
1264 signal_toggle_menu(m_xToolBox->GetItemCommand(nItemId).toUtf8());
1265 break;
1266 }
1267 }
1268 }
1269}
1270
1271namespace
1272{
1273class SalInstanceSizeGroup : public weld::SizeGroup
1274{
1275private:
1276 std::shared_ptr<VclSizeGroup> m_xGroup;
1277
1278public:
1279 SalInstanceSizeGroup()
1280 : m_xGroup(std::make_shared<VclSizeGroup>())
1281 {
1282 }
1283 virtual void add_widget(weld::Widget* pWidget) override
1284 {
1285 SalInstanceWidget* pVclWidget = dynamic_cast<SalInstanceWidget*>(pWidget);
1286 assert(pVclWidget && pVclWidget->getWidget());
1287 pVclWidget->getWidget()->add_to_size_group(m_xGroup);
1288 }
1289 virtual void set_mode(VclSizeGroupMode eMode) override { m_xGroup->set_mode(eMode); }
1290};
1291}
1292
1294{
1297}
1298
1300{
1301 if (rEvent.GetId() == VclEventId::WindowActivate
1302 || rEvent.GetId() == VclEventId::WindowDeactivate)
1303 {
1305 return;
1306 }
1308}
1309
1311 bool bTakeOwnership)
1312 : SalInstanceWidget(pContainer, pBuilder, bTakeOwnership)
1313 , m_xContainer(pContainer)
1314{
1315}
1316
1318{
1319 SalInstanceWidget* pVclWidget = dynamic_cast<SalInstanceWidget*>(pWidget);
1320 assert(pVclWidget);
1321 SalInstanceContainer* pNewVclParent = dynamic_cast<SalInstanceContainer*>(pNewParent);
1322 assert(!pNewParent || pNewVclParent);
1323 vcl::Window* pVclWindow = pVclWidget->getWidget();
1324 if (pNewVclParent)
1325 {
1326 vcl::Window* pNew = pNewVclParent->getWidget();
1327 if (!pNew->isDisposed())
1328 pVclWindow->SetParent(pNewVclParent->getWidget());
1329 else
1330 SAL_WARN("vcl", "ignoring move because new parent is already disposed");
1331 }
1332 else
1333 {
1334 pVclWindow->Hide();
1335 pVclWindow->SetParent(ImplGetDefaultWindow());
1336 }
1337}
1338
1340{
1343 pFirstChild->ImplControlFocus();
1344}
1345
1346css::uno::Reference<css::awt::XWindow> SalInstanceContainer::CreateChildFrame()
1347{
1348 auto xPage = VclPtr<VclBin>::Create(m_xContainer.get());
1349 xPage->set_expand(true);
1350 xPage->Show();
1351 return css::uno::Reference<css::awt::XWindow>(xPage->GetComponentInterface(),
1352 css::uno::UNO_QUERY);
1353}
1354
1355std::unique_ptr<weld::Container> SalInstanceWidget::weld_parent() const
1356{
1357 vcl::Window* pParent = m_xWidget->GetParent();
1358 if (!pParent)
1359 return nullptr;
1360 return std::make_unique<SalInstanceContainer>(pParent, m_pBuilder, false);
1361}
1362
1363void SalInstanceWidget::DoRecursivePaint(vcl::Window* pWindow, const Point& rRenderLogicPos,
1364 OutputDevice& rOutput)
1365{
1366 rOutput.Push();
1367 bool bOldMapModeEnabled = pWindow->IsMapModeEnabled();
1368
1369 if (pWindow->GetMapMode().GetMapUnit() != rOutput.GetMapMode().GetMapUnit())
1370 {
1371 // This is needed for e.g. the scrollbar in writer comments in margins that has its map unit in pixels
1372 // as seen with bin/run gtktiledviewer --enable-tiled-annotations on a document containing a comment
1373 // long enough to need a scrollbar
1374 pWindow->EnableMapMode();
1375 MapMode aMapMode = pWindow->GetMapMode();
1376 aMapMode.SetMapUnit(rOutput.GetMapMode().GetMapUnit());
1377 aMapMode.SetScaleX(rOutput.GetMapMode().GetScaleX());
1378 aMapMode.SetScaleY(rOutput.GetMapMode().GetScaleY());
1379 pWindow->SetMapMode(aMapMode);
1380 }
1381
1383 Size aChildSizePixel(pWindow->GetSizePixel());
1384 xOutput->SetOutputSizePixel(aChildSizePixel);
1385
1386 MapMode aMapMode(xOutput->GetMapMode());
1387 aMapMode.SetMapUnit(rOutput.GetMapMode().GetMapUnit());
1388 aMapMode.SetScaleX(rOutput.GetMapMode().GetScaleX());
1389 aMapMode.SetScaleY(rOutput.GetMapMode().GetScaleY());
1390 xOutput->SetMapMode(aMapMode);
1391
1392 Size aTempLogicSize(xOutput->PixelToLogic(aChildSizePixel));
1393 Size aRenderLogicSize(rOutput.PixelToLogic(aChildSizePixel));
1394
1395 switch (rOutput.GetOutDevType())
1396 {
1397 case OUTDEV_WINDOW:
1398 case OUTDEV_VIRDEV:
1399 xOutput->DrawOutDev(Point(), aTempLogicSize, rRenderLogicPos, aRenderLogicSize,
1400 rOutput);
1401 break;
1402 case OUTDEV_PRINTER:
1403 case OUTDEV_PDF:
1404 xOutput->SetBackground(rOutput.GetBackground());
1405 xOutput->Erase();
1406 break;
1407 }
1408
1409 //set ReallyVisible to match Visible, we restore the original state after Paint
1410 WindowImpl* pImpl = pWindow->ImplGetWindowImpl();
1411 bool bRVisible = pImpl->mbReallyVisible;
1412 pImpl->mbReallyVisible = pWindow->IsVisible();
1413
1414 pWindow->ApplySettings(*xOutput);
1415 pWindow->Paint(*xOutput, tools::Rectangle(Point(), pWindow->PixelToLogic(aChildSizePixel)));
1416
1417 pImpl->mbReallyVisible = bRVisible;
1418
1419 switch (rOutput.GetOutDevType())
1420 {
1421 case OUTDEV_WINDOW:
1422 case OUTDEV_VIRDEV:
1423 rOutput.DrawOutDev(rRenderLogicPos, aRenderLogicSize, Point(), aTempLogicSize,
1424 *xOutput);
1425 break;
1426 case OUTDEV_PRINTER:
1427 case OUTDEV_PDF:
1428 rOutput.DrawBitmapEx(rRenderLogicPos, aRenderLogicSize,
1429 xOutput->GetBitmapEx(Point(), aTempLogicSize));
1430 break;
1431 }
1432
1433 bool bHasMirroredGraphics = pWindow->GetOutDev()->HasMirroredGraphics();
1434
1435 xOutput.disposeAndClear();
1436
1437 pWindow->EnableMapMode(bOldMapModeEnabled);
1438 rOutput.Pop();
1439
1440 for (vcl::Window* pChild = pWindow->GetWindow(GetWindowType::FirstChild); pChild;
1442 {
1443 if (!pChild->IsVisible())
1444 continue;
1445
1446 tools::Long nDeltaX
1447 = pChild->GetOutDev()->GetOutOffXPixel() - pWindow->GetOutDev()->GetOutOffXPixel();
1448 if (bHasMirroredGraphics)
1449 nDeltaX = pWindow->GetOutDev()->GetOutputWidthPixel() - nDeltaX
1450 - pChild->GetOutDev()->GetOutputWidthPixel();
1451
1452 tools::Long nDeltaY
1453 = pChild->GetOutDev()->GetOutOffYPixel() - pWindow->GetOutDev()->GetOutOffYPixel();
1454
1455 Point aPos(rRenderLogicPos);
1456 aPos += Point(nDeltaX, nDeltaY);
1457
1458 DoRecursivePaint(pChild, aPos, rOutput);
1459 }
1460}
1461
1462void SalInstanceWidget::draw(OutputDevice& rOutput, const Point& rPos, const Size& rSizePixel)
1463{
1464 Size aOrigSize(m_xWidget->GetSizePixel());
1465 bool bChangeSize = aOrigSize != rSizePixel;
1466 if (bChangeSize)
1467 m_xWidget->SetSizePixel(rSizePixel);
1468
1469 DoRecursivePaint(m_xWidget, rPos, rOutput);
1470
1471 if (bChangeSize)
1472 m_xWidget->SetSizePixel(aOrigSize);
1473}
1474
1476 bool bTakeOwnership)
1477 : SalInstanceContainer(pContainer, pBuilder, bTakeOwnership)
1478 , m_xBox(pContainer)
1479{
1480}
1481void SalInstanceBox::reorder_child(weld::Widget* pWidget, int nNewPosition)
1482{
1483 SalInstanceWidget* pVclWidget = dynamic_cast<SalInstanceWidget*>(pWidget);
1484 assert(pVclWidget);
1485 pVclWidget->getWidget()->reorderWithinParent(nNewPosition);
1486}
1487
1489
1490namespace
1491{
1492void CollectChildren(const vcl::Window& rCurrent, const basegfx::B2IPoint& rTopLeft,
1493 weld::ScreenShotCollection& rControlDataCollection)
1494{
1495 if (!rCurrent.IsVisible())
1496 return;
1497
1498 const Point aCurrentPos(rCurrent.GetPosPixel());
1499 const Size aCurrentSize(rCurrent.GetSizePixel());
1500 const basegfx::B2IPoint aCurrentTopLeft(rTopLeft.getX() + aCurrentPos.X(),
1501 rTopLeft.getY() + aCurrentPos.Y());
1502 const basegfx::B2IRange aCurrentRange(
1503 aCurrentTopLeft,
1504 aCurrentTopLeft + basegfx::B2IPoint(aCurrentSize.Width(), aCurrentSize.Height()));
1505
1506 if (!aCurrentRange.isEmpty())
1507 {
1508 rControlDataCollection.emplace_back(rCurrent.GetHelpId(), aCurrentRange);
1510
1511 for (sal_uInt16 a(0); a < rCurrent.GetChildCount(); a++)
1512 {
1513 vcl::Window* pChild = rCurrent.GetChild(a);
1514 if (nullptr != pChild)
1515 {
1516 CollectChildren(*pChild, aCurrentTopLeft, rControlDataCollection);
1517 }
1518 }
1519}
1520}
1521
1523{
1524 for (vcl::Window* pChild = pParent->GetWindow(GetWindowType::FirstChild); pChild;
1525 pChild = pChild->GetWindow(GetWindowType::Next))
1526 override_child_help(pChild);
1527 pParent->SetHelpHdl(LINK(this, SalInstanceWindow, HelpHdl));
1528}
1529
1531{
1532 for (vcl::Window* pChild = pParent->GetWindow(GetWindowType::FirstChild); pChild;
1533 pChild = pChild->GetWindow(GetWindowType::Next))
1534 clear_child_help(pChild);
1536}
1537
1539 bool bTakeOwnership)
1540 : SalInstanceContainer(pWindow, pBuilder, bTakeOwnership)
1541 , m_xWindow(pWindow)
1542{
1543 // tdf#129745 only override child help for the normal case, not for
1544 // m_pBuilder of null which is the toplevel application frame case.
1545 if (m_pBuilder)
1547}
1548
1549void SalInstanceWindow::set_title(const OUString& rTitle) { m_xWindow->SetText(rTitle); }
1550
1551OUString SalInstanceWindow::get_title() const { return m_xWindow->GetText(); }
1552
1553css::uno::Reference<css::awt::XWindow> SalInstanceWindow::GetXWindow()
1554{
1555 css::uno::Reference<css::awt::XWindow> xWindow(m_xWindow->GetComponentInterface(),
1556 css::uno::UNO_QUERY);
1557 return xWindow;
1558}
1559
1560namespace
1561{
1562void resize_to_request(vcl::Window* pWindow)
1563{
1564 if (SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(pWindow))
1565 {
1566 pSysWin->setOptimalLayoutSize(true);
1567 return;
1568 }
1569 if (DockingWindow* pDockWin = dynamic_cast<DockingWindow*>(pWindow))
1570 {
1571 pDockWin->setOptimalLayoutSize();
1572 return;
1573 }
1574 assert(false && "must be system or docking window");
1575}
1576}
1577
1579
1581
1583
1585
1587
1589
1591{
1593}
1594
1595void SalInstanceWindow::set_centered_on_parent(bool /*bTrackGeometryRequests*/)
1596{
1597 if (vcl::Window* pParent = m_xWidget->GetParent())
1598 {
1599 Size aParentGeometry(pParent->GetSizePixel());
1600 Size aGeometry(m_xWidget->get_preferred_size());
1601 auto nX = (aParentGeometry.Width() - aGeometry.Width()) / 2;
1602 auto nY = (aParentGeometry.Height() - aGeometry.Height()) / 2;
1603 m_xWidget->SetPosPixel(Point(nX, nY));
1604 }
1605}
1606
1608
1610
1612{
1614}
1615
1617{
1618 vcl::Window* pChildLoop = _pWindow->GetWindow(GetWindowType::FirstChild);
1619 while (pChildLoop)
1620 {
1621 // does the window participate in the tabbing order?
1622 if (pChildLoop->GetStyle() & WB_DIALOGCONTROL)
1623 implResetDefault(pChildLoop);
1624
1625 // is it a button?
1626 WindowType eType = pChildLoop->GetType();
1631 {
1632 pChildLoop->SetStyle(pChildLoop->GetStyle() & ~WB_DEFBUTTON);
1633 }
1634
1635 // the next one ...
1636 pChildLoop = pChildLoop->GetWindow(GetWindowType::Next);
1637 }
1638}
1639
1641
1643{
1644 SalInstanceWidget* pVclNew = dynamic_cast<SalInstanceWidget*>(pNew);
1645 vcl::Window* pWidgetNew = pVclNew ? pVclNew->getWidget() : nullptr;
1646 SalInstanceWidget* pVclOld = dynamic_cast<SalInstanceWidget*>(pOld);
1647 vcl::Window* pWidgetOld = pVclOld ? pVclOld->getWidget() : nullptr;
1648 if (pWidgetOld)
1649 pWidgetOld->set_property("has-default", OUString::boolean(false));
1650 else
1652 if (pWidgetNew)
1653 pWidgetNew->set_property("has-default", OUString::boolean(true));
1654}
1655
1657{
1658 const SalInstanceWidget* pVclCandidate = dynamic_cast<const SalInstanceWidget*>(pCandidate);
1659 vcl::Window* pWidget = pVclCandidate ? pVclCandidate->getWidget() : nullptr;
1660 return pWidget && pWidget->GetStyle() & WB_DEFBUTTON;
1661}
1662
1664{
1665 SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(m_xWindow.get());
1666 assert(pSysWin);
1667 pSysWin->SetWindowState(rStr);
1668}
1669
1671{
1672 SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(m_xWindow.get());
1673 assert(pSysWin);
1674 return pSysWin->GetWindowState(nMask);
1675}
1676
1678
1680{
1681 SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(m_xWindow.get());
1682 assert(pSysWin);
1683 return pSysWin->createScreenshot();
1684}
1685
1687{
1689
1690 // collect all children. Choose start pos to be negative
1691 // of target dialog's position to get all positions relative to (0,0)
1692 const Point aParentPos(m_xWindow->GetPosPixel());
1693 const basegfx::B2IPoint aTopLeft(-aParentPos.X(), -aParentPos.Y());
1694 CollectChildren(*m_xWindow, aTopLeft, aRet);
1695
1696 return aRet;
1697}
1698
1700{
1701 // tdf#129745 only undo overriding child help for the normal case, not for
1702 // m_pBuilder of null which is the toplevel application frame case.
1703 if (m_pBuilder)
1705}
1706
1708{
1709 help();
1710 return false;
1711}
1712
1713typedef std::set<VclPtr<vcl::Window>> winset;
1714
1715namespace
1716{
1717void hideUnless(const vcl::Window* pTop, const winset& rVisibleWidgets,
1718 std::vector<VclPtr<vcl::Window>>& rWasVisibleWidgets)
1719{
1720 for (vcl::Window* pChild = pTop->GetWindow(GetWindowType::FirstChild); pChild;
1721 pChild = pChild->GetWindow(GetWindowType::Next))
1722 {
1723 if (!pChild->IsVisible())
1724 continue;
1725 if (rVisibleWidgets.find(pChild) == rVisibleWidgets.end())
1726 {
1727 rWasVisibleWidgets.emplace_back(pChild);
1728 pChild->Hide();
1729 }
1730 else if (isContainerWindow(pChild))
1731 {
1732 hideUnless(pChild, rVisibleWidgets, rWasVisibleWidgets);
1733 }
1734 }
1735}
1736}
1737
1739 bool bTakeOwnership)
1740 : SalInstanceWindow(pDialog, pBuilder, bTakeOwnership)
1741 , m_xDialog(pDialog)
1742 , m_nOldEditWidthReq(0)
1743 , m_nOldBorderWidth(0)
1744{
1745 const bool bScreenshotMode(officecfg::Office::Common::Misc::ScreenshotMode::get());
1746 if (bScreenshotMode)
1747 {
1748 m_xDialog->SetPopupMenuHdl(LINK(this, SalInstanceDialog, PopupScreenShotMenuHdl));
1749 }
1750}
1751
1752bool SalInstanceDialog::runAsync(std::shared_ptr<weld::DialogController> aOwner,
1753 const std::function<void(sal_Int32)>& rEndDialogFn)
1754{
1756 aCtx.mxOwnerDialogController = aOwner;
1757 aCtx.maEndDialogFn = rEndDialogFn;
1758 VclButtonBox* pActionArea = m_xDialog->get_action_area();
1759 if (pActionArea)
1760 sort_native_button_order(*pActionArea);
1761 return m_xDialog->StartExecuteAsync(aCtx);
1762}
1763
1764bool SalInstanceDialog::runAsync(std::shared_ptr<Dialog> const& rxSelf,
1765 const std::function<void(sal_Int32)>& rEndDialogFn)
1766{
1767 assert(rxSelf.get() == this);
1769 // In order to store a shared_ptr to ourself, we have to have been constructed by make_shared,
1770 // which is that rxSelf enforces.
1771 aCtx.mxOwnerSelf = rxSelf;
1772 aCtx.maEndDialogFn = rEndDialogFn;
1773 VclButtonBox* pActionArea = m_xDialog->get_action_area();
1774 if (pActionArea)
1775 sort_native_button_order(*pActionArea);
1776 return m_xDialog->StartExecuteAsync(aCtx);
1777}
1778
1780{
1781 SalInstanceWidget* pVclEdit = dynamic_cast<SalInstanceWidget*>(pEdit);
1782 assert(pVclEdit);
1783 SalInstanceWidget* pVclButton = dynamic_cast<SalInstanceWidget*>(pButton);
1784
1785 vcl::Window* pRefEdit = pVclEdit->getWidget();
1786 vcl::Window* pRefBtn = pVclButton ? pVclButton->getWidget() : nullptr;
1787
1788 auto nOldEditWidth = pRefEdit->GetSizePixel().Width();
1790
1791 //We want just pRefBtn and pRefEdit to be shown
1792 //mark widgets we want to be visible, starting with pRefEdit
1793 //and all its direct parents.
1794 winset aVisibleWidgets;
1795 vcl::Window* pContentArea = m_xDialog->get_content_area();
1796 for (vcl::Window* pCandidate = pRefEdit;
1797 pCandidate && (pCandidate != pContentArea && pCandidate->IsVisible());
1798 pCandidate = pCandidate->GetWindow(GetWindowType::RealParent))
1799 {
1800 aVisibleWidgets.insert(pCandidate);
1801 }
1802 //same again with pRefBtn, except stop if there's a
1803 //shared parent in the existing widgets
1804 for (vcl::Window* pCandidate = pRefBtn;
1805 pCandidate && (pCandidate != pContentArea && pCandidate->IsVisible());
1806 pCandidate = pCandidate->GetWindow(GetWindowType::RealParent))
1807 {
1808 if (aVisibleWidgets.insert(pCandidate).second)
1809 break;
1810 }
1811
1812 //hide everything except the aVisibleWidgets
1813 hideUnless(pContentArea, aVisibleWidgets, m_aHiddenWidgets);
1814
1815 // the insert function case has an initially hidden edit widget, so it has
1816 // not start size, so take larger of actual size and size request
1817 pRefEdit->set_width_request(std::max(nOldEditWidth, m_nOldEditWidthReq));
1818 m_nOldBorderWidth = m_xDialog->get_border_width();
1819 m_xDialog->set_border_width(0);
1820 if (vcl::Window* pActionArea = m_xDialog->get_action_area())
1821 pActionArea->Hide();
1822 m_xDialog->setOptimalLayoutSize(true);
1823 m_xRefEdit = pRefEdit;
1824}
1825
1827{
1828 // All others: Show();
1829 for (VclPtr<vcl::Window> const& pWindow : m_aHiddenWidgets)
1830 {
1831 pWindow->Show();
1832 }
1833 m_aHiddenWidgets.clear();
1834
1836 m_xRefEdit.clear();
1837 m_xDialog->set_border_width(m_nOldBorderWidth);
1838 if (vcl::Window* pActionArea = m_xDialog->get_action_area())
1839 pActionArea->Show();
1840 m_xDialog->setOptimalLayoutSize(true);
1841}
1842
1845{
1846 m_xDialog->SetInstallLOKNotifierHdl(rLink);
1847}
1848
1850{
1851 VclButtonBox* pActionArea = m_xDialog->get_action_area();
1852 if (pActionArea)
1853 sort_native_button_order(*pActionArea);
1854 return m_xDialog->Execute();
1855}
1856
1857void SalInstanceDialog::response(int nResponse) { m_xDialog->EndDialog(nResponse); }
1858
1859void SalInstanceDialog::add_button(const OUString& rText, int nResponse, const OString& rHelpId)
1860{
1861 VclButtonBox* pBox = m_xDialog->get_action_area();
1862 VclPtr<PushButton> xButton(
1864 xButton->SetText(rText);
1865 xButton->SetHelpId(rHelpId);
1866
1867 switch (nResponse)
1868 {
1869 case RET_OK:
1870 xButton->set_id("ok");
1871 break;
1872 case RET_CLOSE:
1873 xButton->set_id("close");
1874 break;
1875 case RET_CANCEL:
1876 xButton->set_id("cancel");
1877 break;
1878 case RET_YES:
1879 xButton->set_id("yes");
1880 break;
1881 case RET_NO:
1882 xButton->set_id("no");
1883 break;
1884 }
1885
1886 xButton->Show();
1887 m_xDialog->add_button(xButton, nResponse, true);
1888}
1889
1891{
1892 if (get_modal() == bModal)
1893 return;
1894 m_xDialog->SetModalInputMode(bModal);
1895}
1896
1897bool SalInstanceDialog::get_modal() const { return m_xDialog->IsModalInputMode(); }
1898
1900{
1901 m_xDialog->set_default_response(nResponse);
1902}
1903
1905{
1906 return new SalInstanceContainer(m_xDialog->get_content_area(), m_pBuilder, false);
1907}
1908
1909IMPL_LINK(SalInstanceDialog, PopupScreenShotMenuHdl, const CommandEvent&, rCEvt, bool)
1910{
1911 if (CommandEventId::ContextMenu == rCEvt.GetCommand())
1912 {
1913 const Point aMenuPos(rCEvt.GetMousePosPixel());
1915 sal_uInt16 nLocalID(1);
1916
1917 aMenu->InsertItem(nLocalID, VclResId(SV_BUTTONTEXT_SCREENSHOT));
1918 aMenu->SetHelpText(nLocalID, VclResId(SV_HELPTEXT_SCREENSHOT));
1919 aMenu->SetHelpId(nLocalID, "InteractiveScreenshotMode");
1920 aMenu->EnableItem(nLocalID);
1921
1922 const sal_uInt16 nId(aMenu->Execute(m_xDialog, aMenuPos));
1923
1924 // 0 == no selection (so not usable as ID)
1925 if (0 != nId)
1926 {
1927 // open screenshot annotation dialog
1930 = pFact->CreateScreenshotAnnotationDlg(*this);
1932
1933 if (pDialog)
1934 {
1935 // currently just execute the dialog, no need to do
1936 // different things for ok/cancel. This may change later,
1937 // for that case use 'if (pDlg->Execute() == RET_OK)'
1938 pDialog->Execute();
1939 }
1940 }
1941
1942 // consume event when:
1943 // - CommandEventId::ContextMenu
1944 // - bScreenshotMode
1945 return true;
1946 }
1947
1948 return false;
1949}
1950
1952 SalInstanceBuilder* pBuilder,
1953 bool bTakeOwnership)
1954 : SalInstanceDialog(pDialog, pBuilder, bTakeOwnership)
1955 , m_xMessageDialog(pDialog)
1956{
1957}
1958
1960{
1961 m_xMessageDialog->set_primary_text(rText);
1962}
1963
1965{
1966 return m_xMessageDialog->get_primary_text();
1967}
1968
1970{
1971 m_xMessageDialog->set_secondary_text(rText);
1972}
1973
1975{
1976 return m_xMessageDialog->get_secondary_text();
1977}
1978
1980{
1981 return new SalInstanceContainer(m_xMessageDialog->get_message_area(), m_pBuilder, false);
1982}
1983
1984namespace
1985{
1986class SalInstanceAssistant : public SalInstanceDialog, public virtual weld::Assistant
1987{
1988private:
1990 std::vector<std::unique_ptr<SalInstanceContainer>> m_aPages;
1991 std::vector<VclPtr<TabPage>> m_aAddedPages;
1992 std::vector<int> m_aIds;
1993 std::vector<VclPtr<VclGrid>> m_aAddedGrids;
1994 Idle m_aUpdateRoadmapIdle;
1995
1996 int find_page(std::string_view rIdent) const
1997 {
1998 for (size_t i = 0; i < m_aAddedPages.size(); ++i)
1999 {
2000 if (m_aAddedPages[i]->get_id().toUtf8() == rIdent)
2001 return i;
2002 }
2003 return -1;
2004 }
2005
2006 int find_id(int nId) const
2007 {
2008 for (size_t i = 0; i < m_aIds.size(); ++i)
2009 {
2010 if (nId == m_aIds[i])
2011 return i;
2012 }
2013 return -1;
2014 }
2015
2016 DECL_LINK(OnRoadmapItemSelected, LinkParamNone*, void);
2017 DECL_LINK(UpdateRoadmap_Hdl, Timer*, void);
2018
2019public:
2020 SalInstanceAssistant(vcl::RoadmapWizard* pDialog, SalInstanceBuilder* pBuilder,
2021 bool bTakeOwnership)
2022 : SalInstanceDialog(pDialog, pBuilder, bTakeOwnership)
2023 , m_xWizard(pDialog)
2024 , m_aUpdateRoadmapIdle("SalInstanceAssistant m_aUpdateRoadmapIdle")
2025 {
2026 m_xWizard->SetItemSelectHdl(LINK(this, SalInstanceAssistant, OnRoadmapItemSelected));
2027
2028 m_aUpdateRoadmapIdle.SetInvokeHandler(LINK(this, SalInstanceAssistant, UpdateRoadmap_Hdl));
2029 m_aUpdateRoadmapIdle.SetPriority(TaskPriority::HIGHEST);
2030 }
2031
2032 virtual int get_current_page() const override { return find_id(m_xWizard->GetCurLevel()); }
2033
2034 virtual int get_n_pages() const override { return m_aAddedPages.size(); }
2035
2036 virtual OString get_page_ident(int nPage) const override
2037 {
2038 return m_aAddedPages[nPage]->get_id().toUtf8();
2039 }
2040
2041 virtual OString get_current_page_ident() const override
2042 {
2044 }
2045
2046 virtual void set_current_page(int nPage) override
2047 {
2049
2050 // take the first shown page as the size for all pages
2051 if (m_xWizard->GetPageSizePixel().Width() == 0)
2052 {
2053 Size aFinalSize;
2054 for (int i = 0, nPages = get_n_pages(); i < nPages; ++i)
2055 {
2056 TabPage* pPage = m_xWizard->GetPage(m_aIds[i]);
2057 assert(pPage);
2058 Size aPageSize(pPage->get_preferred_size());
2059 if (aPageSize.Width() > aFinalSize.Width())
2060 aFinalSize.setWidth(aPageSize.Width());
2061 if (aPageSize.Height() > aFinalSize.Height())
2062 aFinalSize.setHeight(aPageSize.Height());
2063 }
2064 m_xWizard->SetPageSizePixel(aFinalSize);
2065 }
2066
2067 (void)m_xWizard->ShowPage(m_aIds[nPage]);
2069 }
2070
2071 virtual void set_current_page(const OString& rIdent) override
2072 {
2073 int nIndex = find_page(rIdent);
2074 if (nIndex == -1)
2075 return;
2076 set_current_page(nIndex);
2077 }
2078
2079 virtual void set_page_index(const OString& rIdent, int nNewIndex) override
2080 {
2081 int nOldIndex = find_page(rIdent);
2082
2083 if (nOldIndex == -1)
2084 return;
2085
2086 if (nOldIndex == nNewIndex)
2087 return;
2088
2090
2091 auto entry = std::move(m_aAddedPages[nOldIndex]);
2092 m_aAddedPages.erase(m_aAddedPages.begin() + nOldIndex);
2093 m_aAddedPages.insert(m_aAddedPages.begin() + nNewIndex, std::move(entry));
2094
2095 int nId = m_aIds[nOldIndex];
2096 m_aIds.erase(m_aIds.begin() + nOldIndex);
2097 m_aIds.insert(m_aIds.begin() + nNewIndex, nId);
2098
2099 m_aUpdateRoadmapIdle.Start();
2100
2102 }
2103
2104 virtual weld::Container* append_page(const OString& rIdent) override
2105 {
2106 VclPtrInstance<TabPage> xPage(m_xWizard);
2107 VclPtrInstance<VclGrid> xGrid(xPage);
2108 xPage->set_id(OUString::fromUtf8(rIdent));
2109 xPage->Show();
2110 xGrid->set_hexpand(true);
2111 xGrid->set_vexpand(true);
2112 xGrid->Show();
2113 m_xWizard->AddPage(xPage);
2114 m_aIds.push_back(m_aAddedPages.size());
2115 m_xWizard->SetPage(m_aIds.back(), xPage);
2116 m_aAddedPages.push_back(xPage);
2117 m_aAddedGrids.push_back(xGrid);
2118
2119 m_aUpdateRoadmapIdle.Start();
2120
2121 m_aPages.emplace_back(new SalInstanceContainer(xGrid, m_pBuilder, false));
2122 return m_aPages.back().get();
2123 }
2124
2125 virtual OUString get_page_title(const OString& rIdent) const override
2126 {
2127 int nIndex = find_page(rIdent);
2128 if (nIndex == -1)
2129 return OUString();
2130 return m_aAddedPages[nIndex]->GetText();
2131 }
2132
2133 virtual void set_page_title(const OString& rIdent, const OUString& rTitle) override
2134 {
2135 int nIndex = find_page(rIdent);
2136 if (nIndex == -1)
2137 return;
2138 if (m_aAddedPages[nIndex]->GetText() != rTitle)
2139 {
2141 m_aAddedPages[nIndex]->SetText(rTitle);
2142 m_aUpdateRoadmapIdle.Start();
2144 }
2145 }
2146
2147 virtual void set_page_sensitive(const OString& rIdent, bool bSensitive) override
2148 {
2149 int nIndex = find_page(rIdent);
2150 if (nIndex == -1)
2151 return;
2152 if (m_aAddedPages[nIndex]->IsEnabled() != bSensitive)
2153 {
2155 m_aAddedPages[nIndex]->Enable(bSensitive);
2156 m_aUpdateRoadmapIdle.Start();
2158 }
2159 }
2160
2161 virtual void set_page_side_help_id(const OString& rHelpId) override
2162 {
2163 m_xWizard->SetRoadmapHelpId(rHelpId);
2164 }
2165
2166 virtual void set_page_side_image(const OUString& rImage) override
2167 {
2168 m_xWizard->SetRoadmapBitmap(createImage(rImage).GetBitmapEx());
2169 }
2170
2171 weld::Button* weld_widget_for_response(int nResponse) override;
2172
2173 virtual ~SalInstanceAssistant() override
2174 {
2175 for (auto& rGrid : m_aAddedGrids)
2176 rGrid.disposeAndClear();
2177 for (auto& rPage : m_aAddedPages)
2178 rPage.disposeAndClear();
2179 }
2180};
2181}
2182
2183IMPL_LINK_NOARG(SalInstanceAssistant, OnRoadmapItemSelected, LinkParamNone*, void)
2184{
2185 if (notify_events_disabled())
2186 return;
2187 auto nCurItemId = m_xWizard->GetCurrentRoadmapItemID();
2188 int nPageIndex(find_id(nCurItemId));
2189 if (!signal_jump_page(get_page_ident(nPageIndex)) && nCurItemId != m_xWizard->GetCurLevel())
2190 m_xWizard->SelectRoadmapItemByID(m_xWizard->GetCurLevel());
2191}
2192
2193IMPL_LINK_NOARG(SalInstanceAssistant, UpdateRoadmap_Hdl, Timer*, void)
2194{
2195 disable_notify_events();
2196
2197 m_xWizard->DeleteRoadmapItems();
2198
2199 int nPos = 0;
2200 for (size_t i = 0; i < m_aAddedPages.size(); ++i)
2201 {
2202 const OUString& rLabel = m_aAddedPages[i]->GetText();
2203 bool bSensitive = m_aAddedPages[i]->IsEnabled();
2204 if (rLabel.isEmpty())
2205 continue;
2206 m_xWizard->InsertRoadmapItem(nPos++, rLabel, m_aIds[i], bSensitive);
2207 }
2208
2209 m_xWizard->SelectRoadmapItemByID(m_aIds[get_current_page()], false);
2210
2211 m_xWizard->ShowRoadmap(nPos != 0);
2212
2213 enable_notify_events();
2214}
2215
2217 bool bTakeOwnership)
2218 : SalInstanceContainer(pFrame, pBuilder, bTakeOwnership)
2219 , m_xFrame(pFrame)
2220{
2221}
2222
2223void SalInstanceFrame::set_label(const OUString& rText) { m_xFrame->set_label(rText); }
2224
2225OUString SalInstanceFrame::get_label() const { return m_xFrame->get_label(); }
2226
2227namespace
2228{
2229class SalInstancePaned : public SalInstanceContainer, public virtual weld::Paned
2230{
2231private:
2232 VclPtr<VclPaned> m_xPaned;
2233
2234public:
2235 SalInstancePaned(VclPaned* pPaned, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2236 : SalInstanceContainer(pPaned, pBuilder, bTakeOwnership)
2237 , m_xPaned(pPaned)
2238 {
2239 }
2240
2241 virtual void set_position(int nPos) override { m_xPaned->set_position(nPos); }
2242
2243 virtual int get_position() const override { return m_xPaned->get_position(); }
2244};
2245
2246class SalInstanceScrolledWindow : public SalInstanceContainer, public virtual weld::ScrolledWindow
2247{
2248private:
2249 VclPtr<VclScrolledWindow> m_xScrolledWindow;
2250 Link<ScrollBar*, void> m_aOrigVScrollHdl;
2251 Link<ScrollBar*, void> m_aOrigHScrollHdl;
2252 bool m_bUserManagedScrolling;
2253
2254 DECL_LINK(VscrollHdl, ScrollBar*, void);
2255 DECL_LINK(HscrollHdl, ScrollBar*, void);
2256
2257 static void customize_scrollbars(ScrollBar& rScrollBar, const Color& rButtonTextColor,
2258 const Color& rBackgroundColor, const Color& rShadowColor,
2259 const Color& rFaceColor)
2260 {
2261 rScrollBar.EnableNativeWidget(false);
2262 AllSettings aSettings = rScrollBar.GetSettings();
2263 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
2264 aStyleSettings.SetButtonTextColor(rButtonTextColor);
2265 aStyleSettings.SetCheckedColor(rBackgroundColor); // background
2266 aStyleSettings.SetShadowColor(rShadowColor);
2267 aStyleSettings.SetFaceColor(rFaceColor);
2268 aSettings.SetStyleSettings(aStyleSettings);
2269 rScrollBar.SetSettings(aSettings);
2270 }
2271
2272public:
2273 SalInstanceScrolledWindow(VclScrolledWindow* pScrolledWindow, SalInstanceBuilder* pBuilder,
2274 bool bTakeOwnership, bool bUserManagedScrolling)
2275 : SalInstanceContainer(pScrolledWindow, pBuilder, bTakeOwnership)
2276 , m_xScrolledWindow(pScrolledWindow)
2277 , m_bUserManagedScrolling(bUserManagedScrolling)
2278 {
2279 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2280 m_aOrigVScrollHdl = rVertScrollBar.GetScrollHdl();
2281 rVertScrollBar.SetScrollHdl(LINK(this, SalInstanceScrolledWindow, VscrollHdl));
2282 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2283 m_aOrigHScrollHdl = rHorzScrollBar.GetScrollHdl();
2284 rHorzScrollBar.SetScrollHdl(LINK(this, SalInstanceScrolledWindow, HscrollHdl));
2285 m_xScrolledWindow->setUserManagedScrolling(m_bUserManagedScrolling);
2286 }
2287
2288 virtual void hadjustment_configure(int value, int lower, int upper, int step_increment,
2289 int page_increment, int page_size) override
2290 {
2291 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2292 rHorzScrollBar.SetRangeMin(lower);
2293 rHorzScrollBar.SetRangeMax(upper);
2294 rHorzScrollBar.SetLineSize(step_increment);
2295 rHorzScrollBar.SetPageSize(page_increment);
2296 rHorzScrollBar.SetThumbPos(value);
2297 rHorzScrollBar.SetVisibleSize(page_size);
2298 }
2299
2300 virtual int hadjustment_get_value() const override
2301 {
2302 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2303 return rHorzScrollBar.GetThumbPos();
2304 }
2305
2306 virtual void hadjustment_set_value(int value) override
2307 {
2308 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2309 rHorzScrollBar.SetThumbPos(value);
2310 if (!m_bUserManagedScrolling)
2311 m_aOrigHScrollHdl.Call(&rHorzScrollBar);
2312 }
2313
2314 virtual int hadjustment_get_upper() const override
2315 {
2316 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2317 return rHorzScrollBar.GetRangeMax();
2318 }
2319
2320 virtual void hadjustment_set_upper(int upper) override
2321 {
2322 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2323 rHorzScrollBar.SetRangeMax(upper);
2324 }
2325
2326 virtual int hadjustment_get_page_size() const override
2327 {
2328 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2329 return rHorzScrollBar.GetVisibleSize();
2330 }
2331
2332 virtual void hadjustment_set_page_size(int size) override
2333 {
2334 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2335 return rHorzScrollBar.SetVisibleSize(size);
2336 }
2337
2338 virtual void hadjustment_set_page_increment(int size) override
2339 {
2340 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2341 return rHorzScrollBar.SetPageSize(size);
2342 }
2343
2344 virtual void hadjustment_set_step_increment(int size) override
2345 {
2346 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2347 return rHorzScrollBar.SetLineSize(size);
2348 }
2349
2350 virtual void set_hpolicy(VclPolicyType eHPolicy) override
2351 {
2352 WinBits nWinBits = m_xScrolledWindow->GetStyle() & ~(WB_AUTOHSCROLL | WB_HSCROLL);
2353 if (eHPolicy == VclPolicyType::ALWAYS)
2354 nWinBits |= WB_HSCROLL;
2355 else if (eHPolicy == VclPolicyType::AUTOMATIC)
2356 nWinBits |= WB_AUTOHSCROLL;
2357 m_xScrolledWindow->SetStyle(nWinBits);
2358 m_xScrolledWindow->queue_resize();
2359 }
2360
2361 virtual VclPolicyType get_hpolicy() const override
2362 {
2363 WinBits nWinBits = m_xScrolledWindow->GetStyle();
2364 if (nWinBits & WB_AUTOHSCROLL)
2366 else if (nWinBits & WB_HSCROLL)
2367 return VclPolicyType::ALWAYS;
2368 return VclPolicyType::NEVER;
2369 }
2370
2371 virtual void vadjustment_configure(int value, int lower, int upper, int step_increment,
2372 int page_increment, int page_size) override
2373 {
2374 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2375 rVertScrollBar.SetRangeMin(lower);
2376 rVertScrollBar.SetRangeMax(upper);
2377 rVertScrollBar.SetLineSize(step_increment);
2378 rVertScrollBar.SetPageSize(page_increment);
2379 rVertScrollBar.SetThumbPos(value);
2380 rVertScrollBar.SetVisibleSize(page_size);
2381 }
2382
2383 virtual int vadjustment_get_value() const override
2384 {
2385 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2386 return rVertScrollBar.GetThumbPos();
2387 }
2388
2389 virtual void vadjustment_set_value(int value) override
2390 {
2391 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2392 rVertScrollBar.SetThumbPos(value);
2393 if (!m_bUserManagedScrolling)
2394 m_aOrigVScrollHdl.Call(&rVertScrollBar);
2395 }
2396
2397 virtual int vadjustment_get_upper() const override
2398 {
2399 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2400 return rVertScrollBar.GetRangeMax();
2401 }
2402
2403 virtual void vadjustment_set_upper(int upper) override
2404 {
2405 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2406 rVertScrollBar.SetRangeMax(upper);
2407 }
2408
2409 virtual int vadjustment_get_lower() const override
2410 {
2411 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2412 return rVertScrollBar.GetRangeMin();
2413 }
2414
2415 virtual void vadjustment_set_lower(int lower) override
2416 {
2417 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2418 rVertScrollBar.SetRangeMin(lower);
2419 }
2420
2421 virtual int vadjustment_get_page_size() const override
2422 {
2423 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2424 return rVertScrollBar.GetVisibleSize();
2425 }
2426
2427 virtual void vadjustment_set_page_size(int size) override
2428 {
2429 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2430 return rVertScrollBar.SetVisibleSize(size);
2431 }
2432
2433 virtual void vadjustment_set_page_increment(int size) override
2434 {
2435 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2436 return rVertScrollBar.SetPageSize(size);
2437 }
2438
2439 virtual void vadjustment_set_step_increment(int size) override
2440 {
2441 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2442 return rVertScrollBar.SetLineSize(size);
2443 }
2444
2445 virtual void set_vpolicy(VclPolicyType eVPolicy) override
2446 {
2447 WinBits nWinBits = m_xScrolledWindow->GetStyle() & ~(WB_AUTOVSCROLL | WB_VSCROLL);
2448 if (eVPolicy == VclPolicyType::ALWAYS)
2449 nWinBits |= WB_VSCROLL;
2450 else if (eVPolicy == VclPolicyType::AUTOMATIC)
2451 nWinBits |= WB_AUTOVSCROLL;
2452 m_xScrolledWindow->SetStyle(nWinBits);
2453 m_xScrolledWindow->queue_resize();
2454 }
2455
2456 virtual VclPolicyType get_vpolicy() const override
2457 {
2458 WinBits nWinBits = m_xScrolledWindow->GetStyle();
2459 if (nWinBits & WB_AUTOVSCROLL)
2461 else if (nWinBits & WB_VSCROLL)
2462 return VclPolicyType::ALWAYS;
2463 return VclPolicyType::NEVER;
2464 }
2465
2466 virtual int get_scroll_thickness() const override
2467 {
2468 return m_xScrolledWindow->getVertScrollBar().get_preferred_size().Width();
2469 }
2470
2471 virtual void set_scroll_thickness(int nThickness) override
2472 {
2473 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2474 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2475 rHorzScrollBar.set_height_request(nThickness);
2476 rVertScrollBar.set_width_request(nThickness);
2477 }
2478
2479 virtual void customize_scrollbars(const Color& rBackgroundColor, const Color& rShadowColor,
2480 const Color& rFaceColor) override
2481 {
2482 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2483 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2484 customize_scrollbars(rHorzScrollBar, Color(0, 0, 0), rBackgroundColor, rShadowColor,
2485 rFaceColor);
2486 customize_scrollbars(rVertScrollBar, Color(0, 0, 0), rBackgroundColor, rShadowColor,
2487 rFaceColor);
2488 }
2489
2490 virtual ~SalInstanceScrolledWindow() override
2491 {
2492 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2493 rVertScrollBar.SetScrollHdl(m_aOrigVScrollHdl);
2494 }
2495};
2496}
2497
2498IMPL_LINK(SalInstanceScrolledWindow, VscrollHdl, ScrollBar*, pScrollBar, void)
2499{
2500 signal_vadjustment_changed();
2501 if (!m_bUserManagedScrolling)
2502 m_aOrigVScrollHdl.Call(pScrollBar);
2503}
2504
2505IMPL_LINK_NOARG(SalInstanceScrolledWindow, HscrollHdl, ScrollBar*, void)
2506{
2507 signal_hadjustment_changed();
2508 if (!m_bUserManagedScrolling)
2509 m_aOrigHScrollHdl.Call(&m_xScrolledWindow->getHorzScrollBar());
2510}
2511
2512namespace
2513{
2514class SalInstanceScrollbar : public SalInstanceWidget, public virtual weld::Scrollbar
2515{
2516private:
2517 VclPtr<ScrollBar> m_xScrollBar;
2518
2519 DECL_LINK(ScrollHdl, ScrollBar*, void);
2520
2521public:
2522 SalInstanceScrollbar(ScrollBar* pScrollbar, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2523 : SalInstanceWidget(pScrollbar, pBuilder, bTakeOwnership)
2524 , m_xScrollBar(pScrollbar)
2525 {
2526 m_xScrollBar->SetScrollHdl(LINK(this, SalInstanceScrollbar, ScrollHdl));
2527 m_xScrollBar->EnableDrag();
2528 }
2529
2530 virtual void adjustment_configure(int value, int lower, int upper, int step_increment,
2531 int page_increment, int page_size) override
2532 {
2533 m_xScrollBar->SetRangeMin(lower);
2534 m_xScrollBar->SetRangeMax(upper);
2535 m_xScrollBar->SetLineSize(step_increment);
2536 m_xScrollBar->SetPageSize(page_increment);
2537 m_xScrollBar->SetThumbPos(value);
2538 m_xScrollBar->SetVisibleSize(page_size);
2539 }
2540
2541 virtual int adjustment_get_value() const override { return m_xScrollBar->GetThumbPos(); }
2542
2543 virtual void adjustment_set_value(int value) override { m_xScrollBar->SetThumbPos(value); }
2544
2545 virtual int adjustment_get_upper() const override { return m_xScrollBar->GetRangeMax(); }
2546
2547 virtual void adjustment_set_upper(int upper) override { m_xScrollBar->SetRangeMax(upper); }
2548
2549 virtual int adjustment_get_lower() const override { return m_xScrollBar->GetRangeMin(); }
2550
2551 virtual void adjustment_set_lower(int lower) override { m_xScrollBar->SetRangeMin(lower); }
2552
2553 virtual int adjustment_get_page_size() const override { return m_xScrollBar->GetVisibleSize(); }
2554
2555 virtual void adjustment_set_page_size(int size) override { m_xScrollBar->SetVisibleSize(size); }
2556
2557 virtual int adjustment_get_page_increment() const override
2558 {
2559 return m_xScrollBar->GetPageSize();
2560 }
2561
2562 virtual void adjustment_set_page_increment(int size) override
2563 {
2564 m_xScrollBar->SetPageSize(size);
2565 }
2566
2567 virtual int adjustment_get_step_increment() const override
2568 {
2569 return m_xScrollBar->GetLineSize();
2570 }
2571
2572 virtual void adjustment_set_step_increment(int size) override
2573 {
2574 m_xScrollBar->SetLineSize(size);
2575 }
2576
2577 virtual ScrollType get_scroll_type() const override { return m_xScrollBar->GetType(); }
2578
2579 virtual int get_scroll_thickness() const override
2580 {
2581 if (m_xScrollBar->GetStyle() & WB_HORZ)
2582 return m_xScrollBar->get_preferred_size().Height();
2583 return m_xScrollBar->get_preferred_size().Width();
2584 }
2585
2586 virtual void set_scroll_thickness(int nThickness) override
2587 {
2588 if (m_xScrollBar->GetStyle() & WB_HORZ)
2589 m_xScrollBar->set_height_request(nThickness);
2590 else
2591 m_xScrollBar->set_width_request(nThickness);
2592 }
2593};
2594}
2595
2596IMPL_LINK_NOARG(SalInstanceScrollbar, ScrollHdl, ScrollBar*, void) { signal_adjustment_changed(); }
2597
2599 bool bTakeOwnership)
2600 : SalInstanceWidget(pNotebook, pBuilder, bTakeOwnership)
2601 , m_xNotebook(pNotebook)
2602{
2603 m_xNotebook->SetActivatePageHdl(LINK(this, SalInstanceNotebook, ActivatePageHdl));
2604 m_xNotebook->SetDeactivatePageHdl(LINK(this, SalInstanceNotebook, DeactivatePageHdl));
2605}
2606
2608{
2610}
2611
2613{
2615}
2616
2618{
2620}
2621
2622int SalInstanceNotebook::get_page_index(const OString& rIdent) const
2623{
2624 sal_uInt16 nPageId = m_xNotebook->GetPageId(rIdent);
2625 sal_uInt16 nPageIndex = m_xNotebook->GetPagePos(nPageId);
2626 if (nPageIndex == TAB_PAGE_NOTFOUND)
2627 return -1;
2628 return nPageIndex;
2629}
2630
2632{
2633 int nPageIndex = get_page_index(rIdent);
2634 if (nPageIndex == -1)
2635 return nullptr;
2636 sal_uInt16 nPageId = m_xNotebook->GetPageId(rIdent);
2638 vcl::Window* pChild = pPage->GetChild(0);
2639 if (m_aPages.size() < nPageIndex + 1U)
2640 m_aPages.resize(nPageIndex + 1U);
2641 if (!m_aPages[nPageIndex])
2642 m_aPages[nPageIndex] = std::make_shared<SalInstanceContainer>(pChild, m_pBuilder, false);
2643 return m_aPages[nPageIndex].get();
2644}
2645
2647{
2649}
2650
2651void SalInstanceNotebook::set_current_page(const OString& rIdent)
2652{
2654}
2655
2656void SalInstanceNotebook::remove_page(const OString& rIdent)
2657{
2658 sal_uInt16 nPageId = m_xNotebook->GetPageId(rIdent);
2659 sal_uInt16 nPageIndex = m_xNotebook->GetPagePos(nPageId);
2660 if (nPageIndex == TAB_PAGE_NOTFOUND)
2661 return;
2662
2664 if (nPageIndex < m_aPages.size())
2665 m_aPages.erase(m_aPages.begin() + nPageIndex);
2666
2667 auto iter = m_aAddedPages.find(rIdent);
2668 if (iter != m_aAddedPages.end())
2669 {
2670 iter->second.second.disposeAndClear();
2671 iter->second.first.disposeAndClear();
2672 m_aAddedPages.erase(iter);
2673 }
2674}
2675
2676void SalInstanceNotebook::insert_page(const OString& rIdent, const OUString& rLabel, int nPos)
2677{
2678 sal_uInt16 nPageCount = m_xNotebook->GetPageCount();
2679 sal_uInt16 nLastPageId = nPageCount ? m_xNotebook->GetPageId(nPageCount - 1) : 0;
2680 sal_uInt16 nNewPageId = nLastPageId + 1;
2681 while (m_xNotebook->GetPagePos(nNewPageId) != TAB_PAGE_NOTFOUND)
2682 ++nNewPageId;
2683 m_xNotebook->InsertPage(nNewPageId, rLabel, nPos == -1 ? TAB_APPEND : nPos);
2685 VclPtrInstance<VclGrid> xGrid(xPage);
2686 xPage->Show();
2687 xGrid->set_hexpand(true);
2688 xGrid->set_vexpand(true);
2689 xGrid->Show();
2690 m_xNotebook->SetTabPage(nNewPageId, xPage);
2691 m_xNotebook->SetPageName(nNewPageId, rIdent);
2692 m_aAddedPages.try_emplace(rIdent, xPage, xGrid);
2693
2694 if (nPos != -1)
2695 {
2696 unsigned int nPageIndex = static_cast<unsigned int>(nPos);
2697 if (nPageIndex < m_aPages.size())
2698 m_aPages.insert(m_aPages.begin() + nPageIndex, nullptr);
2699 }
2700}
2701
2703
2704OUString SalInstanceNotebook::get_tab_label_text(const OString& rIdent) const
2705{
2706 return m_xNotebook->GetPageText(m_xNotebook->GetPageId(rIdent));
2707}
2708
2709void SalInstanceNotebook::set_tab_label_text(const OString& rIdent, const OUString& rText)
2710{
2711 return m_xNotebook->SetPageText(m_xNotebook->GetPageId(rIdent), rText);
2712}
2713
2715{
2716 m_xNotebook->set_property("show-tabs", OUString::boolean(bShow));
2717}
2718
2720{
2721 for (auto& rItem : m_aAddedPages)
2722 {
2723 rItem.second.second.disposeAndClear();
2724 rItem.second.first.disposeAndClear();
2725 }
2728}
2729
2731{
2732 return !m_aLeavePageHdl.IsSet() || m_aLeavePageHdl.Call(get_current_page_ident());
2733}
2734
2736{
2737 m_aEnterPageHdl.Call(get_current_page_ident());
2738}
2739
2740namespace
2741{
2742class SalInstanceVerticalNotebook : public SalInstanceWidget, public virtual weld::Notebook
2743{
2744private:
2745 VclPtr<VerticalTabControl> m_xNotebook;
2746 mutable std::vector<std::unique_ptr<SalInstanceContainer>> m_aPages;
2747
2748 DECL_LINK(DeactivatePageHdl, VerticalTabControl*, bool);
2749 DECL_LINK(ActivatePageHdl, VerticalTabControl*, void);
2750
2751public:
2752 SalInstanceVerticalNotebook(VerticalTabControl* pNotebook, SalInstanceBuilder* pBuilder,
2753 bool bTakeOwnership)
2754 : SalInstanceWidget(pNotebook, pBuilder, bTakeOwnership)
2755 , m_xNotebook(pNotebook)
2756 {
2757 m_xNotebook->SetActivatePageHdl(LINK(this, SalInstanceVerticalNotebook, ActivatePageHdl));
2758 m_xNotebook->SetDeactivatePageHdl(
2759 LINK(this, SalInstanceVerticalNotebook, DeactivatePageHdl));
2760 }
2761
2762 virtual int get_current_page() const override
2763 {
2764 return m_xNotebook->GetPagePos(m_xNotebook->GetCurPageId());
2765 }
2766
2767 virtual OString get_page_ident(int nPage) const override
2768 {
2769 return m_xNotebook->GetPageId(nPage);
2770 }
2771
2772 virtual OString get_current_page_ident() const override { return m_xNotebook->GetCurPageId(); }
2773
2774 virtual int get_page_index(const OString& rIdent) const override
2775 {
2776 sal_uInt16 nPageIndex = m_xNotebook->GetPagePos(rIdent);
2777 if (nPageIndex == TAB_PAGE_NOTFOUND)
2778 return -1;
2779 return nPageIndex;
2780 }
2781
2782 virtual weld::Container* get_page(const OString& rIdent) const override
2783 {
2784 int nPageIndex = get_page_index(rIdent);
2785 if (nPageIndex == -1)
2786 return nullptr;
2787 auto pChild = m_xNotebook->GetPage(rIdent);
2788 if (m_aPages.size() < nPageIndex + 1U)
2789 m_aPages.resize(nPageIndex + 1U);
2790 if (!m_aPages[nPageIndex])
2791 m_aPages[nPageIndex].reset(new SalInstanceContainer(pChild, m_pBuilder, false));
2792 return m_aPages[nPageIndex].get();
2793 }
2794
2795 virtual void set_current_page(int nPage) override
2796 {
2797 m_xNotebook->SetCurPageId(m_xNotebook->GetPageId(nPage));
2798 }
2799
2800 virtual void set_current_page(const OString& rIdent) override
2801 {
2802 m_xNotebook->SetCurPageId(rIdent);
2803 }
2804
2805 virtual void remove_page(const OString& rIdent) override
2806 {
2807 sal_uInt16 nPageIndex = m_xNotebook->GetPagePos(rIdent);
2808 if (nPageIndex == TAB_PAGE_NOTFOUND)
2809 return;
2810 m_xNotebook->RemovePage(rIdent);
2811 if (nPageIndex < m_aPages.size())
2812 m_aPages.erase(m_aPages.begin() + nPageIndex);
2813 }
2814
2815 virtual void insert_page(const OString& rIdent, const OUString& rLabel, int nPos) override
2816 {
2817 VclPtrInstance<VclGrid> xGrid(m_xNotebook->GetPageParent());
2818 xGrid->set_hexpand(true);
2819 xGrid->set_vexpand(true);
2820 m_xNotebook->InsertPage(rIdent, rLabel, Image(), "", xGrid, nPos);
2821
2822 if (nPos != -1)
2823 {
2824 unsigned int nPageIndex = static_cast<unsigned int>(nPos);
2825 if (nPageIndex < m_aPages.size())
2826 m_aPages.insert(m_aPages.begin() + nPageIndex, nullptr);
2827 }
2828 }
2829
2830 virtual int get_n_pages() const override { return m_xNotebook->GetPageCount(); }
2831
2832 virtual void set_tab_label_text(const OString& rIdent, const OUString& rText) override
2833 {
2834 return m_xNotebook->SetPageText(rIdent, rText);
2835 }
2836
2837 virtual OUString get_tab_label_text(const OString& rIdent) const override
2838 {
2839 return m_xNotebook->GetPageText(rIdent);
2840 }
2841
2842 virtual void set_show_tabs(bool /*bShow*/) override
2843 {
2844 // if someone needs this they will have to implement it in VerticalTabControl
2845 assert(false && "not implemented");
2846 }
2847
2848 virtual ~SalInstanceVerticalNotebook() override
2849 {
2852 }
2853};
2854}
2855
2856IMPL_LINK_NOARG(SalInstanceVerticalNotebook, DeactivatePageHdl, VerticalTabControl*, bool)
2857{
2858 return !m_aLeavePageHdl.IsSet() || m_aLeavePageHdl.Call(get_current_page_ident());
2859}
2860
2861IMPL_LINK_NOARG(SalInstanceVerticalNotebook, ActivatePageHdl, VerticalTabControl*, void)
2862{
2863 m_aEnterPageHdl.Call(get_current_page_ident());
2864}
2865
2867 bool bTakeOwnership)
2868 : SalInstanceWidget(pButton, pBuilder, bTakeOwnership)
2869 , m_xButton(pButton)
2870 , m_aOldClickHdl(pButton->GetClickHdl())
2871{
2872 m_xButton->SetClickHdl(LINK(this, SalInstanceButton, ClickHdl));
2873}
2874
2875void SalInstanceButton::set_label(const OUString& rText) { m_xButton->SetText(rText); }
2876
2878{
2879 m_xButton->SetImageAlign(ImageAlign::Left);
2880 if (pDevice)
2881 m_xButton->SetModeImage(createImage(*pDevice));
2882 else
2883 m_xButton->SetModeImage(Image());
2884}
2885
2886void SalInstanceButton::set_image(const css::uno::Reference<css::graphic::XGraphic>& rImage)
2887{
2888 m_xButton->SetImageAlign(ImageAlign::Left);
2889 m_xButton->SetModeImage(Image(rImage));
2890}
2891
2892void SalInstanceButton::set_from_icon_name(const OUString& rIconName)
2893{
2894 m_xButton->SetModeImage(Image(StockImage::Yes, rIconName));
2895}
2896
2898{
2899 WinBits nBits = m_xButton->GetStyle();
2900 nBits &= ~WB_WORDBREAK;
2901 if (wrap)
2902 nBits |= WB_WORDBREAK;
2903 m_xButton->SetStyle(nBits);
2904 m_xButton->queue_resize();
2905}
2906
2908{
2909 m_xButton->SetControlFont(rFont);
2910 m_xButton->Invalidate();
2911}
2912
2914{
2915 if (pDevice)
2916 m_xButton->SetCustomButtonImage(createImage(*pDevice));
2917 else
2918 m_xButton->SetCustomButtonImage(Image());
2919 m_xButton->Invalidate();
2920}
2921
2922OUString SalInstanceButton::get_label() const { return m_xButton->GetText(); }
2923
2925
2926IMPL_LINK(SalInstanceButton, ClickHdl, ::Button*, pButton, void)
2927{
2928 //if there's no handler set, disengage our intercept and
2929 //run the click again to get default behaviour for cancel/ok
2930 //etc buttons.
2931 if (!m_aClickHdl.IsSet())
2932 {
2933 pButton->SetClickHdl(m_aOldClickHdl);
2934 pButton->Click();
2935 pButton->SetClickHdl(LINK(this, SalInstanceButton, ClickHdl));
2936 return;
2937 }
2938 signal_clicked();
2939}
2940
2942{
2943 PushButton* pButton = dynamic_cast<PushButton*>(m_xDialog->get_widget_for_response(nResponse));
2944 return pButton ? new SalInstanceButton(pButton, nullptr, false) : nullptr;
2945}
2946
2947weld::Button* SalInstanceAssistant::weld_widget_for_response(int nResponse)
2948{
2949 PushButton* pButton = nullptr;
2950 if (nResponse == RET_YES)
2951 pButton = m_xWizard->m_pNextPage;
2952 else if (nResponse == RET_NO)
2953 pButton = m_xWizard->m_pPrevPage;
2954 else if (nResponse == RET_OK)
2955 pButton = m_xWizard->m_pFinish;
2956 else if (nResponse == RET_CANCEL)
2957 pButton = m_xWizard->m_pCancel;
2958 else if (nResponse == RET_HELP)
2959 pButton = m_xWizard->m_pHelp;
2960 if (pButton)
2961 return new SalInstanceButton(pButton, nullptr, false);
2962 return nullptr;
2963}
2964
2966 bool bTakeOwnership)
2967 : SalInstanceButton(pButton, pBuilder, bTakeOwnership)
2968 , m_xMenuButton(pButton)
2969 , m_nLastId(0)
2970{
2971 m_xMenuButton->SetActivateHdl(LINK(this, SalInstanceMenuButton, ActivateHdl));
2972 m_xMenuButton->SetSelectHdl(LINK(this, SalInstanceMenuButton, MenuSelectHdl));
2973 if (PopupMenu* pMenu = m_xMenuButton->GetPopupMenu())
2974 {
2976 const auto nCount = pMenu->GetItemCount();
2977 m_nLastId = nCount ? pMenu->GetItemId(nCount - 1) : 0;
2978 }
2979}
2980
2982{
2983 if (active == get_active())
2984 return;
2985 if (active)
2986 m_xMenuButton->ExecuteMenu();
2987 else
2988 m_xMenuButton->CancelMenu();
2989}
2990
2991bool SalInstanceMenuButton::get_active() const { return m_xMenuButton->InPopupMode(); }
2992
2994{
2995 //not available
2996}
2997
2998bool SalInstanceMenuButton::get_inconsistent() const { return false; }
2999
3000void SalInstanceMenuButton::insert_item(int pos, const OUString& rId, const OUString& rStr,
3001 const OUString* pIconName, VirtualDevice* pImageSurface,
3002 TriState eCheckRadioFalse)
3003{
3004 m_nLastId = insert_to_menu(m_nLastId, m_xMenuButton->GetPopupMenu(), pos, rId, rStr, pIconName,
3005 pImageSurface, nullptr, eCheckRadioFalse);
3006}
3007
3008void SalInstanceMenuButton::insert_separator(int pos, const OUString& rId)
3009{
3010 auto nInsertPos = pos == -1 ? MENU_APPEND : pos;
3011 m_xMenuButton->GetPopupMenu()->InsertSeparator(rId.toUtf8(), nInsertPos);
3012}
3013
3014void SalInstanceMenuButton::set_item_sensitive(const OString& rIdent, bool bSensitive)
3015{
3016 PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
3017 pMenu->EnableItem(rIdent, bSensitive);
3018}
3019
3021{
3022 PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
3023 pMenu->RemoveItem(pMenu->GetItemPos(pMenu->GetItemId(rId)));
3024}
3025
3027{
3028 PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
3029 pMenu->Clear();
3030}
3031
3032void SalInstanceMenuButton::set_item_active(const OString& rIdent, bool bActive)
3033{
3034 PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
3035 pMenu->CheckItem(rIdent, bActive);
3036}
3037
3038void SalInstanceMenuButton::set_item_label(const OString& rIdent, const OUString& rText)
3039{
3040 PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
3041 pMenu->SetItemText(pMenu->GetItemId(rIdent), rText);
3042}
3043
3044OUString SalInstanceMenuButton::get_item_label(const OString& rIdent) const
3045{
3046 PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
3047 return pMenu->GetItemText(pMenu->GetItemId(rIdent));
3048}
3049
3050void SalInstanceMenuButton::set_item_visible(const OString& rIdent, bool bShow)
3051{
3052 PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
3053 pMenu->ShowItem(pMenu->GetItemId(rIdent), bShow);
3054}
3055
3057{
3058 SalInstanceWidget* pPopoverWidget = dynamic_cast<SalInstanceWidget*>(pPopover);
3059 m_xMenuButton->SetPopover(pPopoverWidget ? pPopoverWidget->getWidget() : nullptr);
3060}
3061
3063{
3065 m_xMenuButton->SetActivateHdl(Link<::MenuButton*, void>());
3066}
3067
3069{
3070 signal_selected(m_xMenuButton->GetCurItemIdent());
3071}
3072
3074{
3075 if (notify_events_disabled())
3076 return;
3077 signal_toggled();
3078}
3079
3080namespace
3081{
3082class SalInstanceMenuToggleButton : public SalInstanceMenuButton,
3083 public virtual weld::MenuToggleButton
3084{
3085private:
3086 VclPtr<::MenuToggleButton> m_xMenuToggleButton;
3087
3088public:
3089 SalInstanceMenuToggleButton(::MenuToggleButton* pButton, SalInstanceBuilder* pBuilder,
3090 bool bTakeOwnership)
3091 : SalInstanceMenuButton(pButton, pBuilder, bTakeOwnership)
3092 , m_xMenuToggleButton(pButton)
3093 {
3094 m_xMenuToggleButton->SetDelayMenu(true);
3095 m_xMenuToggleButton->SetDropDown(PushButtonDropdownStyle::SplitMenuButton);
3096 }
3097
3098 virtual void set_active(bool active) override
3099 {
3101 m_xMenuToggleButton->SetActive(active);
3103 }
3104
3105 virtual bool get_active() const override { return m_xMenuToggleButton->GetActive(); }
3106};
3107}
3108
3109namespace
3110{
3111class SalInstanceLinkButton : public SalInstanceWidget, public virtual weld::LinkButton
3112{
3113private:
3114 VclPtr<FixedHyperlink> m_xButton;
3115 Link<FixedHyperlink&, void> m_aOrigClickHdl;
3116
3117 DECL_LINK(ClickHdl, FixedHyperlink&, void);
3118
3119public:
3120 SalInstanceLinkButton(FixedHyperlink* pButton, SalInstanceBuilder* pBuilder,
3121 bool bTakeOwnership)
3122 : SalInstanceWidget(pButton, pBuilder, bTakeOwnership)
3123 , m_xButton(pButton)
3124 {
3125 m_aOrigClickHdl = m_xButton->GetClickHdl();
3126 m_xButton->SetClickHdl(LINK(this, SalInstanceLinkButton, ClickHdl));
3127 }
3128
3129 virtual void set_label(const OUString& rText) override { m_xButton->SetText(rText); }
3130
3131 virtual OUString get_label() const override { return m_xButton->GetText(); }
3132
3133 virtual void set_uri(const OUString& rUri) override { m_xButton->SetURL(rUri); }
3134
3135 virtual OUString get_uri() const override { return m_xButton->GetURL(); }
3136
3137 virtual ~SalInstanceLinkButton() override { m_xButton->SetClickHdl(m_aOrigClickHdl); }
3138};
3139}
3140
3141IMPL_LINK(SalInstanceLinkButton, ClickHdl, FixedHyperlink&, rButton, void)
3142{
3143 bool bConsumed = signal_activate_link();
3144 if (!bConsumed)
3145 m_aOrigClickHdl.Call(rButton);
3146}
3147
3149 bool bTakeOwnership)
3150 : SalInstanceButton(pButton, pBuilder, bTakeOwnership)
3151 , m_xRadioButton(pButton)
3152{
3153 m_xRadioButton->SetToggleHdl(LINK(this, SalInstanceRadioButton, ToggleHdl));
3154}
3155
3157{
3159 m_xRadioButton->Check(active);
3161}
3162
3163bool SalInstanceRadioButton::get_active() const { return m_xRadioButton->IsChecked(); }
3164
3166{
3167 m_xRadioButton->SetImageAlign(ImageAlign::Center);
3168 if (pDevice)
3169 m_xRadioButton->SetModeImage(createImage(*pDevice));
3170 else
3171 m_xRadioButton->SetModeImage(Image());
3172}
3173
3174void SalInstanceRadioButton::set_image(const css::uno::Reference<css::graphic::XGraphic>& rImage)
3175{
3176 m_xRadioButton->SetImageAlign(ImageAlign::Center);
3177 m_xRadioButton->SetModeImage(Image(rImage));
3178}
3179
3180void SalInstanceRadioButton::set_from_icon_name(const OUString& rIconName)
3181{
3182 m_xRadioButton->SetModeRadioImage(Image(StockImage::Yes, rIconName));
3183}
3184
3186{
3187 //not available
3188}
3189
3190bool SalInstanceRadioButton::get_inconsistent() const { return false; }
3191
3193{
3195}
3196
3198{
3199 if (notify_events_disabled())
3200 return;
3201 signal_toggled();
3202}
3203
3204namespace
3205{
3206class SalInstanceToggleButton : public SalInstanceButton, public virtual weld::ToggleButton
3207{
3208private:
3209 VclPtr<PushButton> m_xToggleButton;
3210
3211 DECL_LINK(ToggleListener, VclWindowEvent&, void);
3212
3213public:
3214 SalInstanceToggleButton(PushButton* pButton, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3215 : SalInstanceButton(pButton, pBuilder, bTakeOwnership)
3216 , m_xToggleButton(pButton)
3217 {
3218 }
3219
3220 virtual void connect_toggled(const Link<Toggleable&, void>& rLink) override
3221 {
3222 assert(!m_aToggleHdl.IsSet());
3223 m_xToggleButton->AddEventListener(LINK(this, SalInstanceToggleButton, ToggleListener));
3225 }
3226
3227 virtual void set_active(bool active) override
3228 {
3230 m_xToggleButton->Check(active);
3232 }
3233
3234 virtual bool get_active() const override { return m_xToggleButton->IsChecked(); }
3235
3236 virtual void set_inconsistent(bool inconsistent) override
3237 {
3239 m_xToggleButton->SetState(inconsistent ? TRISTATE_INDET : TRISTATE_FALSE);
3241 }
3242
3243 virtual bool get_inconsistent() const override
3244 {
3245 return m_xToggleButton->GetState() == TRISTATE_INDET;
3246 }
3247
3248 virtual ~SalInstanceToggleButton() override
3249 {
3250 if (m_aToggleHdl.IsSet())
3251 m_xToggleButton->RemoveEventListener(
3252 LINK(this, SalInstanceToggleButton, ToggleListener));
3253 }
3254};
3255}
3256
3257IMPL_LINK(SalInstanceToggleButton, ToggleListener, VclWindowEvent&, rEvent, void)
3258{
3259 if (notify_events_disabled())
3260 return;
3261 if (rEvent.GetId() == VclEventId::PushbuttonToggle)
3262 signal_toggled();
3263}
3264
3266 bool bTakeOwnership)
3267 : SalInstanceButton(pButton, pBuilder, bTakeOwnership)
3268 , m_xCheckButton(pButton)
3269{
3271}
3272
3274{
3277 m_xCheckButton->Check(active);
3279}
3280
3282
3284{
3289}
3290
3292{
3294}
3295
3297{
3299}
3300
3302{
3303 if (notify_events_disabled())
3304 return;
3305 m_xCheckButton->EnableTriState(false);
3306 signal_toggled();
3307}
3308
3309namespace
3310{
3311class SalInstanceScale : public SalInstanceWidget, public virtual weld::Scale
3312{
3313private:
3314 VclPtr<Slider> m_xScale;
3315
3316 DECL_LINK(SlideHdl, Slider*, void);
3317
3318public:
3319 SalInstanceScale(Slider* pScale, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3320 : SalInstanceWidget(pScale, pBuilder, bTakeOwnership)
3321 , m_xScale(pScale)
3322 {
3323 m_xScale->SetSlideHdl(LINK(this, SalInstanceScale, SlideHdl));
3324 }
3325
3326 virtual void set_value(int value) override { m_xScale->SetThumbPos(value); }
3327
3328 virtual void set_range(int min, int max) override
3329 {
3330 m_xScale->SetRangeMin(min);
3331 m_xScale->SetRangeMax(max);
3332 }
3333
3334 virtual int get_value() const override { return m_xScale->GetThumbPos(); }
3335
3336 virtual void set_increments(int step, int page) override
3337 {
3338 m_xScale->SetLineSize(step);
3339 m_xScale->SetPageSize(page);
3340 }
3341
3342 virtual void get_increments(int& step, int& page) const override
3343 {
3344 step = m_xScale->GetLineSize();
3345 page = m_xScale->GetPageSize();
3346 }
3347
3348 virtual ~SalInstanceScale() override { m_xScale->SetSlideHdl(Link<Slider*, void>()); }
3349};
3350}
3351
3352IMPL_LINK_NOARG(SalInstanceScale, SlideHdl, Slider*, void) { signal_value_changed(); }
3353
3354namespace
3355{
3356class SalInstanceSpinner : public SalInstanceWidget, public virtual weld::Spinner
3357{
3358private:
3359 VclPtr<Throbber> m_xThrobber;
3360
3361public:
3362 SalInstanceSpinner(Throbber* pThrobber, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3363 : SalInstanceWidget(pThrobber, pBuilder, bTakeOwnership)
3364 , m_xThrobber(pThrobber)
3365 {
3366 }
3367
3368 virtual void start() override { m_xThrobber->start(); }
3369
3370 virtual void stop() override { m_xThrobber->stop(); }
3371};
3372
3373class SalInstanceProgressBar : public SalInstanceWidget, public virtual weld::ProgressBar
3374{
3375private:
3376 VclPtr<::ProgressBar> m_xProgressBar;
3377
3378public:
3379 SalInstanceProgressBar(::ProgressBar* pProgressBar, SalInstanceBuilder* pBuilder,
3380 bool bTakeOwnership)
3381 : SalInstanceWidget(pProgressBar, pBuilder, bTakeOwnership)
3382 , m_xProgressBar(pProgressBar)
3383 {
3384 }
3385
3386 virtual void set_percentage(int value) override { m_xProgressBar->SetValue(value); }
3387
3388 virtual OUString get_text() const override { return m_xProgressBar->GetText(); }
3389
3390 virtual void set_text(const OUString& rText) override { m_xProgressBar->SetText(rText); }
3391};
3392
3393class SalInstanceCalendar : public SalInstanceWidget, public virtual weld::Calendar
3394{
3395private:
3396 VclPtr<::Calendar> m_xCalendar;
3397
3398 DECL_LINK(SelectHdl, ::Calendar*, void);
3399 DECL_LINK(ActivateHdl, ::Calendar*, void);
3400
3401public:
3402 SalInstanceCalendar(::Calendar* pCalendar, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3403 : SalInstanceWidget(pCalendar, pBuilder, bTakeOwnership)
3404 , m_xCalendar(pCalendar)
3405 {
3406 m_xCalendar->SetSelectHdl(LINK(this, SalInstanceCalendar, SelectHdl));
3407 m_xCalendar->SetActivateHdl(LINK(this, SalInstanceCalendar, ActivateHdl));
3408 }
3409
3410 virtual void set_date(const Date& rDate) override { m_xCalendar->SetCurDate(rDate); }
3411
3412 virtual Date get_date() const override { return m_xCalendar->GetFirstSelectedDate(); }
3413
3414 virtual ~SalInstanceCalendar() override
3415 {
3416 m_xCalendar->SetSelectHdl(Link<::Calendar*, void>());
3417 m_xCalendar->SetActivateHdl(Link<::Calendar*, void>());
3418 }
3419};
3420}
3421
3422IMPL_LINK_NOARG(SalInstanceCalendar, SelectHdl, ::Calendar*, void)
3423{
3424 if (notify_events_disabled())
3425 return;
3426 signal_selected();
3427}
3428
3429IMPL_LINK_NOARG(SalInstanceCalendar, ActivateHdl, ::Calendar*, void)
3430{
3431 if (notify_events_disabled())
3432 return;
3433 signal_activated();
3434}
3435
3437 bool bTakeOwnership)
3438 : SalInstanceWidget(pImage, pBuilder, bTakeOwnership)
3439 , m_xImage(pImage)
3440{
3441}
3442
3443void SalInstanceImage::set_from_icon_name(const OUString& rIconName)
3444{
3446}
3447
3449{
3450 if (pDevice)
3451 m_xImage->SetImage(createImage(*pDevice));
3452 else
3454}
3455
3456void SalInstanceImage::set_image(const css::uno::Reference<css::graphic::XGraphic>& rImage)
3457{
3458 m_xImage->SetImage(::Image(rImage));
3459}
3460
3462 : TextFilter(OUString())
3463 , m_rInsertTextHdl(rInsertTextHdl)
3464{
3465}
3466
3467OUString WeldTextFilter::filter(const OUString& rText)
3468{
3469 if (!m_rInsertTextHdl.IsSet())
3470 return rText;
3471 OUString sText(rText);
3472 const bool bContinue = m_rInsertTextHdl.Call(sText);
3473 if (!bContinue)
3474 return OUString();
3475 return sText;
3476}
3477
3478SalInstanceEntry::SalInstanceEntry(Edit* pEntry, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3479 : SalInstanceWidget(pEntry, pBuilder, bTakeOwnership)
3480 , m_xEntry(pEntry)
3481 , m_aTextFilter(m_aInsertTextHdl)
3482{
3483 m_xEntry->SetModifyHdl(LINK(this, SalInstanceEntry, ChangeHdl));
3484 m_xEntry->SetActivateHdl(LINK(this, SalInstanceEntry, ActivateHdl));
3485 m_xEntry->SetTextFilter(&m_aTextFilter);
3486}
3487
3488void SalInstanceEntry::set_text(const OUString& rText)
3489{
3491 m_xEntry->SetText(rText);
3493}
3494
3495OUString SalInstanceEntry::get_text() const { return m_xEntry->GetText(); }
3496
3497void SalInstanceEntry::set_width_chars(int nChars) { m_xEntry->SetWidthInChars(nChars); }
3498
3499int SalInstanceEntry::get_width_chars() const { return m_xEntry->GetWidthInChars(); }
3500
3501void SalInstanceEntry::set_max_length(int nChars) { m_xEntry->SetMaxTextLen(nChars); }
3502
3503void SalInstanceEntry::select_region(int nStartPos, int nEndPos)
3504{
3506 tools::Long nStart = nStartPos < 0 ? SELECTION_MAX : nStartPos;
3507 tools::Long nEnd = nEndPos < 0 ? SELECTION_MAX : nEndPos;
3508 m_xEntry->SetSelection(Selection(nStart, nEnd));
3510}
3511
3512bool SalInstanceEntry::get_selection_bounds(int& rStartPos, int& rEndPos)
3513{
3514 const Selection& rSelection = m_xEntry->GetSelection();
3515 rStartPos = rSelection.Min();
3516 rEndPos = rSelection.Max();
3517 return rSelection.Len();
3518}
3519
3520void SalInstanceEntry::replace_selection(const OUString& rText)
3521{
3522 m_xEntry->ReplaceSelected(rText);
3523}
3524
3526{
3528 if (nCursorPos < 0)
3529 m_xEntry->SetCursorAtLast();
3530 else
3531 m_xEntry->SetSelection(Selection(nCursorPos, nCursorPos));
3533}
3534
3535int SalInstanceEntry::get_position() const { return m_xEntry->GetSelection().Max(); }
3536
3537void SalInstanceEntry::set_editable(bool bEditable) { m_xEntry->SetReadOnly(!bEditable); }
3538
3539bool SalInstanceEntry::get_editable() const { return !m_xEntry->IsReadOnly(); }
3540
3541void SalInstanceEntry::set_overwrite_mode(bool bOn) { m_xEntry->SetInsertMode(!bOn); }
3542
3543bool SalInstanceEntry::get_overwrite_mode() const { return !m_xEntry->IsInsertMode(); }
3544
3545namespace
3546{
3547void set_message_type(Edit* pEntry, weld::EntryMessageType eType)
3548{
3549 switch (eType)
3550 {
3552 pEntry->SetForceControlBackground(false);
3553 pEntry->SetControlForeground();
3554 pEntry->SetControlBackground();
3555 break;
3557 // tdf#114603: enable setting the background to a different color;
3558 // relevant for GTK; see also #i75179#
3559 pEntry->SetForceControlBackground(true);
3560 pEntry->SetControlForeground(COL_BLACK);
3561 pEntry->SetControlBackground(COL_YELLOW);
3562 break;
3564 // tdf#114603: enable setting the background to a different color;
3565 // relevant for GTK; see also #i75179#
3566 pEntry->SetForceControlBackground(true);
3567 pEntry->SetControlForeground(COL_WHITE);
3568 pEntry->SetControlBackground(0xff6563);
3569 break;
3570 }
3571}
3572}
3573
3575{
3577}
3578
3580{
3581 m_xEntry->SetControlFont(rFont);
3582 m_xEntry->Invalidate();
3583}
3584
3586{
3587 if (rColor == COL_AUTO)
3588 m_xEntry->SetControlForeground();
3589 else
3590 m_xEntry->SetControlForeground(rColor);
3591}
3592
3594{
3595 assert(!m_aCursorPositionHdl.IsSet());
3596 m_xEntry->AddEventListener(LINK(this, SalInstanceEntry, CursorListener));
3598}
3599
3601{
3602 m_xEntry->SetPlaceholderText(rText);
3603}
3604
3606
3608
3610{
3611 m_xEntry->Cut();
3612 m_xEntry->Modify();
3613}
3614
3616
3618{
3619 m_xEntry->Paste();
3620 m_xEntry->Modify();
3621}
3622
3623namespace
3624{
3625void set_alignment(Edit& rEntry, TxtAlign eXAlign)
3626{
3627 WinBits nAlign(0);
3628 switch (eXAlign)
3629 {
3630 case TxtAlign::Left:
3631 nAlign = WB_LEFT;
3632 break;
3633 case TxtAlign::Center:
3634 nAlign = WB_CENTER;
3635 break;
3636 case TxtAlign::Right:
3637 nAlign = WB_RIGHT;
3638 break;
3639 }
3640 WinBits nBits = rEntry.GetStyle();
3641 nBits &= ~(WB_LEFT | WB_CENTER | WB_RIGHT);
3642 rEntry.SetStyle(nBits | nAlign);
3643}
3644}
3645
3647
3649{
3650 if (m_aCursorPositionHdl.IsSet())
3651 m_xEntry->RemoveEventListener(LINK(this, SalInstanceEntry, CursorListener));
3652 m_xEntry->SetTextFilter(nullptr);
3653 m_xEntry->SetActivateHdl(Link<Edit&, bool>());
3654 m_xEntry->SetModifyHdl(Link<Edit&, void>());
3655}
3656
3657IMPL_LINK_NOARG(SalInstanceEntry, ChangeHdl, Edit&, void) { signal_changed(); }
3658
3659IMPL_LINK(SalInstanceEntry, CursorListener, VclWindowEvent&, rEvent, void)
3660{
3661 if (notify_events_disabled())
3662 return;
3663 if (rEvent.GetId() == VclEventId::EditSelectionChanged
3664 || rEvent.GetId() == VclEventId::EditCaretChanged)
3665 signal_cursor_position();
3666}
3667
3668IMPL_LINK_NOARG(SalInstanceEntry, ActivateHdl, Edit&, bool) { return m_aActivateHdl.Call(*this); }
3669
3671
3673
3674namespace
3675{
3676// tdf#131581 if the TreeView is hidden then there are possibly additional
3677// optimizations available
3678class UpdateGuardIfHidden
3679{
3680private:
3681 SvTabListBox& m_rTreeView;
3682 bool m_bOrigUpdate;
3683 bool m_bOrigEnableInvalidate;
3684
3685public:
3686 UpdateGuardIfHidden(SvTabListBox& rTreeView)
3687 : m_rTreeView(rTreeView)
3688 // tdf#136962 only do SetUpdateMode(false) optimization if the widget is currently hidden
3689 , m_bOrigUpdate(!m_rTreeView.IsVisible() && m_rTreeView.IsUpdateMode())
3690 // tdf#137432 only do EnableInvalidate(false) optimization if the widget is currently hidden
3691 , m_bOrigEnableInvalidate(!m_rTreeView.IsVisible()
3692 && m_rTreeView.GetModel()->IsEnableInvalidate())
3693 {
3694 if (m_bOrigUpdate)
3695 m_rTreeView.SetUpdateMode(false);
3696 if (m_bOrigEnableInvalidate)
3697 m_rTreeView.GetModel()->EnableInvalidate(false);
3698 }
3699
3700 ~UpdateGuardIfHidden()
3701 {
3702 if (m_bOrigEnableInvalidate)
3703 m_rTreeView.GetModel()->EnableInvalidate(true);
3704 if (m_bOrigUpdate)
3705 m_rTreeView.SetUpdateMode(true);
3706 }
3707};
3708}
3709
3710// Each row has a cell for the expander image, (and an optional cell for a
3711// checkbutton if enable_toggle_buttons has been called) which precede
3712// index 0
3714{
3716 ++col; // skip checkbutton column
3717 ++col; //skip expander column
3718 return col;
3719}
3720
3722{
3724 --col; // skip checkbutton column
3725 --col; //skip expander column
3726 return col;
3727}
3728
3730{
3731 return o3tl::trim(m_xTreeView->GetEntryText(pEntry)) == u"<dummy>";
3732}
3733
3735{
3736 if (pEntry->HasChildren())
3737 {
3738 auto pChild = m_xTreeView->FirstChild(pEntry);
3739 assert(pChild);
3740 if (IsDummyEntry(pChild))
3741 return pChild;
3742 }
3743 return nullptr;
3744}
3745
3747{
3748 if (rColor == COL_AUTO)
3749 pEntry->SetTextColor(std::optional<Color>());
3750 else
3751 pEntry->SetTextColor(rColor);
3752}
3753
3754void SalInstanceTreeView::AddStringItem(SvTreeListEntry* pEntry, const OUString& rStr, int nCol)
3755{
3756 auto xCell = std::make_unique<SvLBoxString>(rStr);
3757 if (m_aCustomRenders.count(nCol))
3758 xCell->SetCustomRender();
3759 pEntry->AddItem(std::move(xCell));
3760}
3761
3762void SalInstanceTreeView::do_insert(const weld::TreeIter* pParent, int pos, const OUString* pStr,
3763 const OUString* pId, const OUString* pIconName,
3764 const VirtualDevice* pImageSurface, bool bChildrenOnDemand,
3765 weld::TreeIter* pRet, bool bIsSeparator)
3766{
3768 const SalInstanceTreeIter* pVclIter = static_cast<const SalInstanceTreeIter*>(pParent);
3769 SvTreeListEntry* iter = pVclIter ? pVclIter->iter : nullptr;
3770 auto nInsertPos = pos == -1 ? TREELIST_APPEND : pos;
3771 void* pUserData;
3772 if (pId)
3773 {
3774 m_aUserData.emplace_back(std::make_unique<OUString>(*pId));
3775 pUserData = m_aUserData.back().get();
3776 }
3777 else
3778 pUserData = nullptr;
3779
3780 SvTreeListEntry* pEntry = new SvTreeListEntry;
3781 if (bIsSeparator)
3782 pEntry->SetFlags(pEntry->GetFlags() | SvTLEntryFlags::IS_SEPARATOR);
3783
3785 AddStringItem(pEntry, "", -1);
3786
3787 if (pIconName || pImageSurface)
3788 {
3789 Image aImage(pIconName ? createImage(*pIconName) : createImage(*pImageSurface));
3790 pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(aImage, aImage, false));
3791 }
3792 else
3793 {
3794 Image aDummy;
3795 pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(aDummy, aDummy, false));
3796 }
3797 if (pStr)
3798 AddStringItem(pEntry, *pStr, 0);
3799 pEntry->SetUserData(pUserData);
3800 m_xTreeView->Insert(pEntry, iter, nInsertPos);
3801
3802 if (pRet)
3803 {
3804 SalInstanceTreeIter* pVclRetIter = static_cast<SalInstanceTreeIter*>(pRet);
3805 pVclRetIter->iter = pEntry;
3806 }
3807
3808 if (bChildrenOnDemand)
3809 {
3810 SvTreeListEntry* pPlaceHolder
3811 = m_xTreeView->InsertEntry("<dummy>", pEntry, false, 0, nullptr);
3812 SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pPlaceHolder);
3813 pViewData->SetSelectable(false);
3814 }
3815
3816 if (bIsSeparator)
3817 {
3818 SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry);
3819 pViewData->SetSelectable(false);
3820 }
3821
3823}
3824
3826{
3827 SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry);
3828 m_xTreeView->InitViewData(pViewData, pEntry);
3830}
3831
3833{
3835 return;
3837}
3838
3840{
3841 assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
3842 // if it's the placeholder to allow a blank column, replace it now
3843 if (pEntry->GetItem(col).GetType() != SvLBoxItemType::Button)
3844 {
3846 pEntry->ReplaceItem(std::make_unique<SvLBoxButton>(pData), 0);
3848 }
3849 SvLBoxItem& rItem = pEntry->GetItem(col);
3850 assert(dynamic_cast<SvLBoxButton*>(&rItem));
3851 switch (eState)
3852 {
3853 case TRISTATE_TRUE:
3854 static_cast<SvLBoxButton&>(rItem).SetStateChecked();
3855 break;
3856 case TRISTATE_FALSE:
3857 static_cast<SvLBoxButton&>(rItem).SetStateUnchecked();
3858 break;
3859 case TRISTATE_INDET:
3860 static_cast<SvLBoxButton&>(rItem).SetStateTristate();
3861 break;
3862 }
3863
3864 InvalidateModelEntry(pEntry);
3865}
3866
3868{
3869 if (static_cast<size_t>(col) == pEntry->ItemCount())
3870 return TRISTATE_FALSE;
3871
3872 assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
3873 SvLBoxItem& rItem = pEntry->GetItem(col);
3874 assert(dynamic_cast<SvLBoxButton*>(&rItem));
3875 SvLBoxButton& rToggle = static_cast<SvLBoxButton&>(rItem);
3876 if (rToggle.IsStateTristate())
3877 return TRISTATE_INDET;
3878 else if (rToggle.IsStateChecked())
3879 return TRISTATE_TRUE;
3880 return TRISTATE_FALSE;
3881}
3882
3884{
3885 if (col == -1)
3886 {
3888 return do_get_toggle(pEntry, 0);
3889 }
3891 return do_get_toggle(pEntry, col);
3892}
3893
3895{
3896 if (col == -1)
3897 {
3899 do_set_toggle(pEntry, eState, 0);
3900 return;
3901 }
3902
3904
3905 // blank out missing entries
3906 for (int i = pEntry->ItemCount(); i < col; ++i)
3907 AddStringItem(pEntry, "", i - 1);
3908
3909 if (static_cast<size_t>(col) == pEntry->ItemCount())
3910 {
3912 pEntry->AddItem(std::make_unique<SvLBoxButton>(pData));
3914 }
3915
3916 do_set_toggle(pEntry, eState, col);
3917}
3918
3920{
3922
3923 assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
3924 SvLBoxItem& rItem = pEntry->GetItem(col);
3925 assert(dynamic_cast<SvLBoxString*>(&rItem));
3926 return static_cast<SvLBoxString&>(rItem).IsEmphasized();
3927}
3928
3929void SalInstanceTreeView::set_header_item_width(const std::vector<int>& rWidths)
3930{
3931 LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
3932 if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
3933 {
3934 for (size_t i = 0; i < rWidths.size(); ++i)
3935 pHeaderBar->SetItemSize(pHeaderBar->GetItemId(i), rWidths[i]);
3936 }
3937}
3938
3940 bool bTakeOwnership)
3941 : SalInstanceWidget(pTreeView, pBuilder, bTakeOwnership)
3942 , m_xTreeView(pTreeView)
3943 , m_aCheckButtonData(pTreeView, false)
3944 , m_aRadioButtonData(pTreeView, true)
3945 , m_bTogglesAsRadio(false)
3946 , m_nSortColumn(-1)
3947{
3951 m_xTreeView->SetDeselectHdl(LINK(this, SalInstanceTreeView, DeSelectHdl));
3952 m_xTreeView->SetDoubleClickHdl(LINK(this, SalInstanceTreeView, DoubleClickHdl));
3953 m_xTreeView->SetExpandingHdl(LINK(this, SalInstanceTreeView, ExpandingHdl));
3954 m_xTreeView->SetPopupMenuHdl(LINK(this, SalInstanceTreeView, PopupMenuHdl));
3955 m_xTreeView->SetCustomRenderHdl(LINK(this, SalInstanceTreeView, CustomRenderHdl));
3956 m_xTreeView->SetCustomMeasureHdl(LINK(this, SalInstanceTreeView, CustomMeasureHdl));
3957 const tools::Long aTabPositions[] = { 0 };
3958 m_xTreeView->SetTabs(SAL_N_ELEMENTS(aTabPositions), aTabPositions);
3959 LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
3960
3961 if (pHeaderBox)
3962 {
3963 if (HeaderBar* pHeaderBar = pHeaderBox->GetHeaderBar())
3964 {
3965 //make the last entry fill available space
3966 pHeaderBar->SetItemSize(pHeaderBar->GetItemId(pHeaderBar->GetItemCount() - 1),
3968 pHeaderBar->SetEndDragHdl(LINK(this, SalInstanceTreeView, EndDragHdl));
3969 pHeaderBar->SetSelectHdl(LINK(this, SalInstanceTreeView, HeaderBarClickedHdl));
3970 }
3971 pHeaderBox->SetEditingEntryHdl(LINK(this, SalInstanceTreeView, EditingEntryHdl));
3972 pHeaderBox->SetEditedEntryHdl(LINK(this, SalInstanceTreeView, EditedEntryHdl));
3973 }
3974 else
3975 {
3976 static_cast<LclTabListBox&>(*m_xTreeView)
3977 .SetModelChangedHdl(LINK(this, SalInstanceTreeView, ModelChangedHdl));
3978 static_cast<LclTabListBox&>(*m_xTreeView)
3979 .SetStartDragHdl(LINK(this, SalInstanceTreeView, StartDragHdl));
3980 static_cast<LclTabListBox&>(*m_xTreeView)
3981 .SetEndDragHdl(LINK(this, SalInstanceTreeView, FinishDragHdl));
3982 static_cast<LclTabListBox&>(*m_xTreeView)
3983 .SetEditingEntryHdl(LINK(this, SalInstanceTreeView, EditingEntryHdl));
3984 static_cast<LclTabListBox&>(*m_xTreeView)
3985 .SetEditedEntryHdl(LINK(this, SalInstanceTreeView, EditedEntryHdl));
3986 }
3989}
3990
3992{
3995}
3996
3998{
3999 std::vector<tools::Long> aWidths;
4001 if (aWidths.size() > 2)
4002 {
4003 std::vector<int> aColWidths;
4004 for (size_t i = 1; i < aWidths.size() - 1; ++i)
4005 aColWidths.push_back(aWidths[i] - aWidths[i - 1]);
4006 set_column_fixed_widths(aColWidths);
4007 }
4008}
4009
4011{
4012 bool bIsFirstFreeze = IsFirstFreeze();
4014 if (bIsFirstFreeze)
4015 {
4016 m_xTreeView->SetUpdateMode(false);
4018 }
4019}
4020
4022{
4023 bool bIsLastThaw = IsLastThaw();
4024 if (bIsLastThaw)
4025 {
4028 }
4030}
4031
4032void SalInstanceTreeView::set_column_fixed_widths(const std::vector<int>& rWidths)
4033{
4034 std::vector<tools::Long> aTabPositions{ 0 };
4035 for (size_t i = 0; i < rWidths.size(); ++i)
4036 aTabPositions.push_back(aTabPositions[i] + rWidths[i]);
4037 m_xTreeView->SetTabs(aTabPositions.size(), aTabPositions.data(), MapUnit::MapPixel);
4038 set_header_item_width(rWidths);
4039 // call Resize to recalculate based on the new tabs
4041}
4042
4043void SalInstanceTreeView::set_column_editables(const std::vector<bool>& rEditables)
4044{
4045 size_t nTabCount = rEditables.size();
4046 for (size_t i = 0; i < nTabCount; ++i)
4047 m_xTreeView->SetTabEditable(i, rEditables[i]);
4048}
4049
4051{
4053}
4054
4056{
4057 LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
4058 if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
4059 return pHeaderBar->GetItemSize(pHeaderBar->GetItemId(nColumn));
4060 // GetTab(0) gives the position of the bitmap which is automatically inserted by the TabListBox.
4061 // So the first text column's width is Tab(2)-Tab(1).
4062 auto nWidthPixel
4063 = m_xTreeView->GetLogicTab(nColumn + 2) - m_xTreeView->GetLogicTab(nColumn + 1);
4064 nWidthPixel -= SV_TAB_BORDER;
4065 return nWidthPixel;
4066}
4067
4068OUString SalInstanceTreeView::get_column_title(int nColumn) const
4069{
4070 LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
4071 if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
4072 {
4073 return pHeaderBar->GetItemText(pHeaderBar->GetItemId(nColumn));
4074 }
4075 return OUString();
4076}
4077
4078void SalInstanceTreeView::set_column_title(int nColumn, const OUString& rTitle)
4079{
4080 LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
4081 if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
4082 {
4083 return pHeaderBar->SetItemText(pHeaderBar->GetItemId(nColumn), rTitle);
4084 }
4085}
4086
4088{
4089 assert(n_children() == 0 && "tree must be empty");
4090 if (bEnable)
4091 m_aCustomRenders.insert(nColumn);
4092 else
4093 m_aCustomRenders.erase(nColumn);
4094}
4095
4097{
4098 // invalidate the entries
4099 SvTreeList* pModel = m_xTreeView->GetModel();
4100 for (SvTreeListEntry* pEntry = m_xTreeView->First(); pEntry; pEntry = m_xTreeView->Next(pEntry))
4101 pModel->InvalidateEntry(pEntry);
4102}
4103
4105{
4106 if (LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get()))
4107 pHeaderBox->GetParent()->Show();
4109}
4110
4112{
4113 if (LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get()))
4114 pHeaderBox->GetParent()->Hide();
4116}
4117
4118void SalInstanceTreeView::insert(const weld::TreeIter* pParent, int pos, const OUString* pStr,
4119 const OUString* pId, const OUString* pIconName,
4120 VirtualDevice* pImageSurface, bool bChildrenOnDemand,
4121 weld::TreeIter* pRet)
4122{
4123 do_insert(pParent, pos, pStr, pId, pIconName, pImageSurface, bChildrenOnDemand, pRet, false);
4124}
4125
4126void SalInstanceTreeView::insert_separator(int pos, const OUString& /*rId*/)
4127{
4128 OUString sSep(VclResId(STR_SEPARATOR));
4129 do_insert(nullptr, pos, &sSep, nullptr, nullptr, nullptr, false, nullptr, true);
4130}
4131
4133 int nSourceCount, const std::function<void(weld::TreeIter&, int nSourceIndex)>& func,
4134 const weld::TreeIter* pParent, const std::vector<int>* pFixedWidths)
4135{
4136 const SalInstanceTreeIter* pVclIter = static_cast<const SalInstanceTreeIter*>(pParent);
4137 SvTreeListEntry* pVclParent = pVclIter ? pVclIter->iter : nullptr;
4138
4139 freeze();
4140 if (!pVclParent)
4141 clear();
4142 else
4143 {
4144 while (SvTreeListEntry* pChild = m_xTreeView->FirstChild(pVclParent))
4145 m_xTreeView->RemoveEntry(pChild);
4146 }
4147 SalInstanceTreeIter aVclIter(static_cast<SvTreeListEntry*>(nullptr));
4148
4150
4151 if (pFixedWidths)
4152 set_header_item_width(*pFixedWidths);
4153
4154 bool bHasAutoCheckButton(m_xTreeView->nTreeFlags & SvTreeFlags::CHKBTN);
4155 size_t nExtraCols = bHasAutoCheckButton ? 2 : 1;
4156
4157 Image aDummy;
4158 for (int i = 0; i < nSourceCount; ++i)
4159 {
4160 aVclIter.iter = new SvTreeListEntry;
4161 if (bHasAutoCheckButton)
4162 AddStringItem(aVclIter.iter, "", -1);
4163 aVclIter.iter->AddItem(std::make_unique<SvLBoxContextBmp>(aDummy, aDummy, false));
4164 m_xTreeView->Insert(aVclIter.iter, pVclParent, TREELIST_APPEND);
4165 func(aVclIter, i);
4166
4167 if (!pFixedWidths)
4168 continue;
4169
4170 size_t nFixedWidths = std::min(pFixedWidths->size(), aVclIter.iter->ItemCount());
4171 for (size_t j = 0; j < nFixedWidths; ++j)
4172 {
4173 SvLBoxItem& rItem = aVclIter.iter->GetItem(j + nExtraCols);
4174 SvViewDataItem* pViewDataItem = m_xTreeView->GetViewDataItem(aVclIter.iter, &rItem);
4175 pViewDataItem->mnWidth = (*pFixedWidths)[j];
4176 }
4177 }
4178
4180
4181 thaw();
4182}
4183
4184void SalInstanceTreeView::set_font_color(int pos, const Color& rColor)
4185{
4186 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4187 set_font_color(pEntry, rColor);
4188}
4189
4191{
4192 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4193 set_font_color(rVclIter.iter, rColor);
4194}
4195
4197{
4199 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4200 m_xTreeView->RemoveEntry(pEntry);
4202}
4203
4204int SalInstanceTreeView::find_text(const OUString& rText) const
4205{
4206 for (SvTreeListEntry* pEntry = m_xTreeView->First(); pEntry; pEntry = m_xTreeView->Next(pEntry))
4207 {
4208 if (SvTabListBox::GetEntryText(pEntry, 0) == rText)
4209 return SvTreeList::GetRelPos(pEntry);
4210 }
4211 return -1;
4212}
4213
4214int SalInstanceTreeView::find_id(const OUString& rId) const
4215{
4216 for (SvTreeListEntry* pEntry = m_xTreeView->First(); pEntry; pEntry = m_xTreeView->Next(pEntry))
4217 {
4218 const OUString* pId = static_cast<const OUString*>(pEntry->GetUserData());
4219 if (!pId)
4220 continue;
4221 if (rId == *pId)
4222 return SvTreeList::GetRelPos(pEntry);
4223 }
4224 return -1;
4225}
4226
4227void SalInstanceTreeView::swap(int pos1, int pos2)
4228{
4229 int min = std::min(pos1, pos2);
4230 int max = std::max(pos1, pos2);
4231 SvTreeList* pModel = m_xTreeView->GetModel();
4232 SvTreeListEntry* pEntry1 = pModel->GetEntry(nullptr, min);
4233 SvTreeListEntry* pEntry2 = pModel->GetEntry(nullptr, max);
4234 pModel->Move(pEntry1, pEntry2);
4235}
4236
4238{
4240 m_xTreeView->Clear();
4241 m_aUserData.clear();
4243}
4244
4246{
4247 return m_xTreeView->GetModel()->GetChildList(nullptr).size();
4248}
4249
4251{
4252 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4253 return m_xTreeView->GetModel()->GetChildList(rVclIter.iter).size();
4254}
4255
4257{
4258 assert(m_xTreeView->IsUpdateMode()
4259 && "don't select when frozen, select after thaw. Note selection doesn't survive a "
4260 "freeze");
4262 if (pos == -1 || (pos == 0 && n_children() == 0))
4263 m_xTreeView->SelectAll(false);
4264 else
4265 {
4266 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4267 assert(pEntry && "bad pos?");
4268 m_xTreeView->Select(pEntry, true);
4269 m_xTreeView->MakeVisible(pEntry);
4270 }
4272}
4273
4275{
4277 if (!pEntry)
4278 return -1;
4279 return SvTreeList::GetRelPos(pEntry);
4280}
4281
4283{
4285 if (pos == -1)
4286 m_xTreeView->SetCurEntry(nullptr);
4287 else
4288 {
4289 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4290 m_xTreeView->SetCurEntry(pEntry);
4291 }
4293}
4294
4296{
4297 assert(m_xTreeView->IsUpdateMode()
4298 && "don't select when frozen, select after thaw. Note selection doesn't survive a "
4299 "freeze");
4301 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4302 m_xTreeView->MakeVisible(pEntry);
4304}
4305
4307{
4308 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4309 return m_xTreeView->IsSelected(pEntry);
4310}
4311
4313{
4314 assert(m_xTreeView->IsUpdateMode()
4315 && "don't select when frozen, select after thaw. Note selection doesn't survive a "
4316 "freeze");
4318 if (pos == -1)
4319 m_xTreeView->SelectAll(true);
4320 else
4321 {
4322 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4323 m_xTreeView->Select(pEntry, false);
4324 }
4326}
4327
4329{
4330 std::vector<int> aRows;
4331
4332 aRows.reserve(m_xTreeView->GetSelectionCount());
4333 for (SvTreeListEntry* pEntry = m_xTreeView->FirstSelected(); pEntry;
4334 pEntry = m_xTreeView->NextSelected(pEntry))
4335 aRows.push_back(SvTreeList::GetRelPos(pEntry));
4336
4337 return aRows;
4338}
4339
4340OUString SalInstanceTreeView::get_text(SvTreeListEntry* pEntry, int col) const
4341{
4342 if (col == -1)
4343 return SvTabListBox::GetEntryText(pEntry, 0);
4344
4346
4347 if (static_cast<size_t>(col) == pEntry->ItemCount())
4348 return OUString();
4349
4350 assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
4351 SvLBoxItem& rItem = pEntry->GetItem(col);
4352 assert(dynamic_cast<SvLBoxString*>(&rItem));
4353 return static_cast<SvLBoxString&>(rItem).GetText();
4354}
4355
4356OUString SalInstanceTreeView::get_text(int pos, int col) const
4357{
4358 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4359 return get_text(pEntry, col);
4360}
4361
4362void SalInstanceTreeView::set_text(SvTreeListEntry* pEntry, const OUString& rText, int col)
4363{
4364 if (col == -1)
4365 {
4366 m_xTreeView->SetEntryText(pEntry, rText);
4367 return;
4368 }
4369
4371
4372 // blank out missing entries
4373 for (int i = pEntry->ItemCount(); i < col; ++i)
4374 AddStringItem(pEntry, "", i - 1);
4375
4376 if (static_cast<size_t>(col) == pEntry->ItemCount())
4377 {
4378 AddStringItem(pEntry, rText, col - 1);
4379 SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry);
4380 m_xTreeView->InitViewData(pViewData, pEntry);
4381 }
4382 else
4383 {
4384 assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
4385 SvLBoxItem& rItem = pEntry->GetItem(col);
4386 assert(dynamic_cast<SvLBoxString*>(&rItem));
4387 static_cast<SvLBoxString&>(rItem).SetText(rText);
4388 }
4389
4390 InvalidateModelEntry(pEntry);
4391}
4392
4393void SalInstanceTreeView::set_text(int pos, const OUString& rText, int col)
4394{
4395 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4396 set_text(pEntry, rText, col);
4397}
4398
4399void SalInstanceTreeView::set_sensitive(SvTreeListEntry* pEntry, bool bSensitive, int col)
4400{
4401 if (col == -1)
4402 {
4403 auto nFlags = pEntry->GetFlags() & ~SvTLEntryFlags::SEMITRANSPARENT;
4404 if (!bSensitive)
4405 nFlags = nFlags | SvTLEntryFlags::SEMITRANSPARENT;
4406 pEntry->SetFlags(nFlags);
4407 const sal_uInt16 nCount = pEntry->ItemCount();
4408 for (sal_uInt16 nCur = 0; nCur < nCount; ++nCur)
4409 {
4410 SvLBoxItem& rItem = pEntry->GetItem(nCur);
4411 if (rItem.GetType() == SvLBoxItemType::String
4412 || rItem.GetType() == SvLBoxItemType::Button
4413 || rItem.GetType() == SvLBoxItemType::ContextBmp)
4414 {
4415 rItem.Enable(bSensitive);
4416 InvalidateModelEntry(pEntry);
4417 }
4418 }
4419 return;
4420 }
4421
4423
4424 assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
4425 SvLBoxItem& rItem = pEntry->GetItem(col);
4426 rItem.Enable(bSensitive);
4427
4428 InvalidateModelEntry(pEntry);
4429}
4430
4432{
4433 if (static_cast<size_t>(col) == pEntry->ItemCount())
4434 return false;
4435
4436 assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
4437 SvLBoxItem& rItem = pEntry->GetItem(col);
4438 return rItem.isEnable();
4439}
4440
4442{
4444 return do_get_sensitive(pEntry, col);
4445}
4446
4447void SalInstanceTreeView::set_sensitive(int pos, bool bSensitive, int col)
4448{
4449 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4450 set_sensitive(pEntry, bSensitive, col);
4451}
4452
4453bool SalInstanceTreeView::get_sensitive(int pos, int col) const
4454{
4455 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4456 return get_sensitive(pEntry, col);
4457}
4458
4459void SalInstanceTreeView::set_sensitive(const weld::TreeIter& rIter, bool bSensitive, int col)
4460{
4461 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4462 set_sensitive(rVclIter.iter, bSensitive, col);
4463}
4464
4466{
4467 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4468 return get_sensitive(rVclIter.iter, col);
4469}
4470
4472{
4473 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4474 return get_toggle(pEntry, col);
4475}
4476
4478{
4479 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4480 return get_toggle(rVclIter.iter, col);
4481}
4482
4484{
4485 assert(n_children() == 0 && "tree must be empty");
4487
4490 // EnableCheckButton clobbered this, restore it
4491 pData->SetLink(LINK(this, SalInstanceTreeView, ToggleHdl));
4492}
4493
4494void SalInstanceTreeView::set_toggle(int pos, TriState eState, int col)
4495{
4496 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4497 set_toggle(pEntry, eState, col);
4498}
4499
4501{
4502 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4503 set_toggle(rVclIter.iter, eState, col);
4504}
4505
4507{
4508 m_xTreeView->SetClicksToToggle(nToggleBehavior);
4509}
4510
4512{
4513 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4514 rVclIter.iter->SetExtraIndent(nIndentLevel);
4515}
4516
4518{
4520
4521 assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
4522 SvLBoxItem& rItem = pEntry->GetItem(col);
4523 assert(dynamic_cast<SvLBoxString*>(&rItem));
4524 static_cast<SvLBoxString&>(rItem).Emphasize(bOn);
4525
4526 InvalidateModelEntry(pEntry);
4527}
4528
4529void SalInstanceTreeView::set_text_emphasis(const weld::TreeIter& rIter, bool bOn, int col)
4530{
4531 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4532 set_text_emphasis(rVclIter.iter, bOn, col);
4533}
4534
4535void SalInstanceTreeView::set_text_emphasis(int pos, bool bOn, int col)
4536{
4537 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4538 set_text_emphasis(pEntry, bOn, col);
4539}
4540
4542{
4543 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4544 return get_text_emphasis(rVclIter.iter, col);
4545}
4546
4547bool SalInstanceTreeView::get_text_emphasis(int pos, int col) const
4548{
4549 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4550 return get_text_emphasis(pEntry, col);
4551}
4552
4553void SalInstanceTreeView::set_text_align(SvTreeListEntry* pEntry, double fAlign, int col)
4554{
4556
4557 assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
4558 SvLBoxItem& rItem = pEntry->GetItem(col);
4559 assert(dynamic_cast<SvLBoxString*>(&rItem));
4560 static_cast<SvLBoxString&>(rItem).Align(fAlign);
4561
4562 InvalidateModelEntry(pEntry);
4563}
4564
4565void SalInstanceTreeView::set_text_align(const weld::TreeIter& rIter, double fAlign, int col)
4566{
4567 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4568 set_text_align(rVclIter.iter, fAlign, col);
4569}
4570
4571void SalInstanceTreeView::set_text_align(int pos, double fAlign, int col)
4572{
4573 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4574 set_text_align(pEntry, fAlign, col);
4575}
4576
4578 const Link<const iter_string&, bool>& rEndLink)
4579{
4580 m_xTreeView->EnableInplaceEditing(rStartLink.IsSet() || rEndLink.IsSet());
4581 weld::TreeView::connect_editing(rStartLink, rEndLink);
4582}
4583
4585{
4586 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4587 m_xTreeView->EditEntry(rVclIter.iter);
4588}
4589
4591
4592void SalInstanceTreeView::set_image(SvTreeListEntry* pEntry, const Image& rImage, int col)
4593{
4594 if (col == -1)
4595 {
4596 m_xTreeView->