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{
246 if (!m_bEventListener)
247 {
248 m_xWidget->AddEventListener(LINK(this, SalInstanceWidget, EventListener));
249 m_bEventListener = true;
250 }
251}
252
253// we want the ability to mark key events as handled, so use this variant
254// for those, we get all keystrokes in this case, so we will need to filter
255// them later
257{
259 {
260 Application::AddKeyListener(LINK(this, SalInstanceWidget, KeyEventListener));
261 m_bKeyEventListener = true;
262 }
263}
264
265// we want the ability to know about mouse events that happen in our children
266// so use this variant, we will need to filter them later
268{
270 {
271 m_xWidget->AddChildEventListener(LINK(this, SalInstanceWidget, MouseEventListener));
273 }
274}
275
277{
281 {
282 // turn off WB_CLIPCHILDREN otherwise the bg won't extend "under"
283 // transparent children of the widget e.g. expander in sidebar panel header
285 // and toggle mbClipChildren on instead otherwise the bg won't fill e.g.
286 // deck titlebar header when its width is stretched
288 pImpl->mbClipChildren = true;
289 }
290}
291
293 bool bTakeOwnership)
294 : m_xWidget(pWidget)
295 , m_pBuilder(pBuilder)
296 , m_bTakeOwnership(bTakeOwnership)
297 , m_bEventListener(false)
298 , m_bKeyEventListener(false)
299 , m_bMouseEventListener(false)
300 , m_nBlockNotify(0)
301 , m_nFreezeCount(0)
302{
303}
304
305void SalInstanceWidget::set_sensitive(bool sensitive) { m_xWidget->Enable(sensitive); }
306
308
310
312
314{
315 auto nStyle = m_xWidget->GetStyle() & ~(WB_TABSTOP | WB_NOTABSTOP);
316 if (bCanFocus)
317 nStyle |= WB_TABSTOP;
318 else
319 nStyle |= WB_NOTABSTOP;
320 m_xWidget->SetStyle(nStyle);
321}
322
324{
325 if (has_focus())
326 return;
328}
329
331
333
335
337
339
340void SalInstanceWidget::set_size_request(int nWidth, int nHeight)
341{
344}
345
347{
349}
350
352
354{
356}
357
359
360Size SalInstanceWidget::get_pixel_size(const OUString& rText) const
361{
362 //TODO, or do I want GetTextBoundRect ?, just using width at the moment anyway
364}
365
367
368OString SalInstanceWidget::get_buildable_name() const { return m_xWidget->get_id().toUtf8(); }
369
371{
372 return m_xWidget->set_id(OUString::fromUtf8(rId));
373}
374
375void SalInstanceWidget::set_help_id(const OString& rId) { return m_xWidget->SetHelpId(rId); }
376
378
380{
382}
383
385
387
389{
391}
392
394
395void SalInstanceWidget::set_hexpand(bool bExpand) { m_xWidget->set_hexpand(bExpand); }
396
398
399void SalInstanceWidget::set_vexpand(bool bExpand) { m_xWidget->set_vexpand(bExpand); }
400
402
404
406
408
410
412
414
416
418
419void SalInstanceWidget::set_accessible_name(const OUString& rName)
420{
422}
423
424void SalInstanceWidget::set_accessible_description(const OUString& rDescription)
425{
426 m_xWidget->SetAccessibleDescription(rDescription);
427}
428
430
432{
434}
435
437{
439 pOldLabel->SetAccessibleRelationLabelFor(nullptr);
440 vcl::Window* pA11yLabel
441 = pLabel ? dynamic_cast<SalInstanceWidget&>(*pLabel).getWidget() : nullptr;
443 if (pA11yLabel)
445}
446
447void SalInstanceWidget::set_tooltip_text(const OUString& rTip)
448{
450}
451
453
455{
456 vcl::Cursor* pCursor = static_cast<vcl::Cursor*>(pData);
457 if (!pCursor)
458 return;
459
460 m_xWidget->SetCursor(pCursor);
461}
462
464{
467}
468
470{
471 m_xWidget->SetMnemonicActivateHdl(LINK(this, SalInstanceWidget, MnemonicActivateHdl));
473}
474
476{
479}
480
482{
485}
486
488{
491}
492
494{
497}
498
500{
503}
504
506{
509}
510
512{
515}
516
517bool SalInstanceWidget::get_extents_relative_to(const Widget& rRelative, int& x, int& y, int& width,
518 int& height) const
519{
521 dynamic_cast<const SalInstanceWidget&>(rRelative).getWidget()));
522 x = aRect.Left();
523 y = aRect.Top();
524 width = aRect.GetWidth();
525 height = aRect.GetHeight();
526 return true;
527}
528
530
532
534
536
538
540{
541 if (m_nFreezeCount == 0)
542 m_xWidget->SetUpdateMode(false);
544}
545
547{
549 if (m_nFreezeCount == 0)
551}
552
554{
555 if (!m_xWidget)
556 {
557 return;
558 }
559
560 if (bBusy)
562 else
564}
565
567
569{
570 if (m_aMnemonicActivateHdl.IsSet())
573 m_xWidget->RemoveChildEventListener(LINK(this, SalInstanceWidget, MouseEventListener));
575 Application::RemoveKeyListener(LINK(this, SalInstanceWidget, KeyEventListener));
577 m_xWidget->RemoveEventListener(LINK(this, SalInstanceWidget, EventListener));
580}
581
583
585
587
589
590OUString SalInstanceWidget::strip_mnemonic(const OUString& rLabel) const
591{
592 return rLabel.replaceFirst("~", "");
593}
594
596{
597 // create with (annoying) separate alpha layer that LibreOffice itself uses
600}
601
603{
604private:
611
612 void SetFlash()
613 {
614 Color aColor(Application::GetSettings().GetStyleSettings().GetHighlightColor());
616 }
617
619 {
622 else
624 }
625
626 void Flash()
627 {
628 constexpr int FlashesWanted = 1;
629
630 if (m_nFlashCount % 2 == 0)
631 ClearFlash();
632 else
633 SetFlash();
634
635 if (m_nFlashCount == FlashesWanted * 2)
636 return;
637
639
641 }
642
643 DECL_LINK(FlashTimeout, Timer*, void);
644
645public:
647 : m_xWidget(std::move(xWidget))
648 , m_aFlashTimer("SalFlashAttention")
650 , m_nFlashCount(1)
651 {
654 }
655
656 void Start()
657 {
662 }
663
665};
666
667IMPL_LINK_NOARG(SalFlashAttention, FlashTimeout, Timer*, void) { Flash(); }
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 pVclWindow->SetParent(pNewVclParent->getWidget());
1326 else
1327 {
1328 pVclWindow->Hide();
1329 pVclWindow->SetParent(ImplGetDefaultWindow());
1330 }
1331}
1332
1334{
1337 pFirstChild->ImplControlFocus();
1338}
1339
1340css::uno::Reference<css::awt::XWindow> SalInstanceContainer::CreateChildFrame()
1341{
1342 auto xPage = VclPtr<VclBin>::Create(m_xContainer.get());
1343 xPage->set_expand(true);
1344 xPage->Show();
1345 return css::uno::Reference<css::awt::XWindow>(xPage->GetComponentInterface(),
1346 css::uno::UNO_QUERY);
1347}
1348
1349std::unique_ptr<weld::Container> SalInstanceWidget::weld_parent() const
1350{
1351 vcl::Window* pParent = m_xWidget->GetParent();
1352 if (!pParent)
1353 return nullptr;
1354 return std::make_unique<SalInstanceContainer>(pParent, m_pBuilder, false);
1355}
1356
1357void SalInstanceWidget::DoRecursivePaint(vcl::Window* pWindow, const Point& rRenderLogicPos,
1358 OutputDevice& rOutput)
1359{
1360 rOutput.Push();
1361 bool bOldMapModeEnabled = pWindow->IsMapModeEnabled();
1362
1363 if (pWindow->GetMapMode().GetMapUnit() != rOutput.GetMapMode().GetMapUnit())
1364 {
1365 // This is needed for e.g. the scrollbar in writer comments in margins that has its map unit in pixels
1366 // as seen with bin/run gtktiledviewer --enable-tiled-annotations on a document containing a comment
1367 // long enough to need a scrollbar
1368 pWindow->EnableMapMode();
1369 MapMode aMapMode = pWindow->GetMapMode();
1370 aMapMode.SetMapUnit(rOutput.GetMapMode().GetMapUnit());
1371 aMapMode.SetScaleX(rOutput.GetMapMode().GetScaleX());
1372 aMapMode.SetScaleY(rOutput.GetMapMode().GetScaleY());
1373 pWindow->SetMapMode(aMapMode);
1374 }
1375
1377 Size aChildSizePixel(pWindow->GetSizePixel());
1378 xOutput->SetOutputSizePixel(aChildSizePixel);
1379
1380 MapMode aMapMode(xOutput->GetMapMode());
1381 aMapMode.SetMapUnit(rOutput.GetMapMode().GetMapUnit());
1382 aMapMode.SetScaleX(rOutput.GetMapMode().GetScaleX());
1383 aMapMode.SetScaleY(rOutput.GetMapMode().GetScaleY());
1384 xOutput->SetMapMode(aMapMode);
1385
1386 Size aTempLogicSize(xOutput->PixelToLogic(aChildSizePixel));
1387 Size aRenderLogicSize(rOutput.PixelToLogic(aChildSizePixel));
1388
1389 switch (rOutput.GetOutDevType())
1390 {
1391 case OUTDEV_WINDOW:
1392 case OUTDEV_VIRDEV:
1393 xOutput->DrawOutDev(Point(), aTempLogicSize, rRenderLogicPos, aRenderLogicSize,
1394 rOutput);
1395 break;
1396 case OUTDEV_PRINTER:
1397 case OUTDEV_PDF:
1398 xOutput->SetBackground(rOutput.GetBackground());
1399 xOutput->Erase();
1400 break;
1401 }
1402
1403 //set ReallyVisible to match Visible, we restore the original state after Paint
1404 WindowImpl* pImpl = pWindow->ImplGetWindowImpl();
1405 bool bRVisible = pImpl->mbReallyVisible;
1406 pImpl->mbReallyVisible = pWindow->IsVisible();
1407
1408 pWindow->ApplySettings(*xOutput);
1409 pWindow->Paint(*xOutput, tools::Rectangle(Point(), pWindow->PixelToLogic(aChildSizePixel)));
1410
1411 pImpl->mbReallyVisible = bRVisible;
1412
1413 switch (rOutput.GetOutDevType())
1414 {
1415 case OUTDEV_WINDOW:
1416 case OUTDEV_VIRDEV:
1417 rOutput.DrawOutDev(rRenderLogicPos, aRenderLogicSize, Point(), aTempLogicSize,
1418 *xOutput);
1419 break;
1420 case OUTDEV_PRINTER:
1421 case OUTDEV_PDF:
1422 rOutput.DrawBitmapEx(rRenderLogicPos, aRenderLogicSize,
1423 xOutput->GetBitmapEx(Point(), aTempLogicSize));
1424 break;
1425 }
1426
1427 bool bHasMirroredGraphics = pWindow->GetOutDev()->HasMirroredGraphics();
1428
1429 xOutput.disposeAndClear();
1430
1431 pWindow->EnableMapMode(bOldMapModeEnabled);
1432 rOutput.Pop();
1433
1434 for (vcl::Window* pChild = pWindow->GetWindow(GetWindowType::FirstChild); pChild;
1435 pChild = pChild->GetWindow(GetWindowType::Next))
1436 {
1437 if (!pChild->IsVisible())
1438 continue;
1439
1440 tools::Long nDeltaX
1441 = pChild->GetOutDev()->GetOutOffXPixel() - pWindow->GetOutDev()->GetOutOffXPixel();
1442 if (bHasMirroredGraphics)
1443 nDeltaX = pWindow->GetOutDev()->GetOutputWidthPixel() - nDeltaX
1444 - pChild->GetOutDev()->GetOutputWidthPixel();
1445
1446 tools::Long nDeltaY
1447 = pChild->GetOutDev()->GetOutOffYPixel() - pWindow->GetOutDev()->GetOutOffYPixel();
1448
1449 Point aPos(rRenderLogicPos);
1450 aPos += Point(nDeltaX, nDeltaY);
1451
1452 DoRecursivePaint(pChild, aPos, rOutput);
1453 }
1454}
1455
1456void SalInstanceWidget::draw(OutputDevice& rOutput, const Point& rPos, const Size& rSizePixel)
1457{
1458 Size aOrigSize(m_xWidget->GetSizePixel());
1459 bool bChangeSize = aOrigSize != rSizePixel;
1460 if (bChangeSize)
1461 m_xWidget->SetSizePixel(rSizePixel);
1462
1463 DoRecursivePaint(m_xWidget, rPos, rOutput);
1464
1465 if (bChangeSize)
1466 m_xWidget->SetSizePixel(aOrigSize);
1467}
1468
1470 bool bTakeOwnership)
1471 : SalInstanceContainer(pContainer, pBuilder, bTakeOwnership)
1472 , m_xBox(pContainer)
1473{
1474}
1475void SalInstanceBox::reorder_child(weld::Widget* pWidget, int nNewPosition)
1476{
1477 SalInstanceWidget* pVclWidget = dynamic_cast<SalInstanceWidget*>(pWidget);
1478 assert(pVclWidget);
1479 pVclWidget->getWidget()->reorderWithinParent(nNewPosition);
1480}
1481
1483
1484namespace
1485{
1486void CollectChildren(const vcl::Window& rCurrent, const basegfx::B2IPoint& rTopLeft,
1487 weld::ScreenShotCollection& rControlDataCollection)
1488{
1489 if (!rCurrent.IsVisible())
1490 return;
1491
1492 const Point aCurrentPos(rCurrent.GetPosPixel());
1493 const Size aCurrentSize(rCurrent.GetSizePixel());
1494 const basegfx::B2IPoint aCurrentTopLeft(rTopLeft.getX() + aCurrentPos.X(),
1495 rTopLeft.getY() + aCurrentPos.Y());
1496 const basegfx::B2IRange aCurrentRange(
1497 aCurrentTopLeft,
1498 aCurrentTopLeft + basegfx::B2IPoint(aCurrentSize.Width(), aCurrentSize.Height()));
1499
1500 if (!aCurrentRange.isEmpty())
1501 {
1502 rControlDataCollection.emplace_back(rCurrent.GetHelpId(), aCurrentRange);
1503 }
1504
1505 for (sal_uInt16 a(0); a < rCurrent.GetChildCount(); a++)
1507 vcl::Window* pChild = rCurrent.GetChild(a);
1508 if (nullptr != pChild)
1509 {
1510 CollectChildren(*pChild, aCurrentTopLeft, rControlDataCollection);
1511 }
1512 }
1513}
1514}
1515
1517{
1518 for (vcl::Window* pChild = pParent->GetWindow(GetWindowType::FirstChild); pChild;
1519 pChild = pChild->GetWindow(GetWindowType::Next))
1520 override_child_help(pChild);
1521 pParent->SetHelpHdl(LINK(this, SalInstanceWindow, HelpHdl));
1522}
1523
1525{
1526 for (vcl::Window* pChild = pParent->GetWindow(GetWindowType::FirstChild); pChild;
1527 pChild = pChild->GetWindow(GetWindowType::Next))
1528 clear_child_help(pChild);
1530}
1531
1533 bool bTakeOwnership)
1534 : SalInstanceContainer(pWindow, pBuilder, bTakeOwnership)
1535 , m_xWindow(pWindow)
1536{
1537 // tdf#129745 only override child help for the normal case, not for
1538 // m_pBuilder of null which is the toplevel application frame case.
1539 if (m_pBuilder)
1541}
1542
1543void SalInstanceWindow::set_title(const OUString& rTitle) { m_xWindow->SetText(rTitle); }
1544
1545OUString SalInstanceWindow::get_title() const { return m_xWindow->GetText(); }
1546
1547css::uno::Reference<css::awt::XWindow> SalInstanceWindow::GetXWindow()
1549 css::uno::Reference<css::awt::XWindow> xWindow(m_xWindow->GetComponentInterface(),
1550 css::uno::UNO_QUERY);
1551 return xWindow;
1552}
1553
1554namespace
1555{
1556void resize_to_request(vcl::Window* pWindow)
1557{
1558 if (SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(pWindow))
1559 {
1560 pSysWin->setOptimalLayoutSize(true);
1561 return;
1562 }
1563 if (DockingWindow* pDockWin = dynamic_cast<DockingWindow*>(pWindow))
1564 {
1565 pDockWin->setOptimalLayoutSize();
1566 return;
1567 }
1568 assert(false && "must be system or docking window");
1569}
1570}
1571
1573
1575
1577
1579
1581
1583
1585{
1587}
1588
1589void SalInstanceWindow::set_centered_on_parent(bool /*bTrackGeometryRequests*/)
1590{
1591 if (vcl::Window* pParent = m_xWidget->GetParent())
1592 {
1593 Size aParentGeometry(pParent->GetSizePixel());
1594 Size aGeometry(m_xWidget->get_preferred_size());
1595 auto nX = (aParentGeometry.Width() - aGeometry.Width()) / 2;
1596 auto nY = (aParentGeometry.Height() - aGeometry.Height()) / 2;
1597 m_xWidget->SetPosPixel(Point(nX, nY));
1598 }
1599}
1600
1602
1604
1606{
1608}
1609
1611{
1612 vcl::Window* pChildLoop = _pWindow->GetWindow(GetWindowType::FirstChild);
1613 while (pChildLoop)
1614 {
1615 // does the window participate in the tabbing order?
1616 if (pChildLoop->GetStyle() & WB_DIALOGCONTROL)
1617 implResetDefault(pChildLoop);
1618
1619 // is it a button?
1620 WindowType eType = pChildLoop->GetType();
1625 {
1626 pChildLoop->SetStyle(pChildLoop->GetStyle() & ~WB_DEFBUTTON);
1627 }
1628
1629 // the next one ...
1630 pChildLoop = pChildLoop->GetWindow(GetWindowType::Next);
1631 }
1632}
1633
1635
1637{
1638 SalInstanceWidget* pVclNew = dynamic_cast<SalInstanceWidget*>(pNew);
1639 vcl::Window* pWidgetNew = pVclNew ? pVclNew->getWidget() : nullptr;
1640 SalInstanceWidget* pVclOld = dynamic_cast<SalInstanceWidget*>(pOld);
1641 vcl::Window* pWidgetOld = pVclOld ? pVclOld->getWidget() : nullptr;
1642 if (pWidgetOld)
1643 pWidgetOld->set_property("has-default", OUString::boolean(false));
1644 else
1646 if (pWidgetNew)
1647 pWidgetNew->set_property("has-default", OUString::boolean(true));
1648}
1649
1651{
1652 const SalInstanceWidget* pVclCandidate = dynamic_cast<const SalInstanceWidget*>(pCandidate);
1653 vcl::Window* pWidget = pVclCandidate ? pVclCandidate->getWidget() : nullptr;
1654 return pWidget && pWidget->GetStyle() & WB_DEFBUTTON;
1655}
1656
1658{
1659 SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(m_xWindow.get());
1660 assert(pSysWin);
1661 pSysWin->SetWindowState(rStr);
1662}
1663
1665{
1666 SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(m_xWindow.get());
1667 assert(pSysWin);
1668 return pSysWin->GetWindowState(nMask);
1669}
1670
1672
1674{
1675 SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(m_xWindow.get());
1676 assert(pSysWin);
1677 return pSysWin->createScreenshot();
1678}
1679
1681{
1683
1684 // collect all children. Choose start pos to be negative
1685 // of target dialog's position to get all positions relative to (0,0)
1686 const Point aParentPos(m_xWindow->GetPosPixel());
1687 const basegfx::B2IPoint aTopLeft(-aParentPos.X(), -aParentPos.Y());
1688 CollectChildren(*m_xWindow, aTopLeft, aRet);
1689
1690 return aRet;
1691}
1692
1694{
1695 // tdf#129745 only undo overriding child help for the normal case, not for
1696 // m_pBuilder of null which is the toplevel application frame case.
1697 if (m_pBuilder)
1699}
1700
1702{
1703 help();
1704 return false;
1705}
1706
1707typedef std::set<VclPtr<vcl::Window>> winset;
1708
1709namespace
1710{
1711void hideUnless(const vcl::Window* pTop, const winset& rVisibleWidgets,
1712 std::vector<VclPtr<vcl::Window>>& rWasVisibleWidgets)
1713{
1714 for (vcl::Window* pChild = pTop->GetWindow(GetWindowType::FirstChild); pChild;
1715 pChild = pChild->GetWindow(GetWindowType::Next))
1716 {
1717 if (!pChild->IsVisible())
1718 continue;
1719 if (rVisibleWidgets.find(pChild) == rVisibleWidgets.end())
1720 {
1721 rWasVisibleWidgets.emplace_back(pChild);
1722 pChild->Hide();
1723 }
1724 else if (isContainerWindow(pChild))
1725 {
1726 hideUnless(pChild, rVisibleWidgets, rWasVisibleWidgets);
1727 }
1728 }
1729}
1730}
1731
1733 bool bTakeOwnership)
1734 : SalInstanceWindow(pDialog, pBuilder, bTakeOwnership)
1735 , m_xDialog(pDialog)
1736 , m_nOldEditWidthReq(0)
1737 , m_nOldBorderWidth(0)
1738{
1739 const bool bScreenshotMode(officecfg::Office::Common::Misc::ScreenshotMode::get());
1740 if (bScreenshotMode)
1741 {
1742 m_xDialog->SetPopupMenuHdl(LINK(this, SalInstanceDialog, PopupScreenShotMenuHdl));
1743 }
1744}
1745
1746bool SalInstanceDialog::runAsync(std::shared_ptr<weld::DialogController> aOwner,
1747 const std::function<void(sal_Int32)>& rEndDialogFn)
1748{
1750 aCtx.mxOwnerDialogController = aOwner;
1751 aCtx.maEndDialogFn = rEndDialogFn;
1752 VclButtonBox* pActionArea = m_xDialog->get_action_area();
1753 if (pActionArea)
1754 sort_native_button_order(*pActionArea);
1755 return m_xDialog->StartExecuteAsync(aCtx);
1756}
1757
1758bool SalInstanceDialog::runAsync(std::shared_ptr<Dialog> const& rxSelf,
1759 const std::function<void(sal_Int32)>& rEndDialogFn)
1760{
1761 assert(rxSelf.get() == this);
1763 // In order to store a shared_ptr to ourself, we have to have been constructed by make_shared,
1764 // which is that rxSelf enforces.
1765 aCtx.mxOwnerSelf = rxSelf;
1766 aCtx.maEndDialogFn = rEndDialogFn;
1767 VclButtonBox* pActionArea = m_xDialog->get_action_area();
1768 if (pActionArea)
1769 sort_native_button_order(*pActionArea);
1770 return m_xDialog->StartExecuteAsync(aCtx);
1771}
1772
1774{
1775 SalInstanceWidget* pVclEdit = dynamic_cast<SalInstanceWidget*>(pEdit);
1776 assert(pVclEdit);
1777 SalInstanceWidget* pVclButton = dynamic_cast<SalInstanceWidget*>(pButton);
1778
1779 vcl::Window* pRefEdit = pVclEdit->getWidget();
1780 vcl::Window* pRefBtn = pVclButton ? pVclButton->getWidget() : nullptr;
1781
1782 auto nOldEditWidth = pRefEdit->GetSizePixel().Width();
1784
1785 //We want just pRefBtn and pRefEdit to be shown
1786 //mark widgets we want to be visible, starting with pRefEdit
1787 //and all its direct parents.
1788 winset aVisibleWidgets;
1789 vcl::Window* pContentArea = m_xDialog->get_content_area();
1790 for (vcl::Window* pCandidate = pRefEdit;
1791 pCandidate && (pCandidate != pContentArea && pCandidate->IsVisible());
1792 pCandidate = pCandidate->GetWindow(GetWindowType::RealParent))
1793 {
1794 aVisibleWidgets.insert(pCandidate);
1795 }
1796 //same again with pRefBtn, except stop if there's a
1797 //shared parent in the existing widgets
1798 for (vcl::Window* pCandidate = pRefBtn;
1799 pCandidate && (pCandidate != pContentArea && pCandidate->IsVisible());
1800 pCandidate = pCandidate->GetWindow(GetWindowType::RealParent))
1801 {
1802 if (aVisibleWidgets.insert(pCandidate).second)
1803 break;
1804 }
1805
1806 //hide everything except the aVisibleWidgets
1807 hideUnless(pContentArea, aVisibleWidgets, m_aHiddenWidgets);
1808
1809 // the insert function case has an initially hidden edit widget, so it has
1810 // not start size, so take larger of actual size and size request
1811 pRefEdit->set_width_request(std::max(nOldEditWidth, m_nOldEditWidthReq));
1812 m_nOldBorderWidth = m_xDialog->get_border_width();
1813 m_xDialog->set_border_width(0);
1814 if (vcl::Window* pActionArea = m_xDialog->get_action_area())
1815 pActionArea->Hide();
1816 m_xDialog->setOptimalLayoutSize(true);
1817 m_xRefEdit = pRefEdit;
1818}
1819
1821{
1822 // All others: Show();
1823 for (VclPtr<vcl::Window> const& pWindow : m_aHiddenWidgets)
1824 {
1825 pWindow->Show();
1826 }
1827 m_aHiddenWidgets.clear();
1828
1830 m_xRefEdit.clear();
1831 m_xDialog->set_border_width(m_nOldBorderWidth);
1832 if (vcl::Window* pActionArea = m_xDialog->get_action_area())
1833 pActionArea->Show();
1834 m_xDialog->setOptimalLayoutSize(true);
1835}
1836
1839{
1840 m_xDialog->SetInstallLOKNotifierHdl(rLink);
1841}
1842
1844{
1845 VclButtonBox* pActionArea = m_xDialog->get_action_area();
1846 if (pActionArea)
1847 sort_native_button_order(*pActionArea);
1848 return m_xDialog->Execute();
1849}
1850
1851void SalInstanceDialog::response(int nResponse) { m_xDialog->EndDialog(nResponse); }
1852
1853void SalInstanceDialog::add_button(const OUString& rText, int nResponse, const OString& rHelpId)
1854{
1855 VclButtonBox* pBox = m_xDialog->get_action_area();
1856 VclPtr<PushButton> xButton(
1858 xButton->SetText(rText);
1859 xButton->SetHelpId(rHelpId);
1860
1861 switch (nResponse)
1862 {
1863 case RET_OK:
1864 xButton->set_id("ok");
1865 break;
1866 case RET_CLOSE:
1867 xButton->set_id("close");
1868 break;
1869 case RET_CANCEL:
1870 xButton->set_id("cancel");
1871 break;
1872 case RET_YES:
1873 xButton->set_id("yes");
1874 break;
1875 case RET_NO:
1876 xButton->set_id("no");
1877 break;
1878 }
1879
1880 xButton->Show();
1881 m_xDialog->add_button(xButton, nResponse, true);
1882}
1883
1885{
1886 if (get_modal() == bModal)
1887 return;
1888 m_xDialog->SetModalInputMode(bModal);
1889}
1890
1891bool SalInstanceDialog::get_modal() const { return m_xDialog->IsModalInputMode(); }
1892
1894{
1895 m_xDialog->set_default_response(nResponse);
1896}
1897
1899{
1900 return new SalInstanceContainer(m_xDialog->get_content_area(), m_pBuilder, false);
1901}
1902
1903IMPL_LINK(SalInstanceDialog, PopupScreenShotMenuHdl, const CommandEvent&, rCEvt, bool)
1904{
1905 if (CommandEventId::ContextMenu == rCEvt.GetCommand())
1906 {
1907 const Point aMenuPos(rCEvt.GetMousePosPixel());
1909 sal_uInt16 nLocalID(1);
1910
1911 aMenu->InsertItem(nLocalID, VclResId(SV_BUTTONTEXT_SCREENSHOT));
1912 aMenu->SetHelpText(nLocalID, VclResId(SV_HELPTEXT_SCREENSHOT));
1913 aMenu->SetHelpId(nLocalID, "InteractiveScreenshotMode");
1914 aMenu->EnableItem(nLocalID);
1915
1916 const sal_uInt16 nId(aMenu->Execute(m_xDialog, aMenuPos));
1917
1918 // 0 == no selection (so not usable as ID)
1919 if (0 != nId)
1920 {
1921 // open screenshot annotation dialog
1924 = pFact->CreateScreenshotAnnotationDlg(*this);
1926
1927 if (pDialog)
1928 {
1929 // currently just execute the dialog, no need to do
1930 // different things for ok/cancel. This may change later,
1931 // for that case use 'if (pDlg->Execute() == RET_OK)'
1932 pDialog->Execute();
1933 }
1934 }
1935
1936 // consume event when:
1937 // - CommandEventId::ContextMenu
1938 // - bScreenshotMode
1939 return true;
1940 }
1941
1942 return false;
1943}
1944
1946 SalInstanceBuilder* pBuilder,
1947 bool bTakeOwnership)
1948 : SalInstanceDialog(pDialog, pBuilder, bTakeOwnership)
1949 , m_xMessageDialog(pDialog)
1950{
1951}
1952
1954{
1955 m_xMessageDialog->set_primary_text(rText);
1956}
1957
1959{
1960 return m_xMessageDialog->get_primary_text();
1961}
1962
1964{
1965 m_xMessageDialog->set_secondary_text(rText);
1966}
1967
1969{
1970 return m_xMessageDialog->get_secondary_text();
1971}
1972
1974{
1975 return new SalInstanceContainer(m_xMessageDialog->get_message_area(), m_pBuilder, false);
1976}
1977
1978namespace
1979{
1980class SalInstanceAssistant : public SalInstanceDialog, public virtual weld::Assistant
1981{
1982private:
1984 std::vector<std::unique_ptr<SalInstanceContainer>> m_aPages;
1985 std::vector<VclPtr<TabPage>> m_aAddedPages;
1986 std::vector<int> m_aIds;
1987 std::vector<VclPtr<VclGrid>> m_aAddedGrids;
1988 Idle m_aUpdateRoadmapIdle;
1989
1990 int find_page(std::string_view rIdent) const
1991 {
1992 for (size_t i = 0; i < m_aAddedPages.size(); ++i)
1993 {
1994 if (m_aAddedPages[i]->get_id().toUtf8() == rIdent)
1995 return i;
1996 }
1997 return -1;
1998 }
1999
2000 int find_id(int nId) const
2001 {
2002 for (size_t i = 0; i < m_aIds.size(); ++i)
2003 {
2004 if (nId == m_aIds[i])
2005 return i;
2006 }
2007 return -1;
2008 }
2009
2010 DECL_LINK(OnRoadmapItemSelected, LinkParamNone*, void);
2011 DECL_LINK(UpdateRoadmap_Hdl, Timer*, void);
2012
2013public:
2014 SalInstanceAssistant(vcl::RoadmapWizard* pDialog, SalInstanceBuilder* pBuilder,
2015 bool bTakeOwnership)
2016 : SalInstanceDialog(pDialog, pBuilder, bTakeOwnership)
2017 , m_xWizard(pDialog)
2018 , m_aUpdateRoadmapIdle("SalInstanceAssistant m_aUpdateRoadmapIdle")
2019 {
2020 m_xWizard->SetItemSelectHdl(LINK(this, SalInstanceAssistant, OnRoadmapItemSelected));
2021
2022 m_aUpdateRoadmapIdle.SetInvokeHandler(LINK(this, SalInstanceAssistant, UpdateRoadmap_Hdl));
2023 m_aUpdateRoadmapIdle.SetPriority(TaskPriority::HIGHEST);
2024 }
2025
2026 virtual int get_current_page() const override { return find_id(m_xWizard->GetCurLevel()); }
2027
2028 virtual int get_n_pages() const override { return m_aAddedPages.size(); }
2029
2030 virtual OString get_page_ident(int nPage) const override
2031 {
2032 return m_aAddedPages[nPage]->get_id().toUtf8();
2033 }
2034
2035 virtual OString get_current_page_ident() const override
2036 {
2038 }
2039
2040 virtual void set_current_page(int nPage) override
2041 {
2043
2044 // take the first shown page as the size for all pages
2045 if (m_xWizard->GetPageSizePixel().Width() == 0)
2046 {
2047 Size aFinalSize;
2048 for (int i = 0, nPages = get_n_pages(); i < nPages; ++i)
2049 {
2050 TabPage* pPage = m_xWizard->GetPage(m_aIds[i]);
2051 assert(pPage);
2052 Size aPageSize(pPage->get_preferred_size());
2053 if (aPageSize.Width() > aFinalSize.Width())
2054 aFinalSize.setWidth(aPageSize.Width());
2055 if (aPageSize.Height() > aFinalSize.Height())
2056 aFinalSize.setHeight(aPageSize.Height());
2057 }
2058 m_xWizard->SetPageSizePixel(aFinalSize);
2059 }
2060
2061 (void)m_xWizard->ShowPage(m_aIds[nPage]);
2063 }
2064
2065 virtual void set_current_page(const OString& rIdent) override
2066 {
2067 int nIndex = find_page(rIdent);
2068 if (nIndex == -1)
2069 return;
2070 set_current_page(nIndex);
2071 }
2072
2073 virtual void set_page_index(const OString& rIdent, int nNewIndex) override
2074 {
2075 int nOldIndex = find_page(rIdent);
2076
2077 if (nOldIndex == -1)
2078 return;
2079
2080 if (nOldIndex == nNewIndex)
2081 return;
2082
2084
2085 auto entry = std::move(m_aAddedPages[nOldIndex]);
2086 m_aAddedPages.erase(m_aAddedPages.begin() + nOldIndex);
2087 m_aAddedPages.insert(m_aAddedPages.begin() + nNewIndex, std::move(entry));
2088
2089 int nId = m_aIds[nOldIndex];
2090 m_aIds.erase(m_aIds.begin() + nOldIndex);
2091 m_aIds.insert(m_aIds.begin() + nNewIndex, nId);
2092
2093 m_aUpdateRoadmapIdle.Start();
2094
2096 }
2097
2098 virtual weld::Container* append_page(const OString& rIdent) override
2099 {
2100 VclPtrInstance<TabPage> xPage(m_xWizard);
2101 VclPtrInstance<VclGrid> xGrid(xPage);
2102 xPage->set_id(OUString::fromUtf8(rIdent));
2103 xPage->Show();
2104 xGrid->set_hexpand(true);
2105 xGrid->set_vexpand(true);
2106 xGrid->Show();
2107 m_xWizard->AddPage(xPage);
2108 m_aIds.push_back(m_aAddedPages.size());
2109 m_xWizard->SetPage(m_aIds.back(), xPage);
2110 m_aAddedPages.push_back(xPage);
2111 m_aAddedGrids.push_back(xGrid);
2112
2113 m_aUpdateRoadmapIdle.Start();
2114
2115 m_aPages.emplace_back(new SalInstanceContainer(xGrid, m_pBuilder, false));
2116 return m_aPages.back().get();
2117 }
2118
2119 virtual OUString get_page_title(const OString& rIdent) const override
2120 {
2121 int nIndex = find_page(rIdent);
2122 if (nIndex == -1)
2123 return OUString();
2124 return m_aAddedPages[nIndex]->GetText();
2125 }
2126
2127 virtual void set_page_title(const OString& rIdent, const OUString& rTitle) override
2128 {
2129 int nIndex = find_page(rIdent);
2130 if (nIndex == -1)
2131 return;
2132 if (m_aAddedPages[nIndex]->GetText() != rTitle)
2133 {
2135 m_aAddedPages[nIndex]->SetText(rTitle);
2136 m_aUpdateRoadmapIdle.Start();
2138 }
2139 }
2140
2141 virtual void set_page_sensitive(const OString& rIdent, bool bSensitive) override
2142 {
2143 int nIndex = find_page(rIdent);
2144 if (nIndex == -1)
2145 return;
2146 if (m_aAddedPages[nIndex]->IsEnabled() != bSensitive)
2147 {
2149 m_aAddedPages[nIndex]->Enable(bSensitive);
2150 m_aUpdateRoadmapIdle.Start();
2152 }
2153 }
2154
2155 virtual void set_page_side_help_id(const OString& rHelpId) override
2156 {
2157 m_xWizard->SetRoadmapHelpId(rHelpId);
2158 }
2159
2160 weld::Button* weld_widget_for_response(int nResponse) override;
2161
2162 virtual ~SalInstanceAssistant() override
2163 {
2164 for (auto& rGrid : m_aAddedGrids)
2165 rGrid.disposeAndClear();
2166 for (auto& rPage : m_aAddedPages)
2167 rPage.disposeAndClear();
2168 }
2169};
2170}
2171
2172IMPL_LINK_NOARG(SalInstanceAssistant, OnRoadmapItemSelected, LinkParamNone*, void)
2173{
2174 if (notify_events_disabled())
2175 return;
2176 auto nCurItemId = m_xWizard->GetCurrentRoadmapItemID();
2177 int nPageIndex(find_id(nCurItemId));
2178 if (!signal_jump_page(get_page_ident(nPageIndex)) && nCurItemId != m_xWizard->GetCurLevel())
2179 m_xWizard->SelectRoadmapItemByID(m_xWizard->GetCurLevel());
2180}
2181
2182IMPL_LINK_NOARG(SalInstanceAssistant, UpdateRoadmap_Hdl, Timer*, void)
2183{
2184 disable_notify_events();
2185
2186 m_xWizard->DeleteRoadmapItems();
2187
2188 int nPos = 0;
2189 for (size_t i = 0; i < m_aAddedPages.size(); ++i)
2190 {
2191 const OUString& rLabel = m_aAddedPages[i]->GetText();
2192 bool bSensitive = m_aAddedPages[i]->IsEnabled();
2193 if (rLabel.isEmpty())
2194 continue;
2195 m_xWizard->InsertRoadmapItem(nPos++, rLabel, m_aIds[i], bSensitive);
2196 }
2197
2198 m_xWizard->SelectRoadmapItemByID(m_aIds[get_current_page()], false);
2199
2200 m_xWizard->ShowRoadmap(nPos != 0);
2201
2202 enable_notify_events();
2203}
2204
2206 bool bTakeOwnership)
2207 : SalInstanceContainer(pFrame, pBuilder, bTakeOwnership)
2208 , m_xFrame(pFrame)
2209{
2210}
2211
2212void SalInstanceFrame::set_label(const OUString& rText) { m_xFrame->set_label(rText); }
2213
2214OUString SalInstanceFrame::get_label() const { return m_xFrame->get_label(); }
2215
2216namespace
2217{
2218class SalInstancePaned : public SalInstanceContainer, public virtual weld::Paned
2219{
2220private:
2221 VclPtr<VclPaned> m_xPaned;
2222
2223public:
2224 SalInstancePaned(VclPaned* pPaned, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2225 : SalInstanceContainer(pPaned, pBuilder, bTakeOwnership)
2226 , m_xPaned(pPaned)
2227 {
2228 }
2229
2230 virtual void set_position(int nPos) override { m_xPaned->set_position(nPos); }
2231
2232 virtual int get_position() const override { return m_xPaned->get_position(); }
2233};
2234
2235class SalInstanceScrolledWindow : public SalInstanceContainer, public virtual weld::ScrolledWindow
2236{
2237private:
2238 VclPtr<VclScrolledWindow> m_xScrolledWindow;
2239 Link<ScrollBar*, void> m_aOrigVScrollHdl;
2240 Link<ScrollBar*, void> m_aOrigHScrollHdl;
2241 bool m_bUserManagedScrolling;
2242
2243 DECL_LINK(VscrollHdl, ScrollBar*, void);
2244 DECL_LINK(HscrollHdl, ScrollBar*, void);
2245
2246 static void customize_scrollbars(ScrollBar& rScrollBar, const Color& rButtonTextColor,
2247 const Color& rBackgroundColor, const Color& rShadowColor,
2248 const Color& rFaceColor)
2249 {
2250 rScrollBar.EnableNativeWidget(false);
2251 AllSettings aSettings = rScrollBar.GetSettings();
2252 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
2253 aStyleSettings.SetButtonTextColor(rButtonTextColor);
2254 aStyleSettings.SetCheckedColor(rBackgroundColor); // background
2255 aStyleSettings.SetShadowColor(rShadowColor);
2256 aStyleSettings.SetFaceColor(rFaceColor);
2257 aSettings.SetStyleSettings(aStyleSettings);
2258 rScrollBar.SetSettings(aSettings);
2259 }
2260
2261public:
2262 SalInstanceScrolledWindow(VclScrolledWindow* pScrolledWindow, SalInstanceBuilder* pBuilder,
2263 bool bTakeOwnership, bool bUserManagedScrolling)
2264 : SalInstanceContainer(pScrolledWindow, pBuilder, bTakeOwnership)
2265 , m_xScrolledWindow(pScrolledWindow)
2266 , m_bUserManagedScrolling(bUserManagedScrolling)
2267 {
2268 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2269 m_aOrigVScrollHdl = rVertScrollBar.GetScrollHdl();
2270 rVertScrollBar.SetScrollHdl(LINK(this, SalInstanceScrolledWindow, VscrollHdl));
2271 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2272 m_aOrigHScrollHdl = rHorzScrollBar.GetScrollHdl();
2273 rHorzScrollBar.SetScrollHdl(LINK(this, SalInstanceScrolledWindow, HscrollHdl));
2274 m_xScrolledWindow->setUserManagedScrolling(m_bUserManagedScrolling);
2275 }
2276
2277 virtual void hadjustment_configure(int value, int lower, int upper, int step_increment,
2278 int page_increment, int page_size) override
2279 {
2280 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2281 rHorzScrollBar.SetRangeMin(lower);
2282 rHorzScrollBar.SetRangeMax(upper);
2283 rHorzScrollBar.SetLineSize(step_increment);
2284 rHorzScrollBar.SetPageSize(page_increment);
2285 rHorzScrollBar.SetThumbPos(value);
2286 rHorzScrollBar.SetVisibleSize(page_size);
2287 }
2288
2289 virtual int hadjustment_get_value() const override
2290 {
2291 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2292 return rHorzScrollBar.GetThumbPos();
2293 }
2294
2295 virtual void hadjustment_set_value(int value) override
2296 {
2297 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2298 rHorzScrollBar.SetThumbPos(value);
2299 if (!m_bUserManagedScrolling)
2300 m_aOrigHScrollHdl.Call(&rHorzScrollBar);
2301 }
2302
2303 virtual int hadjustment_get_upper() const override
2304 {
2305 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2306 return rHorzScrollBar.GetRangeMax();
2307 }
2308
2309 virtual void hadjustment_set_upper(int upper) override
2310 {
2311 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2312 rHorzScrollBar.SetRangeMax(upper);
2313 }
2314
2315 virtual int hadjustment_get_page_size() const override
2316 {
2317 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2318 return rHorzScrollBar.GetVisibleSize();
2319 }
2320
2321 virtual void hadjustment_set_page_size(int size) override
2322 {
2323 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2324 return rHorzScrollBar.SetVisibleSize(size);
2325 }
2326
2327 virtual void hadjustment_set_page_increment(int size) override
2328 {
2329 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2330 return rHorzScrollBar.SetPageSize(size);
2331 }
2332
2333 virtual void hadjustment_set_step_increment(int size) override
2334 {
2335 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2336 return rHorzScrollBar.SetLineSize(size);
2337 }
2338
2339 virtual void set_hpolicy(VclPolicyType eHPolicy) override
2340 {
2341 WinBits nWinBits = m_xScrolledWindow->GetStyle() & ~(WB_AUTOHSCROLL | WB_HSCROLL);
2342 if (eHPolicy == VclPolicyType::ALWAYS)
2343 nWinBits |= WB_HSCROLL;
2344 else if (eHPolicy == VclPolicyType::AUTOMATIC)
2345 nWinBits |= WB_AUTOHSCROLL;
2346 m_xScrolledWindow->SetStyle(nWinBits);
2347 m_xScrolledWindow->queue_resize();
2348 }
2349
2350 virtual VclPolicyType get_hpolicy() const override
2351 {
2352 WinBits nWinBits = m_xScrolledWindow->GetStyle();
2353 if (nWinBits & WB_AUTOHSCROLL)
2355 else if (nWinBits & WB_HSCROLL)
2356 return VclPolicyType::ALWAYS;
2357 return VclPolicyType::NEVER;
2358 }
2359
2360 virtual void vadjustment_configure(int value, int lower, int upper, int step_increment,
2361 int page_increment, int page_size) override
2362 {
2363 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2364 rVertScrollBar.SetRangeMin(lower);
2365 rVertScrollBar.SetRangeMax(upper);
2366 rVertScrollBar.SetLineSize(step_increment);
2367 rVertScrollBar.SetPageSize(page_increment);
2368 rVertScrollBar.SetThumbPos(value);
2369 rVertScrollBar.SetVisibleSize(page_size);
2370 }
2371
2372 virtual int vadjustment_get_value() const override
2373 {
2374 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2375 return rVertScrollBar.GetThumbPos();
2376 }
2377
2378 virtual void vadjustment_set_value(int value) override
2379 {
2380 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2381 rVertScrollBar.SetThumbPos(value);
2382 if (!m_bUserManagedScrolling)
2383 m_aOrigVScrollHdl.Call(&rVertScrollBar);
2384 }
2385
2386 virtual int vadjustment_get_upper() const override
2387 {
2388 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2389 return rVertScrollBar.GetRangeMax();
2390 }
2391
2392 virtual void vadjustment_set_upper(int upper) override
2393 {
2394 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2395 rVertScrollBar.SetRangeMax(upper);
2396 }
2397
2398 virtual int vadjustment_get_lower() const override
2399 {
2400 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2401 return rVertScrollBar.GetRangeMin();
2402 }
2403
2404 virtual void vadjustment_set_lower(int lower) override
2405 {
2406 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2407 rVertScrollBar.SetRangeMin(lower);
2408 }
2409
2410 virtual int vadjustment_get_page_size() const override
2411 {
2412 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2413 return rVertScrollBar.GetVisibleSize();
2414 }
2415
2416 virtual void vadjustment_set_page_size(int size) override
2417 {
2418 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2419 return rVertScrollBar.SetVisibleSize(size);
2420 }
2421
2422 virtual void vadjustment_set_page_increment(int size) override
2423 {
2424 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2425 return rVertScrollBar.SetPageSize(size);
2426 }
2427
2428 virtual void vadjustment_set_step_increment(int size) override
2429 {
2430 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2431 return rVertScrollBar.SetLineSize(size);
2432 }
2433
2434 virtual void set_vpolicy(VclPolicyType eVPolicy) override
2435 {
2436 WinBits nWinBits = m_xScrolledWindow->GetStyle() & ~(WB_AUTOVSCROLL | WB_VSCROLL);
2437 if (eVPolicy == VclPolicyType::ALWAYS)
2438 nWinBits |= WB_VSCROLL;
2439 else if (eVPolicy == VclPolicyType::AUTOMATIC)
2440 nWinBits |= WB_AUTOVSCROLL;
2441 m_xScrolledWindow->SetStyle(nWinBits);
2442 m_xScrolledWindow->queue_resize();
2443 }
2444
2445 virtual VclPolicyType get_vpolicy() const override
2446 {
2447 WinBits nWinBits = m_xScrolledWindow->GetStyle();
2448 if (nWinBits & WB_AUTOVSCROLL)
2450 else if (nWinBits & WB_VSCROLL)
2451 return VclPolicyType::ALWAYS;
2452 return VclPolicyType::NEVER;
2453 }
2454
2455 virtual int get_scroll_thickness() const override
2456 {
2457 return m_xScrolledWindow->getVertScrollBar().get_preferred_size().Width();
2458 }
2459
2460 virtual void set_scroll_thickness(int nThickness) override
2461 {
2462 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2463 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2464 rHorzScrollBar.set_height_request(nThickness);
2465 rVertScrollBar.set_width_request(nThickness);
2466 }
2467
2468 virtual void customize_scrollbars(const Color& rBackgroundColor, const Color& rShadowColor,
2469 const Color& rFaceColor) override
2470 {
2471 ScrollBar& rHorzScrollBar = m_xScrolledWindow->getHorzScrollBar();
2472 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2473 customize_scrollbars(rHorzScrollBar, Color(0, 0, 0), rBackgroundColor, rShadowColor,
2474 rFaceColor);
2475 customize_scrollbars(rVertScrollBar, Color(0, 0, 0), rBackgroundColor, rShadowColor,
2476 rFaceColor);
2477 }
2478
2479 virtual ~SalInstanceScrolledWindow() override
2480 {
2481 ScrollBar& rVertScrollBar = m_xScrolledWindow->getVertScrollBar();
2482 rVertScrollBar.SetScrollHdl(m_aOrigVScrollHdl);
2483 }
2484};
2485}
2486
2487IMPL_LINK(SalInstanceScrolledWindow, VscrollHdl, ScrollBar*, pScrollBar, void)
2488{
2489 signal_vadjustment_changed();
2490 if (!m_bUserManagedScrolling)
2491 m_aOrigVScrollHdl.Call(pScrollBar);
2492}
2493
2494IMPL_LINK_NOARG(SalInstanceScrolledWindow, HscrollHdl, ScrollBar*, void)
2495{
2496 signal_hadjustment_changed();
2497 if (!m_bUserManagedScrolling)
2498 m_aOrigHScrollHdl.Call(&m_xScrolledWindow->getHorzScrollBar());
2499}
2500
2501namespace
2502{
2503class SalInstanceScrollbar : public SalInstanceWidget, public virtual weld::Scrollbar
2504{
2505private:
2506 VclPtr<ScrollBar> m_xScrollBar;
2507
2508 DECL_LINK(ScrollHdl, ScrollBar*, void);
2509
2510public:
2511 SalInstanceScrollbar(ScrollBar* pScrollbar, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
2512 : SalInstanceWidget(pScrollbar, pBuilder, bTakeOwnership)
2513 , m_xScrollBar(pScrollbar)
2514 {
2515 m_xScrollBar->SetScrollHdl(LINK(this, SalInstanceScrollbar, ScrollHdl));
2516 m_xScrollBar->EnableDrag();
2517 }
2518
2519 virtual void adjustment_configure(int value, int lower, int upper, int step_increment,
2520 int page_increment, int page_size) override
2521 {
2522 m_xScrollBar->SetRangeMin(lower);
2523 m_xScrollBar->SetRangeMax(upper);
2524 m_xScrollBar->SetLineSize(step_increment);
2525 m_xScrollBar->SetPageSize(page_increment);
2526 m_xScrollBar->SetThumbPos(value);
2527 m_xScrollBar->SetVisibleSize(page_size);
2528 }
2529
2530 virtual int adjustment_get_value() const override { return m_xScrollBar->GetThumbPos(); }
2531
2532 virtual void adjustment_set_value(int value) override { m_xScrollBar->SetThumbPos(value); }
2533
2534 virtual int adjustment_get_upper() const override { return m_xScrollBar->GetRangeMax(); }
2535
2536 virtual void adjustment_set_upper(int upper) override { m_xScrollBar->SetRangeMax(upper); }
2537
2538 virtual int adjustment_get_lower() const override { return m_xScrollBar->GetRangeMin(); }
2539
2540 virtual void adjustment_set_lower(int lower) override { m_xScrollBar->SetRangeMin(lower); }
2541
2542 virtual int adjustment_get_page_size() const override { return m_xScrollBar->GetVisibleSize(); }
2543
2544 virtual void adjustment_set_page_size(int size) override { m_xScrollBar->SetVisibleSize(size); }
2545
2546 virtual int adjustment_get_page_increment() const override
2547 {
2548 return m_xScrollBar->GetPageSize();
2549 }
2550
2551 virtual void adjustment_set_page_increment(int size) override
2552 {
2553 m_xScrollBar->SetPageSize(size);
2554 }
2555
2556 virtual int adjustment_get_step_increment() const override
2557 {
2558 return m_xScrollBar->GetLineSize();
2559 }
2560
2561 virtual void adjustment_set_step_increment(int size) override
2562 {
2563 m_xScrollBar->SetLineSize(size);
2564 }
2565
2566 virtual ScrollType get_scroll_type() const override { return m_xScrollBar->GetType(); }
2567
2568 virtual int get_scroll_thickness() const override
2569 {
2570 if (m_xScrollBar->GetStyle() & WB_HORZ)
2571 return m_xScrollBar->get_preferred_size().Height();
2572 return m_xScrollBar->get_preferred_size().Width();
2573 }
2574
2575 virtual void set_scroll_thickness(int nThickness) override
2576 {
2577 if (m_xScrollBar->GetStyle() & WB_HORZ)
2578 m_xScrollBar->set_height_request(nThickness);
2579 else
2580 m_xScrollBar->set_width_request(nThickness);
2581 }
2582};
2583}
2584
2585IMPL_LINK_NOARG(SalInstanceScrollbar, ScrollHdl, ScrollBar*, void) { signal_adjustment_changed(); }
2586
2588 bool bTakeOwnership)
2589 : SalInstanceWidget(pNotebook, pBuilder, bTakeOwnership)
2590 , m_xNotebook(pNotebook)
2591{
2592 m_xNotebook->SetActivatePageHdl(LINK(this, SalInstanceNotebook, ActivatePageHdl));
2593 m_xNotebook->SetDeactivatePageHdl(LINK(this, SalInstanceNotebook, DeactivatePageHdl));
2594}
2595
2597{
2599}
2600
2602{
2604}
2605
2607{
2609}
2610
2611int SalInstanceNotebook::get_page_index(const OString& rIdent) const
2612{
2613 sal_uInt16 nPageId = m_xNotebook->GetPageId(rIdent);
2614 sal_uInt16 nPageIndex = m_xNotebook->GetPagePos(nPageId);
2615 if (nPageIndex == TAB_PAGE_NOTFOUND)
2616 return -1;
2617 return nPageIndex;
2618}
2619
2621{
2622 int nPageIndex = get_page_index(rIdent);
2623 if (nPageIndex == -1)
2624 return nullptr;
2625 sal_uInt16 nPageId = m_xNotebook->GetPageId(rIdent);
2627 vcl::Window* pChild = pPage->GetChild(0);
2628 if (m_aPages.size() < nPageIndex + 1U)
2629 m_aPages.resize(nPageIndex + 1U);
2630 if (!m_aPages[nPageIndex])
2631 m_aPages[nPageIndex] = std::make_shared<SalInstanceContainer>(pChild, m_pBuilder, false);
2632 return m_aPages[nPageIndex].get();
2633}
2634
2636{
2638}
2639
2640void SalInstanceNotebook::set_current_page(const OString& rIdent)
2641{
2643}
2644
2645void SalInstanceNotebook::remove_page(const OString& rIdent)
2646{
2647 sal_uInt16 nPageId = m_xNotebook->GetPageId(rIdent);
2648 sal_uInt16 nPageIndex = m_xNotebook->GetPagePos(nPageId);
2649 if (nPageIndex == TAB_PAGE_NOTFOUND)
2650 return;
2651
2653 if (nPageIndex < m_aPages.size())
2654 m_aPages.erase(m_aPages.begin() + nPageIndex);
2655
2656 auto iter = m_aAddedPages.find(rIdent);
2657 if (iter != m_aAddedPages.end())
2658 {
2659 iter->second.second.disposeAndClear();
2660 iter->second.first.disposeAndClear();
2661 m_aAddedPages.erase(iter);
2662 }
2663}
2664
2665void SalInstanceNotebook::insert_page(const OString& rIdent, const OUString& rLabel, int nPos)
2666{
2667 sal_uInt16 nPageCount = m_xNotebook->GetPageCount();
2668 sal_uInt16 nLastPageId = nPageCount ? m_xNotebook->GetPageId(nPageCount - 1) : 0;
2669 sal_uInt16 nNewPageId = nLastPageId + 1;
2670 while (m_xNotebook->GetPagePos(nNewPageId) != TAB_PAGE_NOTFOUND)
2671 ++nNewPageId;
2672 m_xNotebook->InsertPage(nNewPageId, rLabel, nPos == -1 ? TAB_APPEND : nPos);
2674 VclPtrInstance<VclGrid> xGrid(xPage);
2675 xPage->Show();
2676 xGrid->set_hexpand(true);
2677 xGrid->set_vexpand(true);
2678 xGrid->Show();
2679 m_xNotebook->SetTabPage(nNewPageId, xPage);
2680 m_xNotebook->SetPageName(nNewPageId, rIdent);
2681 m_aAddedPages.try_emplace(rIdent, xPage, xGrid);
2682
2683 if (nPos != -1)
2684 {
2685 unsigned int nPageIndex = static_cast<unsigned int>(nPos);
2686 if (nPageIndex < m_aPages.size())
2687 m_aPages.insert(m_aPages.begin() + nPageIndex, nullptr);
2688 }
2689}
2690
2692
2693OUString SalInstanceNotebook::get_tab_label_text(const OString& rIdent) const
2694{
2695 return m_xNotebook->GetPageText(m_xNotebook->GetPageId(rIdent));
2696}
2697
2698void SalInstanceNotebook::set_tab_label_text(const OString& rIdent, const OUString& rText)
2699{
2700 return m_xNotebook->SetPageText(m_xNotebook->GetPageId(rIdent), rText);
2701}
2702
2704{
2705 m_xNotebook->set_property("show-tabs", OUString::boolean(bShow));
2706}
2707
2709{
2710 for (auto& rItem : m_aAddedPages)
2711 {
2712 rItem.second.second.disposeAndClear();
2713 rItem.second.first.disposeAndClear();
2714 }
2717}
2718
2720{
2721 return !m_aLeavePageHdl.IsSet() || m_aLeavePageHdl.Call(get_current_page_ident());
2722}
2723
2725{
2726 m_aEnterPageHdl.Call(get_current_page_ident());
2727}
2728
2729namespace
2730{
2731class SalInstanceVerticalNotebook : public SalInstanceWidget, public virtual weld::Notebook
2732{
2733private:
2734 VclPtr<VerticalTabControl> m_xNotebook;
2735 mutable std::vector<std::unique_ptr<SalInstanceContainer>> m_aPages;
2736
2737 DECL_LINK(DeactivatePageHdl, VerticalTabControl*, bool);
2738 DECL_LINK(ActivatePageHdl, VerticalTabControl*, void);
2739
2740public:
2741 SalInstanceVerticalNotebook(VerticalTabControl* pNotebook, SalInstanceBuilder* pBuilder,
2742 bool bTakeOwnership)
2743 : SalInstanceWidget(pNotebook, pBuilder, bTakeOwnership)
2744 , m_xNotebook(pNotebook)
2745 {
2746 m_xNotebook->SetActivatePageHdl(LINK(this, SalInstanceVerticalNotebook, ActivatePageHdl));
2747 m_xNotebook->SetDeactivatePageHdl(
2748 LINK(this, SalInstanceVerticalNotebook, DeactivatePageHdl));
2749 }
2750
2751 virtual int get_current_page() const override
2752 {
2753 return m_xNotebook->GetPagePos(m_xNotebook->GetCurPageId());
2754 }
2755
2756 virtual OString get_page_ident(int nPage) const override
2757 {
2758 return m_xNotebook->GetPageId(nPage);
2759 }
2760
2761 virtual OString get_current_page_ident() const override { return m_xNotebook->GetCurPageId(); }
2762
2763 virtual int get_page_index(const OString& rIdent) const override
2764 {
2765 sal_uInt16 nPageIndex = m_xNotebook->GetPagePos(rIdent);
2766 if (nPageIndex == TAB_PAGE_NOTFOUND)
2767 return -1;
2768 return nPageIndex;
2769 }
2770
2771 virtual weld::Container* get_page(const OString& rIdent) const override
2772 {
2773 int nPageIndex = get_page_index(rIdent);
2774 if (nPageIndex == -1)
2775 return nullptr;
2776 auto pChild = m_xNotebook->GetPage(rIdent);
2777 if (m_aPages.size() < nPageIndex + 1U)
2778 m_aPages.resize(nPageIndex + 1U);
2779 if (!m_aPages[nPageIndex])
2780 m_aPages[nPageIndex].reset(new SalInstanceContainer(pChild, m_pBuilder, false));
2781 return m_aPages[nPageIndex].get();
2782 }
2783
2784 virtual void set_current_page(int nPage) override
2785 {
2786 m_xNotebook->SetCurPageId(m_xNotebook->GetPageId(nPage));
2787 }
2788
2789 virtual void set_current_page(const OString& rIdent) override
2790 {
2791 m_xNotebook->SetCurPageId(rIdent);
2792 }
2793
2794 virtual void remove_page(const OString& rIdent) override
2795 {
2796 sal_uInt16 nPageIndex = m_xNotebook->GetPagePos(rIdent);
2797 if (nPageIndex == TAB_PAGE_NOTFOUND)
2798 return;
2799 m_xNotebook->RemovePage(rIdent);
2800 if (nPageIndex < m_aPages.size())
2801 m_aPages.erase(m_aPages.begin() + nPageIndex);
2802 }
2803
2804 virtual void insert_page(const OString& rIdent, const OUString& rLabel, int nPos) override
2805 {
2806 VclPtrInstance<VclGrid> xGrid(m_xNotebook->GetPageParent());
2807 xGrid->set_hexpand(true);
2808 xGrid->set_vexpand(true);
2809 m_xNotebook->InsertPage(rIdent, rLabel, Image(), "", xGrid, nPos);
2810
2811 if (nPos != -1)
2812 {
2813 unsigned int nPageIndex = static_cast<unsigned int>(nPos);
2814 if (nPageIndex < m_aPages.size())
2815 m_aPages.insert(m_aPages.begin() + nPageIndex, nullptr);
2816 }
2817 }
2818
2819 virtual int get_n_pages() const override { return m_xNotebook->GetPageCount(); }
2820
2821 virtual void set_tab_label_text(const OString& rIdent, const OUString& rText) override
2822 {
2823 return m_xNotebook->SetPageText(rIdent, rText);
2824 }
2825
2826 virtual OUString get_tab_label_text(const OString& rIdent) const override
2827 {
2828 return m_xNotebook->GetPageText(rIdent);
2829 }
2830
2831 virtual void set_show_tabs(bool /*bShow*/) override
2832 {
2833 // if someone needs this they will have to implement it in VerticalTabControl
2834 assert(false && "not implemented");
2835 }
2836
2837 virtual ~SalInstanceVerticalNotebook() override
2838 {
2841 }
2842};
2843}
2844
2845IMPL_LINK_NOARG(SalInstanceVerticalNotebook, DeactivatePageHdl, VerticalTabControl*, bool)
2846{
2847 return !m_aLeavePageHdl.IsSet() || m_aLeavePageHdl.Call(get_current_page_ident());
2848}
2849
2850IMPL_LINK_NOARG(SalInstanceVerticalNotebook, ActivatePageHdl, VerticalTabControl*, void)
2851{
2852 m_aEnterPageHdl.Call(get_current_page_ident());
2853}
2854
2856 bool bTakeOwnership)
2857 : SalInstanceWidget(pButton, pBuilder, bTakeOwnership)
2858 , m_xButton(pButton)
2859 , m_aOldClickHdl(pButton->GetClickHdl())
2860{
2861 m_xButton->SetClickHdl(LINK(this, SalInstanceButton, ClickHdl));
2862}
2863
2864void SalInstanceButton::set_label(const OUString& rText) { m_xButton->SetText(rText); }
2865
2867{
2868 m_xButton->SetImageAlign(ImageAlign::Left);
2869 if (pDevice)
2870 m_xButton->SetModeImage(createImage(*pDevice));
2871 else
2872 m_xButton->SetModeImage(Image());
2873}
2874
2875void SalInstanceButton::set_image(const css::uno::Reference<css::graphic::XGraphic>& rImage)
2876{
2877 m_xButton->SetImageAlign(ImageAlign::Left);
2878 m_xButton->SetModeImage(Image(rImage));
2879}
2880
2881void SalInstanceButton::set_from_icon_name(const OUString& rIconName)
2882{
2883 m_xButton->SetModeImage(Image(StockImage::Yes, rIconName));
2884}
2885
2887{
2888 WinBits nBits = m_xButton->GetStyle();
2889 nBits &= ~WB_WORDBREAK;
2890 if (wrap)
2891 nBits |= WB_WORDBREAK;
2892 m_xButton->SetStyle(nBits);
2893 m_xButton->queue_resize();
2894}
2895
2897{
2898 m_xButton->SetControlFont(rFont);
2899 m_xButton->Invalidate();
2900}
2901
2903{
2904 if (pDevice)
2905 m_xButton->SetCustomButtonImage(createImage(*pDevice));
2906 else
2907 m_xButton->SetCustomButtonImage(Image());
2908 m_xButton->Invalidate();
2909}
2910
2911OUString SalInstanceButton::get_label() const { return m_xButton->GetText(); }
2912
2914
2915IMPL_LINK(SalInstanceButton, ClickHdl, ::Button*, pButton, void)
2916{
2917 //if there's no handler set, disengage our intercept and
2918 //run the click again to get default behaviour for cancel/ok
2919 //etc buttons.
2920 if (!m_aClickHdl.IsSet())
2921 {
2922 pButton->SetClickHdl(m_aOldClickHdl);
2923 pButton->Click();
2924 pButton->SetClickHdl(LINK(this, SalInstanceButton, ClickHdl));
2925 return;
2926 }
2927 signal_clicked();
2928}
2929
2931{
2932 PushButton* pButton = dynamic_cast<PushButton*>(m_xDialog->get_widget_for_response(nResponse));
2933 return pButton ? new SalInstanceButton(pButton, nullptr, false) : nullptr;
2934}
2935
2936weld::Button* SalInstanceAssistant::weld_widget_for_response(int nResponse)
2937{
2938 PushButton* pButton = nullptr;
2939 if (nResponse == RET_YES)
2940 pButton = m_xWizard->m_pNextPage;
2941 else if (nResponse == RET_NO)
2942 pButton = m_xWizard->m_pPrevPage;
2943 else if (nResponse == RET_OK)
2944 pButton = m_xWizard->m_pFinish;
2945 else if (nResponse == RET_CANCEL)
2946 pButton = m_xWizard->m_pCancel;
2947 else if (nResponse == RET_HELP)
2948 pButton = m_xWizard->m_pHelp;
2949 if (pButton)
2950 return new SalInstanceButton(pButton, nullptr, false);
2951 return nullptr;
2952}
2953
2955 bool bTakeOwnership)
2956 : SalInstanceButton(pButton, pBuilder, bTakeOwnership)
2957 , m_xMenuButton(pButton)
2958 , m_nLastId(0)
2959{
2960 m_xMenuButton->SetActivateHdl(LINK(this, SalInstanceMenuButton, ActivateHdl));
2961 m_xMenuButton->SetSelectHdl(LINK(this, SalInstanceMenuButton, MenuSelectHdl));
2962 if (PopupMenu* pMenu = m_xMenuButton->GetPopupMenu())
2963 {
2965 const auto nCount = pMenu->GetItemCount();
2966 m_nLastId = nCount ? pMenu->GetItemId(nCount - 1) : 0;
2967 }
2968}
2969
2971{
2972 if (active == get_active())
2973 return;
2974 if (active)
2975 m_xMenuButton->ExecuteMenu();
2976 else
2977 m_xMenuButton->CancelMenu();
2978}
2979
2980bool SalInstanceMenuButton::get_active() const { return m_xMenuButton->InPopupMode(); }
2981
2983{
2984 //not available
2985}
2986
2987bool SalInstanceMenuButton::get_inconsistent() const { return false; }
2988
2989void SalInstanceMenuButton::insert_item(int pos, const OUString& rId, const OUString& rStr,
2990 const OUString* pIconName, VirtualDevice* pImageSurface,
2991 TriState eCheckRadioFalse)
2992{
2993 m_nLastId = insert_to_menu(m_nLastId, m_xMenuButton->GetPopupMenu(), pos, rId, rStr, pIconName,
2994 pImageSurface, nullptr, eCheckRadioFalse);
2995}
2996
2997void SalInstanceMenuButton::insert_separator(int pos, const OUString& rId)
2998{
2999 auto nInsertPos = pos == -1 ? MENU_APPEND : pos;
3000 m_xMenuButton->GetPopupMenu()->InsertSeparator(rId.toUtf8(), nInsertPos);
3001}
3002
3003void SalInstanceMenuButton::set_item_sensitive(const OString& rIdent, bool bSensitive)
3004{
3005 PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
3006 pMenu->EnableItem(rIdent, bSensitive);
3007}
3008
3010{
3011 PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
3012 pMenu->RemoveItem(pMenu->GetItemPos(pMenu->GetItemId(rId)));
3013}
3014
3016{
3017 PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
3018 pMenu->Clear();
3019}
3020
3021void SalInstanceMenuButton::set_item_active(const OString& rIdent, bool bActive)
3022{
3023 PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
3024 pMenu->CheckItem(rIdent, bActive);
3025}
3026
3027void SalInstanceMenuButton::set_item_label(const OString& rIdent, const OUString& rText)
3028{
3029 PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
3030 pMenu->SetItemText(pMenu->GetItemId(rIdent), rText);
3031}
3032
3033OUString SalInstanceMenuButton::get_item_label(const OString& rIdent) const
3034{
3035 PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
3036 return pMenu->GetItemText(pMenu->GetItemId(rIdent));
3037}
3038
3039void SalInstanceMenuButton::set_item_visible(const OString& rIdent, bool bShow)
3040{
3041 PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
3042 pMenu->ShowItem(pMenu->GetItemId(rIdent), bShow);
3043}
3044
3046{
3047 SalInstanceWidget* pPopoverWidget = dynamic_cast<SalInstanceWidget*>(pPopover);
3048 m_xMenuButton->SetPopover(pPopoverWidget ? pPopoverWidget->getWidget() : nullptr);
3049}
3050
3052{
3054 m_xMenuButton->SetActivateHdl(Link<::MenuButton*, void>());
3055}
3056
3058{
3059 signal_selected(m_xMenuButton->GetCurItemIdent());
3060}
3061
3063{
3064 if (notify_events_disabled())
3065 return;
3066 signal_toggled();
3067}
3068
3069namespace
3070{
3071class SalInstanceMenuToggleButton : public SalInstanceMenuButton,
3072 public virtual weld::MenuToggleButton
3073{
3074private:
3075 VclPtr<::MenuToggleButton> m_xMenuToggleButton;
3076
3077public:
3078 SalInstanceMenuToggleButton(::MenuToggleButton* pButton, SalInstanceBuilder* pBuilder,
3079 bool bTakeOwnership)
3080 : SalInstanceMenuButton(pButton, pBuilder, bTakeOwnership)
3081 , m_xMenuToggleButton(pButton)
3082 {
3083 m_xMenuToggleButton->SetDelayMenu(true);
3084 m_xMenuToggleButton->SetDropDown(PushButtonDropdownStyle::SplitMenuButton);
3085 }
3086
3087 virtual void set_active(bool active) override
3088 {
3090 m_xMenuToggleButton->SetActive(active);
3092 }
3093
3094 virtual bool get_active() const override { return m_xMenuToggleButton->GetActive(); }
3095};
3096}
3097
3098namespace
3099{
3100class SalInstanceLinkButton : public SalInstanceWidget, public virtual weld::LinkButton
3101{
3102private:
3103 VclPtr<FixedHyperlink> m_xButton;
3104 Link<FixedHyperlink&, void> m_aOrigClickHdl;
3105
3106 DECL_LINK(ClickHdl, FixedHyperlink&, void);
3107
3108public:
3109 SalInstanceLinkButton(FixedHyperlink* pButton, SalInstanceBuilder* pBuilder,
3110 bool bTakeOwnership)
3111 : SalInstanceWidget(pButton, pBuilder, bTakeOwnership)
3112 , m_xButton(pButton)
3113 {
3114 m_aOrigClickHdl = m_xButton->GetClickHdl();
3115 m_xButton->SetClickHdl(LINK(this, SalInstanceLinkButton, ClickHdl));
3116 }
3117
3118 virtual void set_label(const OUString& rText) override { m_xButton->SetText(rText); }
3119
3120 virtual OUString get_label() const override { return m_xButton->GetText(); }
3121
3122 virtual void set_uri(const OUString& rUri) override { m_xButton->SetURL(rUri); }
3123
3124 virtual OUString get_uri() const override { return m_xButton->GetURL(); }
3125
3126 virtual ~SalInstanceLinkButton() override { m_xButton->SetClickHdl(m_aOrigClickHdl); }
3127};
3128}
3129
3130IMPL_LINK(SalInstanceLinkButton, ClickHdl, FixedHyperlink&, rButton, void)
3131{
3132 bool bConsumed = signal_activate_link();
3133 if (!bConsumed)
3134 m_aOrigClickHdl.Call(rButton);
3135}
3136
3138 bool bTakeOwnership)
3139 : SalInstanceButton(pButton, pBuilder, bTakeOwnership)
3140 , m_xRadioButton(pButton)
3141{
3142 m_xRadioButton->SetToggleHdl(LINK(this, SalInstanceRadioButton, ToggleHdl));
3143}
3144
3146{
3148 m_xRadioButton->Check(active);
3150}
3151
3152bool SalInstanceRadioButton::get_active() const { return m_xRadioButton->IsChecked(); }
3153
3155{
3156 m_xRadioButton->SetImageAlign(ImageAlign::Center);
3157 if (pDevice)
3158 m_xRadioButton->SetModeImage(createImage(*pDevice));
3159 else
3160 m_xRadioButton->SetModeImage(Image());
3161}
3162
3163void SalInstanceRadioButton::set_image(const css::uno::Reference<css::graphic::XGraphic>& rImage)
3164{
3165 m_xRadioButton->SetImageAlign(ImageAlign::Center);
3166 m_xRadioButton->SetModeImage(Image(rImage));
3167}
3168
3169void SalInstanceRadioButton::set_from_icon_name(const OUString& rIconName)
3170{
3171 m_xRadioButton->SetModeRadioImage(Image(StockImage::Yes, rIconName));
3172}
3173
3175{
3176 //not available
3177}
3178
3179bool SalInstanceRadioButton::get_inconsistent() const { return false; }
3180
3182{
3184}
3185
3187{
3188 if (notify_events_disabled())
3189 return;
3190 signal_toggled();
3191}
3192
3193namespace
3194{
3195class SalInstanceToggleButton : public SalInstanceButton, public virtual weld::ToggleButton
3196{
3197private:
3198 VclPtr<PushButton> m_xToggleButton;
3199
3200 DECL_LINK(ToggleListener, VclWindowEvent&, void);
3201
3202public:
3203 SalInstanceToggleButton(PushButton* pButton, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3204 : SalInstanceButton(pButton, pBuilder, bTakeOwnership)
3205 , m_xToggleButton(pButton)
3206 {
3207 }
3208
3209 virtual void connect_toggled(const Link<Toggleable&, void>& rLink) override
3210 {
3211 assert(!m_aToggleHdl.IsSet());
3212 m_xToggleButton->AddEventListener(LINK(this, SalInstanceToggleButton, ToggleListener));
3214 }
3215
3216 virtual void set_active(bool active) override
3217 {
3219 m_xToggleButton->Check(active);
3221 }
3222
3223 virtual bool get_active() const override { return m_xToggleButton->IsChecked(); }
3224
3225 virtual void set_inconsistent(bool inconsistent) override
3226 {
3228 m_xToggleButton->SetState(inconsistent ? TRISTATE_INDET : TRISTATE_FALSE);
3230 }
3231
3232 virtual bool get_inconsistent() const override
3233 {
3234 return m_xToggleButton->GetState() == TRISTATE_INDET;
3235 }
3236
3237 virtual ~SalInstanceToggleButton() override
3238 {
3239 if (m_aToggleHdl.IsSet())
3240 m_xToggleButton->RemoveEventListener(
3241 LINK(this, SalInstanceToggleButton, ToggleListener));
3242 }
3243};
3244}
3245
3246IMPL_LINK(SalInstanceToggleButton, ToggleListener, VclWindowEvent&, rEvent, void)
3247{
3248 if (notify_events_disabled())
3249 return;
3250 if (rEvent.GetId() == VclEventId::PushbuttonToggle)
3251 signal_toggled();
3252}
3253
3255 bool bTakeOwnership)
3256 : SalInstanceButton(pButton, pBuilder, bTakeOwnership)
3257 , m_xCheckButton(pButton)
3258{
3260}
3261
3263{
3266 m_xCheckButton->Check(active);
3268}
3269
3271
3273{
3278}
3279
3281{
3283}
3284
3286{
3288}
3289
3291{
3292 if (notify_events_disabled())
3293 return;
3294 m_xCheckButton->EnableTriState(false);
3295 signal_toggled();
3296}
3297
3298namespace
3299{
3300class SalInstanceScale : public SalInstanceWidget, public virtual weld::Scale
3301{
3302private:
3303 VclPtr<Slider> m_xScale;
3304
3305 DECL_LINK(SlideHdl, Slider*, void);
3306
3307public:
3308 SalInstanceScale(Slider* pScale, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3309 : SalInstanceWidget(pScale, pBuilder, bTakeOwnership)
3310 , m_xScale(pScale)
3311 {
3312 m_xScale->SetSlideHdl(LINK(this, SalInstanceScale, SlideHdl));
3313 }
3314
3315 virtual void set_value(int value) override { m_xScale->SetThumbPos(value); }
3316
3317 virtual void set_range(int min, int max) override
3318 {
3319 m_xScale->SetRangeMin(min);
3320 m_xScale->SetRangeMax(max);
3321 }
3322
3323 virtual int get_value() const override { return m_xScale->GetThumbPos(); }
3324
3325 virtual void set_increments(int step, int page) override
3326 {
3327 m_xScale->SetLineSize(step);
3328 m_xScale->SetPageSize(page);
3329 }
3330
3331 virtual void get_increments(int& step, int& page) const override
3332 {
3333 step = m_xScale->GetLineSize();
3334 page = m_xScale->GetPageSize();
3335 }
3336
3337 virtual ~SalInstanceScale() override { m_xScale->SetSlideHdl(Link<Slider*, void>()); }
3338};
3339}
3340
3341IMPL_LINK_NOARG(SalInstanceScale, SlideHdl, Slider*, void) { signal_value_changed(); }
3342
3343namespace
3344{
3345class SalInstanceSpinner : public SalInstanceWidget, public virtual weld::Spinner
3346{
3347private:
3348 VclPtr<Throbber> m_xThrobber;
3349
3350public:
3351 SalInstanceSpinner(Throbber* pThrobber, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3352 : SalInstanceWidget(pThrobber, pBuilder, bTakeOwnership)
3353 , m_xThrobber(pThrobber)
3354 {
3355 }
3356
3357 virtual void start() override { m_xThrobber->start(); }
3358
3359 virtual void stop() override { m_xThrobber->stop(); }
3360};
3361
3362class SalInstanceProgressBar : public SalInstanceWidget, public virtual weld::ProgressBar
3363{
3364private:
3365 VclPtr<::ProgressBar> m_xProgressBar;
3366
3367public:
3368 SalInstanceProgressBar(::ProgressBar* pProgressBar, SalInstanceBuilder* pBuilder,
3369 bool bTakeOwnership)
3370 : SalInstanceWidget(pProgressBar, pBuilder, bTakeOwnership)
3371 , m_xProgressBar(pProgressBar)
3372 {
3373 }
3374
3375 virtual void set_percentage(int value) override { m_xProgressBar->SetValue(value); }
3376
3377 virtual OUString get_text() const override { return m_xProgressBar->GetText(); }
3378
3379 virtual void set_text(const OUString& rText) override { m_xProgressBar->SetText(rText); }
3380};
3381
3382class SalInstanceCalendar : public SalInstanceWidget, public virtual weld::Calendar
3383{
3384private:
3385 VclPtr<::Calendar> m_xCalendar;
3386
3387 DECL_LINK(SelectHdl, ::Calendar*, void);
3388 DECL_LINK(ActivateHdl, ::Calendar*, void);
3389
3390public:
3391 SalInstanceCalendar(::Calendar* pCalendar, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3392 : SalInstanceWidget(pCalendar, pBuilder, bTakeOwnership)
3393 , m_xCalendar(pCalendar)
3394 {
3395 m_xCalendar->SetSelectHdl(LINK(this, SalInstanceCalendar, SelectHdl));
3396 m_xCalendar->SetActivateHdl(LINK(this, SalInstanceCalendar, ActivateHdl));
3397 }
3398
3399 virtual void set_date(const Date& rDate) override { m_xCalendar->SetCurDate(rDate); }
3400
3401 virtual Date get_date() const override { return m_xCalendar->GetFirstSelectedDate(); }
3402
3403 virtual ~SalInstanceCalendar() override
3404 {
3405 m_xCalendar->SetSelectHdl(Link<::Calendar*, void>());
3406 m_xCalendar->SetActivateHdl(Link<::Calendar*, void>());
3407 }
3408};
3409}
3410
3411IMPL_LINK_NOARG(SalInstanceCalendar, SelectHdl, ::Calendar*, void)
3412{
3413 if (notify_events_disabled())
3414 return;
3415 signal_selected();
3416}
3417
3418IMPL_LINK_NOARG(SalInstanceCalendar, ActivateHdl, ::Calendar*, void)
3419{
3420 if (notify_events_disabled())
3421 return;
3422 signal_activated();
3423}
3424
3426 bool bTakeOwnership)
3427 : SalInstanceWidget(pImage, pBuilder, bTakeOwnership)
3428 , m_xImage(pImage)
3429{
3430}
3431
3432void SalInstanceImage::set_from_icon_name(const OUString& rIconName)
3433{
3435}
3436
3438{
3439 if (pDevice)
3440 m_xImage->SetImage(createImage(*pDevice));
3441 else
3443}
3444
3445void SalInstanceImage::set_image(const css::uno::Reference<css::graphic::XGraphic>& rImage)
3446{
3447 m_xImage->SetImage(::Image(rImage));
3448}
3449
3451 : TextFilter(OUString())
3452 , m_rInsertTextHdl(rInsertTextHdl)
3453{
3454}
3455
3456OUString WeldTextFilter::filter(const OUString& rText)
3457{
3458 if (!m_rInsertTextHdl.IsSet())
3459 return rText;
3460 OUString sText(rText);
3461 const bool bContinue = m_rInsertTextHdl.Call(sText);
3462 if (!bContinue)
3463 return OUString();
3464 return sText;
3465}
3466
3467SalInstanceEntry::SalInstanceEntry(Edit* pEntry, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
3468 : SalInstanceWidget(pEntry, pBuilder, bTakeOwnership)
3469 , m_xEntry(pEntry)
3470 , m_aTextFilter(m_aInsertTextHdl)
3471{
3472 m_xEntry->SetModifyHdl(LINK(this, SalInstanceEntry, ChangeHdl));
3473 m_xEntry->SetActivateHdl(LINK(this, SalInstanceEntry, ActivateHdl));
3474 m_xEntry->SetTextFilter(&m_aTextFilter);
3475}
3476
3477void SalInstanceEntry::set_text(const OUString& rText)
3478{
3480 m_xEntry->SetText(rText);
3482}
3483
3484OUString SalInstanceEntry::get_text() const { return m_xEntry->GetText(); }
3485
3486void SalInstanceEntry::set_width_chars(int nChars) { m_xEntry->SetWidthInChars(nChars); }
3487
3488int SalInstanceEntry::get_width_chars() const { return m_xEntry->GetWidthInChars(); }
3489
3490void SalInstanceEntry::set_max_length(int nChars) { m_xEntry->SetMaxTextLen(nChars); }
3491
3492void SalInstanceEntry::select_region(int nStartPos, int nEndPos)
3493{
3495 tools::Long nStart = nStartPos < 0 ? SELECTION_MAX : nStartPos;
3496 tools::Long nEnd = nEndPos < 0 ? SELECTION_MAX : nEndPos;
3497 m_xEntry->SetSelection(Selection(nStart, nEnd));
3499}
3500
3501bool SalInstanceEntry::get_selection_bounds(int& rStartPos, int& rEndPos)
3502{
3503 const Selection& rSelection = m_xEntry->GetSelection();
3504 rStartPos = rSelection.Min();
3505 rEndPos = rSelection.Max();
3506 return rSelection.Len();
3507}
3508
3509void SalInstanceEntry::replace_selection(const OUString& rText)
3510{
3511 m_xEntry->ReplaceSelected(rText);
3512}
3513
3515{
3517 if (nCursorPos < 0)
3518 m_xEntry->SetCursorAtLast();
3519 else
3520 m_xEntry->SetSelection(Selection(nCursorPos, nCursorPos));
3522}
3523
3524int SalInstanceEntry::get_position() const { return m_xEntry->GetSelection().Max(); }
3525
3526void SalInstanceEntry::set_editable(bool bEditable) { m_xEntry->SetReadOnly(!bEditable); }
3527
3528bool SalInstanceEntry::get_editable() const { return !m_xEntry->IsReadOnly(); }
3529
3530void SalInstanceEntry::set_overwrite_mode(bool bOn) { m_xEntry->SetInsertMode(!bOn); }
3531
3532bool SalInstanceEntry::get_overwrite_mode() const { return !m_xEntry->IsInsertMode(); }
3533
3534namespace
3535{
3536void set_message_type(Edit* pEntry, weld::EntryMessageType eType)
3537{
3538 switch (eType)
3539 {
3541 pEntry->SetForceControlBackground(false);
3542 pEntry->SetControlForeground();
3543 pEntry->SetControlBackground();
3544 break;
3546 // tdf#114603: enable setting the background to a different color;
3547 // relevant for GTK; see also #i75179#
3548 pEntry->SetForceControlBackground(true);
3549 pEntry->SetControlForeground(COL_BLACK);
3550 pEntry->SetControlBackground(COL_YELLOW);
3551 break;
3553 // tdf#114603: enable setting the background to a different color;
3554 // relevant for GTK; see also #i75179#
3555 pEntry->SetForceControlBackground(true);
3556 pEntry->SetControlForeground(COL_WHITE);
3557 pEntry->SetControlBackground(0xff6563);
3558 break;
3559 }
3560}
3561}
3562
3564{
3566}
3567
3569{
3570 m_xEntry->SetControlFont(rFont);
3571 m_xEntry->Invalidate();
3572}
3573
3575{
3576 if (rColor == COL_AUTO)
3577 m_xEntry->SetControlForeground();
3578 else
3579 m_xEntry->SetControlForeground(rColor);
3580}
3581
3583{
3584 assert(!m_aCursorPositionHdl.IsSet());
3585 m_xEntry->AddEventListener(LINK(this, SalInstanceEntry, CursorListener));
3587}
3588
3590{
3591 m_xEntry->SetPlaceholderText(rText);
3592}
3593
3595
3597
3599{
3600 m_xEntry->Cut();
3601 m_xEntry->Modify();
3602}
3603
3605
3607{
3608 m_xEntry->Paste();
3609 m_xEntry->Modify();
3610}
3611
3612namespace
3613{
3614void set_alignment(Edit& rEntry, TxtAlign eXAlign)
3615{
3616 WinBits nAlign(0);
3617 switch (eXAlign)
3618 {
3619 case TxtAlign::Left:
3620 nAlign = WB_LEFT;
3621 break;
3622 case TxtAlign::Center:
3623 nAlign = WB_CENTER;
3624 break;
3625 case TxtAlign::Right:
3626 nAlign = WB_RIGHT;
3627 break;
3628 }
3629 WinBits nBits = rEntry.GetStyle();
3630 nBits &= ~(WB_LEFT | WB_CENTER | WB_RIGHT);
3631 rEntry.SetStyle(nBits | nAlign);
3632}
3633}
3634
3636
3638{
3639 if (m_aCursorPositionHdl.IsSet())
3640 m_xEntry->RemoveEventListener(LINK(this, SalInstanceEntry, CursorListener));
3641 m_xEntry->SetTextFilter(nullptr);
3642 m_xEntry->SetActivateHdl(Link<Edit&, bool>());
3643 m_xEntry->SetModifyHdl(Link<Edit&, void>());
3644}
3645
3646IMPL_LINK_NOARG(SalInstanceEntry, ChangeHdl, Edit&, void) { signal_changed(); }
3647
3648IMPL_LINK(SalInstanceEntry, CursorListener, VclWindowEvent&, rEvent, void)
3649{
3650 if (notify_events_disabled())
3651 return;
3652 if (rEvent.GetId() == VclEventId::EditSelectionChanged
3653 || rEvent.GetId() == VclEventId::EditCaretChanged)
3654 signal_cursor_position();
3655}
3656
3657IMPL_LINK_NOARG(SalInstanceEntry, ActivateHdl, Edit&, bool) { return m_aActivateHdl.Call(*this); }
3658
3660
3662
3663namespace
3664{
3665// tdf#131581 if the TreeView is hidden then there are possibly additional
3666// optimizations available
3667class UpdateGuardIfHidden
3668{
3669private:
3670 SvTabListBox& m_rTreeView;
3671 bool m_bOrigUpdate;
3672 bool m_bOrigEnableInvalidate;
3673
3674public:
3675 UpdateGuardIfHidden(SvTabListBox& rTreeView)
3676 : m_rTreeView(rTreeView)
3677 // tdf#136962 only do SetUpdateMode(false) optimization if the widget is currently hidden
3678 , m_bOrigUpdate(!m_rTreeView.IsVisible() && m_rTreeView.IsUpdateMode())
3679 // tdf#137432 only do EnableInvalidate(false) optimization if the widget is currently hidden
3680 , m_bOrigEnableInvalidate(!m_rTreeView.IsVisible()
3681 && m_rTreeView.GetModel()->IsEnableInvalidate())
3682 {
3683 if (m_bOrigUpdate)
3684 m_rTreeView.SetUpdateMode(false);
3685 if (m_bOrigEnableInvalidate)
3686 m_rTreeView.GetModel()->EnableInvalidate(false);
3687 }
3688
3689 ~UpdateGuardIfHidden()
3690 {
3691 if (m_bOrigEnableInvalidate)
3692 m_rTreeView.GetModel()->EnableInvalidate(true);
3693 if (m_bOrigUpdate)
3694 m_rTreeView.SetUpdateMode(true);
3695 }
3696};
3697}
3698
3699// Each row has a cell for the expander image, (and an optional cell for a
3700// checkbutton if enable_toggle_buttons has been called) which precede
3701// index 0
3703{
3705 ++col; // skip checkbutton column
3706 ++col; //skip expander column
3707 return col;
3708}
3709
3711{
3713 --col; // skip checkbutton column
3714 --col; //skip expander column
3715 return col;
3716}
3717
3719{
3720 return o3tl::trim(m_xTreeView->GetEntryText(pEntry)) == u"<dummy>";
3721}
3722
3724{
3725 if (pEntry->HasChildren())
3726 {
3727 auto pChild = m_xTreeView->FirstChild(pEntry);
3728 assert(pChild);
3729 if (IsDummyEntry(pChild))
3730 return pChild;
3731 }
3732 return nullptr;
3733}
3734
3736{
3737 if (rColor == COL_AUTO)
3738 pEntry->SetTextColor(std::optional<Color>());
3739 else
3740 pEntry->SetTextColor(rColor);
3741}
3742
3743void SalInstanceTreeView::AddStringItem(SvTreeListEntry* pEntry, const OUString& rStr, int nCol)
3744{
3745 auto xCell = std::make_unique<SvLBoxString>(rStr);
3746 if (m_aCustomRenders.count(nCol))
3747 xCell->SetCustomRender();
3748 pEntry->AddItem(std::move(xCell));
3749}
3750
3751void SalInstanceTreeView::do_insert(const weld::TreeIter* pParent, int pos, const OUString* pStr,
3752 const OUString* pId, const OUString* pIconName,
3753 const VirtualDevice* pImageSurface, bool bChildrenOnDemand,
3754 weld::TreeIter* pRet, bool bIsSeparator)
3755{
3757 const SalInstanceTreeIter* pVclIter = static_cast<const SalInstanceTreeIter*>(pParent);
3758 SvTreeListEntry* iter = pVclIter ? pVclIter->iter : nullptr;
3759 auto nInsertPos = pos == -1 ? TREELIST_APPEND : pos;
3760 void* pUserData;
3761 if (pId)
3762 {
3763 m_aUserData.emplace_back(std::make_unique<OUString>(*pId));
3764 pUserData = m_aUserData.back().get();
3765 }
3766 else
3767 pUserData = nullptr;
3768
3769 SvTreeListEntry* pEntry = new SvTreeListEntry;
3770 if (bIsSeparator)
3771 pEntry->SetFlags(pEntry->GetFlags() | SvTLEntryFlags::IS_SEPARATOR);
3772
3774 AddStringItem(pEntry, "", -1);
3775
3776 if (pIconName || pImageSurface)
3777 {
3778 Image aImage(pIconName ? createImage(*pIconName) : createImage(*pImageSurface));
3779 pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(aImage, aImage, false));
3780 }
3781 else
3782 {
3783 Image aDummy;
3784 pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(aDummy, aDummy, false));
3785 }
3786 if (pStr)
3787 AddStringItem(pEntry, *pStr, 0);
3788 pEntry->SetUserData(pUserData);
3789 m_xTreeView->Insert(pEntry, iter, nInsertPos);
3790
3791 if (pRet)
3792 {
3793 SalInstanceTreeIter* pVclRetIter = static_cast<SalInstanceTreeIter*>(pRet);
3794 pVclRetIter->iter = pEntry;
3795 }
3796
3797 if (bChildrenOnDemand)
3798 {
3799 SvTreeListEntry* pPlaceHolder
3800 = m_xTreeView->InsertEntry("<dummy>", pEntry, false, 0, nullptr);
3801 SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pPlaceHolder);
3802 pViewData->SetSelectable(false);
3803 }
3804
3805 if (bIsSeparator)
3806 {
3807 SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry);
3808 pViewData->SetSelectable(false);
3809 }
3810
3812}
3813
3815{
3816 SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry);
3817 m_xTreeView->InitViewData(pViewData, pEntry);
3819}
3820
3822{
3824 return;
3826}
3827
3829{
3830 assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
3831 // if it's the placeholder to allow a blank column, replace it now
3832 if (pEntry->GetItem(col).GetType() != SvLBoxItemType::Button)
3833 {
3835 pEntry->ReplaceItem(std::make_unique<SvLBoxButton>(pData), 0);
3837 }
3838 SvLBoxItem& rItem = pEntry->GetItem(col);
3839 assert(dynamic_cast<SvLBoxButton*>(&rItem));
3840 switch (eState)
3841 {
3842 case TRISTATE_TRUE:
3843 static_cast<SvLBoxButton&>(rItem).SetStateChecked();
3844 break;
3845 case TRISTATE_FALSE:
3846 static_cast<SvLBoxButton&>(rItem).SetStateUnchecked();
3847 break;
3848 case TRISTATE_INDET:
3849 static_cast<SvLBoxButton&>(rItem).SetStateTristate();
3850 break;
3851 }
3852
3853 InvalidateModelEntry(pEntry);
3854}
3855
3857{
3858 if (static_cast<size_t>(col) == pEntry->ItemCount())
3859 return TRISTATE_FALSE;
3860
3861 assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
3862 SvLBoxItem& rItem = pEntry->GetItem(col);
3863 assert(dynamic_cast<SvLBoxButton*>(&rItem));
3864 SvLBoxButton& rToggle = static_cast<SvLBoxButton&>(rItem);
3865 if (rToggle.IsStateTristate())
3866 return TRISTATE_INDET;
3867 else if (rToggle.IsStateChecked())
3868 return TRISTATE_TRUE;
3869 return TRISTATE_FALSE;
3870}
3871
3873{
3874 if (col == -1)
3875 {
3877 return do_get_toggle(pEntry, 0);
3878 }
3879 col = to_internal_model(col);
3880 return do_get_toggle(pEntry, col);
3881}
3882
3884{
3885 if (col == -1)
3886 {
3888 do_set_toggle(pEntry, eState, 0);
3889 return;
3890 }
3891
3892 col = to_internal_model(col);
3893
3894 // blank out missing entries
3895 for (int i = pEntry->ItemCount(); i < col; ++i)
3896 AddStringItem(pEntry, "", i - 1);
3897
3898 if (static_cast<size_t>(col) == pEntry->ItemCount())
3899 {
3901 pEntry->AddItem(std::make_unique<SvLBoxButton>(pData));
3903 }
3904
3905 do_set_toggle(pEntry, eState, col);
3906}
3907
3909{
3910 col = to_internal_model(col);
3911
3912 assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
3913 SvLBoxItem& rItem = pEntry->GetItem(col);
3914 assert(dynamic_cast<SvLBoxString*>(&rItem));
3915 return static_cast<SvLBoxString&>(rItem).IsEmphasized();
3916}
3917
3918void SalInstanceTreeView::set_header_item_width(const std::vector<int>& rWidths)
3919{
3920 LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
3921 if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
3922 {
3923 for (size_t i = 0; i < rWidths.size(); ++i)
3924 pHeaderBar->SetItemSize(pHeaderBar->GetItemId(i), rWidths[i]);
3925 }
3926}
3927
3929 bool bTakeOwnership)
3930 : SalInstanceWidget(pTreeView, pBuilder, bTakeOwnership)
3931 , m_xTreeView(pTreeView)
3932 , m_aCheckButtonData(pTreeView, false)
3933 , m_aRadioButtonData(pTreeView, true)
3934 , m_bTogglesAsRadio(false)
3935 , m_nSortColumn(-1)
3936{
3940 m_xTreeView->SetDeselectHdl(LINK(this, SalInstanceTreeView, DeSelectHdl));
3941 m_xTreeView->SetDoubleClickHdl(LINK(this, SalInstanceTreeView, DoubleClickHdl));
3942 m_xTreeView->SetExpandingHdl(LINK(this, SalInstanceTreeView, ExpandingHdl));
3943 m_xTreeView->SetPopupMenuHdl(LINK(this, SalInstanceTreeView, PopupMenuHdl));
3944 m_xTreeView->SetCustomRenderHdl(LINK(this, SalInstanceTreeView, CustomRenderHdl));
3945 m_xTreeView->SetCustomMeasureHdl(LINK(this, SalInstanceTreeView, CustomMeasureHdl));
3946 const tools::Long aTabPositions[] = { 0 };
3947 m_xTreeView->SetTabs(SAL_N_ELEMENTS(aTabPositions), aTabPositions);
3948 LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
3949
3950 if (pHeaderBox)
3951 {
3952 if (HeaderBar* pHeaderBar = pHeaderBox->GetHeaderBar())
3953 {
3954 //make the last entry fill available space
3955 pHeaderBar->SetItemSize(pHeaderBar->GetItemId(pHeaderBar->GetItemCount() - 1),
3957 pHeaderBar->SetEndDragHdl(LINK(this, SalInstanceTreeView, EndDragHdl));
3958 pHeaderBar->SetSelectHdl(LINK(this, SalInstanceTreeView, HeaderBarClickedHdl));
3959 }
3960 pHeaderBox->SetEditingEntryHdl(LINK(this, SalInstanceTreeView, EditingEntryHdl));
3961 pHeaderBox->SetEditedEntryHdl(LINK(this, SalInstanceTreeView, EditedEntryHdl));
3962 }
3963 else
3964 {
3965 static_cast<LclTabListBox&>(*m_xTreeView)
3966 .SetModelChangedHdl(LINK(this, SalInstanceTreeView, ModelChangedHdl));
3967 static_cast<LclTabListBox&>(*m_xTreeView)
3968 .SetStartDragHdl(LINK(this, SalInstanceTreeView, StartDragHdl));
3969 static_cast<LclTabListBox&>(*m_xTreeView)
3970 .SetEndDragHdl(LINK(this, SalInstanceTreeView, FinishDragHdl));
3971 static_cast<LclTabListBox&>(*m_xTreeView)
3972 .SetEditingEntryHdl(LINK(this, SalInstanceTreeView, EditingEntryHdl));
3973 static_cast<LclTabListBox&>(*m_xTreeView)
3974 .SetEditedEntryHdl(LINK(this, SalInstanceTreeView, EditedEntryHdl));
3975 }
3978}
3979
3981{
3984}
3985
3987{
3988 std::vector<tools::Long> aWidths;
3990 if (aWidths.size() > 2)
3991 {
3992 std::vector<int> aColWidths;
3993 for (size_t i = 1; i < aWidths.size() - 1; ++i)
3994 aColWidths.push_back(aWidths[i] - aWidths[i - 1]);
3995 set_column_fixed_widths(aColWidths);
3996 }
3997}
3998
4000{
4001 bool bIsFirstFreeze = IsFirstFreeze();
4003 if (bIsFirstFreeze)
4004 {
4005 m_xTreeView->SetUpdateMode(false);
4007 }
4008}
4009
4011{
4012 bool bIsLastThaw = IsLastThaw();
4013 if (bIsLastThaw)
4014 {
4017 }
4019}
4020
4021void SalInstanceTreeView::set_column_fixed_widths(const std::vector<int>& rWidths)
4022{
4023 std::vector<tools::Long> aTabPositions{ 0 };
4024 for (size_t i = 0; i < rWidths.size(); ++i)
4025 aTabPositions.push_back(aTabPositions[i] + rWidths[i]);
4026 m_xTreeView->SetTabs(aTabPositions.size(), aTabPositions.data(), MapUnit::MapPixel);
4027 set_header_item_width(rWidths);
4028 // call Resize to recalculate based on the new tabs
4030}
4031
4032void SalInstanceTreeView::set_column_editables(const std::vector<bool>& rEditables)
4033{
4034 size_t nTabCount = rEditables.size();
4035 for (size_t i = 0; i < nTabCount; ++i)
4036 m_xTreeView->SetTabEditable(i, rEditables[i]);
4037}
4038
4040{
4042}
4043
4045{
4046 LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
4047 if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
4048 return pHeaderBar->GetItemSize(pHeaderBar->GetItemId(nColumn));
4049 // GetTab(0) gives the position of the bitmap which is automatically inserted by the TabListBox.
4050 // So the first text column's width is Tab(2)-Tab(1).
4051 auto nWidthPixel
4052 = m_xTreeView->GetLogicTab(nColumn + 2) - m_xTreeView->GetLogicTab(nColumn + 1);
4053 nWidthPixel -= SV_TAB_BORDER;
4054 return nWidthPixel;
4055}
4056
4057OUString SalInstanceTreeView::get_column_title(int nColumn) const
4058{
4059 LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
4060 if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
4061 {
4062 return pHeaderBar->GetItemText(pHeaderBar->GetItemId(nColumn));
4063 }
4064 return OUString();
4065}
4066
4067void SalInstanceTreeView::set_column_title(int nColumn, const OUString& rTitle)
4068{
4069 LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
4070 if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
4071 {
4072 return pHeaderBar->SetItemText(pHeaderBar->GetItemId(nColumn), rTitle);
4073 }
4074}
4075
4077{
4078 assert(n_children() == 0 && "tree must be empty");
4079 if (bEnable)
4080 m_aCustomRenders.insert(nColumn);
4081 else
4082 m_aCustomRenders.erase(nColumn);
4083}
4084
4086{
4087 // invalidate the entries
4088 SvTreeList* pModel = m_xTreeView->GetModel();
4089 for (SvTreeListEntry* pEntry = m_xTreeView->First(); pEntry; pEntry = m_xTreeView->Next(pEntry))
4090 pModel->InvalidateEntry(pEntry);
4091}
4092
4094{
4095 if (LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get()))
4096 pHeaderBox->GetParent()->Show();
4098}
4099
4101{
4102 if (LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get()))
4103 pHeaderBox->GetParent()->Hide();
4105}
4106
4107void SalInstanceTreeView::insert(const weld::TreeIter* pParent, int pos, const OUString* pStr,
4108 const OUString* pId, const OUString* pIconName,
4109 VirtualDevice* pImageSurface, bool bChildrenOnDemand,
4110 weld::TreeIter* pRet)
4111{
4112 do_insert(pParent, pos, pStr, pId, pIconName, pImageSurface, bChildrenOnDemand, pRet, false);
4113}
4114
4115void SalInstanceTreeView::insert_separator(int pos, const OUString& /*rId*/)
4116{
4117 OUString sSep(VclResId(STR_SEPARATOR));
4118 do_insert(nullptr, pos, &sSep, nullptr, nullptr, nullptr, false, nullptr, true);
4119}
4120
4122 int nSourceCount, const std::function<void(weld::TreeIter&, int nSourceIndex)>& func,
4123 const weld::TreeIter* pParent, const std::vector<int>* pFixedWidths)
4124{
4125 const SalInstanceTreeIter* pVclIter = static_cast<const SalInstanceTreeIter*>(pParent);
4126 SvTreeListEntry* pVclParent = pVclIter ? pVclIter->iter : nullptr;
4127
4128 freeze();
4129 if (!pVclParent)
4130 clear();
4131 else
4132 {
4133 while (SvTreeListEntry* pChild = m_xTreeView->FirstChild(pVclParent))
4134 m_xTreeView->RemoveEntry(pChild);
4135 }
4136 SalInstanceTreeIter aVclIter(static_cast<SvTreeListEntry*>(nullptr));
4137
4139
4140 if (pFixedWidths)
4141 set_header_item_width(*pFixedWidths);
4142
4143 bool bHasAutoCheckButton(m_xTreeView->nTreeFlags & SvTreeFlags::CHKBTN);
4144 size_t nExtraCols = bHasAutoCheckButton ? 2 : 1;
4145
4146 Image aDummy;
4147 for (int i = 0; i < nSourceCount; ++i)
4148 {
4149 aVclIter.iter = new SvTreeListEntry;
4150 if (bHasAutoCheckButton)
4151 AddStringItem(aVclIter.iter, "", -1);
4152 aVclIter.iter->AddItem(std::make_unique<SvLBoxContextBmp>(aDummy, aDummy, false));
4153 m_xTreeView->Insert(aVclIter.iter, pVclParent, TREELIST_APPEND);
4154 func(aVclIter, i);
4155
4156 if (!pFixedWidths)
4157 continue;
4158
4159 size_t nFixedWidths = std::min(pFixedWidths->size(), aVclIter.iter->ItemCount());
4160 for (size_t j = 0; j < nFixedWidths; ++j)
4161 {
4162 SvLBoxItem& rItem = aVclIter.iter->GetItem(j + nExtraCols);
4163 SvViewDataItem* pViewDataItem = m_xTreeView->GetViewDataItem(aVclIter.iter, &rItem);
4164 pViewDataItem->mnWidth = (*pFixedWidths)[j];
4165 }
4166 }
4167
4169
4170 thaw();
4171}
4172
4173void SalInstanceTreeView::set_font_color(int pos, const Color& rColor)
4174{
4175 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4176 set_font_color(pEntry, rColor);
4177}
4178
4180{
4181 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4182 set_font_color(rVclIter.iter, rColor);
4183}
4184
4186{
4188 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4189 m_xTreeView->RemoveEntry(pEntry);
4191}
4192
4193int SalInstanceTreeView::find_text(const OUString& rText) const
4194{
4195 for (SvTreeListEntry* pEntry = m_xTreeView->First(); pEntry; pEntry = m_xTreeView->Next(pEntry))
4196 {
4197 if (SvTabListBox::GetEntryText(pEntry, 0) == rText)
4198 return SvTreeList::GetRelPos(pEntry);
4199 }
4200 return -1;
4201}
4202
4203int SalInstanceTreeView::find_id(const OUString& rId) const
4204{
4205 for (SvTreeListEntry* pEntry = m_xTreeView->First(); pEntry; pEntry = m_xTreeView->Next(pEntry))
4206 {
4207 const OUString* pId = static_cast<const OUString*>(pEntry->GetUserData());
4208 if (!pId)
4209 continue;
4210 if (rId == *pId)
4211 return SvTreeList::GetRelPos(pEntry);
4212 }
4213 return -1;
4214}
4215
4216void SalInstanceTreeView::swap(int pos1, int pos2)
4217{
4218 int min = std::min(pos1, pos2);
4219 int max = std::max(pos1, pos2);
4220 SvTreeList* pModel = m_xTreeView->GetModel();
4221 SvTreeListEntry* pEntry1 = pModel->GetEntry(nullptr, min);
4222 SvTreeListEntry* pEntry2 = pModel->GetEntry(nullptr, max);
4223 pModel->Move(pEntry1, pEntry2);
4224}
4225
4227{
4229 m_xTreeView->Clear();
4230 m_aUserData.clear();
4232}
4233
4235{
4236 return m_xTreeView->GetModel()->GetChildList(nullptr).size();
4237}
4238
4240{
4241 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4242 return m_xTreeView->GetModel()->GetChildList(rVclIter.iter).size();
4243}
4244
4246{
4247 assert(m_xTreeView->IsUpdateMode()
4248 && "don't select when frozen, select after thaw. Note selection doesn't survive a "
4249 "freeze");
4251 if (pos == -1 || (pos == 0 && n_children() == 0))
4252 m_xTreeView->SelectAll(false);
4253 else
4254 {
4255 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4256 assert(pEntry && "bad pos?");
4257 m_xTreeView->Select(pEntry, true);
4258 m_xTreeView->MakeVisible(pEntry);
4259 }
4261}
4262
4264{
4266 if (!pEntry)
4267 return -1;
4268 return SvTreeList::GetRelPos(pEntry);
4269}
4270
4272{
4274 if (pos == -1)
4275 m_xTreeView->SetCurEntry(nullptr);
4276 else
4277 {
4278 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4279 m_xTreeView->SetCurEntry(pEntry);
4280 }
4282}
4283
4285{
4286 assert(m_xTreeView->IsUpdateMode()
4287 && "don't select when frozen, select after thaw. Note selection doesn't survive a "
4288 "freeze");
4290 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4291 m_xTreeView->MakeVisible(pEntry);
4293}
4294
4296{
4297 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4298 return m_xTreeView->IsSelected(pEntry);
4299}
4300
4302{
4303 assert(m_xTreeView->IsUpdateMode()
4304 && "don't select when frozen, select after thaw. Note selection doesn't survive a "
4305 "freeze");
4307 if (pos == -1)
4308 m_xTreeView->SelectAll(true);
4309 else
4310 {
4311 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4312 m_xTreeView->Select(pEntry, false);
4313 }
4315}
4316
4318{
4319 std::vector<int> aRows;
4320
4321 aRows.reserve(m_xTreeView->GetSelectionCount());
4322 for (SvTreeListEntry* pEntry = m_xTreeView->FirstSelected(); pEntry;
4323 pEntry = m_xTreeView->NextSelected(pEntry))
4324 aRows.push_back(SvTreeList::GetRelPos(pEntry));
4325
4326 return aRows;
4327}
4328
4329OUString SalInstanceTreeView::get_text(SvTreeListEntry* pEntry, int col) const
4330{
4331 if (col == -1)
4332 return SvTabListBox::GetEntryText(pEntry, 0);
4333
4334 col = to_internal_model(col);
4335
4336 if (static_cast<size_t>(col) == pEntry->ItemCount())
4337 return OUString();
4338
4339 assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
4340 SvLBoxItem& rItem = pEntry->GetItem(col);
4341 assert(dynamic_cast<SvLBoxString*>(&rItem));
4342 return static_cast<SvLBoxString&>(rItem).GetText();
4343}
4344
4345OUString SalInstanceTreeView::get_text(int pos, int col) const
4346{
4347 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4348 return get_text(pEntry, col);
4349}
4350
4351void SalInstanceTreeView::set_text(SvTreeListEntry* pEntry, const OUString& rText, int col)
4352{
4353 if (col == -1)
4354 {
4355 m_xTreeView->SetEntryText(pEntry, rText);
4356 return;
4357 }
4358
4359 col = to_internal_model(col);
4360
4361 // blank out missing entries
4362 for (int i = pEntry->ItemCount(); i < col; ++i)
4363 AddStringItem(pEntry, "", i - 1);
4364
4365 if (static_cast<size_t>(col) == pEntry->ItemCount())
4366 {
4367 AddStringItem(pEntry, rText, col - 1);
4368 SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry);
4369 m_xTreeView->InitViewData(pViewData, pEntry);
4370 }
4371 else
4372 {
4373 assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
4374 SvLBoxItem& rItem = pEntry->GetItem(col);
4375 assert(dynamic_cast<SvLBoxString*>(&rItem));
4376 static_cast<SvLBoxString&>(rItem).SetText(rText);
4377 }
4378
4379 InvalidateModelEntry(pEntry);
4380}
4381
4382void SalInstanceTreeView::set_text(int pos, const OUString& rText, int col)
4383{
4384 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4385 set_text(pEntry, rText, col);
4386}
4387
4388void SalInstanceTreeView::set_sensitive(SvTreeListEntry* pEntry, bool bSensitive, int col)
4389{
4390 if (col == -1)
4391 {
4392 auto nFlags = pEntry->GetFlags() & ~SvTLEntryFlags::SEMITRANSPARENT;
4393 if (!bSensitive)
4394 nFlags = nFlags | SvTLEntryFlags::SEMITRANSPARENT;
4395 pEntry->SetFlags(nFlags);
4396 const sal_uInt16 nCount = pEntry->ItemCount();
4397 for (sal_uInt16 nCur = 0; nCur < nCount; ++nCur)
4398 {
4399 SvLBoxItem& rItem = pEntry->GetItem(nCur);
4400 if (rItem.GetType() == SvLBoxItemType::String
4401 || rItem.GetType() == SvLBoxItemType::Button
4402 || rItem.GetType() == SvLBoxItemType::ContextBmp)
4403 {
4404 rItem.Enable(bSensitive);
4405 InvalidateModelEntry(pEntry);
4406 }
4407 }
4408 return;
4409 }
4410
4411 col = to_internal_model(col);
4412
4413 assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
4414 SvLBoxItem& rItem = pEntry->GetItem(col);
4415 rItem.Enable(bSensitive);
4416
4417 InvalidateModelEntry(pEntry);
4418}
4419
4421{
4422 if (static_cast<size_t>(col) == pEntry->ItemCount())
4423 return false;
4424
4425 assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
4426 SvLBoxItem& rItem = pEntry->GetItem(col);
4427 return rItem.isEnable();
4428}
4429
4431{
4432 col = to_internal_model(col);
4433 return do_get_sensitive(pEntry, col);
4434}
4435
4436void SalInstanceTreeView::set_sensitive(int pos, bool bSensitive, int col)
4437{
4438 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4439 set_sensitive(pEntry, bSensitive, col);
4440}
4441
4442bool SalInstanceTreeView::get_sensitive(int pos, int col) const
4443{
4444 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4445 return get_sensitive(pEntry, col);
4446}
4447
4448void SalInstanceTreeView::set_sensitive(const weld::TreeIter& rIter, bool bSensitive, int col)
4449{
4450 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4451 set_sensitive(rVclIter.iter, bSensitive, col);
4452}
4453
4455{
4456 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4457 return get_sensitive(rVclIter.iter, col);
4458}
4459
4461{
4462 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4463 return get_toggle(pEntry, col);
4464}
4465
4467{
4468 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4469 return get_toggle(rVclIter.iter, col);
4470}
4471
4473{
4474 assert(n_children() == 0 && "tree must be empty");
4476
4479 // EnableCheckButton clobbered this, restore it
4480 pData->SetLink(LINK(this, SalInstanceTreeView, ToggleHdl));
4481}
4482
4483void SalInstanceTreeView::set_toggle(int pos, TriState eState, int col)
4484{
4485 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4486 set_toggle(pEntry, eState, col);
4487}
4488
4490{
4491 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4492 set_toggle(rVclIter.iter, eState, col);
4493}
4494
4496{
4497 m_xTreeView->SetClicksToToggle(nToggleBehavior);
4498}
4499
4501{
4502 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4503 rVclIter.iter->SetExtraIndent(nIndentLevel);
4504}
4505
4507{
4508 col = to_internal_model(col);
4509
4510 assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
4511 SvLBoxItem& rItem = pEntry->GetItem(col);
4512 assert(dynamic_cast<SvLBoxString*>(&rItem));
4513 static_cast<SvLBoxString&>(rItem).Emphasize(bOn);
4514
4515 InvalidateModelEntry(pEntry);
4516}
4517
4518void SalInstanceTreeView::set_text_emphasis(const weld::TreeIter& rIter, bool bOn, int col)
4519{
4520 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4521 set_text_emphasis(rVclIter.iter, bOn, col);
4522}
4523
4524void SalInstanceTreeView::set_text_emphasis(int pos, bool bOn, int col)
4525{
4526 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4527 set_text_emphasis(pEntry, bOn, col);
4528}
4529
4531{
4532 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4533 return get_text_emphasis(rVclIter.iter, col);
4534}
4535
4536bool SalInstanceTreeView::get_text_emphasis(int pos, int col) const
4537{
4538 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4539 return get_text_emphasis(pEntry, col);
4540}
4541
4542void SalInstanceTreeView::set_text_align(SvTreeListEntry* pEntry, double fAlign, int col)
4543{
4544 col = to_internal_model(col);
4545
4546 assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
4547 SvLBoxItem& rItem = pEntry->GetItem(col);
4548 assert(dynamic_cast<SvLBoxString*>(&rItem));
4549 static_cast<SvLBoxString&>(rItem).Align(fAlign);
4550
4551 InvalidateModelEntry(pEntry);
4552}
4553
4554void SalInstanceTreeView::set_text_align(const weld::TreeIter& rIter, double fAlign, int col)
4555{
4556 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4557 set_text_align(rVclIter.iter, fAlign, col);
4558}
4559
4560void SalInstanceTreeView::set_text_align(int pos, double fAlign, int col)
4561{
4562 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
4563 set_text_align(pEntry, fAlign, col);
4564}
4565
4567 const Link<const iter_string&, bool>& rEndLink)
4568{
4569 m_xTreeView->EnableInplaceEditing(rStartLink.IsSet() || rEndLink.IsSet());
4570 weld::TreeView::connect_editing(rStartLink, rEndLink);
4571}
4572
4574{
4575 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4576 m_xTreeView->EditEntry(rVclIter.iter);
4577}
4578
4580
4581void SalInstanceTreeView::set_image(SvTreeListEntry* pEntry, const Image& rImage, int col)
4582{
4583 if (col == -1)
4584 {
4585 m_xTreeView->SetExpandedEntryBmp(pEntry, rImage);
4586 m_xTreeView->SetCollapsedEntryBmp(pEntry, rImage);
4587 return;
4588 }
4589
4590 col = to_internal_model(col);
4591
4592 // blank out missing entries
4593 for (int i = pEntry->ItemCount(); i < col; ++i)
4594 AddStringItem(pEntry, "", i - 1);
4595
4596 if (static_cast<size_t>(col) == pEntry->ItemCount())
4597 {
4598 pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(rImage, rImage, false));
4599 SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry);
4600 m_xTreeView->InitViewData(pViewData, pEntry);
4601 }
4602 else
4603 {
4604 assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount());
4605 SvLBoxItem& rItem = pEntry->GetItem(col);
4606 assert(dynamic_cast<SvLBoxContextBmp*>(&rItem));
4607 static_cast<SvLBoxContextBmp&>(rItem).SetBitmap1(rImage);
4608 static_cast<SvLBoxContextBmp&>(rItem).SetBitmap2(rImage);
4609 }
4610
4612 InvalidateModelEntry(pEntry);
4613}
4614
4615void SalInstanceTreeView::set_image(int pos, const OUString& rImage, int col)
4616{
4617 set_image(m_xTreeView->GetEntry(nullptr, pos), createImage(rImage), col);
4618}
4619
4621 const css::uno::Reference<css::graphic::XGraphic>& rImage,
4622 int col)
4623{
4624 set_image(m_xTreeView->GetEntry(nullptr, pos), Image(rImage), col);
4625}
4626
4627void SalInstanceTreeView::set_image(int pos, VirtualDevice& rImage, int col)
4628{
4629 set_image(m_xTreeView->GetEntry(nullptr, pos), createImage(rImage), col);
4630}
4631
4632void SalInstanceTreeView::set_image(const weld::TreeIter& rIter, const OUString& rImage, int col)
4633{
4634 const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
4635 set_image(rVclIter.iter, createImage(rImage), col);
4636}
4637
4638void