diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /svx/source/sidebar/paragraph | |
parent | Initial commit. (diff) | |
download | libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | svx/source/sidebar/paragraph/ParaLineSpacingControl.cxx | 439 | ||||
-rw-r--r-- | svx/source/sidebar/paragraph/ParaLineSpacingControl.hxx | 80 | ||||
-rw-r--r-- | svx/source/sidebar/paragraph/ParaLineSpacingPopup.cxx | 99 | ||||
-rw-r--r-- | svx/source/sidebar/paragraph/ParaPropertyPanel.cxx | 491 | ||||
-rw-r--r-- | svx/source/sidebar/paragraph/ParaPropertyPanel.hxx | 135 | ||||
-rw-r--r-- | svx/source/sidebar/paragraph/ParaSpacingControl.cxx | 257 | ||||
-rw-r--r-- | svx/source/sidebar/paragraph/ParaSpacingWindow.cxx | 341 | ||||
-rw-r--r-- | svx/source/sidebar/paragraph/ParaSpacingWindow.hxx | 110 |
8 files changed, 1952 insertions, 0 deletions
diff --git a/svx/source/sidebar/paragraph/ParaLineSpacingControl.cxx b/svx/source/sidebar/paragraph/ParaLineSpacingControl.cxx new file mode 100644 index 000000000..fee659817 --- /dev/null +++ b/svx/source/sidebar/paragraph/ParaLineSpacingControl.cxx @@ -0,0 +1,439 @@ +/* -*- 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 "ParaLineSpacingControl.hxx" + +#include <editeng/editids.hrc> +#include <editeng/lspcitem.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/module.hxx> +#include <sfx2/sfxsids.hrc> +#include <sfx2/viewfrm.hxx> +#include <svtools/unitconv.hxx> + +#include <svl/intitem.hxx> +#include <svl/itempool.hxx> + +#include <ParaLineSpacingPopup.hxx> + +#define DEFAULT_LINE_SPACING 200 +#define FIX_DIST_DEF 283 +#define LINESPACE_1 100 +#define LINESPACE_15 150 +#define LINESPACE_2 200 +#define LINESPACE_115 115 + +// values of the mxLineDist listbox +#define LLINESPACE_1 0 +#define LLINESPACE_115 1 +#define LLINESPACE_15 2 +#define LLINESPACE_2 3 +#define LLINESPACE_PROP 4 +#define LLINESPACE_MIN 5 +#define LLINESPACE_DURCH 6 +#define LLINESPACE_FIX 7 + +#define MIN_FIXED_DISTANCE 28 + +using namespace svx; + +ParaLineSpacingControl::ParaLineSpacingControl(SvxLineSpacingToolBoxControl* pControl, weld::Widget* pParent) + : WeldToolbarPopup(pControl->getFrameInterface(), pParent, "svx/ui/paralinespacingcontrol.ui", "ParaLineSpacingControl") + , mxControl(pControl) + , meLNSpaceUnit(MapUnit::Map100thMM) + , mxSpacing1Button(m_xBuilder->weld_button("spacing_1")) + , mxSpacing115Button(m_xBuilder->weld_button("spacing_115")) + , mxSpacing15Button(m_xBuilder->weld_button("spacing_15")) + , mxSpacing2Button(m_xBuilder->weld_button("spacing_2")) + , mxLineDist(m_xBuilder->weld_combo_box("line_dist")) + , mxLineDistLabel(m_xBuilder->weld_label("value_label")) + , mxLineDistAtPercentBox(m_xBuilder->weld_metric_spin_button("percent_box", FieldUnit::PERCENT)) + , mxLineDistAtMetricBox(m_xBuilder->weld_metric_spin_button("metric_box", FieldUnit::CM)) + , mpActLineDistFld(mxLineDistAtPercentBox.get()) +{ + Link<weld::Button&,void> aLink = LINK(this, ParaLineSpacingControl, PredefinedValuesHandler); + mxSpacing1Button->connect_clicked(aLink); + mxSpacing115Button->connect_clicked(aLink); + mxSpacing15Button->connect_clicked(aLink); + mxSpacing2Button->connect_clicked(aLink); + + Link<weld::ComboBox&,void> aLink3 = LINK( this, ParaLineSpacingControl, LineSPDistHdl_Impl ); + mxLineDist->connect_changed(aLink3); + SelectEntryPos(LLINESPACE_1); + + Link<weld::MetricSpinButton&,void> aLink2 = LINK( this, ParaLineSpacingControl, LineSPDistAtHdl_Impl ); + mxLineDistAtPercentBox->connect_value_changed( aLink2 ); + mxLineDistAtMetricBox->connect_value_changed( aLink2 ); + + FieldUnit eUnit = FieldUnit::INCH; + const SfxUInt16Item* pItem = nullptr; + SfxViewFrame* pCurrent = SfxViewFrame::Current(); + if (pCurrent && pCurrent->GetBindings().GetDispatcher()->QueryState(SID_ATTR_METRIC, pItem) >= SfxItemState::DEFAULT) + eUnit = static_cast<FieldUnit>(pItem->GetValue()); + else + eUnit = SfxModule::GetCurrentFieldUnit(); + + SetFieldUnit(*mxLineDistAtMetricBox, eUnit); + + Initialize(); +} + +void ParaLineSpacingControl::GrabFocus() +{ + switch (mxLineDist->get_active()) + { + case LLINESPACE_1: + mxSpacing1Button->grab_focus(); + break; + case LLINESPACE_115: + mxSpacing115Button->grab_focus(); + break; + case LLINESPACE_15: + mxSpacing15Button->grab_focus(); + break; + case LLINESPACE_2: + mxSpacing2Button->grab_focus(); + break; + default: + mxLineDist->grab_focus(); + break; + } +} + +ParaLineSpacingControl::~ParaLineSpacingControl() +{ +} + +void ParaLineSpacingControl::Initialize() +{ + const SvxLineSpacingItem* pItem(nullptr); + SfxViewFrame* pCurrent = SfxViewFrame::Current(); + const bool bItemStateSet(nullptr != pCurrent); + const SfxItemState eState(bItemStateSet + ? pCurrent->GetBindings().GetDispatcher()->QueryState(SID_ATTR_PARA_LINESPACE, pItem) + : SfxItemState::DEFAULT); + + mxLineDist->set_sensitive(true); + + if( bItemStateSet && (eState == SfxItemState::DEFAULT || eState == SfxItemState::SET) ) + { + const SvxLineSpacingItem* currSPItem = pItem; + MapUnit eUnit = pCurrent->GetPool().GetMetric(currSPItem->Which()); + meLNSpaceUnit = eUnit; + + switch( currSPItem->GetLineSpaceRule() ) + { + case SvxLineSpaceRule::Auto: + { + SvxInterLineSpaceRule eInter = currSPItem->GetInterLineSpaceRule(); + + switch( eInter ) + { + case SvxInterLineSpaceRule::Off: + SelectEntryPos(LLINESPACE_1); + break; + + case SvxInterLineSpaceRule::Prop: + { + if ( LINESPACE_1 == currSPItem->GetPropLineSpace() ) + { + SelectEntryPos(LLINESPACE_1); + } + else if ( LINESPACE_115 == currSPItem->GetPropLineSpace() ) + { + SelectEntryPos(LLINESPACE_115); + } + else if ( LINESPACE_15 == currSPItem->GetPropLineSpace() ) + { + SelectEntryPos(LLINESPACE_15); + } + else if ( LINESPACE_2 == currSPItem->GetPropLineSpace() ) + { + SelectEntryPos(LLINESPACE_2); + } + else + { + SelectEntryPos(LLINESPACE_PROP); + mxLineDistAtPercentBox->set_value(mxLineDistAtPercentBox->normalize(currSPItem->GetPropLineSpace()), FieldUnit::PERCENT); + } + } + break; + + case SvxInterLineSpaceRule::Fix: + { + SelectEntryPos(LLINESPACE_DURCH); + SetMetricValue(*mxLineDistAtMetricBox, currSPItem->GetInterLineSpace(), eUnit); + } + break; + default: + break; + } + } + break; + case SvxLineSpaceRule::Fix: + { + SelectEntryPos(LLINESPACE_FIX); + SetMetricValue(*mxLineDistAtMetricBox, currSPItem->GetLineHeight(), eUnit); + } + break; + + case SvxLineSpaceRule::Min: + { + SelectEntryPos(LLINESPACE_MIN); + SetMetricValue(*mxLineDistAtMetricBox, currSPItem->GetLineHeight(), eUnit); + } + break; + default: + break; + } + } + else if( bItemStateSet && eState == SfxItemState::DISABLED ) + { + mxLineDist->set_sensitive(false); + mxLineDistLabel->set_sensitive(false); + mpActLineDistFld->set_sensitive(false); + mpActLineDistFld->set_text(""); + + } + else // !bItemStateSet || eState == SfxItemState::DONTCARE || eState == SfxItemState::UNKNOWN + { + mxLineDistLabel->set_sensitive(false); + mpActLineDistFld->set_sensitive(false); + mpActLineDistFld->set_text(""); + mxLineDist->set_active(-1); + } + + mxLineDist->save_value(); +} + +void ParaLineSpacingControl::UpdateMetricFields() +{ + switch (mxLineDist->get_active()) + { + case LLINESPACE_1: + case LLINESPACE_115: + case LLINESPACE_15: + case LLINESPACE_2: + if (mpActLineDistFld == mxLineDistAtPercentBox.get()) + mxLineDistAtMetricBox->hide(); + else + mxLineDistAtPercentBox->hide(); + + mxLineDistLabel->set_sensitive(false); + mpActLineDistFld->show(); + mpActLineDistFld->set_sensitive(false); + mpActLineDistFld->set_text(""); + break; + + case LLINESPACE_DURCH: + mxLineDistAtPercentBox->hide(); + + mpActLineDistFld = mxLineDistAtMetricBox.get(); + mxLineDistAtMetricBox->set_min(0, FieldUnit::NONE); + + if (mxLineDistAtMetricBox->get_text().isEmpty()) + mxLineDistAtMetricBox->set_value(mxLineDistAtMetricBox->normalize(0), FieldUnit::NONE); + + mxLineDistLabel->set_sensitive(true); + mpActLineDistFld->show(); + mpActLineDistFld->set_sensitive(true); + break; + + case LLINESPACE_MIN: + mxLineDistAtPercentBox->hide(); + + mpActLineDistFld = mxLineDistAtMetricBox.get(); + mxLineDistAtMetricBox->set_min(0, FieldUnit::NONE); + + if (mxLineDistAtMetricBox->get_text().isEmpty()) + mxLineDistAtMetricBox->set_value(mxLineDistAtMetricBox->normalize(0), FieldUnit::TWIP); + + mxLineDistLabel->set_sensitive(true); + mpActLineDistFld->show(); + mpActLineDistFld->set_sensitive(true); + break; + + case LLINESPACE_PROP: + mxLineDistAtMetricBox->hide(); + + mpActLineDistFld = mxLineDistAtPercentBox.get(); + + if (mxLineDistAtPercentBox->get_text().isEmpty()) + mxLineDistAtPercentBox->set_value(mxLineDistAtPercentBox->normalize(100), FieldUnit::TWIP); + + mxLineDistLabel->set_sensitive(true); + mpActLineDistFld->show(); + mpActLineDistFld->set_sensitive(true); + break; + + case LLINESPACE_FIX: + mxLineDistAtPercentBox->hide(); + + mpActLineDistFld = mxLineDistAtMetricBox.get(); + sal_Int64 nTemp = mxLineDistAtMetricBox->get_value(FieldUnit::NONE); + mxLineDistAtMetricBox->set_min(mxLineDistAtMetricBox->normalize(MIN_FIXED_DISTANCE), FieldUnit::TWIP); + + if (mxLineDistAtMetricBox->get_value(FieldUnit::NONE) != nTemp) + SetMetricValue(*mxLineDistAtMetricBox, FIX_DIST_DEF, MapUnit::MapTwip); + + mxLineDistLabel->set_sensitive(true); + mpActLineDistFld->show(); + mpActLineDistFld->set_sensitive(true); + break; + } +} + +void ParaLineSpacingControl::SelectEntryPos(sal_Int32 nPos) +{ + mxLineDist->set_active(nPos); + UpdateMetricFields(); +} + +IMPL_LINK_NOARG(ParaLineSpacingControl, LineSPDistHdl_Impl, weld::ComboBox&, void) +{ + UpdateMetricFields(); + ExecuteLineSpace(); +} + +IMPL_LINK_NOARG( ParaLineSpacingControl, LineSPDistAtHdl_Impl, weld::MetricSpinButton&, void ) +{ + ExecuteLineSpace(); +} + +void ParaLineSpacingControl::ExecuteLineSpace() +{ + mxLineDist->save_value(); + + SvxLineSpacingItem aSpacing(DEFAULT_LINE_SPACING, SID_ATTR_PARA_LINESPACE); + const sal_Int32 nPos = mxLineDist->get_active(); + + switch ( nPos ) + { + case LLINESPACE_1: + case LLINESPACE_115: + case LLINESPACE_15: + case LLINESPACE_2: + SetLineSpace(aSpacing, nPos); + break; + + case LLINESPACE_PROP: + SetLineSpace(aSpacing, nPos, mxLineDistAtPercentBox->denormalize(static_cast<tools::Long>(mxLineDistAtPercentBox->get_value(FieldUnit::PERCENT)))); + break; + + case LLINESPACE_MIN: + case LLINESPACE_DURCH: + case LLINESPACE_FIX: + SetLineSpace(aSpacing, nPos, GetCoreValue(*mxLineDistAtMetricBox, meLNSpaceUnit)); + break; + + default: + break; + } + + if (SfxViewFrame* pViewFrm = SfxViewFrame::Current()) + { + pViewFrm->GetBindings().GetDispatcher()->ExecuteList( + SID_ATTR_PARA_LINESPACE, SfxCallMode::RECORD, { &aSpacing }); + } +} + +void ParaLineSpacingControl::SetLineSpace(SvxLineSpacingItem& rLineSpace, sal_Int32 eSpace, tools::Long lValue) +{ + switch ( eSpace ) + { + case LLINESPACE_1: + rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto ); + rLineSpace.SetInterLineSpaceRule( SvxInterLineSpaceRule::Off ); + break; + + case LLINESPACE_115: + rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto ); + rLineSpace.SetPropLineSpace( LINESPACE_115 ); + break; + + case LLINESPACE_15: + rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto ); + rLineSpace.SetPropLineSpace( LINESPACE_15 ); + break; + + case LLINESPACE_2: + rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto ); + rLineSpace.SetPropLineSpace( LINESPACE_2 ); + break; + + case LLINESPACE_PROP: + rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto ); + rLineSpace.SetPropLineSpace( static_cast<sal_uInt16>(lValue) ); + break; + + case LLINESPACE_MIN: + rLineSpace.SetLineHeight( static_cast<sal_uInt16>(lValue) ); + rLineSpace.SetInterLineSpaceRule( SvxInterLineSpaceRule::Off ); + break; + + case LLINESPACE_DURCH: + rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto ); + rLineSpace.SetInterLineSpace( static_cast<sal_uInt16>(lValue) ); + break; + + case LLINESPACE_FIX: + rLineSpace.SetLineHeight(static_cast<sal_uInt16>(lValue)); + rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Fix ); + rLineSpace.SetInterLineSpaceRule( SvxInterLineSpaceRule::Off ); + break; + } +} + +IMPL_LINK(ParaLineSpacingControl, PredefinedValuesHandler, weld::Button&, rControl, void) +{ + if (&rControl == mxSpacing1Button.get()) + { + ExecuteLineSpacing(LLINESPACE_1); + } + else if (&rControl == mxSpacing115Button.get()) + { + ExecuteLineSpacing(LLINESPACE_115); + } + else if (&rControl == mxSpacing15Button.get()) + { + ExecuteLineSpacing(LLINESPACE_15); + } + else if (&rControl == mxSpacing2Button.get()) + { + ExecuteLineSpacing(LLINESPACE_2); + } +} + +void ParaLineSpacingControl::ExecuteLineSpacing(sal_Int32 nEntry) +{ + SvxLineSpacingItem aSpacing(DEFAULT_LINE_SPACING, SID_ATTR_PARA_LINESPACE); + + SetLineSpace(aSpacing, nEntry); + + if (SfxViewFrame* pViewFrm = SfxViewFrame::Current()) + { + pViewFrm->GetBindings().GetDispatcher()->ExecuteList( + SID_ATTR_PARA_LINESPACE, SfxCallMode::RECORD, { &aSpacing }); + } + + // close when the user used the buttons + mxControl->EndPopupMode(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/paragraph/ParaLineSpacingControl.hxx b/svx/source/sidebar/paragraph/ParaLineSpacingControl.hxx new file mode 100644 index 000000000..e49556f16 --- /dev/null +++ b/svx/source/sidebar/paragraph/ParaLineSpacingControl.hxx @@ -0,0 +1,80 @@ +/* -*- 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 . + */ +#pragma once + +#include <svtools/toolbarmenu.hxx> + +class SvxLineSpacingItem; + +namespace svx +{ +class SvxLineSpacingToolBoxControl; + +class ParaLineSpacingControl : public WeldToolbarPopup +{ +public: + explicit ParaLineSpacingControl(SvxLineSpacingToolBoxControl* pControl, weld::Widget* pParent); + virtual ~ParaLineSpacingControl() override; + + /// Setup the widgets with values from the document. + void Initialize(); + + virtual void GrabFocus() override; + +private: + rtl::Reference<SvxLineSpacingToolBoxControl> mxControl; + + MapUnit meLNSpaceUnit; + + std::unique_ptr<weld::Button> mxSpacing1Button; + std::unique_ptr<weld::Button> mxSpacing115Button; + std::unique_ptr<weld::Button> mxSpacing15Button; + std::unique_ptr<weld::Button> mxSpacing2Button; + + std::unique_ptr<weld::ComboBox> mxLineDist; + + std::unique_ptr<weld::Label> mxLineDistLabel; + std::unique_ptr<weld::MetricSpinButton> mxLineDistAtPercentBox; + std::unique_ptr<weld::MetricSpinButton> mxLineDistAtMetricBox; + weld::MetricSpinButton* mpActLineDistFld; + +private: + /// Take the values from the widgets, and update the paragraph accordingly. + void ExecuteLineSpace(); + + /// Set one particular value. + static void SetLineSpace(SvxLineSpacingItem& rLineSpace, sal_Int32 eSpace, + tools::Long lValue = 0); + + /// For the buttons - set the values, and close the popup. + void ExecuteLineSpacing(sal_Int32 aEntry); + + /// Set mpActlineDistFld and visibility of mpLineDist* fields according to what is just selected. + void UpdateMetricFields(); + + /// Set the entry and update the metric fields. + void SelectEntryPos(sal_Int32 nPos); + + DECL_LINK(LineSPDistHdl_Impl, weld::ComboBox&, void); + DECL_LINK(LineSPDistAtHdl_Impl, weld::MetricSpinButton&, void); + DECL_LINK(PredefinedValuesHandler, weld::Button&, void); +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/paragraph/ParaLineSpacingPopup.cxx b/svx/source/sidebar/paragraph/ParaLineSpacingPopup.cxx new file mode 100644 index 000000000..d8e427840 --- /dev/null +++ b/svx/source/sidebar/paragraph/ParaLineSpacingPopup.cxx @@ -0,0 +1,99 @@ +/* -*- 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 "ParaLineSpacingControl.hxx" + +#include <ParaLineSpacingPopup.hxx> +#include <vcl/toolbox.hxx> + +using namespace svx; + +SvxLineSpacingToolBoxControl::SvxLineSpacingToolBoxControl( + const css::uno::Reference<css::uno::XComponentContext>& rContext) + : PopupWindowController(rContext, nullptr, OUString()) +{ +} + +SvxLineSpacingToolBoxControl::~SvxLineSpacingToolBoxControl() {} + +void SvxLineSpacingToolBoxControl::initialize(const css::uno::Sequence<css::uno::Any>& rArguments) +{ + PopupWindowController::initialize(rArguments); + + if (m_pToolbar) + { + mxPopoverContainer.reset(new ToolbarPopupContainer(m_pToolbar)); + m_pToolbar->set_item_popover(m_aCommandURL.toUtf8(), mxPopoverContainer->getTopLevel()); + } + + ToolBox* pToolBox = nullptr; + ToolBoxItemId nId; + if (getToolboxId(nId, &pToolBox)) + pToolBox->SetItemBits(nId, ToolBoxItemBits::DROPDOWNONLY | pToolBox->GetItemBits(nId)); +} + +void SAL_CALL SvxLineSpacingToolBoxControl::execute(sal_Int16 /*KeyModifier*/) +{ + if (m_pToolbar) + { + // Toggle the popup also when toolbutton is activated + const OString aId(m_aCommandURL.toUtf8()); + m_pToolbar->set_menu_item_active(aId, !m_pToolbar->get_menu_item_active(aId)); + } + else + { + // Open the popup also when Enter key is pressed. + createPopupWindow(); + } +} + +std::unique_ptr<WeldToolbarPopup> SvxLineSpacingToolBoxControl::weldPopupWindow() +{ + return std::make_unique<ParaLineSpacingControl>(this, m_pToolbar); +} + +VclPtr<vcl::Window> SvxLineSpacingToolBoxControl::createVclPopupWindow(vcl::Window* pParent) +{ + mxInterimPopover = VclPtr<InterimToolbarPopup>::Create( + getFrameInterface(), pParent, + std::make_unique<ParaLineSpacingControl>(this, pParent->GetFrameWeld())); + + mxInterimPopover->Show(); + + return mxInterimPopover; +} + +OUString SvxLineSpacingToolBoxControl::getImplementationName() +{ + return "com.sun.star.comp.svx.LineSpacingToolBoxControl"; +} + +css::uno::Sequence<OUString> SvxLineSpacingToolBoxControl::getSupportedServiceNames() +{ + return { "com.sun.star.frame.ToolbarController" }; +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +com_sun_star_comp_svx_LineSpacingToolBoxControl_get_implementation( + css::uno::XComponentContext* rContext, css::uno::Sequence<css::uno::Any> const&) +{ + return cppu::acquire(new SvxLineSpacingToolBoxControl(rContext)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/paragraph/ParaPropertyPanel.cxx b/svx/source/sidebar/paragraph/ParaPropertyPanel.cxx new file mode 100644 index 000000000..f4e2fd83b --- /dev/null +++ b/svx/source/sidebar/paragraph/ParaPropertyPanel.cxx @@ -0,0 +1,491 @@ +/* -*- 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 "ParaPropertyPanel.hxx" +#include <sfx2/dispatch.hxx> +#include <sfx2/module.hxx> +#include <sfx2/viewfrm.hxx> +#include <sfx2/weldutils.hxx> +#include <editeng/lrspitem.hxx> +#include <editeng/ulspitem.hxx> +#include <svx/dlgctrl.hxx> +#include <svx/svxids.hrc> +#include <svl/intitem.hxx> +#include <sfx2/objsh.hxx> +#include <svtools/unitconv.hxx> +#include <sal/log.hxx> + +#include <com/sun/star/lang/IllegalArgumentException.hpp> + +using namespace css; +using namespace css::uno; + +namespace svx::sidebar { +#define DEFAULT_VALUE 0 + +#define MAX_DURCH 31680 // tdf#68335: 1584 pt for UX interoperability with Word + +#define MAX_SW 1709400 +#define MAX_SC_SD 116220200 +#define NEGA_MAXVALUE -10000000 + +std::unique_ptr<PanelLayout> ParaPropertyPanel::Create ( + weld::Widget* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings, + const css::uno::Reference<css::ui::XSidebar>& rxSidebar) +{ + if (pParent == nullptr) + throw lang::IllegalArgumentException("no parent Window given to ParaPropertyPanel::Create", nullptr, 0); + if ( ! rxFrame.is()) + throw lang::IllegalArgumentException("no XFrame given to ParaPropertyPanel::Create", nullptr, 1); + if (pBindings == nullptr) + throw lang::IllegalArgumentException("no SfxBindings given to ParaPropertyPanel::Create", nullptr, 2); + + return std::make_unique<ParaPropertyPanel>(pParent, rxFrame, pBindings, rxSidebar); +} + +void ParaPropertyPanel::HandleContextChange ( + const vcl::EnumContext& rContext) +{ + if (maContext == rContext) + { + // Nothing to do. + return; + } + + maContext = rContext; + switch (maContext.GetCombinedContext_DI()) + { + case CombinedEnumContext(Application::Calc, Context::DrawText): + case CombinedEnumContext(Application::WriterVariants, Context::DrawText): + mxTBxVertAlign->show(); + mxTBxBackColor->hide(); + mxTBxNumBullet->hide(); + ReSize(); + break; + + case CombinedEnumContext(Application::DrawImpress, Context::Draw): + case CombinedEnumContext(Application::DrawImpress, Context::TextObject): + case CombinedEnumContext(Application::DrawImpress, Context::Graphic): + case CombinedEnumContext(Application::DrawImpress, Context::DrawText): + case CombinedEnumContext(Application::DrawImpress, Context::Table): + mxTBxVertAlign->show(); + mxTBxBackColor->hide(); + mxTBxNumBullet->hide(); + ReSize(); + break; + + case CombinedEnumContext(Application::WriterVariants, Context::Default): + case CombinedEnumContext(Application::WriterVariants, Context::Text): + mxTBxVertAlign->hide(); + mxTBxBackColor->show(); + mxTBxNumBullet->show(); + ReSize(); + break; + + case CombinedEnumContext(Application::WriterVariants, Context::Table): + mxTBxVertAlign->show(); + mxTBxBackColor->show(); + mxTBxNumBullet->show(); + ReSize(); + break; + + case CombinedEnumContext(Application::WriterVariants, Context::Annotation): + mxTBxVertAlign->hide(); + mxTBxBackColor->hide(); + mxTBxNumBullet->hide(); + ReSize(); + break; + + case CombinedEnumContext(Application::Calc, Context::EditCell): + case CombinedEnumContext(Application::Calc, Context::Cell): + case CombinedEnumContext(Application::Calc, Context::Pivot): + case CombinedEnumContext(Application::Calc, Context::Sparkline): + case CombinedEnumContext(Application::DrawImpress, Context::Text): + case CombinedEnumContext(Application::DrawImpress, Context::OutlineText): + break; + + default: + break; + } +} + +void ParaPropertyPanel::ReSize() +{ + if (mxSidebar.is()) + mxSidebar->requestLayout(); +} + +void ParaPropertyPanel::InitToolBoxIndent() +{ + Link<weld::MetricSpinButton&,void> aLink = LINK( this, ParaPropertyPanel, ModifyIndentHdl_Impl ); + mxLeftIndent->connect_value_changed( aLink ); + mxRightIndent->connect_value_changed( aLink ); + mxFLineIndent->connect_value_changed( aLink ); + + m_eLRSpaceUnit = maLRSpaceControl.GetCoreMetric(); +} + +void ParaPropertyPanel::InitToolBoxSpacing() +{ + Link<weld::MetricSpinButton&,void> aLink = LINK( this, ParaPropertyPanel, ULSpaceHdl_Impl ); + mxTopDist->connect_value_changed(aLink); + mxBottomDist->connect_value_changed( aLink ); + + m_eULSpaceUnit = maULSpaceControl.GetCoreMetric(); +} + +void ParaPropertyPanel::initial() +{ + limitMetricWidths(); + + //toolbox + InitToolBoxIndent(); + InitToolBoxSpacing(); +} + +// for Paragraph Indent +IMPL_LINK_NOARG( ParaPropertyPanel, ModifyIndentHdl_Impl, weld::MetricSpinButton&, void) +{ + SvxLRSpaceItem aMargin( SID_ATTR_PARA_LRSPACE ); + aMargin.SetTextLeft(mxLeftIndent->GetCoreValue(m_eLRSpaceUnit)); + aMargin.SetRight(mxRightIndent->GetCoreValue(m_eLRSpaceUnit)); + aMargin.SetTextFirstLineOffset(static_cast<short>(mxFLineIndent->GetCoreValue(m_eLRSpaceUnit))); + + GetBindings()->GetDispatcher()->ExecuteList( + SID_ATTR_PARA_LRSPACE, SfxCallMode::RECORD, { &aMargin }); +} + + +// for Paragraph Spacing +IMPL_LINK_NOARG( ParaPropertyPanel, ULSpaceHdl_Impl, weld::MetricSpinButton&, void) +{ + SvxULSpaceItem aMargin( SID_ATTR_PARA_ULSPACE ); + aMargin.SetUpper( static_cast<sal_uInt16>(mxTopDist->GetCoreValue(m_eULSpaceUnit))); + aMargin.SetLower( static_cast<sal_uInt16>(mxBottomDist->GetCoreValue(m_eULSpaceUnit))); + + GetBindings()->GetDispatcher()->ExecuteList( + SID_ATTR_PARA_ULSPACE, SfxCallMode::RECORD, { &aMargin }); +} + +// for Paragraph State change +void ParaPropertyPanel::NotifyItemUpdate( + sal_uInt16 nSID, + SfxItemState eState, + const SfxPoolItem* pState) +{ + switch (nSID) + { + case SID_ATTR_METRIC: + { + m_eMetricUnit = GetCurrentUnit(eState,pState); + if( m_eMetricUnit!=m_last_eMetricUnit ) + { + mxLeftIndent->SetFieldUnit(m_eMetricUnit); + mxRightIndent->SetFieldUnit(m_eMetricUnit); + mxFLineIndent->SetFieldUnit(m_eMetricUnit); + mxTopDist->SetFieldUnit(m_eMetricUnit); + mxBottomDist->SetFieldUnit(m_eMetricUnit); + + limitMetricWidths(); + } + m_last_eMetricUnit = m_eMetricUnit; + } + break; + + case SID_ATTR_PARA_LRSPACE: + StateChangedIndentImpl( eState, pState ); + break; + + case SID_ATTR_PARA_ULSPACE: + StateChangedULImpl( eState, pState ); + break; + } +} + +void ParaPropertyPanel::StateChangedIndentImpl( SfxItemState eState, const SfxPoolItem* pState ) +{ + switch (maContext.GetCombinedContext_DI()) + { + + case CombinedEnumContext(Application::WriterVariants, Context::DrawText): + case CombinedEnumContext(Application::WriterVariants, Context::Annotation): + case CombinedEnumContext(Application::Calc, Context::DrawText): + case CombinedEnumContext(Application::DrawImpress, Context::DrawText): + case CombinedEnumContext(Application::DrawImpress, Context::Draw): + case CombinedEnumContext(Application::DrawImpress, Context::TextObject): + case CombinedEnumContext(Application::DrawImpress, Context::Graphic): + case CombinedEnumContext(Application::DrawImpress, Context::Table): + { + mxLeftIndent->set_min( DEFAULT_VALUE, FieldUnit::NONE ); + mxRightIndent->set_min( DEFAULT_VALUE, FieldUnit::NONE ); + mxFLineIndent->set_min( DEFAULT_VALUE, FieldUnit::NONE ); + } + break; + case CombinedEnumContext(Application::WriterVariants, Context::Default): + case CombinedEnumContext(Application::WriterVariants, Context::Text): + case CombinedEnumContext(Application::WriterVariants, Context::Table): + { + mxLeftIndent->set_min( NEGA_MAXVALUE, FieldUnit::MM_100TH ); + mxRightIndent->set_min( NEGA_MAXVALUE, FieldUnit::MM_100TH ); + mxFLineIndent->set_min( NEGA_MAXVALUE, FieldUnit::MM_100TH ); + } + break; + } + + bool bDisabled = eState == SfxItemState::DISABLED; + mxLeftIndent->set_sensitive(!bDisabled); + mxRightIndent->set_sensitive(!bDisabled); + mxFLineIndent->set_sensitive(!bDisabled); + + if (pState && eState >= SfxItemState::DEFAULT) + { + const SvxLRSpaceItem* pSpace = static_cast<const SvxLRSpaceItem*>(pState); + maTxtLeft = pSpace->GetTextLeft(); + maTxtLeft = OutputDevice::LogicToLogic(maTxtLeft, m_eLRSpaceUnit, MapUnit::MapTwip); + + tools::Long aTxtRight = pSpace->GetRight(); + aTxtRight = OutputDevice::LogicToLogic(aTxtRight, m_eLRSpaceUnit, MapUnit::MapTwip); + + tools::Long aTxtFirstLineOfst = pSpace->GetTextFirstLineOffset(); + aTxtFirstLineOfst = OutputDevice::LogicToLogic( aTxtFirstLineOfst, m_eLRSpaceUnit, MapUnit::MapTwip ); + + tools::Long nVal = o3tl::convert(maTxtLeft, o3tl::Length::twip, o3tl::Length::mm100); + nVal = static_cast<tools::Long>(mxLeftIndent->normalize( nVal )); + + if ( maContext.GetCombinedContext_DI() != CombinedEnumContext(Application::WriterVariants, Context::Text) + && maContext.GetCombinedContext_DI() != CombinedEnumContext(Application::WriterVariants, Context::Default) + && maContext.GetCombinedContext_DI() != CombinedEnumContext(Application::WriterVariants, Context::Table)) + { + mxFLineIndent->set_min( nVal*-1, FieldUnit::MM_100TH ); + } + + tools::Long nrVal = o3tl::convert(aTxtRight, o3tl::Length::twip, o3tl::Length::mm100); + nrVal = static_cast<tools::Long>(mxRightIndent->normalize( nrVal )); + + switch (maContext.GetCombinedContext_DI()) + { + case CombinedEnumContext(Application::WriterVariants, Context::DrawText): + case CombinedEnumContext(Application::WriterVariants, Context::Text): + case CombinedEnumContext(Application::WriterVariants, Context::Default): + case CombinedEnumContext(Application::WriterVariants, Context::Table): + case CombinedEnumContext(Application::WriterVariants, Context::Annotation): + { + mxLeftIndent->set_max( MAX_SW - nrVal, FieldUnit::MM_100TH ); + mxRightIndent->set_max( MAX_SW - nVal, FieldUnit::MM_100TH ); + mxFLineIndent->set_max( MAX_SW - nVal - nrVal, FieldUnit::MM_100TH ); + } + break; + case CombinedEnumContext(Application::DrawImpress, Context::DrawText): + case CombinedEnumContext(Application::DrawImpress, Context::Draw): + case CombinedEnumContext(Application::DrawImpress, Context::Table): + case CombinedEnumContext(Application::DrawImpress, Context::TextObject): + case CombinedEnumContext(Application::DrawImpress, Context::Graphic): + { + mxLeftIndent->set_max( MAX_SC_SD - nrVal, FieldUnit::MM_100TH ); + mxRightIndent->set_max( MAX_SC_SD - nVal, FieldUnit::MM_100TH ); + mxFLineIndent->set_max( MAX_SC_SD - nVal - nrVal, FieldUnit::MM_100TH ); + } + } + + mxLeftIndent->set_value( nVal, FieldUnit::MM_100TH ); + mxRightIndent->set_value( nrVal, FieldUnit::MM_100TH ); + + tools::Long nfVal = o3tl::convert(aTxtFirstLineOfst, o3tl::Length::twip, o3tl::Length::mm100); + nfVal = static_cast<tools::Long>(mxFLineIndent->normalize( nfVal )); + mxFLineIndent->set_value( nfVal, FieldUnit::MM_100TH ); + } + else if (eState != SfxItemState::DISABLED ) + { + mxLeftIndent->set_text(""); + mxRightIndent->set_text(""); + mxFLineIndent->set_text(""); + } + + limitMetricWidths(); +} + +void ParaPropertyPanel::StateChangedULImpl( SfxItemState eState, const SfxPoolItem* pState ) +{ + mxTopDist->set_max( mxTopDist->normalize( MAX_DURCH ), MapToFieldUnit(m_eULSpaceUnit) ); + mxBottomDist->set_max( mxBottomDist->normalize( MAX_DURCH ), MapToFieldUnit(m_eULSpaceUnit) ); + + bool bDisabled = eState == SfxItemState::DISABLED; + mxTopDist->set_sensitive(!bDisabled); + mxBottomDist->set_sensitive(!bDisabled); + + if( pState && eState >= SfxItemState::DEFAULT ) + { + const SvxULSpaceItem* pOldItem = static_cast<const SvxULSpaceItem*>(pState); + + maUpper = pOldItem->GetUpper(); + maUpper = OutputDevice::LogicToLogic(maUpper, m_eULSpaceUnit, MapUnit::MapTwip); + + maLower = pOldItem->GetLower(); + maLower = OutputDevice::LogicToLogic(maLower, m_eULSpaceUnit, MapUnit::MapTwip); + + sal_Int64 nVal = o3tl::convert(maUpper, o3tl::Length::twip, o3tl::Length::mm100); + nVal = mxTopDist->normalize( nVal ); + mxTopDist->set_value( nVal, FieldUnit::MM_100TH ); + + nVal = o3tl::convert(maLower, o3tl::Length::twip, o3tl::Length::mm100); + nVal = mxBottomDist->normalize( nVal ); + mxBottomDist->set_value( nVal, FieldUnit::MM_100TH ); + } + else if (eState != SfxItemState::DISABLED ) + { + mxTopDist->set_text(""); + mxBottomDist->set_text(""); + } + limitMetricWidths(); +} + +FieldUnit ParaPropertyPanel::GetCurrentUnit( SfxItemState eState, const SfxPoolItem* pState ) +{ + FieldUnit eUnit = FieldUnit::NONE; + + if ( pState && eState >= SfxItemState::DEFAULT ) + eUnit = static_cast<FieldUnit>(static_cast<const SfxUInt16Item*>(pState)->GetValue()); + else + { + SfxViewFrame* pFrame = SfxViewFrame::Current(); + SfxObjectShell* pSh = nullptr; + if ( pFrame ) + pSh = pFrame->GetObjectShell(); + if ( pSh ) //the object shell is not always available during reload + { + SfxModule* pModule = pSh->GetModule(); + if ( pModule ) + { + const SfxPoolItem* pItem = pModule->GetItem( SID_ATTR_METRIC ); + if ( pItem ) + eUnit = static_cast<FieldUnit>(static_cast<const SfxUInt16Item*>(pItem)->GetValue()); + } + else + { + SAL_WARN("svx.sidebar", "GetModuleFieldUnit(): no module found"); + } + } + } + + return eUnit; +} + +ParaPropertyPanel::ParaPropertyPanel(weld::Widget* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings, + const css::uno::Reference<css::ui::XSidebar>& rxSidebar) + : PanelLayout(pParent, "ParaPropertyPanel", "svx/ui/sidebarparagraph.ui"), + //Alignment + mxTBxHorzAlign(m_xBuilder->weld_toolbar("horizontalalignment")), + mxHorzAlignDispatch(new ToolbarUnoDispatcher(*mxTBxHorzAlign, *m_xBuilder, rxFrame)), + mxTBxVertAlign(m_xBuilder->weld_toolbar("verticalalignment")), + mxVertAlignDispatch(new ToolbarUnoDispatcher(*mxTBxVertAlign, *m_xBuilder, rxFrame)), + //NumBullet&Backcolor + mxTBxNumBullet(m_xBuilder->weld_toolbar("numberbullet")), + mxNumBulletDispatch(new ToolbarUnoDispatcher(*mxTBxNumBullet, *m_xBuilder, rxFrame)), + mxTBxBackColor(m_xBuilder->weld_toolbar("backgroundcolor")), + mxBackColorDispatch(new ToolbarUnoDispatcher(*mxTBxBackColor, *m_xBuilder, rxFrame)), + mxTBxWriteDirection(m_xBuilder->weld_toolbar("writedirection")), + mxWriteDirectionDispatch(new ToolbarUnoDispatcher(*mxTBxWriteDirection, *m_xBuilder, rxFrame)), + mxTBxParaSpacing(m_xBuilder->weld_toolbar("paraspacing")), + mxParaSpacingDispatch(new ToolbarUnoDispatcher(*mxTBxParaSpacing, *m_xBuilder, rxFrame)), + mxTBxLineSpacing(m_xBuilder->weld_toolbar("linespacing")), + mxLineSpacingDispatch(new ToolbarUnoDispatcher(*mxTBxLineSpacing, *m_xBuilder, rxFrame)), + mxTBxIndent(m_xBuilder->weld_toolbar("indent")), + mxIndentDispatch(new ToolbarUnoDispatcher(*mxTBxIndent, *m_xBuilder, rxFrame)), + //Paragraph spacing + mxTopDist(new SvxRelativeField(m_xBuilder->weld_metric_spin_button("aboveparaspacing", FieldUnit::CM))), + mxBottomDist(new SvxRelativeField(m_xBuilder->weld_metric_spin_button("belowparaspacing", FieldUnit::CM))), + mxLeftIndent(new SvxRelativeField(m_xBuilder->weld_metric_spin_button("beforetextindent", FieldUnit::CM))), + mxRightIndent(new SvxRelativeField(m_xBuilder->weld_metric_spin_button("aftertextindent", FieldUnit::CM))), + mxFLineIndent(new SvxRelativeField(m_xBuilder->weld_metric_spin_button("firstlineindent", FieldUnit::CM))), + maTxtLeft (0), + maUpper (0), + maLower (0), + m_eMetricUnit(FieldUnit::NONE), + m_last_eMetricUnit(FieldUnit::NONE), + m_eLRSpaceUnit(), + m_eULSpaceUnit(), + maLRSpaceControl (SID_ATTR_PARA_LRSPACE,*pBindings,*this), + maULSpaceControl (SID_ATTR_PARA_ULSPACE, *pBindings,*this), + m_aMetricCtl (SID_ATTR_METRIC, *pBindings,*this), + mpBindings(pBindings), + mxSidebar(rxSidebar) +{ + // tdf#130197 We want to give this toolbar a width as if it had 5 entries + // (the parent grid has homogeneous width set so both columns will have the + // same width). This ParaPropertyPanel is a default panel in writer, so + // subsequent panels, e.g. the TableEditPanel panel can have up to 5 + // entries in each of its column and remain in alignment with this panel + padWidthForSidebar(*mxTBxIndent, rxFrame); + + initial(); + m_aMetricCtl.RequestUpdate(); +} + +void ParaPropertyPanel::limitMetricWidths() +{ + limitWidthForSidebar(*mxTopDist); + limitWidthForSidebar(*mxBottomDist); + limitWidthForSidebar(*mxLeftIndent); + limitWidthForSidebar(*mxRightIndent); + limitWidthForSidebar(*mxFLineIndent); +} + +ParaPropertyPanel::~ParaPropertyPanel() +{ + mxHorzAlignDispatch.reset(); + mxTBxHorzAlign.reset(); + + mxVertAlignDispatch.reset(); + mxTBxVertAlign.reset(); + + mxNumBulletDispatch.reset(); + mxTBxNumBullet.reset(); + + mxBackColorDispatch.reset(); + mxTBxBackColor.reset(); + + mxWriteDirectionDispatch.reset(); + mxTBxWriteDirection.reset(); + + mxParaSpacingDispatch.reset(); + mxTBxParaSpacing.reset(); + + mxLineSpacingDispatch.reset(); + mxTBxLineSpacing.reset(); + + mxIndentDispatch.reset(); + mxTBxIndent.reset(); + + mxTopDist.reset(); + mxBottomDist.reset(); + mxLeftIndent.reset(); + mxRightIndent.reset(); + mxFLineIndent.reset(); + + maLRSpaceControl.dispose(); + maULSpaceControl.dispose(); + m_aMetricCtl.dispose(); +} + +} // end of namespace svx::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/paragraph/ParaPropertyPanel.hxx b/svx/source/sidebar/paragraph/ParaPropertyPanel.hxx new file mode 100644 index 000000000..bd252eb1a --- /dev/null +++ b/svx/source/sidebar/paragraph/ParaPropertyPanel.hxx @@ -0,0 +1,135 @@ +/* -*- 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 . + */ +#pragma once + +#include <sfx2/sidebar/ControllerItem.hxx> +#include <sfx2/sidebar/IContextChangeReceiver.hxx> +#include <sfx2/sidebar/PanelLayout.hxx> +#include <svx/relfld.hxx> + +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/ui/XSidebar.hpp> + +#include <svl/poolitem.hxx> +#include <tools/fldunit.hxx> +#include <vcl/EnumContext.hxx> + +class ToolbarUnoDispatcher; + +namespace svx::sidebar { + +class ParaPropertyPanel + : public PanelLayout, + public ::sfx2::sidebar::IContextChangeReceiver, + public ::sfx2::sidebar::ControllerItem::ItemUpdateReceiverInterface +{ +public: + virtual ~ParaPropertyPanel() override; + + static std::unique_ptr<PanelLayout> Create ( + weld::Widget* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings, + const css::uno::Reference<css::ui::XSidebar>& rxSidebar); + + SfxBindings* GetBindings() { return mpBindings;} + + virtual void HandleContextChange ( + const vcl::EnumContext& rContext) override; + + virtual void NotifyItemUpdate( + const sal_uInt16 nSId, + const SfxItemState eState, + const SfxPoolItem* pState) override; + + virtual void GetControlState( + const sal_uInt16 /*nSId*/, + boost::property_tree::ptree& /*rState*/) override {}; + + static FieldUnit GetCurrentUnit( SfxItemState eState, const SfxPoolItem* pState ); + + ParaPropertyPanel ( + weld::Widget* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings, + const css::uno::Reference<css::ui::XSidebar>& rxSidebar); + +private: + // UI controls + //Alignment + std::unique_ptr<weld::Toolbar> mxTBxHorzAlign; + std::unique_ptr<ToolbarUnoDispatcher> mxHorzAlignDispatch; + std::unique_ptr<weld::Toolbar> mxTBxVertAlign; + std::unique_ptr<ToolbarUnoDispatcher> mxVertAlignDispatch; + //NumBullet&Backcolor + std::unique_ptr<weld::Toolbar> mxTBxNumBullet; + std::unique_ptr<ToolbarUnoDispatcher> mxNumBulletDispatch; + std::unique_ptr<weld::Toolbar> mxTBxBackColor; + std::unique_ptr<ToolbarUnoDispatcher> mxBackColorDispatch; + + std::unique_ptr<weld::Toolbar> mxTBxWriteDirection; + std::unique_ptr<ToolbarUnoDispatcher> mxWriteDirectionDispatch; + std::unique_ptr<weld::Toolbar> mxTBxParaSpacing; + std::unique_ptr<ToolbarUnoDispatcher> mxParaSpacingDispatch; + std::unique_ptr<weld::Toolbar> mxTBxLineSpacing; + std::unique_ptr<ToolbarUnoDispatcher> mxLineSpacingDispatch; + std::unique_ptr<weld::Toolbar> mxTBxIndent; + std::unique_ptr<ToolbarUnoDispatcher> mxIndentDispatch; + + //Paragraph spacing + std::unique_ptr<SvxRelativeField> mxTopDist; + std::unique_ptr<SvxRelativeField> mxBottomDist; + std::unique_ptr<SvxRelativeField> mxLeftIndent; + std::unique_ptr<SvxRelativeField> mxRightIndent; + std::unique_ptr<SvxRelativeField> mxFLineIndent; + + // Data Member + tools::Long maTxtLeft; + tools::Long maUpper; + tools::Long maLower; + + FieldUnit m_eMetricUnit; + FieldUnit m_last_eMetricUnit; + MapUnit m_eLRSpaceUnit; + MapUnit m_eULSpaceUnit; + // Control Items + ::sfx2::sidebar::ControllerItem maLRSpaceControl; + ::sfx2::sidebar::ControllerItem maULSpaceControl; + ::sfx2::sidebar::ControllerItem m_aMetricCtl; + + vcl::EnumContext maContext; + SfxBindings* mpBindings; + css::uno::Reference<css::ui::XSidebar> mxSidebar; + + DECL_LINK(ModifyIndentHdl_Impl, weld::MetricSpinButton&, void); + DECL_LINK(ULSpaceHdl_Impl, weld::MetricSpinButton&, void); + + void StateChangedIndentImpl( SfxItemState eState, const SfxPoolItem* pState ); + void StateChangedULImpl( SfxItemState eState, const SfxPoolItem* pState ); + + void initial(); + void ReSize(); + void InitToolBoxIndent(); + void InitToolBoxSpacing(); + void limitMetricWidths(); +}; + +} // end of namespace svx::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/paragraph/ParaSpacingControl.cxx b/svx/source/sidebar/paragraph/ParaSpacingControl.cxx new file mode 100644 index 000000000..5b4c40969 --- /dev/null +++ b/svx/source/sidebar/paragraph/ParaSpacingControl.cxx @@ -0,0 +1,257 @@ +/* -*- 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 "ParaSpacingWindow.hxx" + +#include <cppuhelper/queryinterface.hxx> +#include <editeng/ulspitem.hxx> +#include <editeng/lrspitem.hxx> +#include <editeng/editids.hrc> +#include <svx/ParaSpacingControl.hxx> +#include <vcl/toolbox.hxx> +#include <sfx2/sfxsids.hrc> +#include <svl/intitem.hxx> +#include <comphelper/processfactory.hxx> + +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/ui/ContextChangeEventMultiplexer.hpp> +#include <com/sun/star/ui/XContextChangeEventMultiplexer.hpp> + +using namespace svx; + +SFX_IMPL_TOOLBOX_CONTROL(ParaAboveSpacingControl, SvxULSpaceItem); +SFX_IMPL_TOOLBOX_CONTROL(ParaBelowSpacingControl, SvxULSpaceItem); + +SFX_IMPL_TOOLBOX_CONTROL(ParaLeftSpacingControl, SvxLRSpaceItem); +SFX_IMPL_TOOLBOX_CONTROL(ParaRightSpacingControl, SvxLRSpaceItem); +SFX_IMPL_TOOLBOX_CONTROL(ParaFirstLineSpacingControl, SvxLRSpaceItem); + +ParaULSpacingControl::ParaULSpacingControl(sal_uInt16 nSlotId, ToolBoxItemId nId, ToolBox& rTbx) + : SfxToolBoxControl(nSlotId, nId, rTbx) +{ + addStatusListener(".uno:MetricUnit"); +} + +ParaULSpacingControl::~ParaULSpacingControl() +{ +} + +void ParaULSpacingControl::StateChangedAtToolBoxControl(sal_uInt16 nSID, SfxItemState eState, + const SfxPoolItem* pState) +{ + ToolBoxItemId nId = GetId(); + ToolBox& rTbx = GetToolBox(); + ParaULSpacingWindow* pWindow = static_cast<ParaULSpacingWindow*>(rTbx.GetItemWindow(nId)); + + DBG_ASSERT( pWindow, "Control not found!" ); + + if(SfxItemState::DISABLED == eState) + pWindow->Disable(); + else + pWindow->Enable(); + + rTbx.EnableItem(nId, SfxItemState::DISABLED != eState); + + if(nSID == SID_ATTR_METRIC && pState && eState >= SfxItemState::DEFAULT) + { + const SfxUInt16Item* pMetricItem = static_cast<const SfxUInt16Item*>(pState); + pWindow->SetUnit(static_cast<FieldUnit>(pMetricItem->GetValue())); + } + else if((nSID == SID_ATTR_PARA_ULSPACE + || nSID == SID_ATTR_PARA_ABOVESPACE + || nSID == SID_ATTR_PARA_BELOWSPACE ) + && pState && eState >= SfxItemState::DEFAULT) + pWindow->SetValue(static_cast<const SvxULSpaceItem*>(pState)); +} + +// ParaAboveSpacingControl + +ParaAboveSpacingControl::ParaAboveSpacingControl(sal_uInt16 nSlotId, ToolBoxItemId nId, ToolBox& rTbx) + : ParaULSpacingControl(nSlotId, nId, rTbx) +{ +} + +VclPtr<InterimItemWindow> ParaAboveSpacingControl::CreateItemWindow(vcl::Window* pParent) +{ + VclPtr<ParaAboveSpacingWindow> pWindow = VclPtr<ParaAboveSpacingWindow>::Create(pParent); + pWindow->Show(); + + return pWindow; +} + +// ParaBelowSpacingControl + +ParaBelowSpacingControl::ParaBelowSpacingControl(sal_uInt16 nSlotId, ToolBoxItemId nId, ToolBox& rTbx) + : ParaULSpacingControl(nSlotId, nId, rTbx) +{ +} + +VclPtr<InterimItemWindow> ParaBelowSpacingControl::CreateItemWindow(vcl::Window* pParent) +{ + VclPtr<ParaBelowSpacingWindow> pWindow = VclPtr<ParaBelowSpacingWindow>::Create(pParent); + pWindow->Show(); + + return pWindow; +} + +// ParaLRSpacingControl + +ParaLRSpacingControl::ParaLRSpacingControl(sal_uInt16 nSlotId, ToolBoxItemId nId, ToolBox& rTbx) + : SfxToolBoxControl(nSlotId, nId, rTbx) +{ + addStatusListener(".uno:MetricUnit"); +} + +ParaLRSpacingControl::~ParaLRSpacingControl() +{ +} + +void SAL_CALL ParaLRSpacingControl::dispose() +{ + if(m_xMultiplexer.is()) + { + m_xMultiplexer->removeAllContextChangeEventListeners(this); + m_xMultiplexer.clear(); + } + + SfxToolBoxControl::dispose(); +} + +void ParaLRSpacingControl::StateChangedAtToolBoxControl(sal_uInt16 nSID, SfxItemState eState, + const SfxPoolItem* pState) +{ + ToolBoxItemId nId = GetId(); + ToolBox& rTbx = GetToolBox(); + ParaLRSpacingWindow* pWindow = static_cast<ParaLRSpacingWindow*>(rTbx.GetItemWindow(nId)); + + DBG_ASSERT( pWindow, "Control not found!" ); + + if(SfxItemState::DISABLED == eState) + pWindow->Disable(); + else + pWindow->Enable(); + + if(!m_xMultiplexer.is() && m_xFrame.is()) + { + m_xMultiplexer = css::ui::ContextChangeEventMultiplexer::get( + ::comphelper::getProcessComponentContext()); + + m_xMultiplexer->addContextChangeEventListener(this, m_xFrame->getController()); + } + + if(nSID == SID_ATTR_METRIC && pState && eState >= SfxItemState::DEFAULT) + { + const SfxUInt16Item* pMetricItem = static_cast<const SfxUInt16Item*>(pState); + pWindow->SetUnit(static_cast<FieldUnit>(pMetricItem->GetValue())); + } + else if(nSID == SID_ATTR_PARA_LRSPACE + || nSID == SID_ATTR_PARA_LEFTSPACE + || nSID == SID_ATTR_PARA_RIGHTSPACE + || nSID == SID_ATTR_PARA_FIRSTLINESPACE + ) + { + pWindow->SetValue(eState, pState); + } +} + +void SAL_CALL ParaLRSpacingControl::notifyContextChangeEvent(const css::ui::ContextChangeEventObject& rEvent) +{ + ToolBoxItemId nId = GetId(); + ToolBox& rTbx = GetToolBox(); + ParaLRSpacingWindow* pWindow = static_cast<ParaLRSpacingWindow*>(rTbx.GetItemWindow(nId)); + + if(pWindow) + { + vcl::EnumContext eContext( + vcl::EnumContext::GetApplicationEnum(rEvent.ApplicationName), + vcl::EnumContext::GetContextEnum(rEvent.ContextName)); + pWindow->SetContext(eContext); + } +} + +::css::uno::Any SAL_CALL ParaLRSpacingControl::queryInterface(const ::css::uno::Type& aType) +{ + ::css::uno::Any a(SfxToolBoxControl::queryInterface(aType)); + if (a.hasValue()) + return a; + + return ::cppu::queryInterface(aType, static_cast<css::ui::XContextChangeEventListener*>(this)); +} + +void SAL_CALL ParaLRSpacingControl::acquire() noexcept +{ + SfxToolBoxControl::acquire(); +} + +void SAL_CALL ParaLRSpacingControl::disposing(const ::css::lang::EventObject&) +{ + SfxToolBoxControl::disposing(); +} + +void SAL_CALL ParaLRSpacingControl::release() noexcept +{ + SfxToolBoxControl::release(); +} + +// ParaLeftSpacingControl + +ParaLeftSpacingControl::ParaLeftSpacingControl(sal_uInt16 nSlotId, ToolBoxItemId nId, ToolBox& rTbx) +: ParaLRSpacingControl(nSlotId, nId, rTbx) +{ +} + +VclPtr<InterimItemWindow> ParaLeftSpacingControl::CreateItemWindow(vcl::Window* pParent) +{ + VclPtr<ParaLeftSpacingWindow> pWindow = VclPtr<ParaLeftSpacingWindow>::Create(pParent); + pWindow->Show(); + + return pWindow; +} + +// ParaRightSpacingControl + +ParaRightSpacingControl::ParaRightSpacingControl(sal_uInt16 nSlotId, ToolBoxItemId nId, ToolBox& rTbx) +: ParaLRSpacingControl(nSlotId, nId, rTbx) +{ +} + +VclPtr<InterimItemWindow> ParaRightSpacingControl::CreateItemWindow(vcl::Window* pParent) +{ + VclPtr<ParaRightSpacingWindow> pWindow = VclPtr<ParaRightSpacingWindow>::Create(pParent); + pWindow->Show(); + + return pWindow; +} + +// ParaFirstLineSpacingControl + +ParaFirstLineSpacingControl::ParaFirstLineSpacingControl(sal_uInt16 nSlotId, ToolBoxItemId nId, ToolBox& rTbx) +: ParaLRSpacingControl(nSlotId, nId, rTbx) +{ +} + +VclPtr<InterimItemWindow> ParaFirstLineSpacingControl::CreateItemWindow(vcl::Window* pParent) +{ + VclPtr<ParaFirstLineSpacingWindow> pWindow = VclPtr<ParaFirstLineSpacingWindow>::Create(pParent); + pWindow->Show(); + + return pWindow; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/paragraph/ParaSpacingWindow.cxx b/svx/source/sidebar/paragraph/ParaSpacingWindow.cxx new file mode 100644 index 000000000..fa164dd02 --- /dev/null +++ b/svx/source/sidebar/paragraph/ParaSpacingWindow.cxx @@ -0,0 +1,341 @@ +/* -*- 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 "ParaSpacingWindow.hxx" +#include <editeng/editids.hrc> +#include <editeng/lrspitem.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/app.hxx> +#include <sfx2/viewfrm.hxx> +#include <svl/itempool.hxx> + +using namespace svx; + +#define DEFAULT_VALUE 0 +#define MAX_DURCH 31680 // tdf#68335: 1584 pt for UX interoperability with Word +#define MAX_SW 1709400 +#define MAX_SC_SD 116220200 +#define NEGA_MAXVALUE -10000000 + +// ParaULSpacingWindow + +ParaULSpacingWindow::ParaULSpacingWindow(vcl::Window* pParent) + : InterimItemWindow(pParent, "svx/ui/paraulspacing.ui", "ParaULSpacingWindow") + , m_eUnit(MapUnit::MapTwip) +{ + m_xAboveSpacing = std::make_unique<SvxRelativeField>(m_xBuilder->weld_metric_spin_button("aboveparaspacing", FieldUnit::CM)); + m_xBelowSpacing = std::make_unique<SvxRelativeField>(m_xBuilder->weld_metric_spin_button("belowparaspacing", FieldUnit::CM)); + m_xAboveContainer = m_xBuilder->weld_container("above"); + m_xBelowContainer = m_xBuilder->weld_container("below"); + + Link<weld::MetricSpinButton&,void> aLink = LINK(this, ParaULSpacingWindow, ModifySpacingHdl); + m_xAboveSpacing->connect_value_changed(aLink); + m_xBelowSpacing->connect_value_changed(aLink); + + /// set the initial values of max width + m_xAboveSpacing->set_max(m_xAboveSpacing->normalize(MAX_DURCH), FieldUnit::CM); + m_xBelowSpacing->set_max(m_xBelowSpacing->normalize(MAX_DURCH), FieldUnit::CM); +} + +ParaULSpacingWindow::~ParaULSpacingWindow() +{ + disposeOnce(); +} + +void ParaULSpacingWindow::dispose() +{ + m_xAboveSpacing.reset(); + m_xBelowSpacing.reset(); + m_xAboveContainer.reset(); + m_xBelowContainer.reset(); + + InterimItemWindow::dispose(); +} + +void ParaULSpacingWindow::SetUnit(FieldUnit eUnit) +{ + m_xAboveSpacing->SetFieldUnit(eUnit); + m_xBelowSpacing->SetFieldUnit(eUnit); + + SfxItemPool &rPool = SfxGetpApp()->GetPool(); + m_eUnit = rPool.GetMetric(SID_ATTR_PARA_ULSPACE); + + m_xAboveSpacing->set_max(m_xAboveSpacing->normalize(MAX_DURCH), MapToFieldUnit(m_eUnit)); + m_xBelowSpacing->set_max(m_xBelowSpacing->normalize(MAX_DURCH), MapToFieldUnit(m_eUnit)); +} + +void ParaULSpacingWindow::SetValue(const SvxULSpaceItem* pItem) +{ + sal_Int64 nVal = pItem->GetUpper(); + nVal = m_xAboveSpacing->normalize(nVal); + m_xAboveSpacing->set_value(nVal, FieldUnit::MM_100TH); + + nVal = pItem->GetLower(); + nVal = m_xBelowSpacing->normalize(nVal); + m_xBelowSpacing->set_value(nVal, FieldUnit::MM_100TH); +} + +IMPL_LINK_NOARG(ParaULSpacingWindow, ModifySpacingHdl, weld::MetricSpinButton&, void) +{ + SfxViewFrame* pFrame = SfxViewFrame::Current(); + if (!pFrame) + return; + SfxDispatcher* pDisp = pFrame->GetBindings().GetDispatcher(); + if(pDisp) + { + SvxULSpaceItem aMargin(SID_ATTR_PARA_ULSPACE); + aMargin.SetUpper(m_xAboveSpacing->GetCoreValue(m_eUnit)); + aMargin.SetLower(m_xBelowSpacing->GetCoreValue(m_eUnit)); + pDisp->ExecuteList(SID_ATTR_PARA_ULSPACE, SfxCallMode::RECORD, {&aMargin}); + } +} + +// ParaAboveSpacingWindow +ParaAboveSpacingWindow::ParaAboveSpacingWindow(vcl::Window* pParent) + : ParaULSpacingWindow(pParent) +{ + InitControlBase(&m_xAboveSpacing->get_widget()); + + m_xAboveContainer->show(); + m_xBelowContainer->hide(); + + SetSizePixel(get_preferred_size()); +} + +// ParaBelowSpacingWindow +ParaBelowSpacingWindow::ParaBelowSpacingWindow(vcl::Window* pParent) + : ParaULSpacingWindow(pParent) +{ + InitControlBase(&m_xBelowSpacing->get_widget()); + + m_xAboveContainer->hide(); + m_xBelowContainer->show(); + + SetSizePixel(get_preferred_size()); +} + +// ParaLRSpacingWindow +ParaLRSpacingWindow::ParaLRSpacingWindow(vcl::Window* pParent) + : InterimItemWindow(pParent, "svx/ui/paralrspacing.ui", "ParaLRSpacingWindow") + , m_eUnit(MapUnit::MapTwip) +{ + m_xBeforeSpacing = std::make_unique<SvxRelativeField>(m_xBuilder->weld_metric_spin_button("beforetextindent", FieldUnit::CM)); + m_xAfterSpacing = std::make_unique<SvxRelativeField>(m_xBuilder->weld_metric_spin_button("aftertextindent", FieldUnit::CM)); + m_xFLSpacing = std::make_unique<SvxRelativeField>(m_xBuilder->weld_metric_spin_button("firstlineindent", FieldUnit::CM)); + m_xBeforeContainer = m_xBuilder->weld_container("before"); + m_xAfterContainer = m_xBuilder->weld_container("after"); + m_xFirstLineContainer = m_xBuilder->weld_container("firstline"); + + Link<weld::MetricSpinButton&,void> aLink = LINK(this, ParaLRSpacingWindow, ModifySpacingHdl); + m_xBeforeSpacing->connect_value_changed(aLink); + m_xAfterSpacing->connect_value_changed(aLink); + m_xFLSpacing->connect_value_changed(aLink); + + /// set the initial values of max width + m_xBeforeSpacing->set_min(NEGA_MAXVALUE, FieldUnit::MM_100TH); + m_xAfterSpacing->set_min(NEGA_MAXVALUE, FieldUnit::MM_100TH); + m_xFLSpacing->set_min(NEGA_MAXVALUE, FieldUnit::MM_100TH); +} + +ParaLRSpacingWindow::~ParaLRSpacingWindow() +{ + disposeOnce(); +} + +void ParaLRSpacingWindow::dispose() +{ + m_xBeforeSpacing.reset(); + m_xAfterSpacing.reset(); + m_xFLSpacing.reset(); + m_xBeforeContainer.reset(); + m_xAfterContainer.reset(); + m_xFirstLineContainer.reset(); + + InterimItemWindow::dispose(); +} + +void ParaLRSpacingWindow::SetContext(const vcl::EnumContext& eContext) +{ + m_aContext = eContext; +} + +void ParaLRSpacingWindow::SetValue(SfxItemState eState, const SfxPoolItem* pState) +{ + switch(m_aContext.GetCombinedContext_DI()) + { + + case CombinedEnumContext(Application::WriterVariants, Context::DrawText): + case CombinedEnumContext(Application::WriterVariants, Context::Annotation): + case CombinedEnumContext(Application::Calc, Context::DrawText): + case CombinedEnumContext(Application::DrawImpress, Context::DrawText): + case CombinedEnumContext(Application::DrawImpress, Context::Draw): + case CombinedEnumContext(Application::DrawImpress, Context::TextObject): + case CombinedEnumContext(Application::DrawImpress, Context::Graphic): + case CombinedEnumContext(Application::DrawImpress, Context::Table): + { + m_xBeforeSpacing->set_min(DEFAULT_VALUE, FieldUnit::NONE); + m_xAfterSpacing->set_min(DEFAULT_VALUE, FieldUnit::NONE); + m_xFLSpacing->set_min(DEFAULT_VALUE, FieldUnit::NONE); + } + break; + case CombinedEnumContext(Application::WriterVariants, Context::Default): + case CombinedEnumContext(Application::WriterVariants, Context::Text): + case CombinedEnumContext(Application::WriterVariants, Context::Table): + { + m_xBeforeSpacing->set_min(NEGA_MAXVALUE, FieldUnit::MM_100TH); + m_xAfterSpacing->set_min(NEGA_MAXVALUE, FieldUnit::MM_100TH); + m_xFLSpacing->set_min(NEGA_MAXVALUE, FieldUnit::MM_100TH); + } + break; + } + + if(pState && eState >= SfxItemState::DEFAULT) + { + m_xBeforeSpacing->set_sensitive(true); + m_xAfterSpacing->set_sensitive(true); + m_xFLSpacing->set_sensitive(true); + + const SvxLRSpaceItem* pSpace = static_cast<const SvxLRSpaceItem*>(pState); + tools::Long aTxtLeft = pSpace->GetTextLeft(); + tools::Long aTxtRight = pSpace->GetRight(); + tools::Long aTxtFirstLineOfst = pSpace->GetTextFirstLineOffset(); + + aTxtLeft = m_xBeforeSpacing->normalize(aTxtLeft); + + if(m_aContext.GetCombinedContext_DI() != CombinedEnumContext(Application::WriterVariants, Context::Text) + && m_aContext.GetCombinedContext_DI() != CombinedEnumContext(Application::WriterVariants, Context::Default) + && m_aContext.GetCombinedContext_DI() != CombinedEnumContext(Application::WriterVariants, Context::Table)) + { + m_xFLSpacing->set_min(aTxtLeft*-1, FieldUnit::MM_100TH); + } + + aTxtRight = m_xAfterSpacing->normalize(aTxtRight); + + switch(m_aContext.GetCombinedContext_DI()) + { + case CombinedEnumContext(Application::WriterVariants, Context::DrawText): + case CombinedEnumContext(Application::WriterVariants, Context::Text): + case CombinedEnumContext(Application::WriterVariants, Context::Default): + case CombinedEnumContext(Application::WriterVariants, Context::Table): + case CombinedEnumContext(Application::WriterVariants, Context::Annotation): + { + m_xBeforeSpacing->set_max(MAX_SW - aTxtRight, FieldUnit::MM_100TH); + m_xAfterSpacing->set_max(MAX_SW - aTxtLeft, FieldUnit::MM_100TH); + m_xFLSpacing->set_max(MAX_SW - aTxtLeft - aTxtRight, FieldUnit::MM_100TH); + } + break; + case CombinedEnumContext(Application::DrawImpress, Context::DrawText): + case CombinedEnumContext(Application::DrawImpress, Context::Draw): + case CombinedEnumContext(Application::DrawImpress, Context::Table): + case CombinedEnumContext(Application::DrawImpress, Context::TextObject): + case CombinedEnumContext(Application::DrawImpress, Context::Graphic): + { + m_xBeforeSpacing->set_max(MAX_SC_SD - aTxtRight, FieldUnit::MM_100TH); + m_xAfterSpacing->set_max(MAX_SC_SD - aTxtLeft, FieldUnit::MM_100TH); + m_xFLSpacing->set_max(MAX_SC_SD - aTxtLeft - aTxtRight, FieldUnit::MM_100TH); + } + } + + m_xBeforeSpacing->set_value(aTxtLeft, FieldUnit::MM_100TH); + m_xAfterSpacing->set_value(aTxtRight, FieldUnit::MM_100TH); + + aTxtFirstLineOfst = m_xFLSpacing->normalize(aTxtFirstLineOfst); + m_xFLSpacing->set_value(aTxtFirstLineOfst, FieldUnit::MM_100TH); + } + else if(eState == SfxItemState::DISABLED) + { + m_xBeforeSpacing->set_sensitive(false); + m_xAfterSpacing->set_sensitive(false); + m_xFLSpacing->set_sensitive(false); + } + else + { + m_xBeforeSpacing->set_text(""); + m_xAfterSpacing->set_text(""); + m_xFLSpacing->set_text(""); + } +} + +void ParaLRSpacingWindow::SetUnit(FieldUnit eUnit) +{ + m_xBeforeSpacing->SetFieldUnit(eUnit); + m_xAfterSpacing->SetFieldUnit(eUnit); + m_xFLSpacing->SetFieldUnit(eUnit); + + SfxItemPool &rPool = SfxGetpApp()->GetPool(); + m_eUnit = rPool.GetMetric(SID_ATTR_PARA_LRSPACE); +} + +IMPL_LINK_NOARG(ParaLRSpacingWindow, ModifySpacingHdl, weld::MetricSpinButton&, void) +{ + SfxViewFrame* pFrame = SfxViewFrame::Current(); + if (!pFrame) + return; + SfxDispatcher* pDisp = pFrame->GetBindings().GetDispatcher(); + if(pDisp) + { + SvxLRSpaceItem aMargin(SID_ATTR_PARA_LRSPACE); + aMargin.SetTextLeft(m_xBeforeSpacing->GetCoreValue(m_eUnit)); + aMargin.SetRight(m_xAfterSpacing->GetCoreValue(m_eUnit)); + aMargin.SetTextFirstLineOffset(m_xFLSpacing->GetCoreValue(m_eUnit)); + + pDisp->ExecuteList(SID_ATTR_PARA_LRSPACE, SfxCallMode::RECORD, {&aMargin}); + } +} + +// ParaLeftSpacingWindow +ParaLeftSpacingWindow::ParaLeftSpacingWindow(vcl::Window* pParent) + : ParaLRSpacingWindow(pParent) +{ + InitControlBase(&m_xBeforeSpacing->get_widget()); + + m_xBeforeContainer->show(); + m_xAfterContainer->hide(); + m_xFirstLineContainer->hide(); + + SetSizePixel(get_preferred_size()); +} + +// ParaRightSpacingWindow +ParaRightSpacingWindow::ParaRightSpacingWindow(vcl::Window* pParent) + : ParaLRSpacingWindow(pParent) +{ + InitControlBase(&m_xAfterSpacing->get_widget()); + + m_xBeforeContainer->hide(); + m_xAfterContainer->show(); + m_xFirstLineContainer->hide(); + + SetSizePixel(get_preferred_size()); +} + +// ParaFirstLineSpacingWindow +ParaFirstLineSpacingWindow::ParaFirstLineSpacingWindow(vcl::Window* pParent) + : ParaLRSpacingWindow(pParent) +{ + InitControlBase(&m_xFLSpacing->get_widget()); + + m_xBeforeContainer->hide(); + m_xAfterContainer->hide(); + m_xFirstLineContainer->show(); + + SetSizePixel(get_preferred_size()); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/paragraph/ParaSpacingWindow.hxx b/svx/source/sidebar/paragraph/ParaSpacingWindow.hxx new file mode 100644 index 000000000..f1730f933 --- /dev/null +++ b/svx/source/sidebar/paragraph/ParaSpacingWindow.hxx @@ -0,0 +1,110 @@ +/* -*- 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 . + */ +#pragma once + +#include <editeng/ulspitem.hxx> +#include <vcl/EnumContext.hxx> +#include <vcl/InterimItemWindow.hxx> +#include <svx/relfld.hxx> + +using namespace com::sun::star; + +namespace svx +{ +class ParaULSpacingWindow : public InterimItemWindow +{ +public: + virtual ~ParaULSpacingWindow() override; + virtual void dispose() override; + + void SetValue(const SvxULSpaceItem* pItem); + void SetUnit(FieldUnit eUnit); + +protected: + ParaULSpacingWindow(vcl::Window* pParent); + + std::unique_ptr<SvxRelativeField> m_xAboveSpacing; + std::unique_ptr<SvxRelativeField> m_xBelowSpacing; + std::unique_ptr<weld::Container> m_xAboveContainer; + std::unique_ptr<weld::Container> m_xBelowContainer; + + MapUnit m_eUnit; + + DECL_LINK(ModifySpacingHdl, weld::MetricSpinButton&, void); +}; + +class ParaAboveSpacingWindow : public ParaULSpacingWindow +{ +public: + explicit ParaAboveSpacingWindow(vcl::Window* pParent); +}; + +class ParaBelowSpacingWindow : public ParaULSpacingWindow +{ +public: + explicit ParaBelowSpacingWindow(vcl::Window* pParent); +}; + +class ParaLRSpacingWindow : public InterimItemWindow +{ +public: + virtual ~ParaLRSpacingWindow() override; + virtual void dispose() override; + + void SetValue(SfxItemState eState, const SfxPoolItem* pState); + void SetUnit(FieldUnit eUnit); + void SetContext(const vcl::EnumContext& eContext); + +protected: + ParaLRSpacingWindow(vcl::Window* pParent); + + std::unique_ptr<SvxRelativeField> m_xBeforeSpacing; + std::unique_ptr<SvxRelativeField> m_xAfterSpacing; + std::unique_ptr<SvxRelativeField> m_xFLSpacing; + std::unique_ptr<weld::Container> m_xBeforeContainer; + std::unique_ptr<weld::Container> m_xAfterContainer; + std::unique_ptr<weld::Container> m_xFirstLineContainer; + + MapUnit m_eUnit; + + vcl::EnumContext m_aContext; + + DECL_LINK(ModifySpacingHdl, weld::MetricSpinButton&, void); +}; + +class ParaLeftSpacingWindow : public ParaLRSpacingWindow +{ +public: + explicit ParaLeftSpacingWindow(vcl::Window* pParent); +}; + +class ParaRightSpacingWindow : public ParaLRSpacingWindow +{ +public: + explicit ParaRightSpacingWindow(vcl::Window* pParent); +}; + +class ParaFirstLineSpacingWindow : public ParaLRSpacingWindow +{ +public: + explicit ParaFirstLineSpacingWindow(vcl::Window* pParent); +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |