summaryrefslogtreecommitdiffstats
path: root/svx/source/stbctrls
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
commit267c6f2ac71f92999e969232431ba04678e7437e (patch)
tree358c9467650e1d0a1d7227a21dac2e3d08b622b2 /svx/source/stbctrls
parentInitial commit. (diff)
downloadlibreoffice-267c6f2ac71f92999e969232431ba04678e7437e.tar.xz
libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.zip
Adding upstream version 4:24.2.0.upstream/4%24.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'svx/source/stbctrls')
-rw-r--r--svx/source/stbctrls/insctrl.cxx83
-rw-r--r--svx/source/stbctrls/modctrl.cxx159
-rw-r--r--svx/source/stbctrls/modctrl_internal.hxx30
-rw-r--r--svx/source/stbctrls/pszctrl.cxx533
-rw-r--r--svx/source/stbctrls/selctrl.cxx195
-rw-r--r--svx/source/stbctrls/stbctrls.h35
-rw-r--r--svx/source/stbctrls/xmlsecctrl.cxx162
-rw-r--r--svx/source/stbctrls/zoomctrl.cxx251
-rw-r--r--svx/source/stbctrls/zoomsliderctrl.cxx392
9 files changed, 1840 insertions, 0 deletions
diff --git a/svx/source/stbctrls/insctrl.cxx b/svx/source/stbctrls/insctrl.cxx
new file mode 100644
index 0000000000..3ad0fdc1e4
--- /dev/null
+++ b/svx/source/stbctrls/insctrl.cxx
@@ -0,0 +1,83 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <vcl/status.hxx>
+#include <svl/eitem.hxx>
+#include <tools/debug.hxx>
+
+#include <svx/strings.hrc>
+
+#include <svx/insctrl.hxx>
+#include <svx/dialmgr.hxx>
+
+SFX_IMPL_STATUSBAR_CONTROL(SvxInsertStatusBarControl, SfxBoolItem);
+
+SvxInsertStatusBarControl::SvxInsertStatusBarControl( sal_uInt16 _nSlotId,
+ sal_uInt16 _nId,
+ StatusBar& rStb ) :
+
+ SfxStatusBarControl( _nSlotId, _nId, rStb ),
+ bInsert( true )
+{
+}
+
+SvxInsertStatusBarControl::~SvxInsertStatusBarControl()
+{
+}
+
+void SvxInsertStatusBarControl::StateChangedAtStatusBarControl( sal_uInt16 , SfxItemState eState,
+ const SfxPoolItem* pState )
+{
+ if ( SfxItemState::DEFAULT != eState )
+ GetStatusBar().SetItemText( GetId(), "" );
+ else
+ {
+ DBG_ASSERT( dynamic_cast<const SfxBoolItem*>( pState) != nullptr, "invalid item type" );
+ const SfxBoolItem* pItem = static_cast<const SfxBoolItem*>(pState);
+ bInsert = pItem->GetValue();
+
+ if ( bInsert )
+ GetStatusBar().SetQuickHelpText( GetId(), SvxResId( RID_SVXSTR_INSERT_HELPTEXT ) );
+ else
+ GetStatusBar().SetQuickHelpText( GetId(), SvxResId( RID_SVXSTR_OVERWRITE_HELPTEXT ) );
+
+ DrawItemText_Impl();
+ }
+}
+
+void SvxInsertStatusBarControl::Paint( const UserDrawEvent& )
+{
+}
+
+void SvxInsertStatusBarControl::DrawItemText_Impl()
+{
+ OUString aText = "";
+ // tdf#107918 on macOS without an Insert key it's hard to figure out how to switch modes
+ // so we show both Insert and Overwrite
+#ifdef MACOSX
+ if ( bInsert )
+ aText = SvxResId( RID_SVXSTR_INSERT_TEXT );
+#endif
+ if ( !bInsert )
+ aText = SvxResId( RID_SVXSTR_OVERWRITE_TEXT );
+
+ GetStatusBar().SetItemText( GetId(), aText );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/stbctrls/modctrl.cxx b/svx/source/stbctrls/modctrl.cxx
new file mode 100644
index 0000000000..d658175260
--- /dev/null
+++ b/svx/source/stbctrls/modctrl.cxx
@@ -0,0 +1,159 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <vcl/status.hxx>
+#include <vcl/image.hxx>
+#include <vcl/timer.hxx>
+#include <vcl/idle.hxx>
+#include <vcl/event.hxx>
+#include <svl/eitem.hxx>
+#include <tools/debug.hxx>
+
+#include <svx/strings.hrc>
+#include <svx/modctrl.hxx>
+#include <svx/dialmgr.hxx>
+
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include "modctrl_internal.hxx"
+#include <bitmaps.hlst>
+
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::beans::PropertyValue;
+
+SFX_IMPL_STATUSBAR_CONTROL(SvxModifyControl, SfxBoolItem);
+
+struct SvxModifyControl::ImplData
+{
+ enum ModificationState
+ {
+ MODIFICATION_STATE_NO = 0,
+ MODIFICATION_STATE_YES,
+ MODIFICATION_STATE_FEEDBACK,
+ MODIFICATION_STATE_SIZE
+ };
+
+ Idle maIdle { "svx::SvxModifyControl maIdle" };
+ Image maImages[MODIFICATION_STATE_SIZE];
+
+ ModificationState mnModState;
+
+ ImplData():
+ mnModState(MODIFICATION_STATE_NO)
+ {
+ maImages[MODIFICATION_STATE_NO] = Image(StockImage::Yes, RID_SVXBMP_DOC_MODIFIED_NO);
+ maImages[MODIFICATION_STATE_YES] = Image(StockImage::Yes, RID_SVXBMP_DOC_MODIFIED_YES);
+ maImages[MODIFICATION_STATE_FEEDBACK] = Image(StockImage::Yes, RID_SVXBMP_DOC_MODIFIED_FEEDBACK);
+
+ maIdle.SetPriority(TaskPriority::LOWEST);
+ }
+};
+
+SvxModifyControl::SvxModifyControl( sal_uInt16 _nSlotId, sal_uInt16 _nId, StatusBar& rStb ) :
+ SfxStatusBarControl( _nSlotId, _nId, rStb ),
+ mxImpl(std::make_shared<ImplData>())
+{
+ mxImpl->maIdle.SetInvokeHandler( LINK(this, SvxModifyControl, OnTimer) );
+}
+
+
+void SvxModifyControl::StateChangedAtStatusBarControl( sal_uInt16, SfxItemState eState,
+ const SfxPoolItem* pState )
+{
+ if ( SfxItemState::DEFAULT != eState )
+ return;
+
+ DBG_ASSERT( dynamic_cast<const SfxBoolItem*>( pState) != nullptr, "invalid item type" );
+ const SfxBoolItem* pItem = static_cast<const SfxBoolItem*>(pState);
+ mxImpl->maIdle.Stop();
+
+ bool modified = pItem->GetValue();
+ bool start = ( !modified && mxImpl->mnModState == ImplData::MODIFICATION_STATE_YES); // should timer be started and feedback image displayed ?
+
+ mxImpl->mnModState = (start ? ImplData::MODIFICATION_STATE_FEEDBACK : (modified ? ImplData::MODIFICATION_STATE_YES : ImplData::MODIFICATION_STATE_NO));
+
+ _repaint();
+
+ TranslateId pResId = modified ? RID_SVXSTR_DOC_MODIFIED_YES : RID_SVXSTR_DOC_MODIFIED_NO;
+ GetStatusBar().SetQuickHelpText(GetId(), SvxResId(pResId));
+
+ if ( start )
+ mxImpl->maIdle.Start();
+}
+
+
+IMPL_LINK( SvxModifyControl, OnTimer, Timer *, pTimer, void )
+{
+ if (pTimer == nullptr)
+ return;
+
+ pTimer->Stop();
+ mxImpl->mnModState = ImplData::MODIFICATION_STATE_NO;
+
+ _repaint();
+}
+
+
+void SvxModifyControl::_repaint()
+{
+ GetStatusBar().SetItemData( GetId(), nullptr ); // force repaint
+}
+
+/**
+ * Given a bounding rectangle and an image, determine the top-left position
+ * of the image so that the image would look centered both horizontally and
+ * vertically.
+ *
+ * @param rBoundingRect bounding rectangle
+ * @param rImg image
+ *
+ * @return Point top-left corner of the centered image position
+ */
+Point centerImage(const tools::Rectangle& rBoundingRect, const Image& rImg)
+{
+ Size aImgSize = rImg.GetSizePixel();
+ Size aRectSize = rBoundingRect.GetSize();
+ tools::Long nXOffset = (aRectSize.getWidth() - aImgSize.getWidth())/2;
+ tools::Long nYOffset = (aRectSize.getHeight() - aImgSize.getHeight())/2;
+ Point aPt = rBoundingRect.TopLeft();
+ aPt += Point(nXOffset, nYOffset);
+ return aPt;
+}
+
+void SvxModifyControl::Paint( const UserDrawEvent& rUsrEvt )
+{
+ vcl::RenderContext* pDev = rUsrEvt.GetRenderContext();
+ tools::Rectangle aRect(rUsrEvt.GetRect());
+
+ ImplData::ModificationState state = mxImpl->mnModState;
+ Point aPt = centerImage(aRect, mxImpl->maImages[state]);
+ pDev->DrawImage(aPt, mxImpl->maImages[state]);
+}
+
+void SvxModifyControl::Click()
+{
+ if (mxImpl->mnModState != ImplData::MODIFICATION_STATE_YES)
+ // document not modified. nothing to do here.
+ return;
+
+ Sequence<PropertyValue> aArgs;
+ execute(".uno:Save", aArgs);
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/stbctrls/modctrl_internal.hxx b/svx/source/stbctrls/modctrl_internal.hxx
new file mode 100644
index 0000000000..d6d3d68345
--- /dev/null
+++ b/svx/source/stbctrls/modctrl_internal.hxx
@@ -0,0 +1,30 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_SVX_SOURCE_STBCTRLS_MODCTRL_INTERNAL_HXX
+#define INCLUDED_SVX_SOURCE_STBCTRLS_MODCTRL_INTERNAL_HXX
+
+#include <tools/gen.hxx>
+
+class Image;
+
+Point centerImage(const tools::Rectangle& rBoundingRect, const Image& rImg);
+
+#endif // INCLUDED_SVX_SOURCE_STBCTRLS_MODCTRL_INTERNAL_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/stbctrls/pszctrl.cxx b/svx/source/stbctrls/pszctrl.cxx
new file mode 100644
index 0000000000..6de9554391
--- /dev/null
+++ b/svx/source/stbctrls/pszctrl.cxx
@@ -0,0 +1,533 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <comphelper/propertyvalue.hxx>
+#include <vcl/commandevent.hxx>
+#include <vcl/event.hxx>
+#include <vcl/fieldvalues.hxx>
+#include <vcl/status.hxx>
+#include <vcl/image.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <vcl/weldutils.hxx>
+#include <svl/stritem.hxx>
+#include <svl/ptitem.hxx>
+#include <sfx2/module.hxx>
+#include <svx/dialmgr.hxx>
+#include <svx/statusitem.hxx>
+#include <svx/strings.hrc>
+#include <svl/intitem.hxx>
+#include <sal/log.hxx>
+
+#include <svx/pszctrl.hxx>
+
+#define PAINT_OFFSET 5
+
+#include <editeng/sizeitem.hxx>
+#include "stbctrls.h"
+
+#include <svx/svxids.hrc>
+#include <bitmaps.hlst>
+#include <unotools/localedatawrapper.hxx>
+
+#include <com/sun/star/beans/PropertyValue.hpp>
+
+/* [Description]
+
+ Function used to create a text representation of
+ a metric value
+
+ nVal is the metric value in the unit eUnit.
+
+ [cross reference]
+
+ <SvxPosSizeStatusBarControl::Paint(const UserDrawEvent&)>
+*/
+
+OUString SvxPosSizeStatusBarControl::GetMetricStr_Impl( tools::Long nVal ) const
+{
+ // deliver and set the Metric of the application
+ FieldUnit eOutUnit = SfxModule::GetModuleFieldUnit( getFrameInterface() );
+
+ OUString sMetric;
+ const sal_Unicode cSep = Application::GetSettings().GetLocaleDataWrapper().getNumDecimalSep()[0];
+ sal_Int64 nConvVal = vcl::ConvertValue( nVal * 100, 0, 0, FieldUnit::MM_100TH, eOutUnit );
+
+ if ( nConvVal < 0 && ( nConvVal / 100 == 0 ) )
+ sMetric += "-";
+ sMetric += OUString::number(nConvVal / 100);
+
+ if( FieldUnit::NONE != eOutUnit )
+ {
+ sMetric += OUStringChar(cSep);
+ sal_Int64 nFract = nConvVal % 100;
+
+ if ( nFract < 0 )
+ nFract *= -1;
+ if ( nFract < 10 )
+ sMetric += "0";
+ sMetric += OUString::number(nFract);
+ }
+
+ return sMetric;
+}
+
+
+SFX_IMPL_STATUSBAR_CONTROL(SvxPosSizeStatusBarControl, SvxSizeItem);
+
+namespace {
+
+class FunctionPopup_Impl
+{
+ std::unique_ptr<weld::Builder> m_xBuilder;
+ std::unique_ptr<weld::Menu> m_xMenu;
+ sal_uInt32 m_nSelected;
+ static sal_uInt16 id_to_function(std::u16string_view rIdent);
+ static OUString function_to_id(sal_uInt16 nFunc);
+public:
+ explicit FunctionPopup_Impl(sal_uInt32 nCheckEncoded);
+ OUString Execute(weld::Window* pParent, const tools::Rectangle& rRect)
+ {
+ return m_xMenu->popup_at_rect(pParent, rRect);
+ }
+ sal_uInt32 GetSelected(std::u16string_view curident) const;
+};
+
+}
+
+sal_uInt16 FunctionPopup_Impl::id_to_function(std::u16string_view rIdent)
+{
+ if (rIdent == u"avg")
+ return PSZ_FUNC_AVG;
+ else if (rIdent == u"counta")
+ return PSZ_FUNC_COUNT2;
+ else if (rIdent == u"count")
+ return PSZ_FUNC_COUNT;
+ else if (rIdent == u"max")
+ return PSZ_FUNC_MAX;
+ else if (rIdent == u"min")
+ return PSZ_FUNC_MIN;
+ else if (rIdent == u"sum")
+ return PSZ_FUNC_SUM;
+ else if (rIdent == u"selection")
+ return PSZ_FUNC_SELECTION_COUNT;
+ else if (rIdent == u"none")
+ return PSZ_FUNC_NONE;
+ return 0;
+}
+
+OUString FunctionPopup_Impl::function_to_id(sal_uInt16 nFunc)
+{
+ switch (nFunc)
+ {
+ case PSZ_FUNC_AVG:
+ return "avg";
+ case PSZ_FUNC_COUNT2:
+ return "counta";
+ case PSZ_FUNC_COUNT:
+ return "count";
+ case PSZ_FUNC_MAX:
+ return "max";
+ case PSZ_FUNC_MIN:
+ return "min";
+ case PSZ_FUNC_SUM:
+ return "sum";
+ case PSZ_FUNC_SELECTION_COUNT:
+ return "selection";
+ case PSZ_FUNC_NONE:
+ return "none";
+ }
+ return {};
+}
+
+FunctionPopup_Impl::FunctionPopup_Impl(sal_uInt32 nCheckEncoded)
+ : m_xBuilder(Application::CreateBuilder(nullptr, "svx/ui/functionmenu.ui"))
+ , m_xMenu(m_xBuilder->weld_menu("menu"))
+ , m_nSelected(nCheckEncoded)
+{
+ for ( sal_uInt16 nCheck = 1; nCheck < 32; ++nCheck )
+ if ( nCheckEncoded & (1u << nCheck) )
+ m_xMenu->set_active(function_to_id(nCheck), true);
+}
+
+sal_uInt32 FunctionPopup_Impl::GetSelected(std::u16string_view curident) const
+{
+ sal_uInt32 nSelected = m_nSelected;
+ sal_uInt16 nCurItemId = id_to_function(curident);
+ if ( nCurItemId == PSZ_FUNC_NONE )
+ nSelected = ( 1 << PSZ_FUNC_NONE );
+ else
+ {
+ nSelected &= (~( 1u << PSZ_FUNC_NONE )); // Clear the "None" bit
+ nSelected ^= ( 1u << nCurItemId ); // Toggle the bit corresponding to nCurItemId
+ if ( !nSelected )
+ nSelected = ( 1u << PSZ_FUNC_NONE );
+ }
+ return nSelected;
+}
+
+struct SvxPosSizeStatusBarControl_Impl
+
+/* [Description]
+
+ This implementation-structure of the class SvxPosSizeStatusBarControl
+ is done for the un-linking of the changes of the exported interface such as
+ the toning down of symbols that are visible externally.
+
+ One instance exists for each SvxPosSizeStatusBarControl-instance
+ during its life time
+*/
+
+{
+ Point aPos; // valid when a position is shown
+ Size aSize; // valid when a size is shown
+ OUString aStr; // valid when a text is shown
+ bool bPos; // show position ?
+ bool bSize; // set size ?
+ bool bTable; // set table index ?
+ bool bHasMenu; // set StarCalc popup menu ?
+ sal_uInt32 nFunctionSet; // the selected StarCalc functions encoded in 32 bits
+ Image aPosImage; // Image to show the position
+ Image aSizeImage; // Image to show the size
+};
+
+/* [Description]
+
+ Ctor():
+ Create an instance of the implementation class,
+ load the images for the position and size
+*/
+
+#define STR_POSITION ".uno:Position"
+#define STR_TABLECELL ".uno:StateTableCell"
+#define STR_FUNC ".uno:StatusBarFunc"
+
+SvxPosSizeStatusBarControl::SvxPosSizeStatusBarControl( sal_uInt16 _nSlotId,
+ sal_uInt16 _nId,
+ StatusBar& rStb ) :
+ SfxStatusBarControl( _nSlotId, _nId, rStb ),
+ pImpl( new SvxPosSizeStatusBarControl_Impl )
+{
+ pImpl->bPos = false;
+ pImpl->bSize = false;
+ pImpl->bTable = false;
+ pImpl->bHasMenu = false;
+ pImpl->nFunctionSet = 0;
+ pImpl->aPosImage = Image(StockImage::Yes, RID_SVXBMP_POSITION);
+ pImpl->aSizeImage = Image(StockImage::Yes, RID_SVXBMP_SIZE);
+
+ addStatusListener( STR_POSITION); // SID_ATTR_POSITION
+ addStatusListener( STR_TABLECELL); // SID_TABLE_CELL
+ addStatusListener( STR_FUNC); // SID_PSZ_FUNCTION
+ ImplUpdateItemText();
+}
+
+/* [Description]
+
+ Dtor():
+ remove the pointer to the implementation class, so that the timer is stopped
+
+*/
+
+SvxPosSizeStatusBarControl::~SvxPosSizeStatusBarControl()
+{
+}
+
+
+/* [Description]
+
+ SID_PSZ_FUNCTION activates the popup menu for Calc:
+
+ Status overview
+ Depending on the type of the item, a special setting is enabled, the others disabled.
+
+ NULL/Void SfxPointItem SvxSizeItem SfxStringItem
+ ------------------------------------------------------------------------
+ Position sal_False FALSE
+ Size FALSE TRUE FALSE
+ Text sal_False sal_False TRUE
+
+*/
+
+void SvxPosSizeStatusBarControl::StateChangedAtStatusBarControl( sal_uInt16 nSID, SfxItemState eState,
+ const SfxPoolItem* pState )
+{
+ // Because the combi-controller, always sets the current Id as HelpId
+ // first clean the cached HelpText
+ GetStatusBar().SetHelpText( GetId(), "" );
+
+ switch ( nSID )
+ {
+ case SID_ATTR_POSITION : GetStatusBar().SetHelpId( GetId(), STR_POSITION ); break;
+ case SID_TABLE_CELL: GetStatusBar().SetHelpId( GetId(), STR_TABLECELL ); break;
+ case SID_PSZ_FUNCTION: GetStatusBar().SetHelpId( GetId(), STR_FUNC ); break;
+ default: break;
+ }
+
+ if ( nSID == SID_PSZ_FUNCTION )
+ {
+ if ( eState == SfxItemState::DEFAULT )
+ {
+ pImpl->bHasMenu = true;
+ if ( auto pUInt32Item = dynamic_cast< const SfxUInt32Item* >(pState) )
+ pImpl->nFunctionSet = pUInt32Item->GetValue();
+ }
+ else
+ pImpl->bHasMenu = false;
+ }
+ else if ( SfxItemState::DEFAULT != eState )
+ {
+ // don't switch to empty display before an empty state was
+ // notified for all display types
+
+ if ( nSID == SID_TABLE_CELL )
+ pImpl->bTable = false;
+ else if ( nSID == SID_ATTR_POSITION )
+ pImpl->bPos = false;
+ else if ( nSID == GetSlotId() ) // controller is registered for SID_ATTR_SIZE
+ pImpl->bSize = false;
+ else
+ {
+ SAL_WARN( "svx.stbcrtls","unknown slot id");
+ }
+ }
+ else if ( auto pPointItem = dynamic_cast<const SfxPointItem*>( pState) )
+ {
+ // show position
+ pImpl->aPos = pPointItem->GetValue();
+ pImpl->bPos = true;
+ pImpl->bTable = false;
+ }
+ else if ( auto pSizeItem = dynamic_cast<const SvxSizeItem*>( pState) )
+ {
+ // show size
+ pImpl->aSize = pSizeItem->GetSize();
+ pImpl->bSize = true;
+ pImpl->bTable = false;
+ }
+ else if ( auto pStatusItem = dynamic_cast<const SvxStatusItem*>( pState) )
+ {
+ // show string (table cell or different)
+ pImpl->aStr = pStatusItem->GetValue();
+ pImpl->bTable = true;
+ pImpl->bPos = false;
+ pImpl->bSize = false;
+ if (!pImpl->aStr.isEmpty())
+ {
+ OUString sTip;
+ switch (pStatusItem->GetCategory())
+ {
+ case StatusCategory::TableCell:
+ sTip = SvxResId(RID_SVXSTR_TABLECELL_HINT);
+ break;
+ case StatusCategory::Section:
+ sTip = SvxResId(RID_SVXSTR_SECTION_HINT);
+ break;
+ case StatusCategory::TableOfContents:
+ sTip = SvxResId(RID_SVXSTR_TOC_HINT);
+ break;
+ case StatusCategory::Numbering:
+ sTip = SvxResId(RID_SVXSTR_NUMBERING_HINT);
+ break;
+ case StatusCategory::ListStyle:
+ sTip = SvxResId(RID_SVXSTR_LIST_STYLE_HINT);
+ break;
+ case StatusCategory::Formula:
+ sTip = SvxResId(RID_SVXSTR_FORMULA_HINT);
+ break;
+ case StatusCategory::RowColumn:
+ sTip = SvxResId(RID_SVXSTR_ROW_COLUMN_HINT);
+ break;
+ case StatusCategory::NONE:
+ break;
+ }
+ GetStatusBar().SetQuickHelpText(GetId(), sTip);
+ }
+ }
+ else if ( auto pStringItem = dynamic_cast<const SfxStringItem*>( pState) )
+ {
+ SAL_WARN( "svx.stbcrtls", "this should be a SvxStatusItem not a SfxStringItem" );
+ // show string (table cell or different)
+ pImpl->aStr = pStringItem->GetValue();
+ pImpl->bTable = true;
+ pImpl->bPos = false;
+ pImpl->bSize = false;
+ }
+ else
+ {
+ SAL_WARN( "svx.stbcrtls", "invalid item type" );
+ pImpl->bPos = false;
+ pImpl->bSize = false;
+ pImpl->bTable = false;
+ }
+
+ GetStatusBar().SetItemData( GetId(), nullptr );
+
+ ImplUpdateItemText();
+}
+
+
+/* [Description]
+
+ execute popup menu, when the status enables this
+*/
+
+void SvxPosSizeStatusBarControl::Command( const CommandEvent& rCEvt )
+{
+ if ( rCEvt.GetCommand() == CommandEventId::ContextMenu && pImpl->bHasMenu )
+ {
+ sal_uInt32 nSelect = pImpl->nFunctionSet;
+ if (!nSelect)
+ nSelect = ( 1 << PSZ_FUNC_NONE );
+ tools::Rectangle aRect(rCEvt.GetMousePosPixel(), Size(1,1));
+ weld::Window* pParent = weld::GetPopupParent(GetStatusBar(), aRect);
+ FunctionPopup_Impl aMenu(nSelect);
+ OUString sIdent = aMenu.Execute(pParent, aRect);
+ if (!sIdent.isEmpty())
+ {
+ nSelect = aMenu.GetSelected(sIdent);
+ if (nSelect)
+ {
+ if (nSelect == (1 << PSZ_FUNC_NONE))
+ nSelect = 0;
+
+ css::uno::Any a;
+ SfxUInt32Item aItem( SID_PSZ_FUNCTION, nSelect );
+ aItem.QueryValue( a );
+ css::uno::Sequence< css::beans::PropertyValue > aArgs{ comphelper::makePropertyValue(
+ "StatusBarFunc", a) };
+ execute( ".uno:StatusBarFunc", aArgs );
+ }
+ }
+ }
+ else
+ SfxStatusBarControl::Command( rCEvt );
+}
+
+
+/* [Description]
+
+ Depending on the type to be shown, the value us shown. First the
+ rectangle is repainted (removed).
+*/
+
+void SvxPosSizeStatusBarControl::Paint( const UserDrawEvent& rUsrEvt )
+{
+ vcl::RenderContext* pDev = rUsrEvt.GetRenderContext();
+
+ const tools::Rectangle& rRect = rUsrEvt.GetRect();
+ StatusBar& rBar = GetStatusBar();
+ Point aItemPos = rBar.GetItemTextPos( GetId() );
+ Color aOldLineColor = pDev->GetLineColor();
+ Color aOldFillColor = pDev->GetFillColor();
+ pDev->SetLineColor();
+ pDev->SetFillColor( pDev->GetBackground().GetColor() );
+
+ if ( pImpl->bPos || pImpl->bSize )
+ {
+ // count the position for showing the size
+ tools::Long nSizePosX =
+ rRect.Left() + rRect.GetWidth() / 2 + PAINT_OFFSET;
+ // draw position
+ Point aPnt = rRect.TopLeft();
+ aPnt.AdjustX(PAINT_OFFSET );
+ // vertically centered
+ const tools::Long nSizePosY =
+ (rRect.GetHeight() - pImpl->aPosImage.GetSizePixel().Height()) / 2;
+ aPnt.AdjustY( nSizePosY );
+
+ pDev->DrawImage( aPnt, pImpl->aPosImage );
+ aPnt.AdjustX(pImpl->aPosImage.GetSizePixel().Width() );
+ aPnt.AdjustX(PAINT_OFFSET );
+ OUString aStr = GetMetricStr_Impl( pImpl->aPos.X()) + " / " +
+ GetMetricStr_Impl( pImpl->aPos.Y());
+ tools::Rectangle aRect(aPnt, Point(nSizePosX, rRect.Bottom()));
+ pDev->DrawRect(aRect);
+ vcl::Region aOrigRegion(pDev->GetClipRegion());
+ pDev->SetClipRegion(vcl::Region(aRect));
+ pDev->DrawText(aPnt, aStr);
+ pDev->SetClipRegion(aOrigRegion);
+
+ // draw the size, when available
+ aPnt.setX( nSizePosX );
+
+ if ( pImpl->bSize )
+ {
+ pDev->DrawImage( aPnt, pImpl->aSizeImage );
+ aPnt.AdjustX(pImpl->aSizeImage.GetSizePixel().Width() );
+ Point aDrwPnt = aPnt;
+ aPnt.AdjustX(PAINT_OFFSET );
+ aStr = GetMetricStr_Impl( pImpl->aSize.Width() ) + " x " +
+ GetMetricStr_Impl( pImpl->aSize.Height() );
+ aRect = tools::Rectangle(aDrwPnt, rRect.BottomRight());
+ pDev->DrawRect(aRect);
+ aOrigRegion = pDev->GetClipRegion();
+ pDev->SetClipRegion(vcl::Region(aRect));
+ pDev->DrawText(aPnt, aStr);
+ pDev->SetClipRegion(aOrigRegion);
+ }
+ else
+ pDev->DrawRect( tools::Rectangle( aPnt, rRect.BottomRight() ) );
+ }
+ else if ( pImpl->bTable )
+ {
+ pDev->DrawRect( rRect );
+ pDev->DrawText( Point(
+ rRect.Left() + rRect.GetWidth() / 2 - pDev->GetTextWidth( pImpl->aStr ) / 2,
+ aItemPos.Y() ), pImpl->aStr );
+ }
+ else
+ {
+ // Empty display if neither size nor table position are available.
+ // Date/Time are no longer used (#65302#).
+ pDev->DrawRect( rRect );
+ }
+
+ pDev->SetLineColor( aOldLineColor );
+ pDev->SetFillColor( aOldFillColor );
+}
+
+void SvxPosSizeStatusBarControl::ImplUpdateItemText()
+{
+ // set only strings as text at the statusBar, so that the Help-Tips
+ // can work with the text, when it is too long for the statusBar
+ OUString aText;
+ int nCharsWidth = -1;
+ if ( pImpl->bPos || pImpl->bSize )
+ {
+ aText = GetMetricStr_Impl( pImpl->aPos.X()) + " / " +
+ GetMetricStr_Impl( pImpl->aPos.Y());
+ // widest X/Y string looks like "-999,99"
+ nCharsWidth = 1 + 6 + 3 + 6; // icon + x + slash + y
+ if ( pImpl->bSize )
+ {
+ aText += " " + GetMetricStr_Impl( pImpl->aSize.Width() ) + " x " +
+ GetMetricStr_Impl( pImpl->aSize.Height() );
+ nCharsWidth += 1 + 1 + 4 + 3 + 4; // icon + space + w + x + h
+ }
+ }
+ else if ( pImpl->bTable )
+ aText = pImpl->aStr;
+
+ GetStatusBar().SetItemText( GetId(), aText, nCharsWidth );
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/stbctrls/selctrl.cxx b/svx/source/stbctrls/selctrl.cxx
new file mode 100644
index 0000000000..50bc47f3a4
--- /dev/null
+++ b/svx/source/stbctrls/selctrl.cxx
@@ -0,0 +1,195 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <comphelper/propertyvalue.hxx>
+#include <vcl/event.hxx>
+#include <vcl/status.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weldutils.hxx>
+#include <svl/intitem.hxx>
+#include <tools/urlobj.hxx>
+
+#include <svx/selctrl.hxx>
+
+#include <bitmaps.hlst>
+
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+
+#include <svx/strings.hrc>
+#include <svx/dialmgr.hxx>
+
+SFX_IMPL_STATUSBAR_CONTROL(SvxSelectionModeControl, SfxUInt16Item);
+
+namespace {
+
+/// Popup menu to select the selection type
+class SelectionTypePopup
+{
+ weld::Window* m_pPopupParent;
+ std::unique_ptr<weld::Builder> m_xBuilder;
+ std::unique_ptr<weld::Menu> m_xMenu;
+ static OUString state_to_id(sal_uInt16 nState);
+public:
+ SelectionTypePopup(weld::Window* pPopupParent, sal_uInt16 nCurrent);
+ OUString GetItemTextForState(sal_uInt16 nState) { return m_xMenu->get_label(state_to_id(nState)); }
+ OUString popup_at_rect(const tools::Rectangle& rRect)
+ {
+ return m_xMenu->popup_at_rect(m_pPopupParent, rRect);
+ }
+ void HideSelectionType(const OUString& rIdent)
+ {
+ m_xMenu->remove(rIdent);
+ }
+ static sal_uInt16 id_to_state(std::u16string_view ident);
+};
+
+}
+
+sal_uInt16 SelectionTypePopup::id_to_state(std::u16string_view ident)
+{
+ if (ident == u"block")
+ return 3;
+ else if (ident == u"adding")
+ return 2;
+ else if (ident == u"extending")
+ return 1;
+ else // fall through
+ return 0;
+}
+
+OUString SelectionTypePopup::state_to_id(sal_uInt16 nState)
+{
+ switch (nState)
+ {
+ default: // fall through
+ case 0: return "standard";
+ case 1: return "extending";
+ case 2: return "adding";
+ case 3: return "block";
+ }
+}
+
+SelectionTypePopup::SelectionTypePopup(weld::Window* pPopupParent, sal_uInt16 nCurrent)
+ : m_pPopupParent(pPopupParent)
+ , m_xBuilder(Application::CreateBuilder(m_pPopupParent, "svx/ui/selectionmenu.ui"))
+ , m_xMenu(m_xBuilder->weld_menu("menu"))
+{
+ m_xMenu->set_active(state_to_id(nCurrent), true);
+}
+
+SvxSelectionModeControl::SvxSelectionModeControl( sal_uInt16 _nSlotId,
+ sal_uInt16 _nId,
+ StatusBar& rStb ) :
+ SfxStatusBarControl( _nSlotId, _nId, rStb ),
+ mnState( 0 ),
+ maImages{Image(StockImage::Yes, RID_SVXBMP_STANDARD_SELECTION),
+ Image(StockImage::Yes, RID_SVXBMP_EXTENDING_SELECTION),
+ Image(StockImage::Yes, RID_SVXBMP_ADDING_SELECTION),
+ Image(StockImage::Yes, RID_SVXBMP_BLOCK_SELECTION)},
+ mbFeatureEnabled(false)
+{
+ GetStatusBar().SetQuickHelpText(GetId(), u""_ustr);
+}
+
+void SvxSelectionModeControl::StateChangedAtStatusBarControl( sal_uInt16, SfxItemState eState,
+ const SfxPoolItem* pState )
+{
+ mbFeatureEnabled = SfxItemState::DEFAULT == eState;
+ if (mbFeatureEnabled)
+ {
+ DBG_ASSERT( dynamic_cast< const SfxUInt16Item* >(pState) != nullptr, "invalid item type" );
+ const SfxUInt16Item* pItem = static_cast<const SfxUInt16Item*>(pState);
+ mnState = pItem->GetValue();
+ SelectionTypePopup aPop(GetStatusBar().GetFrameWeld(), mnState);
+ GetStatusBar().SetQuickHelpText(GetId(),
+ SvxResId(RID_SVXSTR_SELECTIONMODE_HELPTEXT).
+ replaceFirst("%1", aPop.GetItemTextForState(mnState)));
+ GetStatusBar().Invalidate();
+ }
+}
+
+bool SvxSelectionModeControl::MouseButtonDown( const MouseEvent& rEvt )
+{
+ if (!mbFeatureEnabled)
+ return true;
+
+ ::tools::Rectangle aRect(rEvt.GetPosPixel(), Size(1, 1));
+ weld::Window* pPopupParent = weld::GetPopupParent(GetStatusBar(), aRect);
+ SelectionTypePopup aPop(pPopupParent, mnState);
+
+ // Check if Calc is opened; if true, hide block selection mode tdf#122280
+ const css::uno::Reference < css::frame::XModel > xModel = m_xFrame->getController()->getModel();
+ css::uno::Reference< css::lang::XServiceInfo > xServices( xModel, css::uno::UNO_QUERY );
+ if ( xServices.is() )
+ {
+ bool bSpecModeCalc = xServices->supportsService("com.sun.star.sheet.SpreadsheetDocument");
+ if (bSpecModeCalc)
+ aPop.HideSelectionType("block");
+ }
+
+ OUString sIdent = aPop.popup_at_rect(aRect);
+ if (!sIdent.isEmpty())
+ {
+ sal_uInt16 nNewState = SelectionTypePopup::id_to_state(sIdent);
+ if ( nNewState != mnState )
+ {
+ mnState = nNewState;
+
+ css::uno::Any a;
+ SfxUInt16Item aState( GetSlotId(), mnState );
+ aState.QueryValue( a );
+ INetURLObject aObj( m_aCommandURL );
+
+ css::uno::Sequence< css::beans::PropertyValue > aArgs{ comphelper::makePropertyValue(
+ aObj.GetURLPath(), a) };
+ execute( aArgs );
+ }
+ }
+
+ return true;
+}
+
+void SvxSelectionModeControl::Click()
+{
+}
+
+void SvxSelectionModeControl::Paint( const UserDrawEvent& rUsrEvt )
+{
+ const tools::Rectangle aControlRect = getControlRect();
+ vcl::RenderContext* pDev = rUsrEvt.GetRenderContext();
+ tools::Rectangle aRect = rUsrEvt.GetRect();
+
+ Size aImgSize( maImages[mnState].GetSizePixel() );
+
+ Point aPos( aRect.Left() + ( aControlRect.GetWidth() - aImgSize.Width() ) / 2,
+ aRect.Top() + ( aControlRect.GetHeight() - aImgSize.Height() ) / 2 );
+
+ if (mbFeatureEnabled)
+ pDev->DrawImage(aPos, maImages[mnState]);
+ else
+ pDev->DrawImage(aPos, Image());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/stbctrls/stbctrls.h b/svx/source/stbctrls/stbctrls.h
new file mode 100644
index 0000000000..3b12d6f950
--- /dev/null
+++ b/svx/source/stbctrls/stbctrls.h
@@ -0,0 +1,35 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_SVX_SOURCE_STBCTRLS_STBCTRLS_H
+#define INCLUDED_SVX_SOURCE_STBCTRLS_STBCTRLS_H
+
+// IDs as in SUBTOTAL_FUNC of Calc
+
+#define PSZ_FUNC_AVG 1
+#define PSZ_FUNC_COUNT2 3
+#define PSZ_FUNC_COUNT 2
+#define PSZ_FUNC_MAX 4
+#define PSZ_FUNC_MIN 5
+#define PSZ_FUNC_SUM 9
+#define PSZ_FUNC_SELECTION_COUNT 13
+#define PSZ_FUNC_NONE 16
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/stbctrls/xmlsecctrl.cxx b/svx/source/stbctrls/xmlsecctrl.cxx
new file mode 100644
index 0000000000..0a26128d94
--- /dev/null
+++ b/svx/source/stbctrls/xmlsecctrl.cxx
@@ -0,0 +1,162 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <comphelper/propertyvalue.hxx>
+#include <vcl/commandevent.hxx>
+#include <vcl/image.hxx>
+#include <vcl/event.hxx>
+#include <vcl/status.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weldutils.hxx>
+#include <sfx2/signaturestate.hxx>
+#include <sfx2/module.hxx>
+
+#include <svl/intitem.hxx>
+
+#include <svx/strings.hrc>
+#include <svx/dialmgr.hxx>
+#include <svx/xmlsecctrl.hxx>
+#include <tools/urlobj.hxx>
+#include <bitmaps.hlst>
+#include <sal/log.hxx>
+
+#include <com/sun/star/beans/PropertyValue.hpp>
+
+SFX_IMPL_STATUSBAR_CONTROL( XmlSecStatusBarControl, SfxUInt16Item );
+
+struct XmlSecStatusBarControl::XmlSecStatusBarControl_Impl
+{
+ SignatureState mnState;
+ Image maImage;
+ Image maImageBroken;
+ Image maImageNotValidated;
+};
+
+
+XmlSecStatusBarControl::XmlSecStatusBarControl( sal_uInt16 _nSlotId, sal_uInt16 _nId, StatusBar& _rStb )
+ :SfxStatusBarControl( _nSlotId, _nId, _rStb )
+ ,mpImpl( new XmlSecStatusBarControl_Impl )
+{
+ mpImpl->mnState = SignatureState::UNKNOWN;
+
+ mpImpl->maImage = Image(StockImage::Yes, RID_SVXBMP_SIGNET);
+ mpImpl->maImageBroken = Image(StockImage::Yes, RID_SVXBMP_SIGNET_BROKEN);
+ mpImpl->maImageNotValidated = Image(StockImage::Yes, RID_SVXBMP_SIGNET_NOTVALIDATED);
+}
+
+XmlSecStatusBarControl::~XmlSecStatusBarControl()
+{
+}
+
+void XmlSecStatusBarControl::StateChangedAtStatusBarControl( sal_uInt16, SfxItemState eState, const SfxPoolItem* pState )
+{
+ if( SfxItemState::DEFAULT != eState )
+ {
+ mpImpl->mnState = SignatureState::UNKNOWN;
+ }
+ else if( auto pUint16Item = dynamic_cast< const SfxUInt16Item* >(pState) )
+ {
+ mpImpl->mnState = static_cast<SignatureState>(pUint16Item->GetValue());
+ }
+ else
+ {
+ SAL_WARN( "svx.stbcrtls", "+XmlSecStatusBarControl::StateChangedAtStatusBarControl(): invalid item type" );
+ mpImpl->mnState = SignatureState::UNKNOWN;
+ }
+
+ GetStatusBar().SetItemData( GetId(), nullptr ); // necessary ?
+
+ GetStatusBar().SetItemText( GetId(), "" ); // necessary ?
+
+ TranslateId pResId = RID_SVXSTR_XMLSEC_NO_SIG;
+ if ( mpImpl->mnState == SignatureState::OK )
+ pResId = RID_SVXSTR_XMLSEC_SIG_OK;
+ else if ( mpImpl->mnState == SignatureState::BROKEN )
+ pResId = RID_SVXSTR_XMLSEC_SIG_NOT_OK;
+ else if ( mpImpl->mnState == SignatureState::NOTVALIDATED )
+ pResId = RID_SVXSTR_XMLSEC_SIG_OK_NO_VERIFY;
+ else if ( mpImpl->mnState == SignatureState::PARTIAL_OK )
+ pResId = RID_SVXSTR_XMLSEC_SIG_CERT_OK_PARTIAL_SIG;
+
+ GetStatusBar().SetQuickHelpText(GetId(), SvxResId(pResId));
+}
+
+void XmlSecStatusBarControl::Command( const CommandEvent& rCEvt )
+{
+ if( rCEvt.GetCommand() == CommandEventId::ContextMenu )
+ {
+ tools::Rectangle aRect(rCEvt.GetMousePosPixel(), Size(1, 1));
+ weld::Window* pPopupParent = weld::GetPopupParent(GetStatusBar(), aRect);
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pPopupParent, "svx/ui/xmlsecstatmenu.ui"));
+ std::unique_ptr<weld::Menu> xPopMenu(xBuilder->weld_menu("menu"));
+ if (!xPopMenu->popup_at_rect(pPopupParent, aRect).isEmpty())
+ {
+ css::uno::Any a;
+ SfxUInt16Item aState( GetSlotId(), 0 );
+ aState.QueryValue( a );
+ INetURLObject aObj( m_aCommandURL );
+
+ css::uno::Sequence< css::beans::PropertyValue > aArgs{ comphelper::makePropertyValue(
+ aObj.GetURLPath(), a) };
+ execute( aArgs );
+ }
+ }
+ else
+ SfxStatusBarControl::Command( rCEvt );
+}
+
+void XmlSecStatusBarControl::Paint( const UserDrawEvent& rUsrEvt )
+{
+ vcl::RenderContext* pDev = rUsrEvt.GetRenderContext();
+
+ tools::Rectangle aRect = rUsrEvt.GetRect();
+ Color aOldLineColor = pDev->GetLineColor();
+ Color aOldFillColor = pDev->GetFillColor();
+
+ pDev->SetLineColor();
+ pDev->SetFillColor( pDev->GetBackground().GetColor() );
+
+ tools::Long yOffset = (aRect.GetHeight() - mpImpl->maImage.GetSizePixel().Height()) / 2;
+
+ if( mpImpl->mnState == SignatureState::OK )
+ {
+ aRect.AdjustTop(yOffset );
+ pDev->DrawImage( aRect.TopLeft(), mpImpl->maImage );
+ }
+ else if( mpImpl->mnState == SignatureState::BROKEN )
+ {
+ aRect.AdjustTop(yOffset );
+ pDev->DrawImage( aRect.TopLeft(), mpImpl->maImageBroken );
+ }
+ else if( mpImpl->mnState == SignatureState::NOTVALIDATED
+ || mpImpl->mnState == SignatureState::PARTIAL_OK)
+ {
+ aRect.AdjustTop(yOffset );
+ pDev->DrawImage( aRect.TopLeft(), mpImpl->maImageNotValidated );
+ }
+ else
+ pDev->DrawRect( aRect );
+
+ pDev->SetLineColor( aOldLineColor );
+ pDev->SetFillColor( aOldFillColor );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/stbctrls/zoomctrl.cxx b/svx/source/stbctrls/zoomctrl.cxx
new file mode 100644
index 0000000000..9a86cc8ffb
--- /dev/null
+++ b/svx/source/stbctrls/zoomctrl.cxx
@@ -0,0 +1,251 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <comphelper/propertyvalue.hxx>
+#include <i18nutil/unicode.hxx>
+#include <svl/voiditem.hxx>
+#include <vcl/commandevent.hxx>
+#include <vcl/event.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/status.hxx>
+#include <vcl/weldutils.hxx>
+#include <vcl/settings.hxx>
+#include <tools/urlobj.hxx>
+#include <sal/log.hxx>
+
+#include <svx/strings.hrc>
+
+#include <svx/zoomctrl.hxx>
+#include <sfx2/zoomitem.hxx>
+#include <svx/dialmgr.hxx>
+#include "modctrl_internal.hxx"
+#include <bitmaps.hlst>
+
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/frame/ModuleManager.hpp>
+
+SFX_IMPL_STATUSBAR_CONTROL(SvxZoomStatusBarControl,SvxZoomItem);
+
+namespace {
+
+class ZoomPopup_Impl
+{
+public:
+ ZoomPopup_Impl(weld::Window* pPopupParent, sal_uInt16 nZ, SvxZoomEnableFlags nValueSet);
+
+ sal_uInt16 GetZoom(std::u16string_view ident) const;
+
+ OUString popup_at_rect(const tools::Rectangle& rRect)
+ {
+ return m_xMenu->popup_at_rect(m_pPopupParent, rRect);
+ }
+
+private:
+ weld::Window* m_pPopupParent;
+ std::unique_ptr<weld::Builder> m_xBuilder;
+ std::unique_ptr<weld::Menu> m_xMenu;
+ sal_uInt16 nZoom;
+};
+
+}
+
+ZoomPopup_Impl::ZoomPopup_Impl(weld::Window* pPopupParent, sal_uInt16 nZ, SvxZoomEnableFlags nValueSet)
+ : m_pPopupParent(pPopupParent)
+ , m_xBuilder(Application::CreateBuilder(m_pPopupParent, "svx/ui/zoommenu.ui"))
+ , m_xMenu(m_xBuilder->weld_menu("menu"))
+ , nZoom(nZ)
+{
+ if ( !(SvxZoomEnableFlags::N50 & nValueSet) )
+ m_xMenu->set_sensitive("50", false);
+ if ( !(SvxZoomEnableFlags::N100 & nValueSet) )
+ m_xMenu->set_sensitive("100", false);
+ if ( !(SvxZoomEnableFlags::N150 & nValueSet) )
+ m_xMenu->set_sensitive("150", false);
+ if ( !(SvxZoomEnableFlags::N200 & nValueSet) )
+ m_xMenu->set_sensitive("200", false);
+ if ( !(SvxZoomEnableFlags::OPTIMAL & nValueSet) )
+ m_xMenu->set_sensitive("optimal", false);
+ if ( !(SvxZoomEnableFlags::WHOLEPAGE & nValueSet) )
+ m_xMenu->set_sensitive("page", false);
+ if ( !(SvxZoomEnableFlags::PAGEWIDTH & nValueSet) )
+ m_xMenu->set_sensitive("width", false);
+}
+
+sal_uInt16 ZoomPopup_Impl::GetZoom(std::u16string_view ident) const
+{
+ sal_uInt16 nRet = nZoom;
+
+ if (ident == u"200")
+ nRet = 200;
+ else if (ident == u"150")
+ nRet = 150;
+ else if (ident == u"100")
+ nRet = 100;
+ else if (ident == u"75")
+ nRet = 75;
+ else if (ident == u"50")
+ nRet = 50;
+ else if (ident == u"optimal" || ident == u"width" || ident == u"page")
+ nRet = 0;
+
+ return nRet;
+}
+
+SvxZoomStatusBarControl::SvxZoomStatusBarControl( sal_uInt16 _nSlotId,
+ sal_uInt16 _nId,
+ StatusBar& rStb ) :
+
+ SfxStatusBarControl( _nSlotId, _nId, rStb ),
+ nZoom( 100 ),
+ nValueSet( SvxZoomEnableFlags::ALL )
+{
+ GetStatusBar().SetQuickHelpText(GetId(), SvxResId(RID_SVXSTR_ZOOMTOOL_HINT));
+ ImplUpdateItemText();
+}
+
+void SvxZoomStatusBarControl::StateChangedAtStatusBarControl( sal_uInt16, SfxItemState eState,
+ const SfxPoolItem* pState )
+{
+ if( SfxItemState::DEFAULT != eState )
+ {
+ GetStatusBar().SetItemText( GetId(), "" );
+ nValueSet = SvxZoomEnableFlags::NONE;
+ }
+ else if ( auto pItem = dynamic_cast< const SfxUInt16Item* >(pState) )
+ {
+ nZoom = pItem->GetValue();
+ ImplUpdateItemText();
+
+ if ( auto pZoomItem = dynamic_cast<const SvxZoomItem*>(pState) )
+ {
+ nValueSet = pZoomItem->GetValueSet();
+ }
+ else
+ {
+ SAL_INFO( "svx", "use SfxZoomItem for SID_ATTR_ZOOM" );
+ nValueSet = SvxZoomEnableFlags::ALL;
+ }
+ }
+}
+
+void SvxZoomStatusBarControl::ImplUpdateItemText()
+{
+ // workaround - don't bother updating when we don't have a real zoom value
+ if (nZoom)
+ {
+ OUString aStr(unicode::formatPercent(nZoom, Application::GetSettings().GetUILanguageTag()));
+ GetStatusBar().SetItemText( GetId(), aStr );
+ }
+}
+
+void SvxZoomStatusBarControl::Paint( const UserDrawEvent& )
+{
+}
+
+void SvxZoomStatusBarControl::Command( const CommandEvent& rCEvt )
+{
+ if ( CommandEventId::ContextMenu == rCEvt.GetCommand() && bool(nValueSet) )
+ {
+ ::tools::Rectangle aRect(rCEvt.GetMousePosPixel(), Size(1, 1));
+ weld::Window* pPopupParent = weld::GetPopupParent(GetStatusBar(), aRect);
+ ZoomPopup_Impl aPop(pPopupParent, nZoom, nValueSet);
+
+ OUString sIdent = aPop.popup_at_rect(aRect);
+ if (!sIdent.isEmpty() && (nZoom != aPop.GetZoom(sIdent) || !nZoom))
+ {
+ nZoom = aPop.GetZoom(sIdent);
+ ImplUpdateItemText();
+ SvxZoomItem aZoom(SvxZoomType::PERCENT, nZoom, TypedWhichId<SvxZoomItem>(GetId()));
+
+ if (sIdent == "optimal")
+ aZoom.SetType(SvxZoomType::OPTIMAL);
+ else if (sIdent == "width")
+ aZoom.SetType(SvxZoomType::PAGEWIDTH);
+ else if (sIdent == "page")
+ aZoom.SetType(SvxZoomType::WHOLEPAGE);
+
+ css::uno::Any a;
+ aZoom.QueryValue( a );
+ INetURLObject aObj( m_aCommandURL );
+
+ css::uno::Sequence< css::beans::PropertyValue > aArgs{ comphelper::makePropertyValue(
+ aObj.GetURLPath(), a) };
+ execute( aArgs );
+ }
+ }
+ else
+ SfxStatusBarControl::Command( rCEvt );
+}
+
+SFX_IMPL_STATUSBAR_CONTROL(SvxZoomPageStatusBarControl,SfxVoidItem);
+
+SvxZoomPageStatusBarControl::SvxZoomPageStatusBarControl(sal_uInt16 _nSlotId,
+ sal_uInt16 _nId, StatusBar& rStb)
+ : SfxStatusBarControl(_nSlotId, _nId, rStb)
+ , maImage(StockImage::Yes, RID_SVXBMP_ZOOM_PAGE)
+{
+ GetStatusBar().SetQuickHelpText(GetId(), SvxResId(RID_SVXSTR_FIT_SLIDE));
+}
+
+void SAL_CALL SvxZoomPageStatusBarControl::initialize( const css::uno::Sequence< css::uno::Any >& aArguments )
+{
+ // Call inherited initialize
+ StatusbarController::initialize(aArguments);
+
+ // Get document type
+ css::uno::Reference< css::frame::XModuleManager2 > xModuleManager = css::frame::ModuleManager::create( m_xContext );
+ OUString aModuleIdentifier = xModuleManager->identify( css::uno::Reference<XInterface>( m_xFrame, css::uno::UnoReference_Query::UNO_QUERY ) );
+
+ // Decide what to show in zoom bar
+ if ( aModuleIdentifier == "com.sun.star.drawing.DrawingDocument" )
+ {
+ GetStatusBar().SetQuickHelpText(GetId(), SvxResId(RID_SVXSTR_FIT_PAGE));
+ }
+ else if ( aModuleIdentifier == "com.sun.star.presentation.PresentationDocument" )
+ {
+ GetStatusBar().SetQuickHelpText(GetId(), SvxResId(RID_SVXSTR_FIT_SLIDE));
+ }
+}
+
+void SvxZoomPageStatusBarControl::Paint(const UserDrawEvent& rUsrEvt)
+{
+ vcl::RenderContext* pDev = rUsrEvt.GetRenderContext();
+ tools::Rectangle aRect = rUsrEvt.GetRect();
+ Point aPt = centerImage(aRect, maImage);
+ pDev->DrawImage(aPt, maImage);
+}
+
+bool SvxZoomPageStatusBarControl::MouseButtonDown(const MouseEvent&)
+{
+ SvxZoomItem aZoom( SvxZoomType::WHOLEPAGE, 0, TypedWhichId<SvxZoomItem>(GetId()) );
+
+ css::uno::Any a;
+ aZoom.QueryValue( a );
+ INetURLObject aObj( m_aCommandURL );
+
+ css::uno::Sequence< css::beans::PropertyValue > aArgs{ comphelper::makePropertyValue(
+ aObj.GetURLPath(), a) };
+ execute( aArgs );
+
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/stbctrls/zoomsliderctrl.cxx b/svx/source/stbctrls/zoomsliderctrl.cxx
new file mode 100644
index 0000000000..475f1da245
--- /dev/null
+++ b/svx/source/stbctrls/zoomsliderctrl.cxx
@@ -0,0 +1,392 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svx/zoomsliderctrl.hxx>
+
+#include <comphelper/propertyvalue.hxx>
+#include <vcl/status.hxx>
+#include <vcl/image.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/event.hxx>
+#include <svx/zoomslideritem.hxx>
+#include <svx/dialmgr.hxx>
+#include <svx/strings.hrc>
+#include <basegfx/utils/zoomtools.hxx>
+#include <bitmaps.hlst>
+#include <com/sun/star/beans/PropertyValue.hpp>
+
+#include <set>
+
+SFX_IMPL_STATUSBAR_CONTROL( SvxZoomSliderControl, SvxZoomSliderItem );
+
+struct SvxZoomSliderControl::SvxZoomSliderControl_Impl
+{
+ sal_uInt16 mnCurrentZoom;
+ sal_uInt16 mnMinZoom;
+ sal_uInt16 mnMaxZoom;
+ sal_uInt16 mnSliderCenter;
+ std::vector< tools::Long > maSnappingPointOffsets;
+ std::vector< sal_uInt16 > maSnappingPointZooms;
+ Image maSliderButton;
+ Image maIncreaseButton;
+ Image maDecreaseButton;
+ bool mbValuesSet;
+ bool mbDraggingStarted;
+
+ SvxZoomSliderControl_Impl() :
+ mnCurrentZoom( 0 ),
+ mnMinZoom( 0 ),
+ mnMaxZoom( 0 ),
+ mnSliderCenter( 0 ),
+ mbValuesSet( false ),
+ mbDraggingStarted( false ) {}
+};
+
+const tools::Long nSliderXOffset = 20;
+const tools::Long nSnappingEpsilon = 5; // snapping epsilon in pixels
+const tools::Long nSnappingPointsMinDist = nSnappingEpsilon; // minimum distance of two adjacent snapping points
+
+// nOffset refers to the origin of the control:
+// + ----------- -
+sal_uInt16 SvxZoomSliderControl::Offset2Zoom( tools::Long nOffset ) const
+{
+ const tools::Long nControlWidth = getControlRect().GetWidth();
+ sal_uInt16 nRet = 0;
+
+ if ( nOffset < nSliderXOffset )
+ return mxImpl->mnMinZoom;
+
+ if ( nOffset > nControlWidth - nSliderXOffset )
+ return mxImpl->mnMaxZoom;
+
+ // check for snapping points:
+ sal_uInt16 nCount = 0;
+ for ( const tools::Long nCurrent : mxImpl->maSnappingPointOffsets )
+ {
+ if ( std::abs(nCurrent - nOffset) < nSnappingEpsilon )
+ {
+ nOffset = nCurrent;
+ nRet = mxImpl->maSnappingPointZooms[ nCount ];
+ break;
+ }
+ ++nCount;
+ }
+
+ if ( 0 == nRet )
+ {
+ if ( nOffset < nControlWidth / 2 )
+ {
+ // first half of slider
+ const tools::Long nFirstHalfRange = mxImpl->mnSliderCenter - mxImpl->mnMinZoom;
+ const tools::Long nHalfSliderWidth = nControlWidth/2 - nSliderXOffset;
+ const tools::Long nZoomPerSliderPixel = (1000 * nFirstHalfRange) / nHalfSliderWidth;
+ const tools::Long nOffsetToSliderLeft = nOffset - nSliderXOffset;
+ nRet = mxImpl->mnMinZoom + sal_uInt16( nOffsetToSliderLeft * nZoomPerSliderPixel / 1000 );
+ }
+ else
+ {
+ // second half of slider
+ const tools::Long nSecondHalfRange = mxImpl->mnMaxZoom - mxImpl->mnSliderCenter;
+ const tools::Long nHalfSliderWidth = nControlWidth/2 - nSliderXOffset;
+ const tools::Long nZoomPerSliderPixel = 1000 * nSecondHalfRange / nHalfSliderWidth;
+ const tools::Long nOffsetToSliderCenter = nOffset - nControlWidth/2;
+ nRet = mxImpl->mnSliderCenter + sal_uInt16( nOffsetToSliderCenter * nZoomPerSliderPixel / 1000 );
+ }
+ }
+
+ if ( nRet < mxImpl->mnMinZoom )
+ nRet = mxImpl->mnMinZoom;
+ else if ( nRet > mxImpl->mnMaxZoom )
+ nRet = mxImpl->mnMaxZoom;
+
+ return nRet;
+}
+
+// returns the offset to the left control border
+tools::Long SvxZoomSliderControl::Zoom2Offset( sal_uInt16 nCurrentZoom ) const
+{
+ const tools::Long nControlWidth = getControlRect().GetWidth();
+ tools::Long nRet = nSliderXOffset;
+
+ const tools::Long nHalfSliderWidth = nControlWidth/2 - nSliderXOffset;
+
+ if ( nCurrentZoom <= mxImpl->mnSliderCenter )
+ {
+ nCurrentZoom = nCurrentZoom - mxImpl->mnMinZoom;
+ const tools::Long nFirstHalfRange = mxImpl->mnSliderCenter - mxImpl->mnMinZoom;
+ const tools::Long nSliderPixelPerZoomPercent = 1000 * nHalfSliderWidth / nFirstHalfRange;
+ const tools::Long nOffset = (nSliderPixelPerZoomPercent * nCurrentZoom) / 1000;
+ nRet += nOffset;
+ }
+ else
+ {
+ nCurrentZoom = nCurrentZoom - mxImpl->mnSliderCenter;
+ const tools::Long nSecondHalfRange = mxImpl->mnMaxZoom - mxImpl->mnSliderCenter;
+ const tools::Long nSliderPixelPerZoomPercent = 1000 * nHalfSliderWidth / nSecondHalfRange;
+ const tools::Long nOffset = (nSliderPixelPerZoomPercent * nCurrentZoom) / 1000;
+ nRet += nHalfSliderWidth + nOffset;
+ }
+
+ return nRet;
+}
+
+SvxZoomSliderControl::SvxZoomSliderControl( sal_uInt16 _nSlotId, sal_uInt16 _nId, StatusBar& rStatusBar ) :
+ SfxStatusBarControl( _nSlotId, _nId, rStatusBar ),
+ mxImpl( new SvxZoomSliderControl_Impl )
+{
+ mxImpl->maSliderButton = Image(StockImage::Yes, RID_SVXBMP_SLIDERBUTTON);
+ mxImpl->maIncreaseButton = Image(StockImage::Yes, RID_SVXBMP_SLIDERINCREASE);
+ mxImpl->maDecreaseButton = Image(StockImage::Yes, RID_SVXBMP_SLIDERDECREASE);
+}
+
+SvxZoomSliderControl::~SvxZoomSliderControl()
+{
+}
+
+void SvxZoomSliderControl::StateChangedAtStatusBarControl( sal_uInt16 /*nSID*/, SfxItemState eState, const SfxPoolItem* pState )
+{
+ if (SfxItemState::DEFAULT != eState || SfxItemState::DISABLED == eState)
+ {
+ GetStatusBar().SetItemText( GetId(), "" );
+ mxImpl->mbValuesSet = false;
+ }
+ else
+ {
+ assert( dynamic_cast<const SvxZoomSliderItem*>( pState) && "invalid item type: should be a SvxZoomSliderItem" );
+ mxImpl->mnCurrentZoom = static_cast<const SvxZoomSliderItem*>( pState )->GetValue();
+ mxImpl->mnMinZoom = static_cast<const SvxZoomSliderItem*>( pState )->GetMinZoom();
+ mxImpl->mnMaxZoom = static_cast<const SvxZoomSliderItem*>( pState )->GetMaxZoom();
+ mxImpl->mnSliderCenter= 100;
+ mxImpl->mbValuesSet = true;
+
+ if ( mxImpl->mnSliderCenter == mxImpl->mnMaxZoom )
+ mxImpl->mnSliderCenter = mxImpl->mnMinZoom + static_cast<sal_uInt16>((mxImpl->mnMaxZoom - mxImpl->mnMinZoom) * 0.5);
+
+
+ DBG_ASSERT( mxImpl->mnMinZoom <= mxImpl->mnCurrentZoom &&
+ mxImpl->mnMinZoom < mxImpl->mnSliderCenter &&
+ mxImpl->mnMaxZoom >= mxImpl->mnCurrentZoom &&
+ mxImpl->mnMaxZoom > mxImpl->mnSliderCenter,
+ "Looks like the zoom slider item is corrupted" );
+
+ const css::uno::Sequence < sal_Int32 > rSnappingPoints = static_cast<const SvxZoomSliderItem*>( pState )->GetSnappingPoints();
+ mxImpl->maSnappingPointOffsets.clear();
+ mxImpl->maSnappingPointZooms.clear();
+
+ // get all snapping points:
+ std::set< sal_uInt16 > aTmpSnappingPoints;
+ for ( const sal_Int32 nSnappingPoint : rSnappingPoints )
+ {
+ aTmpSnappingPoints.insert( static_cast<sal_uInt16>(nSnappingPoint) );
+ }
+
+ // remove snapping points that are too close to each other:
+ tools::Long nLastOffset = 0;
+
+ for ( const sal_uInt16 nCurrent : aTmpSnappingPoints )
+ {
+ const tools::Long nCurrentOffset = Zoom2Offset( nCurrent );
+
+ if ( nCurrentOffset - nLastOffset >= nSnappingPointsMinDist )
+ {
+ mxImpl->maSnappingPointOffsets.push_back( nCurrentOffset );
+ mxImpl->maSnappingPointZooms.push_back( nCurrent );
+ nLastOffset = nCurrentOffset;
+ }
+ }
+ }
+
+ forceRepaint();
+}
+
+void SvxZoomSliderControl::Paint( const UserDrawEvent& rUsrEvt )
+{
+ if ( !mxImpl->mbValuesSet )
+ return;
+
+ const tools::Rectangle aControlRect = getControlRect();
+ vcl::RenderContext* pDev = rUsrEvt.GetRenderContext();
+ tools::Rectangle aRect = rUsrEvt.GetRect();
+ tools::Rectangle aSlider = aRect;
+
+ tools::Long nSliderHeight = 1 * pDev->GetDPIScaleFactor();
+ tools::Long nSnappingHeight = 2 * pDev->GetDPIScaleFactor();
+
+ aSlider.AdjustTop((aControlRect.GetHeight() - nSliderHeight)/2 );
+ aSlider.SetBottom( aSlider.Top() + nSliderHeight - 1 );
+ aSlider.AdjustLeft(nSliderXOffset );
+ aSlider.AdjustRight( -nSliderXOffset );
+
+ Color aOldLineColor = pDev->GetLineColor();
+ Color aOldFillColor = pDev->GetFillColor();
+
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ pDev->SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ pDev->SetFillColor( rStyleSettings.GetDarkShadowColor() );
+
+ // draw slider
+ pDev->DrawRect( aSlider );
+ // shadow
+ pDev->SetLineColor( rStyleSettings.GetShadowColor() );
+ pDev->DrawLine(Point(aSlider.Left()+1,aSlider.Bottom()+1), Point(aSlider.Right()+1,aSlider.Bottom()+1));
+ pDev->SetLineColor( rStyleSettings.GetDarkShadowColor() );
+
+ // draw snapping points:
+ for ( const auto& rSnappingPoint : mxImpl->maSnappingPointOffsets )
+ {
+ tools::Long nSnapPosX = aRect.Left() + rSnappingPoint;
+
+ pDev->DrawRect( tools::Rectangle( nSnapPosX - 1, aSlider.Top() - nSnappingHeight,
+ nSnapPosX, aSlider.Bottom() + nSnappingHeight ) );
+ }
+
+ // draw slider button
+ Point aImagePoint = aRect.TopLeft();
+ aImagePoint.AdjustX(Zoom2Offset( mxImpl->mnCurrentZoom ) );
+ aImagePoint.AdjustX( -(mxImpl->maSliderButton.GetSizePixel().Width()/2) );
+ aImagePoint.AdjustY((aControlRect.GetHeight() - mxImpl->maSliderButton.GetSizePixel().Height())/2 );
+ pDev->DrawImage( aImagePoint, mxImpl->maSliderButton );
+
+ // draw decrease button
+ aImagePoint = aRect.TopLeft();
+ aImagePoint.AdjustX((nSliderXOffset - mxImpl->maDecreaseButton.GetSizePixel().Width())/2 );
+ aImagePoint.AdjustY((aControlRect.GetHeight() - mxImpl->maDecreaseButton.GetSizePixel().Height())/2 );
+ pDev->DrawImage( aImagePoint, mxImpl->maDecreaseButton );
+
+ // draw increase button
+ aImagePoint.setX( aRect.Left() + aControlRect.GetWidth() - mxImpl->maIncreaseButton.GetSizePixel().Width() - (nSliderXOffset - mxImpl->maIncreaseButton.GetSizePixel().Height())/2 );
+ pDev->DrawImage( aImagePoint, mxImpl->maIncreaseButton );
+
+ pDev->SetLineColor( aOldLineColor );
+ pDev->SetFillColor( aOldFillColor );
+}
+
+bool SvxZoomSliderControl::MouseButtonDown( const MouseEvent & rEvt )
+{
+ if ( !mxImpl->mbValuesSet )
+ return true;
+
+ const tools::Rectangle aControlRect = getControlRect();
+ const Point aPoint = rEvt.GetPosPixel();
+ const sal_Int32 nXDiff = aPoint.X() - aControlRect.Left();
+
+ tools::Long nIncDecWidth = mxImpl->maIncreaseButton.GetSizePixel().Width();
+
+ const tools::Long nButtonLeftOffset = (nSliderXOffset - nIncDecWidth)/2;
+ const tools::Long nButtonRightOffset = (nSliderXOffset + nIncDecWidth)/2;
+
+ const tools::Long nOldZoom = mxImpl->mnCurrentZoom;
+
+ // click to - button
+ if ( nXDiff >= nButtonLeftOffset && nXDiff <= nButtonRightOffset )
+ mxImpl->mnCurrentZoom = basegfx::zoomtools::zoomOut( mxImpl->mnCurrentZoom );
+ // click to + button
+ else if ( nXDiff >= aControlRect.GetWidth() - nSliderXOffset + nButtonLeftOffset &&
+ nXDiff <= aControlRect.GetWidth() - nSliderXOffset + nButtonRightOffset )
+ mxImpl->mnCurrentZoom = basegfx::zoomtools::zoomIn( mxImpl->mnCurrentZoom );
+ // click to slider
+ else if( nXDiff >= nSliderXOffset && nXDiff <= aControlRect.GetWidth() - nSliderXOffset )
+ {
+ mxImpl->mnCurrentZoom = Offset2Zoom( nXDiff );
+ mxImpl->mbDraggingStarted = true;
+ }
+
+ if ( mxImpl->mnCurrentZoom < mxImpl->mnMinZoom )
+ mxImpl->mnCurrentZoom = mxImpl->mnMinZoom;
+ else if ( mxImpl->mnCurrentZoom > mxImpl->mnMaxZoom )
+ mxImpl->mnCurrentZoom = mxImpl->mnMaxZoom;
+
+ if ( nOldZoom == mxImpl->mnCurrentZoom )
+ return true;
+
+ repaintAndExecute();
+
+ return true;
+}
+
+bool SvxZoomSliderControl::MouseButtonUp( const MouseEvent & )
+{
+ mxImpl->mbDraggingStarted = false;
+ return true;
+}
+
+bool SvxZoomSliderControl::MouseMove( const MouseEvent & rEvt )
+{
+ if ( !mxImpl->mbValuesSet )
+ return true;
+
+ const short nButtons = rEvt.GetButtons();
+ const tools::Rectangle aControlRect = getControlRect();
+ const Point aPoint = rEvt.GetPosPixel();
+ const sal_Int32 nXDiff = aPoint.X() - aControlRect.Left();
+
+ // check mouse move with button pressed
+ if ( 1 == nButtons && mxImpl->mbDraggingStarted )
+ {
+ if ( nXDiff >= nSliderXOffset && nXDiff <= aControlRect.GetWidth() - nSliderXOffset )
+ {
+ mxImpl->mnCurrentZoom = Offset2Zoom( nXDiff );
+
+ repaintAndExecute();
+ }
+ }
+
+ // Tooltips
+
+ tools::Long nIncDecWidth = mxImpl->maIncreaseButton.GetSizePixel().Width();
+
+ const tools::Long nButtonLeftOffset = (nSliderXOffset - nIncDecWidth)/2;
+ const tools::Long nButtonRightOffset = (nSliderXOffset + nIncDecWidth)/2;
+
+ // click to - button
+ if ( nXDiff >= nButtonLeftOffset && nXDiff <= nButtonRightOffset )
+ GetStatusBar().SetQuickHelpText(GetId(), SvxResId(RID_SVXSTR_ZOOM_OUT));
+ // click to + button
+ else if ( nXDiff >= aControlRect.GetWidth() - nSliderXOffset + nButtonLeftOffset &&
+ nXDiff <= aControlRect.GetWidth() - nSliderXOffset + nButtonRightOffset )
+ GetStatusBar().SetQuickHelpText(GetId(), SvxResId(RID_SVXSTR_ZOOM_IN));
+ else
+ // don't hide the slider and its handle with a tooltip during zooming
+ GetStatusBar().SetQuickHelpText(GetId(), "");
+
+ return true;
+}
+
+void SvxZoomSliderControl::forceRepaint() const
+{
+ GetStatusBar().SetItemData(GetId(), nullptr);
+}
+
+void SvxZoomSliderControl::repaintAndExecute()
+{
+ forceRepaint();
+
+ // commit state change
+ SvxZoomSliderItem aZoomSliderItem(mxImpl->mnCurrentZoom);
+
+ css::uno::Any any;
+ aZoomSliderItem.QueryValue(any);
+
+ css::uno::Sequence<css::beans::PropertyValue> aArgs{ comphelper::makePropertyValue("ZoomSlider",
+ any) };
+ execute(aArgs);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */