summaryrefslogtreecommitdiffstats
path: root/svx/source/tbxctrls/tbunocontroller.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'svx/source/tbxctrls/tbunocontroller.cxx')
-rw-r--r--svx/source/tbxctrls/tbunocontroller.cxx538
1 files changed, 538 insertions, 0 deletions
diff --git a/svx/source/tbxctrls/tbunocontroller.cxx b/svx/source/tbxctrls/tbunocontroller.cxx
new file mode 100644
index 000000000..a8073a1a7
--- /dev/null
+++ b/svx/source/tbxctrls/tbunocontroller.cxx
@@ -0,0 +1,538 @@
+/* -*- 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 <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/status/FontHeight.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+
+#include <comphelper/propertyvalue.hxx>
+#include <rtl/math.hxx>
+#include <vcl/event.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weldutils.hxx>
+#include <vcl/window.hxx>
+#include <vcl/settings.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <svtools/ctrltool.hxx>
+#include <svtools/ctrlbox.hxx>
+#include <svtools/toolboxcontroller.hxx>
+#include <tools/json_writer.hxx>
+#include <vcl/toolbox.hxx>
+#include <cppuhelper/queryinterface.hxx>
+#include <cppuhelper/supportsservice.hxx>
+
+#include <memory>
+
+#include <vcl/InterimItemWindow.hxx>
+
+using namespace ::com::sun::star;
+
+namespace {
+
+class SvxFontSizeBox_Base;
+class SvxFontSizeBox_Impl;
+
+class FontHeightToolBoxControl : public svt::ToolboxController,
+ public lang::XServiceInfo
+{
+ public:
+ explicit FontHeightToolBoxControl(
+ const css::uno::Reference< css::uno::XComponentContext >& rServiceManager );
+
+ // XInterface
+ virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type& aType ) override;
+ virtual void SAL_CALL acquire() noexcept override;
+ virtual void SAL_CALL release() noexcept override;
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override;
+ virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
+
+ // XComponent
+ virtual void SAL_CALL dispose() override;
+
+ // XStatusListener
+ virtual void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& Event ) override;
+
+ // XToolbarController
+ virtual void SAL_CALL execute( sal_Int16 KeyModifier ) override;
+ virtual void SAL_CALL click() override;
+ virtual void SAL_CALL doubleClick() override;
+ virtual css::uno::Reference< css::awt::XWindow > SAL_CALL createPopupWindow() override;
+ virtual css::uno::Reference< css::awt::XWindow > SAL_CALL createItemWindow( const css::uno::Reference< css::awt::XWindow >& Parent ) override;
+
+ void dispatchCommand( const css::uno::Sequence< css::beans::PropertyValue >& rArgs );
+ using svt::ToolboxController::dispatchCommand;
+
+ private:
+ VclPtr<SvxFontSizeBox_Impl> m_xVclBox;
+ std::unique_ptr<SvxFontSizeBox_Base> m_xWeldBox;
+ SvxFontSizeBox_Base* m_pBox;
+};
+
+class SvxFontSizeBox_Base
+{
+public:
+ SvxFontSizeBox_Base(std::unique_ptr<weld::ComboBox> xWidget,
+ const uno::Reference< frame::XFrame >& _xFrame,
+ FontHeightToolBoxControl& rCtrl);
+
+ virtual ~SvxFontSizeBox_Base()
+ {
+ }
+
+ virtual void set_sensitive(bool bSensitive)
+ {
+ m_xWidget->set_sensitive(bSensitive);
+ }
+
+ void statusChanged_Impl(tools::Long nHeight, bool bErase);
+ void UpdateFont();
+
+protected:
+ FontHeightToolBoxControl& m_rCtrl;
+ OUString m_aCurText;
+ bool m_bRelease;
+ uno::Reference<frame::XFrame> m_xFrame;
+ std::unique_ptr<FontSizeBox> m_xWidget;
+
+ void ReleaseFocus_Impl();
+ void Select();
+
+ virtual bool DoKeyInput(const KeyEvent& rKEvt);
+
+ DECL_LINK(SelectHdl, weld::ComboBox&, void);
+ DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
+ DECL_LINK(ActivateHdl, weld::ComboBox&, bool);
+ DECL_LINK(FocusOutHdl, weld::Widget&, void);
+ DECL_LINK(DumpAsPropertyTreeHdl, tools::JsonWriter&, void);
+};
+
+class SvxFontSizeBox_Impl final : public InterimItemWindow
+ , public SvxFontSizeBox_Base
+{
+public:
+ SvxFontSizeBox_Impl(vcl::Window* pParent,
+ const uno::Reference< frame::XFrame >& _xFrame,
+ FontHeightToolBoxControl& rCtrl);
+
+ virtual void dispose() override
+ {
+ m_xWidget.reset();
+ InterimItemWindow::dispose();
+ }
+
+ virtual void GetFocus() override
+ {
+ if (m_xWidget)
+ m_xWidget->grab_focus();
+ InterimItemWindow::GetFocus();
+ }
+
+ virtual ~SvxFontSizeBox_Impl() override
+ {
+ disposeOnce();
+ }
+
+ void SetOptimalSize();
+
+ virtual void DataChanged(const DataChangedEvent& rDCEvt) override;
+
+ virtual void set_sensitive(bool bSensitive) override
+ {
+ m_xWidget->set_sensitive(bSensitive);
+ if (bSensitive)
+ InterimItemWindow::Enable();
+ else
+ InterimItemWindow::Disable();
+ }
+
+private:
+ virtual bool DoKeyInput(const KeyEvent& rKEvt) override;
+};
+
+SvxFontSizeBox_Base::SvxFontSizeBox_Base(std::unique_ptr<weld::ComboBox> xWidget,
+ const uno::Reference<frame::XFrame>& rFrame,
+ FontHeightToolBoxControl& rCtrl)
+ : m_rCtrl(rCtrl)
+ , m_bRelease(true)
+ , m_xFrame(rFrame)
+ , m_xWidget(new FontSizeBox(std::move(xWidget)))
+{
+ m_xWidget->set_value(0);
+ m_xWidget->set_active_or_entry_text("");
+ m_xWidget->disable_entry_completion();
+
+ m_xWidget->connect_changed(LINK(this, SvxFontSizeBox_Base, SelectHdl));
+ m_xWidget->connect_key_press(LINK(this, SvxFontSizeBox_Base, KeyInputHdl));
+ m_xWidget->connect_entry_activate(LINK(this, SvxFontSizeBox_Base, ActivateHdl));
+ m_xWidget->connect_focus_out(LINK(this, SvxFontSizeBox_Base, FocusOutHdl));
+ m_xWidget->connect_get_property_tree(LINK(this, SvxFontSizeBox_Base, DumpAsPropertyTreeHdl));
+}
+
+void SvxFontSizeBox_Base::ReleaseFocus_Impl()
+{
+ if ( !m_bRelease )
+ {
+ m_bRelease = true;
+ return;
+ }
+
+ if ( m_xFrame.is() && m_xFrame->getContainerWindow().is() )
+ m_xFrame->getContainerWindow()->setFocus();
+}
+
+IMPL_LINK(SvxFontSizeBox_Base, SelectHdl, weld::ComboBox&, rCombo, void)
+{
+ if (rCombo.changed_by_direct_pick()) // only when picked from the list
+ Select();
+}
+
+IMPL_LINK_NOARG(SvxFontSizeBox_Base, ActivateHdl, weld::ComboBox&, bool)
+{
+ Select();
+ return true;
+}
+
+void SvxFontSizeBox_Base::Select()
+{
+ sal_Int64 nSelVal = m_xWidget->get_value();
+ float fSelVal = float( nSelVal ) / 10;
+
+ uno::Sequence< beans::PropertyValue > aArgs{ comphelper::makePropertyValue("FontHeight.Height",
+ fSelVal) };
+
+ /* #i33380# DR 2004-09-03 Moved the following line above the Dispatch() call.
+ This instance may be deleted in the meantime (i.e. when a dialog is opened
+ while in Dispatch()), accessing members will crash in this case. */
+ ReleaseFocus_Impl();
+
+ m_rCtrl.dispatchCommand( aArgs );
+}
+
+void SvxFontSizeBox_Base::statusChanged_Impl( tools::Long nPoint, bool bErase )
+{
+ if ( !bErase )
+ {
+ // convert the metric
+ tools::Long nVal = nPoint;
+
+ // changed => set new value
+ if (m_xWidget->get_value() != nVal)
+ m_xWidget->set_value(nVal);
+ }
+ else
+ {
+ // delete value in the display
+ m_xWidget->set_value(-1L);
+ m_xWidget->set_active_or_entry_text("");
+ }
+ m_aCurText = m_xWidget->get_active_text();
+}
+
+void SvxFontSizeBox_Base::UpdateFont()
+{
+ // filling up the sizes list
+ auto nOldVal = m_xWidget->get_value(); // memorize old value
+ FontList aFontList(Application::GetDefaultDevice());
+
+ m_xWidget->Fill(&aFontList);
+
+ m_xWidget->set_value(nOldVal); // restore old value
+ m_aCurText = m_xWidget->get_active_text(); // memorize to reset at ESC
+}
+
+IMPL_LINK(SvxFontSizeBox_Base, KeyInputHdl, const KeyEvent&, rKEvt, bool)
+{
+ return DoKeyInput(rKEvt);
+}
+
+bool SvxFontSizeBox_Base::DoKeyInput(const KeyEvent& rKEvt)
+{
+ bool bHandled = false;
+
+ sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
+
+ switch (nCode)
+ {
+ case KEY_TAB:
+ m_bRelease = false;
+ Select();
+ break;
+
+ case KEY_ESCAPE:
+ m_xWidget->set_active_or_entry_text(m_aCurText);
+ if (!m_rCtrl.IsInSidebar())
+ {
+ ReleaseFocus_Impl();
+ bHandled = true;
+ }
+ break;
+ }
+
+ return bHandled;
+}
+
+bool SvxFontSizeBox_Impl::DoKeyInput(const KeyEvent& rKEvt)
+{
+ return SvxFontSizeBox_Base::DoKeyInput(rKEvt) || ChildKeyInput(rKEvt);
+}
+
+IMPL_LINK_NOARG(SvxFontSizeBox_Base, FocusOutHdl, weld::Widget&, void)
+{
+ if (!m_xWidget->has_focus()) // a combobox can be comprised of different subwidget so double-check if none of those has focus
+ m_xWidget->set_active_or_entry_text(m_aCurText);
+}
+
+void SvxFontSizeBox_Impl::SetOptimalSize()
+{
+ SetSizePixel(get_preferred_size());
+}
+
+SvxFontSizeBox_Impl::SvxFontSizeBox_Impl(vcl::Window* pParent,
+ const uno::Reference<frame::XFrame>& rFrame,
+ FontHeightToolBoxControl& rCtrl)
+ : InterimItemWindow(pParent, "svx/ui/fontsizebox.ui", "FontSizeBox")
+ , SvxFontSizeBox_Base(m_xBuilder->weld_combo_box("fontsizecombobox"), rFrame, rCtrl)
+{
+}
+
+void SvxFontSizeBox_Impl::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
+ (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
+ {
+ SetOptimalSize();
+ }
+}
+
+IMPL_LINK(SvxFontSizeBox_Base, DumpAsPropertyTreeHdl, tools::JsonWriter&, rJsonWriter, void)
+{
+ {
+ auto entriesNode = rJsonWriter.startNode("entries");
+ for (int i = 0, nCount = m_xWidget->get_count(); i < nCount; ++i)
+ {
+ auto entryNode = rJsonWriter.startNode("");
+ rJsonWriter.put("", m_xWidget->get_text(i));
+ }
+ }
+
+ int nActive = m_xWidget->get_active();
+ rJsonWriter.put("selectedCount", static_cast<sal_Int32>(nActive == -1 ? 0 : 1));
+ {
+ auto selectedNode = rJsonWriter.startNode("selectedEntries");
+ if (nActive != -1)
+ {
+ auto node = rJsonWriter.startNode("");
+ rJsonWriter.put("", static_cast<sal_Int32>(nActive));
+ }
+ }
+
+ rJsonWriter.put("command", ".uno:FontHeight");
+}
+
+FontHeightToolBoxControl::FontHeightToolBoxControl( const uno::Reference< uno::XComponentContext >& rxContext )
+ : svt::ToolboxController( rxContext,
+ uno::Reference< frame::XFrame >(),
+ ".uno:FontHeight" ),
+ m_pBox( nullptr )
+{
+ addStatusListener( ".uno:CharFontName");
+}
+
+// XInterface
+css::uno::Any SAL_CALL FontHeightToolBoxControl::queryInterface( const css::uno::Type& aType )
+{
+ uno::Any a = ToolboxController::queryInterface( aType );
+ if ( a.hasValue() )
+ return a;
+
+ return ::cppu::queryInterface( aType, static_cast< lang::XServiceInfo* >( this ));
+}
+
+void SAL_CALL FontHeightToolBoxControl::acquire() noexcept
+{
+ ToolboxController::acquire();
+}
+
+void SAL_CALL FontHeightToolBoxControl::release() noexcept
+{
+ ToolboxController::release();
+}
+
+// XServiceInfo
+sal_Bool SAL_CALL FontHeightToolBoxControl::supportsService( const OUString& ServiceName )
+{
+ return cppu::supportsService(this, ServiceName);
+}
+
+OUString SAL_CALL FontHeightToolBoxControl::getImplementationName()
+{
+ return "com.sun.star.svx.FontHeightToolBoxController";
+}
+
+uno::Sequence< OUString > SAL_CALL FontHeightToolBoxControl::getSupportedServiceNames( )
+{
+ return { "com.sun.star.frame.ToolbarController" };
+}
+
+// XComponent
+void SAL_CALL FontHeightToolBoxControl::dispose()
+{
+ svt::ToolboxController::dispose();
+
+ SolarMutexGuard aSolarMutexGuard;
+ m_xVclBox.disposeAndClear();
+ m_xWeldBox.reset();
+ m_pBox = nullptr;
+}
+
+// XStatusListener
+void SAL_CALL FontHeightToolBoxControl::statusChanged(
+ const frame::FeatureStateEvent& rEvent )
+{
+ if ( !m_pBox )
+ return;
+
+ SolarMutexGuard aSolarMutexGuard;
+ if (rEvent.FeatureURL.Path == "FontHeight")
+ {
+ if ( rEvent.IsEnabled )
+ {
+ m_pBox->set_sensitive(true);
+ frame::status::FontHeight aFontHeight;
+ if ( rEvent.State >>= aFontHeight )
+ {
+ // tdf#83090 - correctly round the height of the font
+ aFontHeight.Height = rtl::math::round(10. * aFontHeight.Height);
+ m_pBox->statusChanged_Impl(tools::Long(aFontHeight.Height), false);
+ }
+ else
+ m_pBox->statusChanged_Impl( tools::Long( -1 ), true );
+ }
+ else
+ {
+ m_pBox->set_sensitive(false);
+ m_pBox->statusChanged_Impl( tools::Long( -1 ), true );
+ }
+
+ if (m_pToolbar)
+ m_pToolbar->set_item_sensitive(m_aCommandURL.toUtf8(), rEvent.IsEnabled);
+ else
+ {
+ ToolBox* pToolBox = nullptr;
+ ToolBoxItemId nId;
+ if (getToolboxId(nId, &pToolBox))
+ pToolBox->EnableItem(nId, rEvent.IsEnabled);
+ }
+ }
+ else if ( rEvent.FeatureURL.Path == "CharFontName" )
+ {
+ m_pBox->UpdateFont();
+ }
+}
+
+// XToolbarController
+void SAL_CALL FontHeightToolBoxControl::execute( sal_Int16 /*KeyModifier*/ )
+{
+}
+
+void SAL_CALL FontHeightToolBoxControl::click()
+{
+}
+
+void SAL_CALL FontHeightToolBoxControl::doubleClick()
+{
+}
+
+uno::Reference< awt::XWindow > SAL_CALL FontHeightToolBoxControl::createPopupWindow()
+{
+ return uno::Reference< awt::XWindow >();
+}
+
+uno::Reference< awt::XWindow > SAL_CALL FontHeightToolBoxControl::createItemWindow(
+ const uno::Reference< awt::XWindow >& xParent )
+{
+ uno::Reference< awt::XWindow > xItemWindow;
+
+ if (m_pBuilder)
+ {
+ SolarMutexGuard aSolarMutexGuard;
+
+ std::unique_ptr<weld::ComboBox> xWidget(m_pBuilder->weld_combo_box("fontsizecombobox"));
+
+ xItemWindow = css::uno::Reference<css::awt::XWindow>(new weld::TransportAsXWindow(xWidget.get()));
+
+ m_xWeldBox.reset(new SvxFontSizeBox_Base(std::move(xWidget), m_xFrame, *this));
+ m_pBox = m_xWeldBox.get();
+ //Get the box to fill itself with all its sizes
+ m_pBox->UpdateFont();
+ }
+ else
+ {
+ VclPtr<vcl::Window> pParent = VCLUnoHelper::GetWindow( xParent );
+ if ( pParent )
+ {
+ SolarMutexGuard aSolarMutexGuard;
+ m_xVclBox = VclPtr<SvxFontSizeBox_Impl>::Create( pParent, m_xFrame, *this );
+ m_pBox = m_xVclBox.get();
+ //Get the box to fill itself with all its sizes
+ m_pBox->UpdateFont();
+ //Make it size itself to its optimal size re above sizes
+ m_xVclBox->SetOptimalSize();
+ xItemWindow = VCLUnoHelper::GetInterface(m_xVclBox);
+ }
+ }
+
+ return xItemWindow;
+}
+
+void FontHeightToolBoxControl::dispatchCommand(
+ const uno::Sequence< beans::PropertyValue >& rArgs )
+{
+ uno::Reference< frame::XDispatchProvider > xDispatchProvider( m_xFrame, uno::UNO_QUERY );
+ if ( xDispatchProvider.is() )
+ {
+ util::URL aURL;
+ uno::Reference< frame::XDispatch > xDispatch;
+ uno::Reference< util::XURLTransformer > xURLTransformer = getURLTransformer();
+
+ aURL.Complete = ".uno:FontHeight";
+ xURLTransformer->parseStrict( aURL );
+ xDispatch = xDispatchProvider->queryDispatch( aURL, OUString(), 0 );
+ if ( xDispatch.is() )
+ xDispatch->dispatch( aURL, rArgs );
+ }
+}
+
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
+com_sun_star_svx_FontHeightToolBoxController_get_implementation(
+ css::uno::XComponentContext *rxContext,
+ css::uno::Sequence<css::uno::Any> const &)
+{
+ return cppu::acquire(new FontHeightToolBoxControl(rxContext));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */