summaryrefslogtreecommitdiffstats
path: root/svx/source/sidebar/paragraph/ParaLineSpacingControl.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'svx/source/sidebar/paragraph/ParaLineSpacingControl.cxx')
-rw-r--r--svx/source/sidebar/paragraph/ParaLineSpacingControl.cxx447
1 files changed, 447 insertions, 0 deletions
diff --git a/svx/source/sidebar/paragraph/ParaLineSpacingControl.cxx b/svx/source/sidebar/paragraph/ParaLineSpacingControl.cxx
new file mode 100644
index 0000000000..bda7eb62e6
--- /dev/null
+++ b/svx/source/sidebar/paragraph/ParaLineSpacingControl.cxx
@@ -0,0 +1,447 @@
+/* -*- 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 <svl/itemset.hxx>
+
+#include <ParaLineSpacingPopup.hxx>
+
+#include <vcl/commandinfoprovider.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;
+ SfxPoolItemHolder aResult;
+ SfxViewFrame* pCurrent(SfxViewFrame::Current());
+ if (pCurrent && pCurrent->GetBindings().GetDispatcher()->QueryState(SID_ATTR_METRIC, aResult) >= SfxItemState::DEFAULT)
+ eUnit = static_cast<FieldUnit>(static_cast<const SfxUInt16Item*>(aResult.getItem())->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()
+{
+ SfxPoolItemHolder aResult;
+ SfxViewFrame* pCurrent = SfxViewFrame::Current();
+ const bool bItemStateSet(nullptr != pCurrent);
+ const SfxItemState eState(bItemStateSet
+ ? pCurrent->GetBindings().GetDispatcher()->QueryState(SID_ATTR_PARA_LINESPACE, aResult)
+ : SfxItemState::DEFAULT);
+
+ mxLineDist->set_sensitive(true);
+
+ if( bItemStateSet && (eState == SfxItemState::DEFAULT || eState == SfxItemState::SET) )
+ {
+ const SvxLineSpacingItem* currSPItem(static_cast<const SvxLineSpacingItem*>(aResult.getItem()));
+ // It seems draw/impress and writer require different MapUnit values for fixed line spacing
+ // metric values to be correctly calculated.
+ MapUnit eUnit = MapUnit::Map100thMM; // works for draw/impress
+ if (vcl::CommandInfoProvider::GetModuleIdentifier(pCurrent->GetFrame().GetFrameInterface())
+ == "com.sun.star.text.TextDocument")
+ eUnit = MapUnit::MapTwip; // works for writer
+ 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: */