31#include <com/sun/star/ui/XSidebarProvider.hpp>
32#include <com/sun/star/frame/XController2.hpp>
42#include <splitwin.hxx>
51#include <officecfg/Office/UI/Sidebar.hxx>
52#include <LibreOfficeKit/LibreOfficeKitEnums.h>
54#include <com/sun/star/awt/XWindowPeer.hpp>
55#include <com/sun/star/frame/XDispatch.hpp>
56#include <com/sun/star/ui/ContextChangeEventMultiplexer.hpp>
57#include <com/sun/star/ui/ContextChangeEventObject.hpp>
58#include <com/sun/star/ui/theUIElementFactoryManager.hpp>
59#include <com/sun/star/util/URL.hpp>
60#include <com/sun/star/rendering/XSpriteCanvas.hpp>
62#include <bitmaps.hlst>
65using namespace css::uno;
69 constexpr OUStringLiteral gsReadOnlyCommandName =
u".uno:EditDoc";
70 const sal_Int32 gnWidthCloseThreshold (70);
71 const sal_Int32 gnWidthOpenThreshold (40);
75 if (rsDeckId == u
"SdCustomAnimationDeck")
76 return ".uno:CustomAnimation";
78 if (rsDeckId == u
"PropertyDeck")
81 if (rsDeckId == u
"SdLayoutsDeck")
82 return ".uno:ModifyPage";
84 if (rsDeckId == u
"SdSlideTransitionDeck")
85 return ".uno:SlideChangeWindow";
87 if (rsDeckId == u
"SdAllMasterPagesDeck")
88 return ".uno:MasterSlidesPanel";
90 if (rsDeckId == u
"SdMasterPagesDeck")
91 return ".uno:MasterSlidesPanel";
93 if (rsDeckId == u
"GalleryDeck")
94 return ".uno:Gallery";
96 OString sUno =
".uno:SidebarDeck." +
OUStringToOString(rsDeckId, RTL_TEXTENCODING_ASCII_US);
97 return std::string(sUno);
107 constexpr OUStringLiteral gsDefaultDeckId(u
"PropertyDeck");
113 : mpParentWindow(pParentWindow),
114 mpViewFrame(pViewFrame),
115 mxFrame(pViewFrame->GetFrame().GetFrameInterface()),
121 const ::std::vector<TabBar::DeckMenuData>& rMenuData) {
return this->ShowPopupMenu(rMainMenu, rSubMenu, rMenuData); },
123 maCurrentContext(OUString(), OUString()),
124 maRequestedContext(OUString(), OUString()),
125 mnRequestedForceFlags(SwitchFlag_NoForce),
126 mbMinimumSidebarWidth(officecfg::Office::UI::Sidebar::General::MinimumWidth::get()),
127 msCurrentDeckId(gsDefaultDeckId),
128 maPropertyChangeForwarder([
this](){
return this->BroadcastPropertyChange(); }),
129 maContextChangeUpdate([
this](){
return this->UpdateConfigurations(); }),
130 mbFloatingDeckClosed(!pParentWindow->IsFloatingMode()),
131 mnSavedSidebarWidth(pParentWindow->GetSizePixel().Width()),
132 maFocusManager([
this](
const Panel& rPanel){
return this->ShowPanel(rPanel); }),
133 mbIsDocumentReadOnly(
false),
134 mpSplitWindow(
nullptr),
135 mnWidthOnSplitterButtonDown(0)
137 mnMaximumSidebarWidth = officecfg::Office::UI::Sidebar::General::MaximumWidth::get() * mpTabBar->GetDPIScaleFactor();
139 mpResourceManager = std::make_unique<ResourceManager>();
148 instance->registerSidebarForFrame(rxFrame->getController());
149 rxFrame->addFrameActionListener(instance);
151 instance->mpParentWindow->AddEventListener(
LINK(instance.get(),
SidebarController, WindowEventHandler));
155 instance->mxThemePropertySet->addPropertyChangeListener(
157 static_cast<css::beans::XPropertyChangeListener*
>(instance.get()));
163 if (instance->mxReadOnlyModeDispatch.is())
164 instance->mxReadOnlyModeDispatch->addStatusListener(instance,
aURL);
176 const css::uno::Reference<css::frame::XFrame>& rxFrame)
178 uno::Reference<frame::XController>
const xController(rxFrame->getController());
181 SAL_WARN(
"sfx.sidebar",
"GetSidebarControllerForFrame: frame has no XController");
184 uno::Reference<ui::XContextChangeEventListener>
const xListener(
186 ::comphelper::getProcessComponentContext(),
188 [] (uno::Reference<uno::XInterface>
const& xRef)
198 css::uno::Reference<css::ui::XContextChangeEventMultiplexer> xMultiplexer (
199 css::ui::ContextChangeEventMultiplexer::get(
200 ::comphelper::getProcessComponentContext()));
201 xMultiplexer->addContextChangeEventListener(
202 static_cast<css::ui::XContextChangeEventListener*
>(
this),
211 css::uno::Reference<css::ui::XContextChangeEventMultiplexer> xMultiplexer (
212 css::ui::ContextChangeEventMultiplexer::get(
213 ::comphelper::getProcessComponentContext()));
214 xMultiplexer->removeContextChangeEventListener(
215 static_cast<css::ui::XContextChangeEventListener*
>(
this),
229 pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED,
230 OString(hide +
"=false"));
249 ,
m_xWidget(m_xBuilder->weld_image(
"image"))
253 m_xWidget->set_from_icon_name(SIDEBAR_CLOSE_INDICATOR);
255 SetSizePixel(get_preferred_size());
260 virtual ~CloseIndicator()
override
265 virtual void dispose()
override
296 for (
const auto& rDeck : aDecks)
298 std::shared_ptr<DeckDescriptor> deckDesc =
mpResourceManager->GetDeckDescriptor(rDeck.msId);
313 static_cast<css::beans::XPropertyChangeListener*
>(
this));
327 mxFrame->removeFrameActionListener(
this);
345 rEvent.ApplicationName,
378 bool bIsReadWrite (
true);
379 if (rEvent.IsEnabled)
380 rEvent.State >>= bIsReadWrite;
400 sal_Int32 nMinimalWidth = 0;
435 bIsDeckVisible = nWidth >= nTabBarDefaultWidth + gnWidthOpenThreshold;
437 bIsDeckVisible = nWidth >= nTabBarDefaultWidth + gnWidthCloseThreshold;
446 if (eAlign == WindowAlign::Left)
448 nDeckX = nTabBarDefaultWidth;
454 nTabX = nWidth - nTabBarDefaultWidth;
471 const sal_Int32 nExtHeight = (
msCurrentDeckId ==
"PropertyDeck" ? 2000 : 600);
473 mpCurrentDeck->setPosSizePixel(nDeckX, 0, nWidth, nExtHeight);
476 mpCurrentDeck->setPosSizePixel(nDeckX, 0, nWidth - nTabBarDefaultWidth, nHeight);
485 mpTabBar->setPosSizePixel(nTabX, 0, nTabBarDefaultWidth, nHeight);
491 sal_Int32 nMinimalWidth = 0;
554 if (!sLastActiveDeck.isEmpty())
582 for (
const auto& rDeck : aDecks)
584 if (rDeck.mbIsEnabled)
591 else if (sNewDeckId.getLength() == 0)
592 sNewDeckId = rDeck.msId;
596 if (sNewDeckId.getLength() == 0)
603 std::shared_ptr<DeckDescriptor> xDescriptor =
mpResourceManager->GetDeckDescriptor(sNewDeckId);
613void collectUIInformation(
const OUString& rDeckId)
616 aDescription.
aAction =
"SIDEBAR";
617 aDescription.
aParent =
"MainWindow";
619 aDescription.
aKeyWord =
"CurrentApp";
627 const OUString& rsDeckId)
630 if ( pSplitWindow && !pSplitWindow->
IsFadeIn() )
650 collectUIInformation(rsDeckId);
667 std::u16string_view rsDeckId)
680 std::u16string_view rsDeckId)
686 std::shared_ptr<DeckDescriptor> xDeckDescriptor =
mpResourceManager->GetDeckDescriptor(rsDeckId);
702 std::shared_ptr<DeckDescriptor> xDeckDescriptor =
mpResourceManager->GetDeckDescriptor(rDeckId);
704 if (!xDeckDescriptor)
708 if (!aDeck || bForceCreate)
718 xDeckDescriptor->mpDeck = aDeck;
724 std::shared_ptr<DeckDescriptor> xDeckDescriptor =
mpResourceManager->GetDeckDescriptor(rDeckId);
735 aPanelContextDescriptors,
741 const sal_Int32 nNewPanelCount (aPanelContextDescriptors.size());
743 sal_Int32 nWriteIndex (0);
745 aNewPanels.resize(nNewPanelCount);
747 for (sal_Int32 nReadIndex=0; nReadIndex<nNewPanelCount; ++nReadIndex)
750 aPanelContextDescriptors[nReadIndex]);
754 if ( ! bIsPanelVisible)
757 auto xOldPanel(pDeck->GetPanel(rPanelContexDescriptor.
msId));
760 xOldPanel->SetLurkMode(
false);
761 aNewPanels[nWriteIndex] = xOldPanel;
768 pDeck->GetPanelParentWindow(),
774 aNewPanels[nWriteIndex] = std::move(aPanel);
778 PanelTitleBar* pTitleBar = aNewPanels[nWriteIndex]->GetTitleBar();
791 aNewPanels.resize(nWriteIndex);
792 pDeck->ResetPanels(std::move(aNewPanels));
807 pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED,
808 OString(hide +
"=false"));
813 pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED,
814 OString(show +
"=true"));
839 aPanelContextDescriptors,
841 rDeckDescriptor.
msId,
844 if (aPanelContextDescriptors.empty())
868 if (bForceNewPanels && !bForceNewDeck)
889 if (eAlign == WindowAlign::Left)
891 nDeckX = nTabBarDefaultWidth;
931 std::u16string_view rsPanelId,
933 const bool bIsInitiallyExpanded,
937 std::shared_ptr<PanelDescriptor> xPanelDescriptor =
mpResourceManager->GetPanelDescriptor(rsPanelId);
939 if (!xPanelDescriptor)
943 auto xPanel = std::make_shared<Panel>(
946 bIsInitiallyExpanded,
953 xPanel->GetElementParentWindow(),
954 xPanelDescriptor->msImplementationURL,
955 xPanelDescriptor->mbWantsCanvas,
960 xPanel->SetUIElement(xUIElement);
971 const Reference<awt::XWindow>& rxWindow,
972 const OUString& rsImplementationURL,
973 const bool bWantsCanvas,
978 const Reference<XComponentContext> xComponentContext (::comphelper::getProcessComponentContext() );
979 const Reference<ui::XUIElementFactory> xUIElementFactory =
980 ui::theUIElementFactoryManager::get( xComponentContext );
985 aCreationArguments.
put(
"ParentWindow",
Any(rxWindow));
987 if (pSfxDockingWindow !=
nullptr)
988 aCreationArguments.
put(
"SfxBindings",
Any(
reinterpret_cast<sal_uInt64
>(&pSfxDockingWindow->
GetBindings())));
990 aCreationArguments.
put(
"Sidebar",
Any(Reference<ui::XSidebar>(
static_cast<ui::XSidebar*
>(
this))));
993 Reference<rendering::XSpriteCanvas> xCanvas (
VCLUnoHelper::GetWindow(rxWindow)->GetOutDev()->GetSpriteCanvas());
994 aCreationArguments.
put(
"Canvas",
Any(xCanvas));
1000 if (!aModule.isEmpty())
1002 aCreationArguments.
put(
"Module",
Any(aModule));
1010 Reference<ui::XUIElement> xUIElement(
1011 xUIElementFactory->createUIElement(
1012 rsImplementationURL,
1027 if (rEvent.GetWindow() == mpParentWindow)
1029 switch (rEvent.GetId())
1031 case VclEventId::WindowShow:
1032 case VclEventId::WindowResize:
1036 case VclEventId::WindowDataChanged:
1040 UpdateTitleBarIcons();
1041 mpParentWindow->Invalidate();
1042 mnRequestedForceFlags |= SwitchFlag_ForceNewDeck | SwitchFlag_ForceNewPanels;
1043 maContextChangeUpdate.RequestCall();
1046 case VclEventId::ObjectDying:
1050 case VclEventId::WindowPaint:
1058 else if (rEvent.GetWindow()==mpSplitWindow && mpSplitWindow!=
nullptr)
1060 switch (rEvent.GetId())
1062 case VclEventId::WindowMouseButtonDown:
1063 mnWidthOnSplitterButtonDown = mpParentWindow->GetSizePixel().Width();
1066 case VclEventId::WindowMouseButtonUp:
1068 ProcessNewWidth(mpParentWindow->GetSizePixel().Width());
1072 case VclEventId::ObjectDying:
1083 const ::std::vector<TabBar::DeckMenuData>& rMenuData)
const
1091 const std::vector<TabBar::DeckMenuData>& rMenuData)
const
1096 for (
const auto& rItem : rMenuData)
1098 OUString sIdent(
"select" + OUString::number(
nIndex));
1101 rMenu.
set_active(sIdent, rItem.mbIsCurrentDeck);
1102 rMenu.
set_sensitive(sIdent, rItem.mbIsEnabled && rItem.mbIsActive);
1106 if (rItem.mbIsCurrentDeck)
1109 OUString sSubIdent(
"nocustomize" + OUString::number(
nIndex));
1110 rCustomizationMenu.
insert(
nIndex, sSubIdent, rItem.msDisplayName,
1112 rCustomizationMenu.
set_active(sSubIdent,
true);
1116 OUString sSubIdent(
"customize" + OUString::number(
nIndex));
1117 rCustomizationMenu.
insert(
nIndex, sSubIdent, rItem.msDisplayName,
1119 rCustomizationMenu.
set_active(sSubIdent, rItem.mbIsEnabled && rItem.mbIsActive);
1126 bool bHideLock =
true;
1127 bool bHideUnLock =
true;
1135 bHideUnLock =
false;
1138 rMenu.
set_visible(
"unlocktaskpanel", !bHideUnLock);
1146 if (rCurItemId ==
"unlocktaskpanel")
1148 mpParentWindow->SetFloatingMode(
true);
1149 if (mpParentWindow->IsFloatingMode())
1150 mpParentWindow->ToTop(ToTopFlags::GrabFocusOnly);
1152 else if (rCurItemId ==
"locktaskpanel")
1154 mpParentWindow->SetFloatingMode(
false);
1156 else if (rCurItemId ==
"hidesidebar")
1163 xDispatch->dispatch(
aURL, Sequence<beans::PropertyValue>());
1178 if (rCurItemId.startsWith(
"select", &sNumber))
1181 SwitchToDeck(mpTabBar->GetDeckIdForIndex(sNumber.toInt32()));
1183 mpParentWindow->GrabFocusToDocument();
1193 if (rCurItemId ==
"restoredefault")
1194 mpTabBar->RestoreHideFlags();
1200 if (rCurItemId.startsWith(
"customize", &sNumber))
1202 mpTabBar->ToggleHideFlag(sNumber.toInt32());
1206 mpResourceManager->GetMatchingDecks (
1208 GetCurrentContext(),
1209 IsDocumentReadOnly(),
1210 mxFrame->getController());
1212 maFocusManager.Clear();
1213 mpTabBar->SetDecks(aDecks);
1214 mpTabBar->HighlightDeck(mpCurrentDeck->GetId());
1215 mpTabBar->UpdateFocusManager(maFocusManager);
1217 mpParentWindow->GrabFocusToDocument();
1236 aJsonWriter.
put(
"type",
"dockingwindow");
1238 aJsonWriter.
put(
"enabled",
false);
1241 else if (pViewShell)
1245 aJsonWriter.
put(
"action",
"close");
1246 aJsonWriter.
put(
"jsontype",
"sidebar");
1260 if ( pSplitWindow && !pSplitWindow->
IsFadeIn() )
1314 mpParentWindow->GetFloatingWindow()->SetPosSizePixel(aNewPos, aNewSize);
1325 pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED,
1326 OString(
uno +
"=true"));
1350 aNewSize.
setWidth(nTabBarDefaultWidth);
1352 mpParentWindow->GetFloatingWindow()->SetPosSizePixel(aNewPos, aNewSize);
1363 pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED,
1364 OString(
uno +
"=false"));
1380 if (pSplitWindow ==
nullptr)
1383 sal_uInt16 nRow (0xffff);
1384 sal_uInt16 nColumn (0xffff);
1388 return nRowCount==1;
1397 if (pSplitWindow ==
nullptr)
1400 sal_uInt16 nRow (0xffff);
1401 sal_uInt16 nColumn (0xffff);
1416 return static_cast<sal_Int32
>(nColumnWidth);
1422 if (pSplitWindow !=
nullptr)
1425 const sal_uInt16 nSetId (pSplitWindow->
GetSet(
nId));
1460 if (bCloseAfterDrag)
1496 const OUString sIconURL(
1497 bIsHighContrastModeActive
1498 ? xDeckDescriptor->msHighContrastTitleBarIconURL
1499 : xDeckDescriptor->msTitleBarIconURL);
1505 for (
const auto& rxPanel : rPanels)
1509 if (!rxPanel->GetTitleBar())
1511 std::shared_ptr<PanelDescriptor> xPanelDescriptor = rResourceManager.
GetPanelDescriptor(rxPanel->GetId());
1512 if (!xPanelDescriptor)
1514 const OUString sIconURL (
1515 bIsHighContrastModeActive
1516 ? xPanelDescriptor->msHighContrastTitleBarIconURL
1517 : xPanelDescriptor->msTitleBarIconURL);
1577 aRect = pTitleBar->GetDragArea();
1587 if (rEvent.Action == css::frame::FrameAction_COMPONENT_DETACHING)
1589 else if (rEvent.Action == css::frame::FrameAction_COMPONENT_REATTACHED)
1608 return context.
msApplication ==
"com.sun.star.chart2.ChartDocument"
1609 || context.
msApplication ==
"com.sun.star.formula.FormulaProperties";
1633 Reference<css::ui::XSidebarProvider> xSidebarProvider =
xController->getSidebar();
1634 if (!xSidebarProvider.is())
1637 Reference<css::ui::XSidebar> xSidebar = xSidebarProvider->getSidebar();
virtual void dispose() override
void setX(tools::Long nX)
constexpr tools::Long X() const
SfxBindings & GetBindings() const
const css::uno::Reference< css::frame::XFrame > & GetFrameInterface() const
SfxViewShell * GetViewShell() const
Returns the SfxViewShell in which they are located in the subshells.
bool GetWindowPos(const SfxDockingWindow *pWindow, sal_uInt16 &rLine, sal_uInt16 &rPos) const
void MoveWindow(SfxDockingWindow *pDockWin, const Size &rSize, sal_uInt16 nLine, sal_uInt16 nPos, bool bNewLine)
tools::Long GetLineSize(sal_uInt16) const
virtual void FadeIn() override
sal_uInt16 GetWindowCount(sal_uInt16 nLine) const
SfxFrame & GetFrame() const
One SfxViewShell more or less represents one edit window for a document, there can be multiple ones f...
bool isLOKMobilePhone() const
Check if the lok client is running on a mobile device.
css::uno::Reference< css::frame::XController > GetController() const
virtual void libreOfficeKitViewCallback(int nType, const OString &pPayload) const override
Invokes the registered callback, if there are any.
static SAL_WARN_UNUSED_RESULT SfxViewShell * Current()
constexpr tools::Long Height() const
void setWidth(tools::Long nWidth)
constexpr tools::Long Width() const
WindowAlign GetAlign() const
sal_uInt16 GetItemId(vcl::Window *pWindow) const
void SetItemSizeRange(sal_uInt16 nId, const Range &rRange)
sal_uInt16 GetSet(sal_uInt16 nId) const
static UITestLogger & getInstance()
void logEvent(const EventDescription &rDescription)
static vcl::Window * GetWindow(const css::uno::Reference< css::awt::XWindow > &rxWindow)
void reset(reference_type *pBody)
static VclPtr< reference_type > Create(Arg &&... arg)
bool put(const OUString &_rValueName, const VALUE_TYPE &_rValue)
css::uno::Sequence< css::beans::PropertyValue > getPropertyValues() const
virtual void SAL_CALL dispose() noexcept final override
static Application GetApplicationEnum(const OUString &rsApplicationName)
static const OUString & GetContextName(const Context eContext)
static Context GetContextEnum(const OUString &rsContextName)
virtual Size GetSizePixel() const
#define TOOLS_WARN_EXCEPTION(area, stream)
Reference< XDispatch > xDispatch
#define LINK(Instance, Class, Member)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
uno::Reference< ui::XContextChangeEventListener > GetFirstListenerWith(css::uno::Reference< css::uno::XComponentContext > const &xComponentContext, uno::Reference< uno::XInterface > const &xEventFocus, std::function< bool(uno::Reference< ui::XContextChangeEventListener > const &)> const &rPredicate)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
std::map< OUString, OUString > aParameters
Reference< XController > xController
Reference< XModel > xModel
WinBits const WB_SIZEABLE