summaryrefslogtreecommitdiffstats
path: root/cui/source/tabpages
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
commit267c6f2ac71f92999e969232431ba04678e7437e (patch)
tree358c9467650e1d0a1d7227a21dac2e3d08b622b2 /cui/source/tabpages
parentInitial commit. (diff)
downloadlibreoffice-267c6f2ac71f92999e969232431ba04678e7437e.tar.xz
libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.zip
Adding upstream version 4:24.2.0.upstream/4%24.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'cui/source/tabpages')
-rw-r--r--cui/source/tabpages/TextColumnsPage.cxx82
-rw-r--r--cui/source/tabpages/align.cxx789
-rw-r--r--cui/source/tabpages/autocdlg.cxx2379
-rw-r--r--cui/source/tabpages/backgrnd.cxx336
-rw-r--r--cui/source/tabpages/bbdlg.cxx89
-rw-r--r--cui/source/tabpages/border.cxx1700
-rw-r--r--cui/source/tabpages/chardlg.cxx3238
-rw-r--r--cui/source/tabpages/chardlg.h26
-rw-r--r--cui/source/tabpages/connect.cxx395
-rw-r--r--cui/source/tabpages/grfpage.cxx832
-rw-r--r--cui/source/tabpages/labdlg.cxx507
-rw-r--r--cui/source/tabpages/macroass.cxx400
-rw-r--r--cui/source/tabpages/measure.cxx755
-rw-r--r--cui/source/tabpages/numfmt.cxx1771
-rw-r--r--cui/source/tabpages/numpages.cxx3400
-rw-r--r--cui/source/tabpages/page.cxx1665
-rw-r--r--cui/source/tabpages/paragrph.cxx2595
-rw-r--r--cui/source/tabpages/swpossizetabpage.cxx1879
-rw-r--r--cui/source/tabpages/tabarea.cxx252
-rw-r--r--cui/source/tabpages/tabline.cxx207
-rw-r--r--cui/source/tabpages/tabstpge.cxx663
-rw-r--r--cui/source/tabpages/textanim.cxx534
-rw-r--r--cui/source/tabpages/textattr.cxx665
-rw-r--r--cui/source/tabpages/tparea.cxx524
-rw-r--r--cui/source/tabpages/tpbitmap.cxx820
-rw-r--r--cui/source/tabpages/tpcolor.cxx795
-rw-r--r--cui/source/tabpages/tpgradnt.cxx674
-rw-r--r--cui/source/tabpages/tphatch.cxx562
-rw-r--r--cui/source/tabpages/tpline.cxx1699
-rw-r--r--cui/source/tabpages/tplnedef.cxx840
-rw-r--r--cui/source/tabpages/tplneend.cxx610
-rw-r--r--cui/source/tabpages/tppattern.cxx553
-rw-r--r--cui/source/tabpages/tpshadow.cxx515
-rw-r--r--cui/source/tabpages/tptrans.cxx546
-rw-r--r--cui/source/tabpages/transfrm.cxx1562
35 files changed, 34859 insertions, 0 deletions
diff --git a/cui/source/tabpages/TextColumnsPage.cxx b/cui/source/tabpages/TextColumnsPage.cxx
new file mode 100644
index 0000000000..5bfd3b47a6
--- /dev/null
+++ b/cui/source/tabpages/TextColumnsPage.cxx
@@ -0,0 +1,82 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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/.
+ */
+
+#include <sal/config.h>
+
+#include <svtools/unitconv.hxx>
+#include <svx/dlgutil.hxx>
+#include <svx/sdmetitm.hxx>
+#include <svx/svddef.hxx>
+
+#include <TextColumnsPage.hxx>
+
+const WhichRangesContainer
+ SvxTextColumnsPage::pRanges(svl::Items<SDRATTR_TEXTCOLUMNS_FIRST, SDRATTR_TEXTCOLUMNS_LAST>);
+
+SvxTextColumnsPage::SvxTextColumnsPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/textcolumnstabpage.ui", "TextColumnsPage", &rInAttrs)
+ , m_xColumnsNumber(m_xBuilder->weld_spin_button("FLD_COL_NUMBER"))
+ , m_xColumnsSpacing(
+ m_xBuilder->weld_metric_spin_button("MTR_FLD_COL_SPACING", GetModuleFieldUnit(rInAttrs)))
+{
+}
+
+SvxTextColumnsPage::~SvxTextColumnsPage() = default;
+
+// read the passed item set
+void SvxTextColumnsPage::Reset(const SfxItemSet* rAttrs)
+{
+ SfxItemPool* pPool = rAttrs->GetPool();
+ assert(pPool);
+
+ {
+ auto pItem = GetItem(*rAttrs, SDRATTR_TEXTCOLUMNS_NUMBER);
+ if (!pItem)
+ pItem = &pPool->GetDefaultItem(SDRATTR_TEXTCOLUMNS_NUMBER);
+ m_xColumnsNumber->set_value(pItem->GetValue());
+ m_xColumnsNumber->save_value();
+ }
+
+ {
+ MapUnit eUnit = pPool->GetMetric(SDRATTR_TEXTCOLUMNS_SPACING);
+ auto pItem = GetItem(*rAttrs, SDRATTR_TEXTCOLUMNS_SPACING);
+ if (!pItem)
+ pItem = &pPool->GetDefaultItem(SDRATTR_TEXTCOLUMNS_SPACING);
+ SetMetricValue(*m_xColumnsSpacing, pItem->GetValue(), eUnit);
+ m_xColumnsSpacing->save_value();
+ }
+}
+
+// fill the passed item set with dialog box attributes
+bool SvxTextColumnsPage::FillItemSet(SfxItemSet* rAttrs)
+{
+ if (m_xColumnsNumber->get_value_changed_from_saved())
+ rAttrs->Put(SfxInt16Item(SDRATTR_TEXTCOLUMNS_NUMBER, m_xColumnsNumber->get_value()));
+
+ if (m_xColumnsSpacing->get_value_changed_from_saved())
+ {
+ SfxItemPool* pPool = rAttrs->GetPool();
+ assert(pPool);
+ MapUnit eUnit = pPool->GetMetric(SDRATTR_TEXTCOLUMNS_SPACING);
+ sal_Int32 nValue = GetCoreValue(*m_xColumnsSpacing, eUnit);
+ rAttrs->Put(SdrMetricItem(SDRATTR_TEXTCOLUMNS_SPACING, nValue));
+ }
+
+ return true;
+}
+
+std::unique_ptr<SfxTabPage> SvxTextColumnsPage::Create(weld::Container* pPage,
+ weld::DialogController* pController,
+ const SfxItemSet* rAttrs)
+{
+ return std::make_unique<SvxTextColumnsPage>(pPage, pController, *rAttrs);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/tabpages/align.cxx b/cui/source/tabpages/align.cxx
new file mode 100644
index 0000000000..33b4116423
--- /dev/null
+++ b/cui/source/tabpages/align.cxx
@@ -0,0 +1,789 @@
+/* -*- 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 <align.hxx>
+
+#include <editeng/svxenum.hxx>
+#include <svx/svxids.hrc>
+#include <svx/strings.hrc>
+#include <svx/dialmgr.hxx>
+#include <bitmaps.hlst>
+#include <svx/rotmodit.hxx>
+#include <svx/sdangitm.hxx>
+
+#include <editeng/frmdiritem.hxx>
+#include <editeng/justifyitem.hxx>
+#include <svl/cjkoptions.hxx>
+#include <svl/intitem.hxx>
+#include <vcl/image.hxx>
+
+#define IID_BOTTOMLOCK 1
+#define IID_TOPLOCK 2
+#define IID_CELLLOCK 3
+
+namespace svx {
+
+const WhichRangesContainer AlignmentTabPage::s_pRanges(
+ svl::Items<
+ SID_ATTR_ALIGN_STACKED, SID_ATTR_ALIGN_LINEBREAK, // 10229 - 10230
+ SID_ATTR_ALIGN_INDENT, SID_ATTR_ALIGN_INDENT, // 10460 - 10460
+ SID_ATTR_ALIGN_DEGREES, SID_ATTR_ALIGN_DEGREES, // 10577 - 10577
+ SID_ATTR_ALIGN_LOCKPOS, SID_ATTR_ALIGN_LOCKPOS, // 10578 - 10578
+ SID_ATTR_ALIGN_HYPHENATION, SID_ATTR_ALIGN_HYPHENATION, // 10931 - 10931
+ SID_ATTR_FRAMEDIRECTION, SID_ATTR_FRAMEDIRECTION, // 10944 - 10944
+ SID_ATTR_ALIGN_ASIANVERTICAL, SID_ATTR_ALIGN_ASIANVERTICAL, // 10949 - 10949
+ SID_ATTR_ALIGN_SHRINKTOFIT, SID_ATTR_ALIGN_SHRINKTOFIT, // 11015 - 11015
+ SID_ATTR_ALIGN_HOR_JUSTIFY, SID_ATTR_ALIGN_VER_JUSTIFY>); // 11571 - 11572
+
+
+namespace {
+
+template<typename JustContainerType, typename JustEnumType>
+void lcl_MaybeResetAlignToDistro(
+ weld::ComboBox& rLB, sal_uInt16 nListId, const SfxItemSet& rCoreAttrs, TypedWhichId<SfxEnumItemInterface> nWhichAlign, TypedWhichId<SfxEnumItemInterface> nWhichJM, JustEnumType eBlock)
+{
+ const SfxEnumItemInterface* p = rCoreAttrs.GetItemIfSet(nWhichAlign);
+ if (!p)
+ // alignment not set.
+ return;
+
+ JustContainerType eVal = static_cast<JustContainerType>(p->GetEnumValue());
+ if (eVal != eBlock)
+ // alignment is not 'justify'. No need to go further.
+ return;
+
+ p = rCoreAttrs.GetItemIfSet(nWhichJM);
+ if (!p)
+ // justification method is not set.
+ return;
+
+ SvxCellJustifyMethod eMethod = static_cast<SvxCellJustifyMethod>(p->GetEnumValue());
+ if (eMethod == SvxCellJustifyMethod::Distribute)
+ {
+ // Select the 'distribute' entry in the specified list box.
+ rLB.set_active_id(OUString::number(nListId));
+ }
+}
+
+void lcl_SetJustifyMethodToItemSet(SfxItemSet& rSet, const SfxItemSet& rOldSet, sal_uInt16 nWhichJM, const weld::ComboBox& rLB, sal_uInt16 nListId)
+{
+ // tdf#138698 unsupported, e.g. dbaccess
+ if (rLB.find_id(OUString::number(nListId)) == -1)
+ return;
+
+ // feature supported , e.g. calc
+ SvxCellJustifyMethod eJM = SvxCellJustifyMethod::Auto;
+ if (rLB.get_active_id().toInt32() == nListId)
+ eJM = SvxCellJustifyMethod::Distribute;
+
+ // tdf#129300 If it would create no change, don't force it
+ const SvxJustifyMethodItem& rOldItem = static_cast<const SvxJustifyMethodItem&>(rOldSet.Get(nWhichJM));
+ if (rOldItem.GetValue() == eJM)
+ {
+ rSet.InvalidateItem(nWhichJM);
+ return;
+ }
+
+ SvxJustifyMethodItem aItem(eJM, nWhichJM);
+ rSet.Put(aItem);
+}
+
+}//namespace
+
+AlignmentTabPage::AlignmentTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/cellalignment.ui", "CellAlignPage", &rCoreAttrs)
+ , m_aVsRefEdge(nullptr)
+ // text alignment
+ , m_xLbHorAlign(m_xBuilder->weld_combo_box("comboboxHorzAlign"))
+ , m_xFtIndent(m_xBuilder->weld_label("labelIndent"))
+ , m_xEdIndent(m_xBuilder->weld_metric_spin_button("spinIndentFrom", FieldUnit::POINT))
+ , m_xFtVerAlign(m_xBuilder->weld_label("labelVertAlign"))
+ , m_xLbVerAlign(m_xBuilder->weld_combo_box("comboboxVertAlign"))
+ //text rotation
+ , m_xFtRotate(m_xBuilder->weld_label("labelDegrees"))
+ , m_xNfRotate(m_xBuilder->weld_metric_spin_button("spinDegrees", FieldUnit::DEGREE))
+ , m_xFtRefEdge(m_xBuilder->weld_label("labelRefEdge"))
+ //Asian mode
+ , m_xCbStacked(m_xBuilder->weld_check_button("checkVertStack"))
+ , m_xCbAsianMode(m_xBuilder->weld_check_button("checkAsianMode"))
+ // Properties
+ , m_xBtnWrap(m_xBuilder->weld_check_button("checkWrapTextAuto"))
+ , m_xBtnHyphen(m_xBuilder->weld_check_button("checkHyphActive"))
+ , m_xBtnShrink(m_xBuilder->weld_check_button("checkShrinkFitCellSize"))
+ , m_xLbFrameDir(new svx::FrameDirectionListBox(m_xBuilder->weld_combo_box("comboTextDirBox")))
+ //ValueSet hover strings
+ , m_xFtBotLock(m_xBuilder->weld_label("labelSTR_BOTTOMLOCK"))
+ , m_xFtTopLock(m_xBuilder->weld_label("labelSTR_TOPLOCK"))
+ , m_xFtCelLock(m_xBuilder->weld_label("labelSTR_CELLLOCK"))
+ , m_xFtABCD(m_xBuilder->weld_label("labelABCD"))
+ , m_xAlignmentFrame(m_xBuilder->weld_widget("alignment"))
+ , m_xOrientFrame(m_xBuilder->weld_widget("orientation"))
+ , m_xPropertiesFrame(m_xBuilder->weld_widget("properties"))
+ , m_xVsRefEdge(new weld::CustomWeld(*m_xBuilder, "references", m_aVsRefEdge))
+ , m_xCtrlDial(new DialControl)
+ , m_xCtrlDialWin(new weld::CustomWeld(*m_xBuilder, "dialcontrol", *m_xCtrlDial))
+{
+ m_xCtrlDial->SetLinkedField(m_xNfRotate.get());
+ m_xCtrlDial->SetText(m_xFtABCD->get_label());
+
+ InitVsRefEgde();
+
+ m_xLbHorAlign->connect_changed(LINK(this, AlignmentTabPage, UpdateEnableHdl));
+
+ m_xCbStacked->connect_toggled(LINK(this, AlignmentTabPage, StackedClickHdl));
+ m_xCbAsianMode->connect_toggled(LINK(this, AlignmentTabPage, AsianModeClickHdl));
+ m_xBtnWrap->connect_toggled(LINK(this, AlignmentTabPage, WrapClickHdl));
+ m_xBtnHyphen->connect_toggled(LINK(this, AlignmentTabPage, HyphenClickHdl));
+ m_xBtnShrink->connect_toggled(LINK(this, AlignmentTabPage, ShrinkClickHdl));
+
+ // Asian vertical mode
+ m_xCbAsianMode->set_visible(SvtCJKOptions::IsVerticalTextEnabled());
+
+ m_xLbFrameDir->append(SvxFrameDirection::Horizontal_LR_TB, SvxResId(RID_SVXSTR_FRAMEDIR_LTR));
+ m_xLbFrameDir->append(SvxFrameDirection::Horizontal_RL_TB, SvxResId(RID_SVXSTR_FRAMEDIR_RTL));
+ m_xLbFrameDir->append(SvxFrameDirection::Environment, SvxResId(RID_SVXSTR_FRAMEDIR_SUPER));
+
+ // This page needs ExchangeSupport.
+ SetExchangeSupport();
+}
+
+AlignmentTabPage::~AlignmentTabPage()
+{
+ m_xCtrlDialWin.reset();
+ m_xCtrlDial.reset();
+ m_xVsRefEdge.reset();
+ m_xLbFrameDir.reset();
+}
+
+std::unique_ptr<SfxTabPage> AlignmentTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<AlignmentTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool AlignmentTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ const SfxItemSet& rOldSet = GetItemSet();
+
+ bool bChanged = SfxTabPage::FillItemSet(rSet);
+
+ sal_uInt16 nWhich = GetWhich(SID_ATTR_ALIGN_HOR_JUSTIFY);
+ if (m_xLbHorAlign->get_value_changed_from_saved())
+ {
+ SvxCellHorJustify eJustify(SvxCellHorJustify::Standard);
+ switch (m_xLbHorAlign->get_active_id().toInt32())
+ {
+ case ALIGNDLG_HORALIGN_STD:
+ eJustify = SvxCellHorJustify::Standard;
+ break;
+ case ALIGNDLG_HORALIGN_LEFT:
+ eJustify = SvxCellHorJustify::Left;
+ break;
+ case ALIGNDLG_HORALIGN_CENTER:
+ eJustify = SvxCellHorJustify::Center;
+ break;
+ case ALIGNDLG_HORALIGN_RIGHT:
+ eJustify = SvxCellHorJustify::Right;
+ break;
+ case ALIGNDLG_HORALIGN_BLOCK:
+ case ALIGNDLG_HORALIGN_DISTRIBUTED:
+ eJustify = SvxCellHorJustify::Block;
+ break;
+ case ALIGNDLG_HORALIGN_FILL:
+ eJustify = SvxCellHorJustify::Repeat;
+ break;
+ }
+ rSet->Put(SvxHorJustifyItem(eJustify, nWhich));
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_INDENT);
+ if (m_xEdIndent->get_value_changed_from_saved())
+ {
+ const SfxUInt16Item* pIndentItem = static_cast<const SfxUInt16Item*>(GetOldItem(
+ *rSet, SID_ATTR_ALIGN_INDENT));
+ assert(pIndentItem);
+ std::unique_ptr<SfxUInt16Item> pNewIndentItem(pIndentItem->Clone());
+ pNewIndentItem->SetValue(m_xEdIndent->get_value(FieldUnit::TWIP));
+ rSet->Put(std::move(pNewIndentItem));
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_VER_JUSTIFY);
+ if (m_xLbVerAlign->get_value_changed_from_saved())
+ {
+ SvxCellVerJustify eJustify(SvxCellVerJustify::Standard);
+ switch (m_xLbVerAlign->get_active_id().toInt32())
+ {
+ case ALIGNDLG_VERALIGN_STD:
+ eJustify = SvxCellVerJustify::Standard;
+ break;
+ case ALIGNDLG_VERALIGN_TOP:
+ eJustify = SvxCellVerJustify::Top;
+ break;
+ case ALIGNDLG_VERALIGN_MID:
+ eJustify = SvxCellVerJustify::Center;
+ break;
+ case ALIGNDLG_VERALIGN_BOTTOM:
+ eJustify = SvxCellVerJustify::Bottom;
+ break;
+ case ALIGNDLG_VERALIGN_BLOCK:
+ case ALIGNDLG_VERALIGN_DISTRIBUTED:
+ eJustify = SvxCellVerJustify::Block;
+ break;
+ }
+ rSet->Put(SvxVerJustifyItem(eJustify, nWhich));
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_DEGREES);
+ if (m_xNfRotate->get_value_changed_from_saved())
+ {
+ const SdrAngleItem* pAngleItem = static_cast<const SdrAngleItem*>(GetOldItem(
+ *rSet, SID_ATTR_ALIGN_DEGREES));
+ assert(pAngleItem);
+ std::unique_ptr<SdrAngleItem> pNewAngleItem(pAngleItem->Clone());
+ pNewAngleItem->SetValue(m_xCtrlDial->GetRotation());
+ rSet->Put(std::move(pNewAngleItem));
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+
+ TypedWhichId<SvxRotateModeItem> nWhichLockPos(GetWhich(SID_ATTR_ALIGN_LOCKPOS));
+ if (m_aVsRefEdge.IsValueChangedFromSaved())
+ {
+ switch (m_aVsRefEdge.GetSelectedItemId())
+ {
+ case IID_CELLLOCK:
+ rSet->Put(SvxRotateModeItem(SvxRotateMode::SVX_ROTATE_MODE_STANDARD, nWhichLockPos));
+ break;
+ case IID_TOPLOCK:
+ rSet->Put(SvxRotateModeItem(SvxRotateMode::SVX_ROTATE_MODE_TOP, nWhichLockPos));
+ break;
+ case IID_BOTTOMLOCK:
+ rSet->Put(SvxRotateModeItem(SvxRotateMode::SVX_ROTATE_MODE_BOTTOM, nWhichLockPos));
+ break;
+ default:
+ m_aVsRefEdge.SetNoSelection();
+ break;
+ }
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhichLockPos, false))
+ rSet->InvalidateItem(nWhichLockPos);
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_STACKED);
+ if (m_xCbStacked->get_state_changed_from_saved())
+ {
+ const SfxBoolItem* pStackItem = static_cast<const SfxBoolItem*>(GetOldItem(
+ *rSet, SID_ATTR_ALIGN_STACKED));
+ assert(pStackItem);
+ std::unique_ptr<SfxBoolItem> pNewStackItem(pStackItem->Clone());
+ pNewStackItem->SetValue(m_xCbStacked->get_active());
+ rSet->Put(std::move(pNewStackItem));
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_ASIANVERTICAL);
+ if (m_xCbAsianMode->get_state_changed_from_saved())
+ {
+ rSet->Put(SfxBoolItem(nWhich, m_xCbAsianMode->get_active()));
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_LINEBREAK);
+ if (m_xBtnWrap->get_state_changed_from_saved())
+ {
+ const SfxBoolItem* pWrapItem = static_cast<const SfxBoolItem*>(GetOldItem(
+ *rSet, SID_ATTR_ALIGN_LINEBREAK));
+ assert(pWrapItem);
+ std::unique_ptr<SfxBoolItem> pNewWrapItem(pWrapItem->Clone());
+ pNewWrapItem->SetValue(m_xBtnWrap->get_active());
+ rSet->Put(std::move(pNewWrapItem));
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_HYPHENATION);
+ if (m_xBtnHyphen->get_state_changed_from_saved())
+ {
+ const SfxBoolItem* pHyphItem = static_cast<const SfxBoolItem*>(GetOldItem(
+ *rSet, SID_ATTR_ALIGN_HYPHENATION));
+ assert(pHyphItem);
+ std::unique_ptr<SfxBoolItem> pNewHyphItem(pHyphItem->Clone());
+ pNewHyphItem->SetValue(m_xBtnHyphen->get_active());
+ rSet->Put(std::move(pNewHyphItem));
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_SHRINKTOFIT);
+ if (m_xBtnShrink->get_state_changed_from_saved())
+ {
+ const SfxBoolItem* pShrinkItem = static_cast<const SfxBoolItem*>(GetOldItem(
+ *rSet, SID_ATTR_ALIGN_SHRINKTOFIT));
+ assert(pShrinkItem);
+ std::unique_ptr<SfxBoolItem> pNewShrinkItem(pShrinkItem->Clone());
+ pNewShrinkItem->SetValue(m_xBtnShrink->get_active());
+ rSet->Put(std::move(pNewShrinkItem));
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+
+ if (m_xLbFrameDir->get_visible())
+ {
+ nWhich = GetWhich(SID_ATTR_FRAMEDIRECTION);
+ if (m_xLbFrameDir->get_value_changed_from_saved())
+ {
+ SvxFrameDirection eDir = m_xLbFrameDir->get_active_id();
+ rSet->Put(SvxFrameDirectionItem(eDir, nWhich));
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+ }
+
+ // Special treatment for distributed alignment; we need to set the justify
+ // method to 'distribute' to distinguish from the normal justification.
+ TypedWhichId<SfxEnumItemInterface> nWhichHorJM(GetWhich(SID_ATTR_ALIGN_HOR_JUSTIFY_METHOD));
+ lcl_SetJustifyMethodToItemSet(*rSet, rOldSet, nWhichHorJM, *m_xLbHorAlign, ALIGNDLG_HORALIGN_DISTRIBUTED);
+ if (!bChanged)
+ bChanged = HasAlignmentChanged(*rSet, nWhichHorJM);
+
+ TypedWhichId<SfxEnumItemInterface> nWhichVerJM(GetWhich(SID_ATTR_ALIGN_VER_JUSTIFY_METHOD));
+ lcl_SetJustifyMethodToItemSet(*rSet, rOldSet, nWhichVerJM, *m_xLbVerAlign, ALIGNDLG_VERALIGN_DISTRIBUTED);
+ if (!bChanged)
+ bChanged = HasAlignmentChanged(*rSet, nWhichVerJM);
+
+ return bChanged;
+}
+
+namespace
+{
+ void ResetBool(sal_uInt16 nWhich, const SfxItemSet* pSet, weld::CheckButton& rBtn, weld::TriStateEnabled& rTriState)
+ {
+ SfxItemState eState = pSet->GetItemState(nWhich);
+ switch (eState)
+ {
+ case SfxItemState::UNKNOWN:
+ rBtn.hide();
+ rTriState.bTriStateEnabled = false;
+ break;
+ case SfxItemState::DISABLED:
+ rBtn.set_sensitive(false);
+ rTriState.bTriStateEnabled = false;
+ break;
+ case SfxItemState::DONTCARE:
+ rBtn.set_state(TRISTATE_INDET);
+ rTriState.bTriStateEnabled = true;
+ break;
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SfxBoolItem& rItem = static_cast<const SfxBoolItem&>(pSet->Get(nWhich));
+ rBtn.set_state(static_cast<TriState>(rItem.GetValue()));
+ rTriState.bTriStateEnabled = false;
+ break;
+ }
+ }
+ rBtn.save_state();
+ }
+}
+
+void AlignmentTabPage::Reset(const SfxItemSet* pCoreAttrs)
+{
+ SfxTabPage::Reset(pCoreAttrs);
+
+ ResetBool(GetWhich(SID_ATTR_ALIGN_STACKED), pCoreAttrs, *m_xCbStacked, m_aStackedState);
+ ResetBool(GetWhich(SID_ATTR_ALIGN_ASIANVERTICAL), pCoreAttrs, *m_xCbAsianMode, m_aAsianModeState);
+ ResetBool(GetWhich(SID_ATTR_ALIGN_LINEBREAK), pCoreAttrs, *m_xBtnWrap, m_aWrapState);
+ ResetBool(GetWhich(SID_ATTR_ALIGN_HYPHENATION), pCoreAttrs, *m_xBtnHyphen, m_aHyphenState);
+ ResetBool(GetWhich(SID_ATTR_ALIGN_SHRINKTOFIT), pCoreAttrs, *m_xBtnShrink, m_aShrinkState);
+
+ sal_uInt16 nWhich = GetWhich(SID_ATTR_ALIGN_HOR_JUSTIFY);
+ SfxItemState eState = pCoreAttrs->GetItemState(nWhich);
+ switch (eState)
+ {
+ case SfxItemState::UNKNOWN:
+ m_xLbHorAlign->hide();
+ break;
+ case SfxItemState::DISABLED:
+ m_xLbHorAlign->set_sensitive(false);
+ break;
+ case SfxItemState::DONTCARE:
+ m_xLbHorAlign->set_active(-1);
+ break;
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxHorJustifyItem& rJustifyItem = static_cast<const SvxHorJustifyItem&>(pCoreAttrs->Get(nWhich));
+ switch (rJustifyItem.GetValue())
+ {
+ case SvxCellHorJustify::Standard:
+ m_xLbHorAlign->set_active_id(OUString::number(ALIGNDLG_HORALIGN_STD));
+ break;
+ case SvxCellHorJustify::Left:
+ m_xLbHorAlign->set_active_id(OUString::number(ALIGNDLG_HORALIGN_LEFT));
+ break;
+ case SvxCellHorJustify::Center:
+ m_xLbHorAlign->set_active_id(OUString::number(ALIGNDLG_HORALIGN_CENTER));
+ break;
+ case SvxCellHorJustify::Right:
+ m_xLbHorAlign->set_active_id(OUString::number(ALIGNDLG_HORALIGN_RIGHT));
+ break;
+ case SvxCellHorJustify::Block:
+ m_xLbHorAlign->set_active_id(OUString::number(ALIGNDLG_HORALIGN_BLOCK));
+ break;
+ case SvxCellHorJustify::Repeat:
+ m_xLbHorAlign->set_active_id(OUString::number(ALIGNDLG_HORALIGN_FILL));
+ break;
+ }
+ break;
+ }
+ }
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_INDENT);
+ eState = pCoreAttrs->GetItemState(nWhich);
+ switch (eState)
+ {
+ case SfxItemState::UNKNOWN:
+ m_xEdIndent->hide();
+ m_xFtIndent->hide();
+ break;
+ case SfxItemState::DISABLED:
+ m_xEdIndent->set_sensitive(false);
+ break;
+ case SfxItemState::DONTCARE:
+ m_xEdIndent->set_text("");
+ break;
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SfxUInt16Item& rIndentItem = static_cast<const SfxUInt16Item&>(pCoreAttrs->Get(nWhich));
+ m_xEdIndent->set_value(rIndentItem.GetValue(), FieldUnit::TWIP);
+ break;
+ }
+ }
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_VER_JUSTIFY);
+ eState = pCoreAttrs->GetItemState(nWhich);
+ switch (eState)
+ {
+ case SfxItemState::UNKNOWN:
+ m_xLbVerAlign->hide();
+ m_xFtVerAlign->hide();
+ break;
+ case SfxItemState::DISABLED:
+ m_xLbVerAlign->set_sensitive(false);
+ break;
+ case SfxItemState::DONTCARE:
+ m_xLbVerAlign->set_active(-1);
+ break;
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxVerJustifyItem& rJustifyItem = static_cast<const SvxVerJustifyItem&>(pCoreAttrs->Get(nWhich));
+ switch (rJustifyItem.GetValue())
+ {
+ case SvxCellVerJustify::Standard:
+ m_xLbVerAlign->set_active_id(OUString::number(ALIGNDLG_VERALIGN_STD));
+ break;
+ case SvxCellVerJustify::Top:
+ m_xLbVerAlign->set_active_id(OUString::number(ALIGNDLG_VERALIGN_TOP));
+ break;
+ case SvxCellVerJustify::Center:
+ m_xLbVerAlign->set_active_id(OUString::number(ALIGNDLG_VERALIGN_MID));
+ break;
+ case SvxCellVerJustify::Bottom:
+ m_xLbVerAlign->set_active_id(OUString::number(ALIGNDLG_VERALIGN_BOTTOM));
+ break;
+ case SvxCellVerJustify::Block:
+ m_xLbVerAlign->set_active_id(OUString::number(ALIGNDLG_VERALIGN_BLOCK));
+ break;
+ }
+ break;
+ }
+ }
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_DEGREES);
+ eState = pCoreAttrs->GetItemState(nWhich);
+ switch (eState)
+ {
+ case SfxItemState::UNKNOWN:
+ m_xNfRotate->hide();
+ m_xCtrlDialWin->hide();
+ break;
+ case SfxItemState::DISABLED:
+ m_xNfRotate->set_sensitive(false);
+ m_xCtrlDialWin->set_sensitive(false);
+ break;
+ case SfxItemState::DONTCARE:
+ m_xCtrlDial->SetNoRotation();
+ break;
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SdrAngleItem& rAlignItem = static_cast<const SdrAngleItem&>(pCoreAttrs->Get(nWhich));
+ m_xCtrlDial->SetRotation(rAlignItem.GetValue());
+ break;
+ }
+ }
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_LOCKPOS);
+ eState = pCoreAttrs->GetItemState(nWhich);
+ switch (eState)
+ {
+ case SfxItemState::UNKNOWN:
+ m_xVsRefEdge->hide();
+ break;
+ case SfxItemState::DISABLED:
+ m_xVsRefEdge->set_sensitive(false);
+ break;
+ case SfxItemState::DONTCARE:
+ m_aVsRefEdge.SetNoSelection();
+ break;
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxRotateModeItem& rRotateModeItem = static_cast<const SvxRotateModeItem&>(pCoreAttrs->Get(nWhich));
+ switch (rRotateModeItem.GetValue())
+ {
+ case SvxRotateMode::SVX_ROTATE_MODE_STANDARD:
+ m_aVsRefEdge.SelectItem(IID_CELLLOCK);
+ break;
+ case SvxRotateMode::SVX_ROTATE_MODE_TOP:
+ m_aVsRefEdge.SelectItem(IID_TOPLOCK);
+ break;
+ case SvxRotateMode::SVX_ROTATE_MODE_BOTTOM:
+ m_aVsRefEdge.SelectItem(IID_BOTTOMLOCK);
+ break;
+ default:
+ m_aVsRefEdge.SetNoSelection();
+ break;
+ }
+ break;
+ }
+ }
+ m_aVsRefEdge.SaveValue();
+
+ //text direction
+ nWhich = GetWhich(SID_ATTR_FRAMEDIRECTION);
+ eState = pCoreAttrs->GetItemState(nWhich);
+ switch (eState)
+ {
+ case SfxItemState::UNKNOWN:
+ m_xLbFrameDir->hide();
+ break;
+ case SfxItemState::DISABLED:
+ m_xLbFrameDir->set_sensitive(false);
+ break;
+ case SfxItemState::DONTCARE:
+ m_xLbFrameDir->set_active(-1);
+ break;
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxFrameDirectionItem& rFrameDirItem = static_cast<const SvxFrameDirectionItem&>(pCoreAttrs->Get(nWhich));
+ m_xLbFrameDir->set_active_id(rFrameDirItem.GetValue());
+ break;
+ }
+ }
+
+ // Special treatment for distributed alignment; we need to set the justify
+ // method to 'distribute' to distinguish from the normal justification.
+ TypedWhichId<SfxEnumItemInterface> nHorJustifyMethodWhich(GetWhich(SID_ATTR_ALIGN_HOR_JUSTIFY_METHOD));
+ SfxItemState eHorJustifyMethodState = pCoreAttrs->GetItemState(nHorJustifyMethodWhich);
+ if (eHorJustifyMethodState == SfxItemState::UNKNOWN)
+ {
+ // feature unknown, e.g. dbaccess, remove the option
+ int nDistribId = m_xLbHorAlign->find_id(OUString::number(ALIGNDLG_HORALIGN_DISTRIBUTED));
+ if (nDistribId != -1)
+ m_xLbHorAlign->remove(nDistribId);
+ }
+ else
+ {
+ // feature known, e.g. calc
+ lcl_MaybeResetAlignToDistro<SvxCellHorJustify, SvxCellHorJustify>(
+ *m_xLbHorAlign, ALIGNDLG_HORALIGN_DISTRIBUTED, *pCoreAttrs,
+ TypedWhichId<SfxEnumItemInterface>(GetWhich(SID_ATTR_ALIGN_HOR_JUSTIFY)), nHorJustifyMethodWhich,
+ SvxCellHorJustify::Block);
+ }
+
+ TypedWhichId<SfxEnumItemInterface> nVerJustifyMethodWhich( GetWhich(SID_ATTR_ALIGN_VER_JUSTIFY_METHOD) );
+ SfxItemState eVerJustifyMethodState = pCoreAttrs->GetItemState(nVerJustifyMethodWhich);
+ if (eVerJustifyMethodState == SfxItemState::UNKNOWN)
+ {
+ // feature unknown, e.g. dbaccess, remove the option
+ int nDistribId = m_xLbVerAlign->find_id(OUString::number(ALIGNDLG_VERALIGN_DISTRIBUTED));
+ if (nDistribId != -1)
+ m_xLbVerAlign->remove(nDistribId);
+ }
+ else
+ {
+ // feature known, e.g. calc
+ lcl_MaybeResetAlignToDistro<SvxCellVerJustify, SvxCellVerJustify>(
+ *m_xLbVerAlign, ALIGNDLG_VERALIGN_DISTRIBUTED, *pCoreAttrs,
+ TypedWhichId<SfxEnumItemInterface>(GetWhich(SID_ATTR_ALIGN_VER_JUSTIFY)), nVerJustifyMethodWhich,
+ SvxCellVerJustify::Block);
+ }
+
+ m_xLbHorAlign->save_value();
+ m_xLbFrameDir->save_value();
+ m_xLbVerAlign->save_value();
+ m_xNfRotate->save_value();
+ m_xEdIndent->save_value();
+
+ UpdateEnableControls();
+}
+
+DeactivateRC AlignmentTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+void AlignmentTabPage::InitVsRefEgde()
+{
+ // remember selection - is deleted in call to ValueSet::Clear()
+ sal_uInt16 nSel = m_aVsRefEdge.GetSelectedItemId();
+
+ Image aBottomLock(StockImage::Yes, RID_SVXBMP_BOTTOMLOCK);
+ Image aTopLock(StockImage::Yes, RID_SVXBMP_TOPLOCK);
+ Image aCellLock(StockImage::Yes, RID_SVXBMP_CELLLOCK);
+
+ m_aVsRefEdge.Clear();
+ m_aVsRefEdge.SetStyle(m_aVsRefEdge.GetStyle() | WB_ITEMBORDER | WB_DOUBLEBORDER);
+
+ m_aVsRefEdge.SetColCount(3);
+ m_aVsRefEdge.InsertItem(IID_BOTTOMLOCK, aBottomLock, m_xFtBotLock->get_label());
+ m_aVsRefEdge.InsertItem(IID_TOPLOCK, aTopLock, m_xFtTopLock->get_label());
+ m_aVsRefEdge.InsertItem(IID_CELLLOCK, aCellLock, m_xFtCelLock->get_label());
+ m_aVsRefEdge.SetOptimalSize();
+
+ m_aVsRefEdge.SelectItem( nSel );
+}
+
+void AlignmentTabPage::UpdateEnableControls()
+{
+ const sal_Int32 nHorAlign = m_xLbHorAlign->get_active_id().toInt32();
+ bool bHorLeft = (nHorAlign == ALIGNDLG_HORALIGN_LEFT);
+ bool bHorBlock = (nHorAlign == ALIGNDLG_HORALIGN_BLOCK);
+ bool bHorFill = (nHorAlign == ALIGNDLG_HORALIGN_FILL);
+ bool bHorDist = (nHorAlign == ALIGNDLG_HORALIGN_DISTRIBUTED);
+
+ // indent edit field only for left alignment
+ m_xFtIndent->set_sensitive( bHorLeft );
+ m_xEdIndent->set_sensitive( bHorLeft );
+
+ // stacked disabled for fill alignment
+ m_xCbStacked->set_sensitive(!bHorFill);
+
+ // hyphenation only for automatic line breaks or for block alignment
+ m_xBtnHyphen->set_sensitive( m_xBtnWrap->get_active() || bHorBlock );
+
+ // shrink only without automatic line break, and not for block, fill or distribute.
+ m_xBtnShrink->set_sensitive( (m_xBtnWrap->get_state() == TRISTATE_FALSE) && !bHorBlock && !bHorFill && !bHorDist );
+
+ // visibility of frames
+ m_xAlignmentFrame->set_visible(m_xLbHorAlign->get_visible() || m_xEdIndent->get_visible() ||
+ m_xLbVerAlign->get_visible());
+ m_xOrientFrame->set_visible(m_xCtrlDialWin->get_visible() || m_xVsRefEdge->get_visible() ||
+ m_xCbStacked->get_visible() || m_xCbAsianMode->get_visible());
+ m_xPropertiesFrame->set_visible(m_xBtnWrap->get_visible() || m_xBtnHyphen->get_visible() ||
+ m_xBtnShrink->get_visible() || m_xLbFrameDir->get_visible());
+
+ bool bStackedText = m_xCbStacked->get_active();
+ // windows to be disabled, if stacked text is turned ON
+ m_xFtRotate->set_sensitive(!bStackedText);
+ m_xFtRefEdge->set_sensitive(!bStackedText);
+ m_xVsRefEdge->set_sensitive(!bStackedText);
+ // windows to be disabled, if stacked text is turned OFF
+ m_xCbAsianMode->set_sensitive(bStackedText);
+ // rotation/stacked disabled for fill alignment/stacked
+ m_xCtrlDialWin->set_sensitive(!bHorFill && !bStackedText);
+ m_xNfRotate->set_sensitive(!bHorFill && !bStackedText);
+}
+
+bool AlignmentTabPage::HasAlignmentChanged( const SfxItemSet& rNew, TypedWhichId<SfxEnumItemInterface> nWhich ) const
+{
+ const SfxItemSet& rOld = GetItemSet();
+ SvxCellJustifyMethod eMethodOld = SvxCellJustifyMethod::Auto;
+ SvxCellJustifyMethod eMethodNew = SvxCellJustifyMethod::Auto;
+ if (const SfxEnumItemInterface* p = rOld.GetItemIfSet(nWhich))
+ {
+ eMethodOld = static_cast<SvxCellJustifyMethod>(p->GetEnumValue());
+ }
+
+ if (const SfxEnumItemInterface* p = rNew.GetItemIfSet(nWhich))
+ {
+ eMethodNew = static_cast<SvxCellJustifyMethod>(p->GetEnumValue());
+ }
+
+ return eMethodOld != eMethodNew;
+}
+
+IMPL_LINK(AlignmentTabPage, StackedClickHdl, weld::Toggleable&, rToggle, void)
+{
+ m_aStackedState.ButtonToggled(rToggle);
+ UpdateEnableControls();
+}
+
+IMPL_LINK(AlignmentTabPage, AsianModeClickHdl, weld::Toggleable&, rToggle, void)
+{
+ m_aAsianModeState.ButtonToggled(rToggle);
+}
+
+IMPL_LINK(AlignmentTabPage, WrapClickHdl, weld::Toggleable&, rToggle, void)
+{
+ m_aWrapState.ButtonToggled(rToggle);
+ UpdateEnableControls();
+}
+
+IMPL_LINK(AlignmentTabPage, HyphenClickHdl, weld::Toggleable&, rToggle, void)
+{
+ m_aHyphenState.ButtonToggled(rToggle);
+}
+
+IMPL_LINK(AlignmentTabPage, ShrinkClickHdl, weld::Toggleable&, rToggle, void)
+{
+ m_aShrinkState.ButtonToggled(rToggle);
+}
+
+IMPL_LINK_NOARG(AlignmentTabPage, UpdateEnableHdl, weld::ComboBox&, void)
+{
+ UpdateEnableControls();
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/autocdlg.cxx b/cui/source/tabpages/autocdlg.cxx
new file mode 100644
index 0000000000..282e8b5405
--- /dev/null
+++ b/cui/source/tabpages/autocdlg.cxx
@@ -0,0 +1,2379 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <i18nutil/unicode.hxx>
+#include <o3tl/safeint.hxx>
+#include <utility>
+#include <vcl/event.hxx>
+#include <vcl/keycodes.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/transfer.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/viewsh.hxx>
+#include <unotools/charclass.hxx>
+#include <unotools/collatorwrapper.hxx>
+#include <comphelper/processfactory.hxx>
+#include <vcl/svapp.hxx>
+#include <sfx2/module.hxx>
+#include <svl/eitem.hxx>
+#include <svl/cjkoptions.hxx>
+#include <svl/ctloptions.hxx>
+#include <svx/SmartTagMgr.hxx>
+#include <com/sun/star/smarttags/XSmartTagRecognizer.hpp>
+#include <rtl/strbuf.hxx>
+#include <o3tl/temporary.hxx>
+#include <osl/diagnose.h>
+#include <tools/debug.hxx>
+
+#include <autocdlg.hxx>
+#include <editeng/acorrcfg.hxx>
+#include <editeng/svxacorr.hxx>
+#include <cui/cuicharmap.hxx>
+#include <strings.hrc>
+#include <dialmgr.hxx>
+#include <svx/svxids.hrc>
+
+static LanguageType eLastDialogLanguage = LANGUAGE_SYSTEM;
+
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star;
+
+OfaAutoCorrDlg::OfaAutoCorrDlg(weld::Window* pParent, const SfxItemSet* _pSet )
+ : SfxTabDialogController(pParent, "cui/ui/autocorrectdialog.ui", "AutoCorrectDialog", _pSet)
+ , m_xLanguageBox(m_xBuilder->weld_widget("langbox"))
+ , m_xLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("lang")))
+{
+ bool bShowSWOptions = false;
+ bool bOpenSmartTagOptions = false;
+
+ if ( _pSet )
+ {
+ const SfxBoolItem* pItem = SfxItemSet::GetItem<SfxBoolItem>(_pSet, SID_AUTO_CORRECT_DLG, false);
+ if ( pItem && pItem->GetValue() )
+ bShowSWOptions = true;
+
+ const SfxBoolItem* pItem2 = SfxItemSet::GetItem<SfxBoolItem>(_pSet, SID_OPEN_SMARTTAGOPTIONS, false);
+ if ( pItem2 && pItem2->GetValue() )
+ bOpenSmartTagOptions = true;
+ }
+
+ AddTabPage("options", OfaAutocorrOptionsPage::Create, nullptr);
+ AddTabPage("applypage", OfaSwAutoFmtOptionsPage::Create, nullptr);
+ AddTabPage("wordcompletion", OfaAutoCompleteTabPage::Create, nullptr);
+ AddTabPage("smarttags", OfaSmartTagOptionsTabPage::Create, nullptr);
+
+ if (!bShowSWOptions)
+ {
+ RemoveTabPage("applypage");
+ RemoveTabPage("wordcompletion");
+ RemoveTabPage("smarttags");
+ }
+ else
+ {
+ // remove smart tag tab page if no extensions are installed
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ SvxSwAutoFormatFlags& rOpt = pAutoCorrect->GetSwFlags();
+ if (!rOpt.pSmartTagMgr || 0 == rOpt.pSmartTagMgr->NumberOfRecognizers())
+ RemoveTabPage("smarttags");
+
+ RemoveTabPage("options");
+ }
+
+ AddTabPage("replace", OfaAutocorrReplacePage::Create, nullptr);
+ AddTabPage("exceptions", OfaAutocorrExceptPage::Create, nullptr);
+ AddTabPage("localized", OfaQuoteTabPage::Create, nullptr);
+
+ // initialize languages
+ //! LANGUAGE_NONE is displayed as '[All]' and the LanguageType
+ //! will be set to LANGUAGE_UNDETERMINED
+ SvxLanguageListFlags nLangList = SvxLanguageListFlags::WESTERN;
+
+ if( SvtCTLOptions::IsCTLFontEnabled() )
+ nLangList |= SvxLanguageListFlags::CTL;
+ if( SvtCJKOptions::IsCJKFontEnabled() )
+ nLangList |= SvxLanguageListFlags::CJK;
+ m_xLanguageLB->SetLanguageList( nLangList, true, true );
+ m_xLanguageLB->set_active_id( LANGUAGE_NONE );
+ int nPos = m_xLanguageLB->get_active();
+ DBG_ASSERT(nPos != -1, "listbox entry missing" );
+ m_xLanguageLB->set_id(nPos, LANGUAGE_UNDETERMINED);
+
+ // Initializing doesn't work for static on linux - therefore here
+ if (LANGUAGE_SYSTEM == eLastDialogLanguage)
+ eLastDialogLanguage = Application::GetSettings().GetLanguageTag().getLanguageType();
+
+ LanguageType nSelectLang = LANGUAGE_UNDETERMINED;
+ nPos = m_xLanguageLB->find_id(eLastDialogLanguage);
+ if (nPos != -1)
+ nSelectLang = eLastDialogLanguage;
+ m_xLanguageLB->set_active_id(nSelectLang);
+
+ m_xLanguageLB->connect_changed(LINK(this, OfaAutoCorrDlg, SelectLanguageHdl));
+
+ if ( bOpenSmartTagOptions )
+ SetCurPageId("smarttags");
+}
+
+OfaAutoCorrDlg::~OfaAutoCorrDlg()
+{
+}
+
+void OfaAutoCorrDlg::EnableLanguage(bool bEnable)
+{
+ m_xLanguageBox->set_sensitive(bEnable);
+}
+
+static bool lcl_FindEntry(weld::TreeView& rLB, const OUString& rEntry,
+ CollatorWrapper const & rCmpClass)
+{
+ int nCount = rLB.n_children();
+ int nSelPos = rLB.get_selected_index();
+ for (int i = 0; i < nCount; i++)
+ {
+ if (0 == rCmpClass.compareString(rEntry, rLB.get_text(i)))
+ {
+ rLB.select(i);
+ return true;
+ }
+ }
+ if (nSelPos != -1)
+ rLB.unselect(nSelPos);
+ return false;
+}
+
+IMPL_LINK_NOARG(OfaAutoCorrDlg, SelectLanguageHdl, weld::ComboBox&, void)
+{
+ LanguageType eNewLang = m_xLanguageLB->get_active_id();
+ // save old settings and fill anew
+ if(eNewLang == eLastDialogLanguage)
+ return;
+
+ OUString sPageId = GetCurPageId();
+ if (sPageId == "replace")
+ {
+ OfaAutocorrReplacePage* pPage = static_cast<OfaAutocorrReplacePage*>(GetTabPage(sPageId));
+ assert(pPage);
+ pPage->SetLanguage(eNewLang);
+ }
+ else if (sPageId == "exceptions")
+ {
+ OfaAutocorrExceptPage* pPage = static_cast<OfaAutocorrExceptPage*>(GetTabPage(sPageId));
+ assert(pPage);
+ pPage->SetLanguage(eNewLang);
+ }
+}
+
+OfaAutocorrOptionsPage::OfaAutocorrOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/acoroptionspage.ui", "AutocorrectOptionsPage", &rSet)
+ , m_sInput(CuiResId(RID_CUISTR_USE_REPLACE))
+ , m_sDoubleCaps(CuiResId(RID_CUISTR_CPTL_STT_WORD))
+ , m_sStartCap(CuiResId(RID_CUISTR_CPTL_STT_SENT))
+ , m_sBoldUnderline(CuiResId(RID_CUISTR_BOLD_UNDER))
+ , m_sURL(CuiResId(RID_CUISTR_DETECT_URL))
+ , m_sDOI(CuiResId(RID_CUISTR_DETECT_DOI))
+ , m_sNoDblSpaces(CuiResId(RID_CUISTR_NO_DBL_SPACES))
+ , m_sDash(CuiResId(RID_CUISTR_DASH))
+ , m_sAccidentalCaps(CuiResId(RID_CUISTR_CORRECT_ACCIDENTAL_CAPS_LOCK))
+ , m_xCheckLB(m_xBuilder->weld_tree_view("checklist"))
+{
+ m_xCheckLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
+ m_xCheckLB->set_size_request(-1, m_xCheckLB->get_height_rows(10));
+}
+
+OfaAutocorrOptionsPage::~OfaAutocorrOptionsPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> OfaAutocorrOptionsPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rSet)
+{
+ return std::make_unique<OfaAutocorrOptionsPage>(pPage, pController, *rSet);
+}
+
+#define CBCOL_FIRST 0
+#define CBCOL_SECOND 1
+#define CBCOL_BOTH 2
+
+bool OfaAutocorrOptionsPage::FillItemSet( SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ ACFlags nFlags = pAutoCorrect->GetFlags();
+
+ int nPos = 0;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::Autocorrect, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::CapitalStartWord, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::CapitalStartSentence, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgWeightUnderl, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::SetINetAttr, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::SetDOIAttr, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgToEnEmDash, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::IgnoreDoubleSpace, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::CorrectCapsLock, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
+
+ bool bReturn = nFlags != pAutoCorrect->GetFlags();
+ if(bReturn )
+ {
+ SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
+ rCfg.SetModified();
+ rCfg.Commit();
+ }
+ return bReturn;
+}
+
+void OfaAutocorrOptionsPage::ActivatePage( const SfxItemSet& )
+{
+ static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage(false);
+}
+
+void OfaAutocorrOptionsPage::InsertEntry(const OUString& rTxt)
+{
+ m_xCheckLB->append();
+ const int nRow = m_xCheckLB->n_children() - 1;
+ m_xCheckLB->set_toggle(nRow, TRISTATE_FALSE);
+ m_xCheckLB->set_text(nRow, rTxt, 0);
+}
+
+void OfaAutocorrOptionsPage::Reset( const SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ const ACFlags nFlags = pAutoCorrect->GetFlags();
+
+ m_xCheckLB->freeze();
+ m_xCheckLB->clear();
+
+ InsertEntry(m_sInput);
+ InsertEntry(m_sDoubleCaps);
+ InsertEntry(m_sStartCap);
+ InsertEntry(m_sBoldUnderline);
+ InsertEntry(m_sURL);
+ InsertEntry(m_sDOI);
+ InsertEntry(m_sDash);
+ InsertEntry(m_sNoDblSpaces);
+ InsertEntry(m_sAccidentalCaps);
+
+ int nPos = 0;
+ m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::Autocorrect) ? TRISTATE_TRUE : TRISTATE_FALSE );
+ m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::CapitalStartWord) ? TRISTATE_TRUE : TRISTATE_FALSE );
+ m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::CapitalStartSentence) ? TRISTATE_TRUE : TRISTATE_FALSE );
+ m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::ChgWeightUnderl) ? TRISTATE_TRUE : TRISTATE_FALSE );
+ m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::SetINetAttr) ? TRISTATE_TRUE : TRISTATE_FALSE );
+ m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::SetDOIAttr) ? TRISTATE_TRUE : TRISTATE_FALSE );
+ m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::ChgToEnEmDash) ? TRISTATE_TRUE : TRISTATE_FALSE );
+ m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::IgnoreDoubleSpace) ? TRISTATE_TRUE : TRISTATE_FALSE );
+ m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::CorrectCapsLock) ? TRISTATE_TRUE : TRISTATE_FALSE );
+
+ m_xCheckLB->thaw();
+}
+
+/*********************************************************************/
+/* */
+/* helping struct for dUserData of the Checklistbox */
+/* */
+/*********************************************************************/
+
+namespace {
+
+struct ImpUserData
+{
+ OUString *pString;
+ vcl::Font *pFont;
+
+ ImpUserData(OUString* pText, vcl::Font* pFnt)
+ { pString = pText; pFont = pFnt;}
+};
+
+
+/*********************************************************************/
+/* */
+/* dialog for per cent settings */
+/* */
+/*********************************************************************/
+
+class OfaAutoFmtPrcntSet : public weld::GenericDialogController
+{
+ std::unique_ptr<weld::MetricSpinButton> m_xPrcntMF;
+public:
+ explicit OfaAutoFmtPrcntSet(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/percentdialog.ui", "PercentDialog")
+ , m_xPrcntMF(m_xBuilder->weld_metric_spin_button("margin", FieldUnit::PERCENT))
+ {
+ }
+
+ weld::MetricSpinButton& GetPrcntFld()
+ {
+ return *m_xPrcntMF;
+ }
+};
+
+/*********************************************************************/
+/* */
+/* use TabPage autoformat */
+/* */
+/*********************************************************************/
+
+enum OfaAutoFmtOptions
+{
+ USE_REPLACE_TABLE,
+ CORR_UPPER,
+ BEGIN_UPPER,
+ BOLD_UNDERLINE,
+ DETECT_URL,
+ DETECT_DOI,
+ REPLACE_DASHES,
+ DEL_SPACES_AT_STT_END,
+ DEL_SPACES_BETWEEN_LINES,
+ IGNORE_DBLSPACE,
+ CORRECT_CAPS_LOCK,
+ APPLY_NUMBERING,
+ APPLY_NUMBERING_AFTER_SPACE,
+ INSERT_BORDER,
+ CREATE_TABLE,
+ REPLACE_STYLES,
+ DEL_EMPTY_NODE,
+ REPLACE_USER_COLL,
+ REPLACE_BULLETS,
+ MERGE_SINGLE_LINE_PARA
+};
+
+}
+
+OfaSwAutoFmtOptionsPage::OfaSwAutoFmtOptionsPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet )
+ : SfxTabPage(pPage, pController, "cui/ui/applyautofmtpage.ui", "ApplyAutoFmtPage", &rSet)
+ , sDeleteEmptyPara(CuiResId(RID_CUISTR_DEL_EMPTY_PARA))
+ , sUseReplaceTbl(CuiResId(RID_CUISTR_USE_REPLACE))
+ , sCapitalStartWord(CuiResId(RID_CUISTR_CPTL_STT_WORD))
+ , sCapitalStartSentence(CuiResId(RID_CUISTR_CPTL_STT_SENT))
+ , sUserStyle(CuiResId(RID_CUISTR_USER_STYLE))
+ , sBullet(CuiResId(RID_CUISTR_BULLET))
+ , sBoldUnder(CuiResId(RID_CUISTR_BOLD_UNDER))
+ , sNoDblSpaces(CuiResId(RID_CUISTR_NO_DBL_SPACES))
+ , sCorrectCapsLock(CuiResId(RID_CUISTR_CORRECT_ACCIDENTAL_CAPS_LOCK))
+ , sDetectURL(CuiResId(RID_CUISTR_DETECT_URL))
+ , sDetectDOI(CuiResId(RID_CUISTR_DETECT_DOI))
+ , sDash(CuiResId(RID_CUISTR_DASH))
+ , sRightMargin(CuiResId(RID_CUISTR_RIGHT_MARGIN))
+ , sNum(CuiResId(RID_CUISTR_NUM))
+ , sBulletsAfterSpace(CuiResId(RID_SVXSTR_NUM_FORMAT_AFTER_SPACE))
+ , sBorder(CuiResId(RID_CUISTR_BORDER))
+ , sTable(CuiResId(RID_CUISTR_CREATE_TABLE))
+ , sReplaceTemplates(CuiResId(RID_CUISTR_REPLACE_TEMPLATES))
+ , sDelSpaceAtSttEnd(CuiResId(RID_CUISTR_DEL_SPACES_AT_STT_END))
+ , sDelSpaceBetweenLines(CuiResId(RID_CUISTR_DEL_SPACES_BETWEEN_LINES))
+ , nPercent(50)
+ , m_xCheckLB(m_xBuilder->weld_tree_view("list"))
+ , m_xEditPB(m_xBuilder->weld_button("edit"))
+{
+ m_xCheckLB->connect_changed(LINK(this, OfaSwAutoFmtOptionsPage, SelectHdl));
+ m_xCheckLB->connect_row_activated(LINK(this, OfaSwAutoFmtOptionsPage, DoubleClickEditHdl));
+
+ std::vector<int> aWidths
+ {
+ o3tl::narrowing<int>(m_xCheckLB->get_pixel_size(m_xCheckLB->get_column_title(0)).Width() * 2),
+ o3tl::narrowing<int>(m_xCheckLB->get_pixel_size(m_xCheckLB->get_column_title(1)).Width() * 2)
+ };
+ m_xCheckLB->set_column_fixed_widths(aWidths);
+
+ m_xEditPB->connect_clicked(LINK(this, OfaSwAutoFmtOptionsPage, EditHdl));
+}
+
+void OfaSwAutoFmtOptionsPage::CreateEntry(const OUString& rTxt, sal_uInt16 nCol)
+{
+ m_xCheckLB->append();
+ const int nRow = m_xCheckLB->n_children() - 1;
+ if (nCol == CBCOL_FIRST || nCol == CBCOL_BOTH)
+ m_xCheckLB->set_toggle(nRow, TRISTATE_FALSE, CBCOL_FIRST);
+ if (nCol == CBCOL_SECOND || nCol == CBCOL_BOTH)
+ m_xCheckLB->set_toggle(nRow, TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_text(nRow, rTxt, 2);
+}
+
+OfaSwAutoFmtOptionsPage::~OfaSwAutoFmtOptionsPage()
+{
+ delete weld::fromId<ImpUserData*>(m_xCheckLB->get_id(REPLACE_BULLETS));
+ delete weld::fromId<ImpUserData*>(m_xCheckLB->get_id(APPLY_NUMBERING));
+ delete weld::fromId<ImpUserData*>(m_xCheckLB->get_id(MERGE_SINGLE_LINE_PARA));
+}
+
+std::unique_ptr<SfxTabPage> OfaSwAutoFmtOptionsPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<OfaSwAutoFmtOptionsPage>(pPage, pController, *rAttrSet);
+}
+
+bool OfaSwAutoFmtOptionsPage::FillItemSet( SfxItemSet* )
+{
+ bool bModified = false;
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
+ ACFlags nFlags = pAutoCorrect->GetFlags();
+
+ bool bCheck = m_xCheckLB->get_toggle(USE_REPLACE_TABLE, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bAutoCorrect != bCheck;
+ pOpt->bAutoCorrect = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::Autocorrect,
+ m_xCheckLB->get_toggle(USE_REPLACE_TABLE, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ bCheck = m_xCheckLB->get_toggle(CORR_UPPER, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bCapitalStartWord != bCheck;
+ pOpt->bCapitalStartWord = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::CapitalStartWord,
+ m_xCheckLB->get_toggle(CORR_UPPER, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ bCheck = m_xCheckLB->get_toggle(BEGIN_UPPER, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bCapitalStartSentence != bCheck;
+ pOpt->bCapitalStartSentence = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::CapitalStartSentence,
+ m_xCheckLB->get_toggle(BEGIN_UPPER, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ bCheck = m_xCheckLB->get_toggle(BOLD_UNDERLINE, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bChgWeightUnderl != bCheck;
+ pOpt->bChgWeightUnderl = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgWeightUnderl,
+ m_xCheckLB->get_toggle(BOLD_UNDERLINE, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::IgnoreDoubleSpace,
+ m_xCheckLB->get_toggle(IGNORE_DBLSPACE, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::CorrectCapsLock,
+ m_xCheckLB->get_toggle(CORRECT_CAPS_LOCK, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ bCheck = m_xCheckLB->get_toggle(DETECT_URL, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bSetINetAttr != bCheck;
+ pOpt->bSetINetAttr = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::SetINetAttr,
+ m_xCheckLB->get_toggle(DETECT_URL, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ bCheck = m_xCheckLB->get_toggle(DETECT_DOI, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bSetDOIAttr != bCheck;
+ pOpt->bSetDOIAttr = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::SetDOIAttr,
+ m_xCheckLB->get_toggle(DETECT_DOI, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ bCheck = m_xCheckLB->get_toggle(DEL_EMPTY_NODE, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bDelEmptyNode != bCheck;
+ pOpt->bDelEmptyNode = bCheck;
+
+ bCheck = m_xCheckLB->get_toggle(REPLACE_USER_COLL, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bChgUserColl != bCheck;
+ pOpt->bChgUserColl = bCheck;
+
+ bCheck = m_xCheckLB->get_toggle(REPLACE_BULLETS, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bChgEnumNum != bCheck;
+ pOpt->bChgEnumNum = bCheck;
+ bModified |= aBulletFont != pOpt->aBulletFont;
+ pOpt->aBulletFont = aBulletFont;
+ bModified |= sBulletChar != OUString(&pOpt->cBullet, 1);
+ pOpt->cBullet = sBulletChar.iterateCodePoints(&o3tl::temporary(sal_Int32(0)));
+
+ bModified |= aByInputBulletFont != pOpt->aByInputBulletFont;
+ bModified |= sByInputBulletChar != OUString(&pOpt->cByInputBullet, 1);
+ pOpt->aByInputBulletFont = aByInputBulletFont;
+ pOpt->cByInputBullet = sByInputBulletChar.iterateCodePoints(&o3tl::temporary(sal_Int32(0)));
+
+ bCheck = m_xCheckLB->get_toggle(MERGE_SINGLE_LINE_PARA, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bRightMargin != bCheck;
+ pOpt->bRightMargin = bCheck;
+ bModified |= nPercent != pOpt->nRightMargin;
+ pOpt->nRightMargin = static_cast<sal_uInt8>(nPercent);
+
+ bCheck = m_xCheckLB->get_toggle(APPLY_NUMBERING, CBCOL_SECOND) == TRISTATE_TRUE;
+ bModified |= pOpt->bSetNumRule != bCheck;
+ pOpt->bSetNumRule = bCheck;
+
+ bCheck = m_xCheckLB->get_toggle(APPLY_NUMBERING_AFTER_SPACE, CBCOL_SECOND) == TRISTATE_TRUE;
+ bModified |= pOpt->bSetNumRuleAfterSpace != bCheck;
+ pOpt->bSetNumRuleAfterSpace = bCheck;
+
+ bCheck = m_xCheckLB->get_toggle(INSERT_BORDER, CBCOL_SECOND) == TRISTATE_TRUE;
+ bModified |= pOpt->bSetBorder != bCheck;
+ pOpt->bSetBorder = bCheck;
+
+ bCheck = m_xCheckLB->get_toggle(CREATE_TABLE, CBCOL_SECOND) == TRISTATE_TRUE;
+ bModified |= pOpt->bCreateTable != bCheck;
+ pOpt->bCreateTable = bCheck;
+
+ bCheck = m_xCheckLB->get_toggle(REPLACE_STYLES, CBCOL_SECOND) == TRISTATE_TRUE;
+ bModified |= pOpt->bReplaceStyles != bCheck;
+ pOpt->bReplaceStyles = bCheck;
+
+ bCheck = m_xCheckLB->get_toggle(REPLACE_DASHES, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bChgToEnEmDash != bCheck;
+ pOpt->bChgToEnEmDash = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgToEnEmDash,
+ m_xCheckLB->get_toggle(REPLACE_DASHES, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ bCheck = m_xCheckLB->get_toggle(DEL_SPACES_AT_STT_END, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bAFormatDelSpacesAtSttEnd != bCheck;
+ pOpt->bAFormatDelSpacesAtSttEnd = bCheck;
+ bCheck = m_xCheckLB->get_toggle(DEL_SPACES_AT_STT_END, CBCOL_SECOND) == TRISTATE_TRUE;
+ bModified |= pOpt->bAFormatByInpDelSpacesAtSttEnd != bCheck;
+ pOpt->bAFormatByInpDelSpacesAtSttEnd = bCheck;
+
+ bCheck = m_xCheckLB->get_toggle(DEL_SPACES_BETWEEN_LINES, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bAFormatDelSpacesBetweenLines != bCheck;
+ pOpt->bAFormatDelSpacesBetweenLines = bCheck;
+ bCheck = m_xCheckLB->get_toggle(DEL_SPACES_BETWEEN_LINES, CBCOL_SECOND) == TRISTATE_TRUE;
+ bModified |= pOpt->bAFormatByInpDelSpacesBetweenLines != bCheck;
+ pOpt->bAFormatByInpDelSpacesBetweenLines = bCheck;
+
+ if(bModified || nFlags != pAutoCorrect->GetFlags())
+ {
+ SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
+ rCfg.SetModified();
+ rCfg.Commit();
+ }
+
+ return true;
+}
+
+void OfaSwAutoFmtOptionsPage::ActivatePage( const SfxItemSet& )
+{
+ static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage(false);
+}
+
+void OfaSwAutoFmtOptionsPage::Reset( const SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
+ const ACFlags nFlags = pAutoCorrect->GetFlags();
+
+ aBulletFont = pOpt->aBulletFont;
+ sBulletChar = OUString(&pOpt->cBullet, 1);
+
+ aByInputBulletFont = pOpt->aByInputBulletFont;
+ sByInputBulletChar = OUString(&pOpt->cByInputBullet, 1);
+
+ nPercent = pOpt->nRightMargin;
+ sMargin = unicode::formatPercent(nPercent, Application::GetSettings().GetUILanguageTag());
+
+ m_xCheckLB->freeze();
+ m_xCheckLB->clear();
+
+ // The following entries have to be inserted in the same order
+ // as in the OfaAutoFmtOptions-enum!
+ CreateEntry(sUseReplaceTbl, CBCOL_BOTH );
+ CreateEntry(sCapitalStartWord, CBCOL_BOTH );
+ CreateEntry(sCapitalStartSentence, CBCOL_BOTH );
+ CreateEntry(sBoldUnder, CBCOL_BOTH );
+ CreateEntry(sDetectURL, CBCOL_BOTH );
+ CreateEntry(sDetectDOI, CBCOL_BOTH );
+ CreateEntry(sDash, CBCOL_BOTH );
+ CreateEntry(sDelSpaceAtSttEnd, CBCOL_BOTH );
+ CreateEntry(sDelSpaceBetweenLines, CBCOL_BOTH );
+
+ CreateEntry(sNoDblSpaces, CBCOL_SECOND);
+ CreateEntry(sCorrectCapsLock, CBCOL_SECOND);
+ CreateEntry(sNum.replaceFirst("%1", sBulletChar), CBCOL_SECOND);
+ CreateEntry(sBulletsAfterSpace, CBCOL_SECOND);
+ CreateEntry(sBorder, CBCOL_SECOND);
+ CreateEntry(sTable, CBCOL_SECOND);
+ CreateEntry(sReplaceTemplates, CBCOL_SECOND);
+ CreateEntry(sDeleteEmptyPara, CBCOL_FIRST );
+ CreateEntry(sUserStyle, CBCOL_FIRST );
+ CreateEntry(sBullet.replaceFirst("%1", sByInputBulletChar), CBCOL_FIRST);
+ CreateEntry(sRightMargin.replaceFirst("%1", sMargin), CBCOL_FIRST);
+
+ m_xCheckLB->set_toggle(USE_REPLACE_TABLE, pOpt->bAutoCorrect ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(USE_REPLACE_TABLE, bool(nFlags & ACFlags::Autocorrect) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(CORR_UPPER, pOpt->bCapitalStartWord ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(CORR_UPPER, bool(nFlags & ACFlags::CapitalStartWord) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(BEGIN_UPPER, pOpt->bCapitalStartSentence ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(BEGIN_UPPER, bool(nFlags & ACFlags::CapitalStartSentence) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(BOLD_UNDERLINE, pOpt->bChgWeightUnderl ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(BOLD_UNDERLINE, bool(nFlags & ACFlags::ChgWeightUnderl) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(DETECT_URL, pOpt->bSetINetAttr ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(DETECT_URL, bool(nFlags & ACFlags::SetINetAttr) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(DETECT_DOI, pOpt->bSetDOIAttr ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(DETECT_DOI, bool(nFlags & ACFlags::SetDOIAttr) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(REPLACE_DASHES, pOpt->bChgToEnEmDash ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(REPLACE_DASHES, bool(nFlags & ACFlags::ChgToEnEmDash) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(DEL_SPACES_AT_STT_END, pOpt->bAFormatDelSpacesAtSttEnd ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(DEL_SPACES_AT_STT_END, pOpt->bAFormatByInpDelSpacesAtSttEnd ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(DEL_SPACES_BETWEEN_LINES, pOpt->bAFormatDelSpacesBetweenLines ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(DEL_SPACES_BETWEEN_LINES, pOpt->bAFormatByInpDelSpacesBetweenLines ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(IGNORE_DBLSPACE, bool(nFlags & ACFlags::IgnoreDoubleSpace) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(CORRECT_CAPS_LOCK, bool(nFlags & ACFlags::CorrectCapsLock) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(APPLY_NUMBERING, pOpt->bSetNumRule ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(APPLY_NUMBERING_AFTER_SPACE, pOpt->bSetNumRuleAfterSpace ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(INSERT_BORDER, pOpt->bSetBorder ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(CREATE_TABLE, pOpt->bCreateTable ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(REPLACE_STYLES, pOpt->bReplaceStyles ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(DEL_EMPTY_NODE, pOpt->bDelEmptyNode ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(REPLACE_USER_COLL, pOpt->bChgUserColl ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(REPLACE_BULLETS, pOpt->bChgEnumNum ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(MERGE_SINGLE_LINE_PARA, pOpt->bRightMargin ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+
+ ImpUserData* pUserData = new ImpUserData(&sBulletChar, &aBulletFont);
+ OUString sId(weld::toId(pUserData));
+ m_xCheckLB->set_id(REPLACE_BULLETS, sId);
+
+ pUserData = new ImpUserData(&sMargin, nullptr);
+ sId = weld::toId(pUserData);
+ m_xCheckLB->set_id(MERGE_SINGLE_LINE_PARA, sId);
+
+ ImpUserData* pUserData2 = new ImpUserData(&sByInputBulletChar, &aByInputBulletFont);
+ sId = weld::toId(pUserData2);
+ m_xCheckLB->set_id(APPLY_NUMBERING, sId);
+
+ m_xCheckLB->thaw();
+}
+
+IMPL_LINK(OfaSwAutoFmtOptionsPage, SelectHdl, weld::TreeView&, rBox, void)
+{
+ m_xEditPB->set_sensitive(rBox.get_selected_id().toInt64() != 0);
+}
+
+IMPL_LINK_NOARG(OfaSwAutoFmtOptionsPage, DoubleClickEditHdl, weld::TreeView&, bool)
+{
+ EditHdl(*m_xEditPB);
+ return true;
+}
+
+IMPL_LINK_NOARG(OfaSwAutoFmtOptionsPage, EditHdl, weld::Button&, void)
+{
+ int nSelEntryPos = m_xCheckLB->get_selected_index();
+ if (nSelEntryPos == REPLACE_BULLETS || nSelEntryPos == APPLY_NUMBERING)
+ {
+ SvxCharacterMap aMapDlg(GetFrameWeld(), nullptr, nullptr);
+ ImpUserData* pUserData = weld::fromId<ImpUserData*>(m_xCheckLB->get_id(nSelEntryPos));
+ aMapDlg.SetCharFont(*pUserData->pFont);
+ aMapDlg.SetChar( (*pUserData->pString)[0] );
+ if (RET_OK == aMapDlg.run())
+ {
+ const vcl::Font& aFont(aMapDlg.GetCharFont());
+ *pUserData->pFont = aFont;
+ sal_UCS4 aChar = aMapDlg.GetChar();
+ // using the UCS4 constructor
+ OUString aOUStr( &aChar, 1 );
+ *pUserData->pString = aOUStr;
+ if (nSelEntryPos == REPLACE_BULLETS)
+ m_xCheckLB->set_text(nSelEntryPos, sNum.replaceFirst("%1", aOUStr), 2);
+ else
+ m_xCheckLB->set_text(nSelEntryPos, sBullet.replaceFirst("%1", aOUStr), 2);
+ }
+ }
+ else if( MERGE_SINGLE_LINE_PARA == nSelEntryPos )
+ {
+ // dialog for per cent settings
+ OfaAutoFmtPrcntSet aDlg(GetFrameWeld());
+ aDlg.GetPrcntFld().set_value(nPercent, FieldUnit::PERCENT);
+ if (aDlg.run() == RET_OK)
+ {
+ nPercent = static_cast<sal_uInt16>(aDlg.GetPrcntFld().get_value(FieldUnit::PERCENT));
+ sMargin = unicode::formatPercent(nPercent, Application::GetSettings().GetUILanguageTag());
+ m_xCheckLB->set_text(nSelEntryPos, sRightMargin.replaceFirst("%1", sMargin), 2);
+ }
+ }
+}
+
+
+OfaAutocorrReplacePage::OfaAutocorrReplacePage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/acorreplacepage.ui", "AcorReplacePage", &rSet)
+ , maCompareClass(comphelper::getProcessComponentContext())
+ , eLang(eLastDialogLanguage)
+ , bHasSelectionText(false)
+ , bFirstSelect(true)
+ , bReplaceEditChanged(false)
+ , bSWriter(true)
+ , m_xTextOnlyCB(m_xBuilder->weld_check_button("textonly"))
+ , m_xShortED(m_xBuilder->weld_entry("origtext"))
+ , m_xReplaceED(m_xBuilder->weld_entry("newtext"))
+ , m_xReplaceTLB(m_xBuilder->weld_tree_view("tabview"))
+ , m_xNewReplacePB(m_xBuilder->weld_button("new"))
+ , m_xReplacePB(m_xBuilder->weld_button("replace"))
+ , m_xDeleteReplacePB(m_xBuilder->weld_button("delete"))
+ , m_xButtonBox(m_xBuilder->weld_container("buttonbox"))
+{
+ sNew = m_xNewReplacePB->get_label();
+ sModify = m_xReplacePB->get_label();
+
+ // lock down the width of the button box to its max
+ // desired width
+ auto nMaxWidth = m_xButtonBox->get_preferred_size().Width();
+ m_xButtonBox->set_size_request(nMaxWidth, -1);
+ m_xReplacePB->hide();
+
+ // tdf#125348 set some small but fixed initial width size, final width will
+ // depend on the size of the entry boxes
+ m_xReplaceTLB->set_size_request(42, m_xReplaceTLB->get_height_rows(10));
+
+ SfxModule *pMod = SfxApplication::GetModule(SfxToolsModule::Writer);
+ bSWriter = pMod == SfxModule::GetActiveModule();
+
+ LanguageTag aLanguageTag( eLastDialogLanguage );
+ maCompareClass.loadDefaultCollator( aLanguageTag.getLocale(), 0 );
+ pCharClass.reset( new CharClass( std::move(aLanguageTag) ) );
+
+ auto nColWidth = m_xReplaceTLB->get_approximate_digit_width() * 32;
+ m_aReplaceFixedWidths.push_back(nColWidth);
+ m_aReplaceFixedWidths.push_back(nColWidth);
+
+ m_xReplaceTLB->connect_changed( LINK(this, OfaAutocorrReplacePage, SelectHdl) );
+ m_xNewReplacePB->connect_clicked( LINK(this, OfaAutocorrReplacePage, NewDelButtonHdl) );
+ m_xDeleteReplacePB->connect_clicked( LINK(this, OfaAutocorrReplacePage, NewDelButtonHdl) );
+ m_xShortED->connect_changed( LINK(this, OfaAutocorrReplacePage, ModifyHdl) );
+ m_xReplaceED->connect_changed( LINK(this, OfaAutocorrReplacePage, ModifyHdl) );
+ m_xShortED->connect_activate( LINK(this, OfaAutocorrReplacePage, NewDelActionHdl) );
+ m_xReplaceED->connect_activate( LINK(this, OfaAutocorrReplacePage, NewDelActionHdl) );
+ m_xShortED->connect_size_allocate(LINK(this, OfaAutocorrReplacePage, EntrySizeAllocHdl));
+ m_xReplaceED->connect_size_allocate(LINK(this, OfaAutocorrReplacePage, EntrySizeAllocHdl));
+}
+
+OfaAutocorrReplacePage::~OfaAutocorrReplacePage()
+{
+ aDoubleStringTable.clear();
+ aChangesTable.clear();
+
+ pCharClass.reset();
+}
+
+std::unique_ptr<SfxTabPage> OfaAutocorrReplacePage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<OfaAutocorrReplacePage>(pPage, pController, *rSet);
+}
+
+void OfaAutocorrReplacePage::ActivatePage( const SfxItemSet& )
+{
+ if(eLang != eLastDialogLanguage)
+ SetLanguage(eLastDialogLanguage);
+ static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage(true);
+}
+
+DeactivateRC OfaAutocorrReplacePage::DeactivatePage( SfxItemSet* )
+{
+ return DeactivateRC::LeavePage;
+}
+
+bool OfaAutocorrReplacePage::FillItemSet( SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+
+ for (StringChangeTable::reverse_iterator it = aChangesTable.rbegin(); it != aChangesTable.rend(); ++it)
+ {
+ LanguageType eCurrentLang = it->first;
+ StringChangeList& rStringChangeList = it->second;
+ std::vector<SvxAutocorrWord> aDeleteWords;
+ std::vector<SvxAutocorrWord> aNewWords;
+
+ aDeleteWords.reserve( rStringChangeList.aDeletedEntries.size() );
+ for (const DoubleString & deleteEntry : rStringChangeList.aDeletedEntries)
+ {
+ SvxAutocorrWord aDeleteWord( deleteEntry.sShort, deleteEntry.sLong );
+ aDeleteWords.push_back( aDeleteWord );
+ }
+
+ aNewWords.reserve( rStringChangeList.aNewEntries.size() );
+ for (const DoubleString & newEntry : rStringChangeList.aNewEntries)
+ {
+ //fdo#67697 if the user data is set then we want to retain the
+ //source formatting of the entry, so don't use the optimized
+ //text-only MakeCombinedChanges for this entry
+ bool bKeepSourceFormatting = newEntry.pUserData == &bHasSelectionText;
+ if (bKeepSourceFormatting)
+ {
+ if (SfxObjectShell* pSh = SfxObjectShell::Current())
+ pAutoCorrect->PutText(newEntry.sShort, *pSh, eCurrentLang);
+ continue;
+ }
+
+ SvxAutocorrWord aNewWord( newEntry.sShort, newEntry.sLong );
+ aNewWords.push_back( aNewWord );
+ }
+ pAutoCorrect->MakeCombinedChanges( aNewWords, aDeleteWords, eCurrentLang );
+ }
+ aChangesTable.clear();
+ return false;
+}
+
+void OfaAutocorrReplacePage::RefillReplaceBox(bool bFromReset,
+ LanguageType eOldLanguage,
+ LanguageType eNewLanguage)
+{
+ eLang = eNewLanguage;
+ if(bFromReset)
+ {
+ aDoubleStringTable.clear();
+ aChangesTable.clear();
+ }
+ else
+ {
+ DoubleStringArray* pArray;
+ if(aDoubleStringTable.find(eOldLanguage) != aDoubleStringTable.end())
+ {
+ pArray = &aDoubleStringTable[eOldLanguage];
+ pArray->clear();
+ }
+ else
+ {
+ pArray = &aDoubleStringTable[eOldLanguage]; // create new array
+ }
+
+ m_xReplaceTLB->all_foreach([this, &pArray](weld::TreeIter& rIter) {
+ pArray->push_back(DoubleString(m_xReplaceTLB->get_text(rIter, 0),
+ m_xReplaceTLB->get_text(rIter, 1)));
+ DoubleString& rDouble = pArray->back();
+ rDouble.pUserData = weld::fromId<void*>(m_xReplaceTLB->get_id(rIter));
+ return false;
+ });
+ }
+
+ if( !bSWriter )
+ aFormatText.clear();
+
+ if (aDoubleStringTable.find(eLang) != aDoubleStringTable.end())
+ {
+ DoubleStringArray& rArray = aDoubleStringTable[eNewLanguage];
+
+ m_xReplaceTLB->bulk_insert_for_each(rArray.size(), [this, &rArray](weld::TreeIter& rIter, int nIndex) {
+ DoubleString &rDouble = rArray[nIndex];
+ bool bTextOnly = nullptr == rDouble.pUserData;
+ // formatted text is only in Writer
+ if (bSWriter || bTextOnly)
+ {
+ if (!bTextOnly)
+ {
+ // that means: with format info or even with selection text
+ OUString sId = weld::toId(rDouble.pUserData);
+ m_xReplaceTLB->set_id(rIter, sId);
+ }
+ m_xReplaceTLB->set_text(rIter, rDouble.sShort, 0);
+ m_xReplaceTLB->set_text(rIter, rDouble.sLong, 1);
+ }
+ else
+ {
+ aFormatText.insert(rDouble.sShort);
+ }
+ }, nullptr, &m_aReplaceFixedWidths);
+ }
+ else
+ {
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ SvxAutocorrWordList* pWordList = pAutoCorrect->LoadAutocorrWordList(eLang);
+ const SvxAutocorrWordList::AutocorrWordSetType & rContent = pWordList->getSortedContent();
+ m_xReplaceTLB->bulk_insert_for_each(rContent.size(), [this, rContent](weld::TreeIter& rIter, int nIndex) {
+ auto const& elem = rContent[nIndex];
+ bool bTextOnly = elem.IsTextOnly();
+ // formatted text is only in Writer
+ if (bSWriter || bTextOnly)
+ {
+ if (!bTextOnly)
+ {
+ // that means: with format info or even with selection text
+ OUString sId = weld::toId(m_xTextOnlyCB.get());
+ m_xReplaceTLB->set_id(rIter, sId);
+ }
+ m_xReplaceTLB->set_text(rIter, elem.GetShort(), 0);
+ m_xReplaceTLB->set_text(rIter, elem.GetLong(), 1);
+ }
+ else
+ {
+ aFormatText.insert(elem.GetShort());
+ }
+ }, nullptr, &m_aReplaceFixedWidths);
+ m_xNewReplacePB->set_sensitive(false);
+ m_xDeleteReplacePB->set_sensitive(false);
+ }
+
+ SfxViewShell* pViewShell = SfxViewShell::Current();
+ if (pViewShell && pViewShell->HasSelection())
+ {
+ bHasSelectionText = true;
+ const OUString sSelection( pViewShell->GetSelectionText() );
+ m_xReplaceED->set_text(sSelection);
+ m_xTextOnlyCB->set_active(!bSWriter);
+ m_xTextOnlyCB->set_sensitive(bSWriter && !sSelection.isEmpty());
+ }
+ else
+ {
+ m_xTextOnlyCB->set_active(true);
+ m_xTextOnlyCB->set_sensitive(false);
+ }
+}
+
+void OfaAutocorrReplacePage::Reset( const SfxItemSet* )
+{
+ RefillReplaceBox(true, eLang, eLang);
+ m_xShortED->grab_focus();
+}
+
+void OfaAutocorrReplacePage::SetLanguage(LanguageType eSet)
+{
+ //save old settings and refill
+ if(eSet != eLang)
+ {
+ RefillReplaceBox(false, eLang, eSet);
+ eLastDialogLanguage = eSet;
+
+ LanguageTag aLanguageTag( eLastDialogLanguage );
+ maCompareClass = CollatorWrapper( comphelper::getProcessComponentContext() );
+ maCompareClass.loadDefaultCollator( aLanguageTag.getLocale(), 0 );
+ pCharClass.reset( new CharClass( std::move(aLanguageTag) ) );
+ ModifyHdl(*m_xShortED);
+ }
+}
+
+IMPL_LINK(OfaAutocorrReplacePage, SelectHdl, weld::TreeView&, rBox, void)
+{
+ if(!bFirstSelect || !bHasSelectionText)
+ {
+ int nEntry = rBox.get_selected_index();
+ OUString sTmpShort(rBox.get_text(nEntry, 0));
+ // if the text is set via ModifyHdl, the cursor is always at the beginning
+ // of a word, although you're editing here
+ bool bSameContent = 0 == maCompareClass.compareString(sTmpShort, m_xShortED->get_text());
+ int nStartPos, nEndPos;
+ m_xShortED->get_selection_bounds(nStartPos, nEndPos);
+ if (m_xShortED->get_text() != sTmpShort)
+ {
+ m_xShortED->set_text(sTmpShort);
+ // if it was only a different notation, the selection has to be set again
+ if (bSameContent)
+ {
+ m_xShortED->select_region(nStartPos, nEndPos);
+ }
+ }
+ m_xReplaceED->set_text(rBox.get_text(nEntry, 1));
+ // with UserData there is a Formatinfo
+ m_xTextOnlyCB->set_active(rBox.get_id(nEntry).isEmpty());
+ }
+ else
+ {
+ bFirstSelect = false;
+ }
+
+ m_xNewReplacePB->set_sensitive(false);
+ m_xDeleteReplacePB->set_sensitive(true);
+};
+
+void OfaAutocorrReplacePage::NewEntry(const OUString& sShort, const OUString& sLong, bool bKeepSourceFormatting)
+{
+ DoubleStringArray& rNewArray = aChangesTable[eLang].aNewEntries;
+ for (size_t i = 0; i < rNewArray.size(); i++)
+ {
+ if (rNewArray[i].sShort == sShort)
+ {
+ rNewArray.erase(rNewArray.begin() + i);
+ break;
+ }
+ }
+
+ DoubleStringArray& rDeletedArray = aChangesTable[eLang].aDeletedEntries;
+ for (size_t i = 0; i < rDeletedArray.size(); i++)
+ {
+ if (rDeletedArray[i].sShort == sShort)
+ {
+ rDeletedArray.erase(rDeletedArray.begin() + i);
+ break;
+ }
+ }
+
+ DoubleString aNewString(sShort, sLong);
+ rNewArray.push_back(aNewString);
+ if (bKeepSourceFormatting)
+ rNewArray.back().pUserData = &bHasSelectionText;
+}
+
+void OfaAutocorrReplacePage::DeleteEntry(const OUString& sShort, const OUString& sLong)
+{
+ DoubleStringArray& rNewArray = aChangesTable[eLang].aNewEntries;
+ for (size_t i = 0; i < rNewArray.size(); i++)
+ {
+ if (rNewArray[i].sShort == sShort)
+ {
+ rNewArray.erase(rNewArray.begin() + i);
+ break;
+ }
+ }
+
+ DoubleStringArray& rDeletedArray = aChangesTable[eLang].aDeletedEntries;
+ for (size_t i = 0; i < rDeletedArray.size(); i++)
+ {
+ if (rDeletedArray[i].sShort == sShort)
+ {
+ rDeletedArray.erase(rDeletedArray.begin() + i);
+ break;
+ }
+ }
+
+ DoubleString aDeletedString(sShort, sLong);
+ rDeletedArray.push_back(aDeletedString);
+}
+
+IMPL_LINK(OfaAutocorrReplacePage, NewDelButtonHdl, weld::Button&, rBtn, void)
+{
+ NewDelHdl(&rBtn);
+}
+
+IMPL_LINK(OfaAutocorrReplacePage, NewDelActionHdl, weld::Entry&, rEdit, bool)
+{
+ return NewDelHdl(&rEdit);
+}
+
+IMPL_LINK_NOARG(OfaAutocorrReplacePage, EntrySizeAllocHdl, const Size&, void)
+{
+ m_aReplaceFixedWidths.clear();
+ int x, y, width, height;
+ if (m_xReplaceED->get_extents_relative_to(*m_xReplaceTLB, x, y, width, height))
+ {
+ m_aReplaceFixedWidths.push_back(x);
+ m_aReplaceFixedWidths.push_back(width - 1);
+ m_xReplaceTLB->set_column_fixed_widths(m_aReplaceFixedWidths);
+ }
+}
+
+bool OfaAutocorrReplacePage::NewDelHdl(const weld::Widget* pBtn)
+{
+ int nEntry = m_xReplaceTLB->get_selected_index();
+ if (pBtn == m_xDeleteReplacePB.get())
+ {
+ DBG_ASSERT( nEntry != -1, "no entry selected" );
+ if (nEntry != -1)
+ {
+ DeleteEntry(m_xReplaceTLB->get_text(nEntry, 0), m_xReplaceTLB->get_text(nEntry, 1));
+ m_xReplaceTLB->remove(nEntry);
+ ModifyHdl(*m_xShortED);
+ return true;
+ }
+ }
+
+ if (pBtn == m_xNewReplacePB.get() || m_xNewReplacePB->get_sensitive())
+ {
+ OUString sEntry(m_xShortED->get_text());
+ if (!sEntry.isEmpty() && (!m_xReplaceED->get_text().isEmpty() ||
+ ( bHasSelectionText && bSWriter ) ))
+ {
+ bool bKeepSourceFormatting = !bReplaceEditChanged && !m_xTextOnlyCB->get_active();
+
+ NewEntry(m_xShortED->get_text(), m_xReplaceED->get_text(), bKeepSourceFormatting);
+ m_xReplaceTLB->freeze();
+ int nPos = -1;
+ if (nEntry != -1)
+ {
+ nPos = nEntry;
+ m_xReplaceTLB->remove(nEntry);
+ }
+ else
+ {
+ int j;
+ int nCount = m_xReplaceTLB->n_children();
+ for (j = 0; j < nCount; ++j)
+ {
+ if (0 >= maCompareClass.compareString(sEntry, m_xReplaceTLB->get_text(j, 0)))
+ break;
+ }
+ nPos = j;
+ }
+
+ OUString sId;
+ if (bKeepSourceFormatting)
+ {
+ sId = weld::toId(&bHasSelectionText); // new formatted text
+ }
+
+ m_xReplaceTLB->insert(nPos, sEntry, &sId, nullptr, nullptr);
+ m_xReplaceTLB->set_text(nPos, m_xReplaceED->get_text(), 1);
+ m_xReplaceTLB->thaw();
+ m_xReplaceTLB->scroll_to_row(nPos);
+ // if the request came from the ReplaceEdit, give focus to the ShortEdit
+ if (m_xReplaceED->has_focus())
+ {
+ m_xShortED->grab_focus();
+ }
+ }
+ }
+ else
+ {
+ // this can only be an enter in one of the two edit fields
+ // which means EndDialog() - has to be evaluated in KeyInput
+ return false;
+ }
+ ModifyHdl(*m_xShortED);
+ return true;
+}
+
+IMPL_LINK(OfaAutocorrReplacePage, ModifyHdl, weld::Entry&, rEdt, void)
+{
+ std::unique_ptr<weld::TreeIter> xFirstSel(m_xReplaceTLB->make_iterator());
+ bool bFirstSelIterSet = m_xReplaceTLB->get_selected(xFirstSel.get());
+ bool bShort = &rEdt == m_xShortED.get();
+ const OUString rEntry = rEdt.get_text();
+ const OUString rRepString = m_xReplaceED->get_text();
+ OUString aWordStr(pCharClass->lowercase(rEntry));
+
+ if(bShort)
+ {
+ if(!rEntry.isEmpty())
+ {
+ bool bFound = false;
+ bool bTmpSelEntry=false;
+
+ m_xReplaceTLB->all_foreach([this, &rEntry, &rRepString, &bFound,
+ &bTmpSelEntry, &bFirstSelIterSet,
+ &xFirstSel, &aWordStr](weld::TreeIter& rIter){
+ OUString aTestStr = m_xReplaceTLB->get_text(rIter, 0);
+ if( maCompareClass.compareString(rEntry, aTestStr ) == 0 )
+ {
+ if (!rRepString.isEmpty())
+ bFirstSelect = true;
+ m_xReplaceTLB->set_cursor(rIter);
+ m_xReplaceTLB->copy_iterator(rIter, *xFirstSel);
+ bFirstSelIterSet = true;
+ m_xNewReplacePB->set_label(sModify);
+ bFound = true;
+ return true;
+ }
+ else
+ {
+ aTestStr = pCharClass->lowercase( aTestStr );
+ if( aTestStr.startsWith(aWordStr) && !bTmpSelEntry )
+ {
+ m_xReplaceTLB->scroll_to_row(rIter);
+ bTmpSelEntry = true;
+ }
+ }
+ return false;
+ });
+ if( !bFound )
+ {
+ m_xReplaceTLB->select(-1);
+ bFirstSelIterSet = false;
+ m_xNewReplacePB->set_label(sNew);
+ if( bReplaceEditChanged )
+ m_xTextOnlyCB->set_sensitive(false);
+ }
+ m_xDeleteReplacePB->set_sensitive(bFound);
+ }
+ else if (m_xReplaceTLB->n_children() > 0)
+ {
+ m_xReplaceTLB->scroll_to_row(0);
+ }
+
+ }
+ else if( !bShort )
+ {
+ bReplaceEditChanged = true;
+ if (bFirstSelIterSet)
+ {
+ m_xNewReplacePB->set_label(sModify);
+ }
+ }
+
+ const OUString& rShortTxt = m_xShortED->get_text();
+ bool bEnableNew = !rShortTxt.isEmpty() &&
+ ( !rRepString.isEmpty() ||
+ ( bHasSelectionText && bSWriter )) &&
+ ( !bFirstSelIterSet || rRepString !=
+ m_xReplaceTLB->get_text(*xFirstSel, 1) );
+ if( bEnableNew )
+ {
+ for (auto const& elem : aFormatText)
+ {
+ if(elem == rShortTxt)
+ {
+ bEnableNew = false;
+ break;
+ }
+ }
+ }
+ m_xNewReplacePB->set_sensitive(bEnableNew);
+}
+
+static bool lcl_FindInArray(std::vector<OUString>& rStrings, std::u16string_view rString)
+{
+ for (auto const& elem : rStrings)
+ {
+ if(elem == rString)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+OfaAutocorrExceptPage::OfaAutocorrExceptPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/acorexceptpage.ui", "AcorExceptPage", &rSet)
+ , maCompareClass(comphelper::getProcessComponentContext())
+ , eLang(eLastDialogLanguage)
+ , m_xAbbrevED(m_xBuilder->weld_entry("abbrev"))
+ , m_xAbbrevLB(m_xBuilder->weld_tree_view("abbrevlist"))
+ , m_xNewAbbrevPB(m_xBuilder->weld_button("newabbrev"))
+ , m_xDelAbbrevPB(m_xBuilder->weld_button("delabbrev"))
+ , m_xAutoAbbrevCB(m_xBuilder->weld_check_button("autoabbrev"))
+ , m_xDoubleCapsED(m_xBuilder->weld_entry("double"))
+ , m_xDoubleCapsLB(m_xBuilder->weld_tree_view("doublelist"))
+ , m_xNewDoublePB(m_xBuilder->weld_button("newdouble"))
+ , m_xDelDoublePB(m_xBuilder->weld_button("deldouble"))
+ , m_xAutoCapsCB(m_xBuilder->weld_check_button("autodouble"))
+{
+ m_xAbbrevLB->make_sorted();
+ m_xAbbrevLB->set_size_request(-1, m_xAbbrevLB->get_height_rows(6));
+
+ m_xDoubleCapsLB->make_sorted();
+ m_xDoubleCapsLB->set_size_request(-1, m_xDoubleCapsLB->get_height_rows(6));
+
+ css::lang::Locale aLcl( LanguageTag::convertToLocale(eLastDialogLanguage ));
+ maCompareClass.loadDefaultCollator( aLcl, 0 );
+
+ m_xNewAbbrevPB->connect_clicked(LINK(this, OfaAutocorrExceptPage, NewDelButtonHdl));
+ m_xDelAbbrevPB->connect_clicked(LINK(this, OfaAutocorrExceptPage, NewDelButtonHdl));
+ m_xNewDoublePB->connect_clicked(LINK(this, OfaAutocorrExceptPage, NewDelButtonHdl));
+ m_xDelDoublePB->connect_clicked(LINK(this, OfaAutocorrExceptPage, NewDelButtonHdl));
+
+ m_xAbbrevLB->connect_changed(LINK(this, OfaAutocorrExceptPage, SelectHdl));
+ m_xDoubleCapsLB->connect_changed(LINK(this, OfaAutocorrExceptPage, SelectHdl));
+ m_xAbbrevED->connect_changed(LINK(this, OfaAutocorrExceptPage, ModifyHdl));
+ m_xDoubleCapsED->connect_changed(LINK(this, OfaAutocorrExceptPage, ModifyHdl));
+
+ m_xAbbrevED->connect_activate(LINK(this, OfaAutocorrExceptPage, NewDelActionHdl));
+ m_xDoubleCapsED->connect_activate(LINK(this, OfaAutocorrExceptPage, NewDelActionHdl));
+}
+
+OfaAutocorrExceptPage::~OfaAutocorrExceptPage()
+{
+ aStringsTable.clear();
+}
+
+std::unique_ptr<SfxTabPage> OfaAutocorrExceptPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rSet)
+{
+ return std::make_unique<OfaAutocorrExceptPage>(pPage, pController, *rSet);
+}
+
+void OfaAutocorrExceptPage::ActivatePage( const SfxItemSet& )
+{
+ if(eLang != eLastDialogLanguage)
+ SetLanguage(eLastDialogLanguage);
+ static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage(true);
+}
+
+DeactivateRC OfaAutocorrExceptPage::DeactivatePage( SfxItemSet* )
+{
+ return DeactivateRC::LeavePage;
+}
+
+bool OfaAutocorrExceptPage::FillItemSet( SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ for(StringsTable::reverse_iterator it1 = aStringsTable.rbegin(); it1 != aStringsTable.rend(); ++it1)
+ {
+ LanguageType eCurLang = it1->first;
+ StringsArrays& rArrays = it1->second;
+ if(eCurLang != eLang) // current language is treated later
+ {
+ SvStringsISortDtor* pWrdList = pAutoCorrect->LoadWordStartExceptList(eCurLang);
+
+ if(pWrdList)
+ {
+ size_t nCount = pWrdList->size();
+ size_t i;
+ for( i = nCount; i; )
+ {
+ OUString aString = (*pWrdList)[ --i ];
+
+ if( !lcl_FindInArray(rArrays.aDoubleCapsStrings, aString))
+ {
+ pWrdList->erase_at(i);
+ }
+ }
+
+ for (auto const& elem : rArrays.aDoubleCapsStrings)
+ {
+ pWrdList->insert(elem);
+ }
+ pAutoCorrect->SaveWordStartExceptList(eCurLang);
+ }
+
+ SvStringsISortDtor* pCplList = pAutoCorrect->LoadCplSttExceptList(eCurLang);
+
+ if(pCplList)
+ {
+ size_t nCount = pCplList->size();
+ size_t i;
+ for( i = nCount; i; )
+ {
+ OUString aString = (*pCplList)[ --i ];
+ if( !lcl_FindInArray(rArrays.aAbbrevStrings, aString))
+ {
+ pCplList->erase_at(i);
+ }
+ }
+
+ for (auto const& elem : rArrays.aAbbrevStrings)
+ {
+ pCplList->insert(elem);
+ }
+
+ pAutoCorrect->SaveCplSttExceptList(eCurLang);
+ }
+ }
+ }
+ aStringsTable.clear();
+
+ SvStringsISortDtor* pWrdList = pAutoCorrect->LoadWordStartExceptList(eLang);
+
+ if(pWrdList)
+ {
+ size_t nCount = pWrdList->size();
+ size_t i;
+ for( i = nCount; i; )
+ {
+ OUString aString = (*pWrdList)[ --i ];
+ if (m_xDoubleCapsLB->find_text(aString) == -1)
+ {
+ pWrdList->erase_at(i);
+ }
+ }
+ nCount = m_xDoubleCapsLB->n_children();
+ for( i = 0; i < nCount; ++i )
+ {
+ pWrdList->insert(m_xDoubleCapsLB->get_text(i));
+ }
+ pAutoCorrect->SaveWordStartExceptList(eLang);
+ }
+
+ SvStringsISortDtor* pCplList = pAutoCorrect->LoadCplSttExceptList(eLang);
+
+ if(pCplList)
+ {
+ size_t nCount = pCplList->size();
+ for( size_t i = nCount; i; )
+ {
+ OUString aString = (*pCplList)[ --i ];
+ if (m_xAbbrevLB->find_text(aString) == -1)
+ {
+ pCplList->erase_at(i);
+ }
+ }
+ sal_Int32 nAbbrevCount = m_xAbbrevLB->n_children();
+ for( sal_Int32 ia = 0; ia < nAbbrevCount; ++ia )
+ {
+ pCplList->insert(m_xAbbrevLB->get_text(ia));
+ }
+ pAutoCorrect->SaveCplSttExceptList(eLang);
+ }
+ if (m_xAutoAbbrevCB->get_state_changed_from_saved())
+ pAutoCorrect->SetAutoCorrFlag( ACFlags::SaveWordCplSttLst, m_xAutoAbbrevCB->get_active());
+ if (m_xAutoCapsCB->get_state_changed_from_saved())
+ pAutoCorrect->SetAutoCorrFlag( ACFlags::SaveWordWordStartLst, m_xAutoCapsCB->get_active());
+ return false;
+}
+
+void OfaAutocorrExceptPage::SetLanguage(LanguageType eSet)
+{
+ if(eLang != eSet)
+ {
+ // save old settings and fill anew
+ RefillReplaceBoxes(false, eLang, eSet);
+ eLastDialogLanguage = eSet;
+ maCompareClass = CollatorWrapper( comphelper::getProcessComponentContext() );
+ maCompareClass.loadDefaultCollator( LanguageTag::convertToLocale( eLastDialogLanguage ), 0 );
+ ModifyHdl(*m_xAbbrevED);
+ ModifyHdl(*m_xDoubleCapsED);
+ }
+}
+
+void OfaAutocorrExceptPage::RefillReplaceBoxes(bool bFromReset,
+ LanguageType eOldLanguage,
+ LanguageType eNewLanguage)
+{
+ eLang = eNewLanguage;
+ if(bFromReset)
+ {
+ aStringsTable.clear();
+ }
+ else
+ {
+ StringsArrays* pArrays;
+ if(aStringsTable.find(eOldLanguage) != aStringsTable.end())
+ {
+ pArrays = &aStringsTable[eOldLanguage];
+ pArrays->aAbbrevStrings.clear();
+ pArrays->aDoubleCapsStrings.clear();
+ }
+ else
+ {
+ pArrays = &aStringsTable[eOldLanguage]; // create new array
+ }
+
+ sal_Int32 i, nCount;
+ nCount = m_xAbbrevLB->n_children();
+ for(i = 0; i < nCount; i++)
+ pArrays->aAbbrevStrings.push_back(m_xAbbrevLB->get_text(i));
+
+ nCount = m_xDoubleCapsLB->n_children();
+ for(i = 0; i < nCount; i++)
+ pArrays->aDoubleCapsStrings.push_back(m_xDoubleCapsLB->get_text(i));
+ }
+ m_xDoubleCapsLB->clear();
+ m_xAbbrevLB->clear();
+ m_xAbbrevED->set_text("");
+ m_xDoubleCapsED->set_text("");
+
+ if(aStringsTable.find(eLang) != aStringsTable.end())
+ {
+ StringsArrays& rArrays = aStringsTable[eLang];
+ for (auto const& elem : rArrays.aAbbrevStrings)
+ m_xAbbrevLB->append_text(elem);
+
+ for (auto const& elem : rArrays.aDoubleCapsStrings)
+ m_xDoubleCapsLB->append_text(elem);
+ }
+ else
+ {
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ const SvStringsISortDtor* pCplList = pAutoCorrect->GetCplSttExceptList(eLang);
+ const SvStringsISortDtor* pWrdList = pAutoCorrect->GetWordStartExceptList(eLang);
+ size_t i;
+ for( i = 0; i < pCplList->size(); i++ )
+ {
+ m_xAbbrevLB->append_text((*pCplList)[i]);
+ }
+ for( i = 0; i < pWrdList->size(); i++ )
+ {
+ m_xDoubleCapsLB->append_text((*pWrdList)[i]);
+ }
+ }
+}
+
+void OfaAutocorrExceptPage::Reset( const SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ RefillReplaceBoxes(true, eLang, eLang);
+ m_xAutoAbbrevCB->set_active(pAutoCorrect->IsAutoCorrFlag( ACFlags::SaveWordCplSttLst));
+ m_xAutoCapsCB->set_active(pAutoCorrect->IsAutoCorrFlag( ACFlags::SaveWordWordStartLst));
+ m_xAutoAbbrevCB->save_state();
+ m_xAutoCapsCB->save_state();
+}
+
+IMPL_LINK(OfaAutocorrExceptPage, NewDelButtonHdl, weld::Button&, rBtn, void)
+{
+ NewDelHdl(&rBtn);
+}
+
+IMPL_LINK(OfaAutocorrExceptPage, NewDelActionHdl, weld::Entry&, rEdit, bool)
+{
+ return NewDelHdl(&rEdit);
+}
+
+bool OfaAutocorrExceptPage::NewDelHdl(const weld::Widget* pBtn)
+{
+ if ((pBtn == m_xNewAbbrevPB.get() || pBtn == m_xAbbrevED.get())
+ && !m_xAbbrevED->get_text().isEmpty() && m_xNewAbbrevPB->get_sensitive())
+ {
+ m_xAbbrevLB->append_text(m_xAbbrevED->get_text());
+ ModifyHdl(*m_xAbbrevED);
+ }
+ else if(pBtn == m_xDelAbbrevPB.get())
+ {
+ m_xAbbrevLB->remove_text(m_xAbbrevED->get_text());
+ ModifyHdl(*m_xAbbrevED);
+ }
+ else if((pBtn == m_xNewDoublePB.get() || pBtn == m_xDoubleCapsED.get() )
+ && !m_xDoubleCapsED->get_text().isEmpty() && m_xNewDoublePB->get_sensitive())
+ {
+ m_xDoubleCapsLB->append_text(m_xDoubleCapsED->get_text());
+ ModifyHdl(*m_xDoubleCapsED);
+ }
+ else if (pBtn == m_xDelDoublePB.get())
+ {
+ m_xDoubleCapsLB->remove_text(m_xDoubleCapsED->get_text());
+ ModifyHdl(*m_xDoubleCapsED);
+ }
+ else
+ {
+ // we didn't do anything, if this was because of 'activate' in an
+ // entry then let it continue to close the dialog like the replace
+ // page does
+ return false;
+ }
+ return true;
+}
+
+IMPL_LINK(OfaAutocorrExceptPage, SelectHdl, weld::TreeView&, rBox, void)
+{
+ if (&rBox == m_xAbbrevLB.get())
+ {
+ m_xAbbrevED->set_text(rBox.get_selected_text());
+ m_xNewAbbrevPB->set_sensitive(false);
+ m_xDelAbbrevPB->set_sensitive(true);
+ }
+ else
+ {
+ m_xDoubleCapsED->set_text(rBox.get_selected_text());
+ m_xNewDoublePB->set_sensitive(false);
+ m_xDelDoublePB->set_sensitive(true);
+ }
+}
+
+IMPL_LINK(OfaAutocorrExceptPage, ModifyHdl, weld::Entry&, rEdt, void)
+{
+ const OUString& sEntry = rEdt.get_text();
+ bool bEntryLen = !sEntry.isEmpty();
+ if (&rEdt == m_xAbbrevED.get())
+ {
+ bool bSame = lcl_FindEntry(*m_xAbbrevLB, sEntry, maCompareClass);
+ if(bSame && sEntry != m_xAbbrevLB->get_selected_text())
+ rEdt.set_text(m_xAbbrevLB->get_selected_text());
+ m_xNewAbbrevPB->set_sensitive(!bSame && bEntryLen);
+ m_xDelAbbrevPB->set_sensitive(bSame && bEntryLen);
+ }
+ else
+ {
+ bool bSame = lcl_FindEntry(*m_xDoubleCapsLB, sEntry, maCompareClass);
+ if(bSame && sEntry != m_xDoubleCapsLB->get_selected_text())
+ rEdt.set_text(m_xDoubleCapsLB->get_selected_text());
+ m_xNewDoublePB->set_sensitive(!bSame && bEntryLen);
+ m_xDelDoublePB->set_sensitive(bSame && bEntryLen);
+ }
+}
+
+namespace {
+
+enum OfaQuoteOptions
+{
+ ADD_NONBRK_SPACE,
+ REPLACE_1ST,
+ TRANSLITERATE_RTL,
+ REPLACE_ANGLE_QUOTES
+};
+
+}
+
+void OfaQuoteTabPage::CreateEntry(weld::TreeView& rCheckLB, const OUString& rTxt, sal_uInt16 nCol, sal_uInt16 nTextCol)
+{
+ rCheckLB.append();
+ const int nRow = rCheckLB.n_children() - 1;
+ if (nCol == CBCOL_FIRST || nCol == CBCOL_BOTH)
+ rCheckLB.set_toggle(nRow, TRISTATE_FALSE, CBCOL_FIRST);
+ if (nCol == CBCOL_SECOND || nCol == CBCOL_BOTH)
+ rCheckLB.set_toggle(nRow, TRISTATE_FALSE, CBCOL_SECOND);
+ rCheckLB.set_text(nRow, rTxt, nTextCol);
+}
+
+OfaQuoteTabPage::OfaQuoteTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/applylocalizedpage.ui", "ApplyLocalizedPage", &rSet)
+ , sNonBrkSpace(CuiResId(RID_CUISTR_NON_BREAK_SPACE))
+ , sOrdinal(CuiResId(RID_CUISTR_ORDINAL))
+ , sTransliterateRTL(CuiResId(RID_CUISTR_OLD_HUNGARIAN))
+ , sAngleQuotes(CuiResId(RID_CUISTR_ANGLE_QUOTES))
+ , cSglStartQuote(0)
+ , cSglEndQuote(0)
+ , cStartQuote(0)
+ , cEndQuote(0)
+ , m_xSingleTypoCB(m_xBuilder->weld_check_button("singlereplace"))
+ , m_xSglStartQuotePB(m_xBuilder->weld_button("startsingle"))
+ , m_xSglStartExFT(m_xBuilder->weld_label("singlestartex"))
+ , m_xSglEndQuotePB(m_xBuilder->weld_button("endsingle"))
+ , m_xSglEndExFT(m_xBuilder->weld_label("singleendex"))
+ , m_xSglStandardPB(m_xBuilder->weld_button("defaultsingle"))
+ , m_xDoubleTypoCB(m_xBuilder->weld_check_button("doublereplace"))
+ , m_xDblStartQuotePB(m_xBuilder->weld_button("startdouble"))
+ , m_xDblStartExFT(m_xBuilder->weld_label("doublestartex"))
+ , m_xDblEndQuotePB(m_xBuilder->weld_button("enddouble"))
+ , m_xDblEndExFT(m_xBuilder->weld_label("doubleendex"))
+ , m_xDblStandardPB(m_xBuilder->weld_button("defaultdouble"))
+ , m_sStandard(m_xSglStartExFT->get_label())
+ , m_xCheckLB(m_xBuilder->weld_tree_view("checklist"))
+ , m_xSwCheckLB(m_xBuilder->weld_tree_view("list"))
+{
+ m_xSwCheckLB->set_size_request(m_xSwCheckLB->get_approximate_digit_width() * 50,
+ m_xSwCheckLB->get_height_rows(6));
+
+ bool bShowSWOptions = false;
+
+ const SfxBoolItem* pItem = rSet.GetItem<SfxBoolItem>(SID_AUTO_CORRECT_DLG, false);
+ if ( pItem && pItem->GetValue() )
+ bShowSWOptions = true;
+
+ if ( bShowSWOptions )
+ {
+ std::vector<int> aWidths
+ {
+ o3tl::narrowing<int>(m_xSwCheckLB->get_pixel_size(m_xSwCheckLB->get_column_title(0)).Width() * 2),
+ o3tl::narrowing<int>(m_xSwCheckLB->get_pixel_size(m_xSwCheckLB->get_column_title(1)).Width() * 2)
+ };
+ m_xSwCheckLB->set_column_fixed_widths(aWidths);
+ m_xCheckLB->hide();
+ }
+ else
+ {
+ m_xCheckLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
+ m_xSwCheckLB->hide();
+ }
+
+ m_xDblStartQuotePB->connect_clicked(LINK(this, OfaQuoteTabPage, QuoteHdl));
+ m_xDblEndQuotePB->connect_clicked(LINK(this, OfaQuoteTabPage, QuoteHdl));
+ m_xSglStartQuotePB->connect_clicked(LINK(this, OfaQuoteTabPage, QuoteHdl));
+ m_xSglEndQuotePB->connect_clicked(LINK(this, OfaQuoteTabPage, QuoteHdl));
+ m_xDblStandardPB->connect_clicked(LINK(this, OfaQuoteTabPage, StdQuoteHdl));
+ m_xSglStandardPB->connect_clicked(LINK(this, OfaQuoteTabPage, StdQuoteHdl));
+}
+
+OfaQuoteTabPage::~OfaQuoteTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> OfaQuoteTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<OfaQuoteTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool OfaQuoteTabPage::FillItemSet( SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+
+ ACFlags nFlags = pAutoCorrect->GetFlags();
+
+ if (m_xCheckLB->get_visible())
+ {
+ int nPos = 0;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::AddNonBrkSpace, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgOrdinalNumber, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::TransliterateRTL, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgAngleQuotes, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
+ }
+
+ bool bModified = false;
+ if (m_xSwCheckLB->get_visible())
+ {
+ SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
+
+ bool bCheck = m_xSwCheckLB->get_toggle(ADD_NONBRK_SPACE, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bAddNonBrkSpace != bCheck;
+ pOpt->bAddNonBrkSpace = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::AddNonBrkSpace,
+ m_xSwCheckLB->get_toggle(ADD_NONBRK_SPACE, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ bCheck = m_xSwCheckLB->get_toggle(REPLACE_1ST, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bChgOrdinalNumber != bCheck;
+ pOpt->bChgOrdinalNumber = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgOrdinalNumber,
+ m_xSwCheckLB->get_toggle(REPLACE_1ST, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ bCheck = m_xSwCheckLB->get_toggle(TRANSLITERATE_RTL, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bTransliterateRTL != bCheck;
+ pOpt->bTransliterateRTL = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::TransliterateRTL,
+ m_xSwCheckLB->get_toggle(TRANSLITERATE_RTL, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ bCheck = m_xSwCheckLB->get_toggle(REPLACE_ANGLE_QUOTES, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bChgAngleQuotes != bCheck;
+ pOpt->bChgAngleQuotes = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgAngleQuotes,
+ m_xSwCheckLB->get_toggle(REPLACE_ANGLE_QUOTES, CBCOL_SECOND) == TRISTATE_TRUE);
+ }
+
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgQuotes, m_xDoubleTypoCB->get_active());
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgSglQuotes, m_xSingleTypoCB->get_active());
+ bool bReturn = nFlags != pAutoCorrect->GetFlags();
+ if(cStartQuote != pAutoCorrect->GetStartDoubleQuote())
+ {
+ bReturn = true;
+ sal_Unicode cUCS2 = static_cast<sal_Unicode>(cStartQuote); //TODO
+ pAutoCorrect->SetStartDoubleQuote(cUCS2);
+ }
+ if(cEndQuote != pAutoCorrect->GetEndDoubleQuote())
+ {
+ bReturn = true;
+ sal_Unicode cUCS2 = static_cast<sal_Unicode>(cEndQuote); //TODO
+ pAutoCorrect->SetEndDoubleQuote(cUCS2);
+ }
+ if(cSglStartQuote != pAutoCorrect->GetStartSingleQuote())
+ {
+ bReturn = true;
+ sal_Unicode cUCS2 = static_cast<sal_Unicode>(cSglStartQuote); //TODO
+ pAutoCorrect->SetStartSingleQuote(cUCS2);
+ }
+ if(cSglEndQuote != pAutoCorrect->GetEndSingleQuote())
+ {
+ bReturn = true;
+ sal_Unicode cUCS2 = static_cast<sal_Unicode>(cSglEndQuote); //TODO
+ pAutoCorrect->SetEndSingleQuote(cUCS2);
+ }
+
+ if( bModified || bReturn )
+ {
+ SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
+ rCfg.SetModified();
+ rCfg.Commit();
+ }
+ return bReturn;
+}
+
+void OfaQuoteTabPage::ActivatePage( const SfxItemSet& )
+{
+ static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage(false);
+}
+
+void OfaQuoteTabPage::Reset( const SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ const ACFlags nFlags = pAutoCorrect->GetFlags();
+
+ // Initialize the Sw options
+ if (m_xSwCheckLB->get_visible())
+ {
+ SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
+
+ m_xSwCheckLB->freeze();
+ m_xSwCheckLB->clear();
+
+ CreateEntry(*m_xSwCheckLB, sNonBrkSpace, CBCOL_BOTH, 2);
+ CreateEntry(*m_xSwCheckLB, sOrdinal, CBCOL_BOTH, 2);
+ CreateEntry(*m_xSwCheckLB, sTransliterateRTL, CBCOL_BOTH, 2);
+ CreateEntry(*m_xSwCheckLB, sAngleQuotes, CBCOL_BOTH, 2);
+
+ m_xSwCheckLB->set_toggle(ADD_NONBRK_SPACE, pOpt->bAddNonBrkSpace ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xSwCheckLB->set_toggle(ADD_NONBRK_SPACE, bool(nFlags & ACFlags::AddNonBrkSpace) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xSwCheckLB->set_toggle(REPLACE_1ST, pOpt->bChgOrdinalNumber ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xSwCheckLB->set_toggle(REPLACE_1ST, bool(nFlags & ACFlags::ChgOrdinalNumber) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xSwCheckLB->set_toggle(TRANSLITERATE_RTL, pOpt->bTransliterateRTL ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xSwCheckLB->set_toggle(TRANSLITERATE_RTL, bool(nFlags & ACFlags::TransliterateRTL) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xSwCheckLB->set_toggle(REPLACE_ANGLE_QUOTES, pOpt->bChgAngleQuotes ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xSwCheckLB->set_toggle(REPLACE_ANGLE_QUOTES, bool(nFlags & ACFlags::ChgAngleQuotes) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+
+ m_xSwCheckLB->thaw();
+ }
+
+ // Initialize the non Sw options
+ if (m_xCheckLB->get_visible())
+ {
+ m_xCheckLB->freeze();
+ m_xCheckLB->clear();
+
+ int nPos = 0;
+ m_xCheckLB->append();
+ m_xCheckLB->set_toggle(nPos, bool(nFlags & ACFlags::AddNonBrkSpace) ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xCheckLB->set_text(nPos++, sNonBrkSpace, 0);
+ m_xCheckLB->append();
+ m_xCheckLB->set_toggle(nPos, bool(nFlags & ACFlags::ChgOrdinalNumber) ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xCheckLB->set_text(nPos++, sOrdinal, 0);
+ m_xCheckLB->append();
+ m_xCheckLB->set_toggle(nPos, bool(nFlags & ACFlags::TransliterateRTL) ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xCheckLB->set_text(nPos++, sTransliterateRTL, 0);
+ m_xCheckLB->append();
+ m_xCheckLB->set_toggle(nPos, bool(nFlags & ACFlags::ChgAngleQuotes) ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xCheckLB->set_text(nPos++, sAngleQuotes, 0);
+
+ m_xCheckLB->thaw();
+ }
+
+ // Initialize the quote stuffs
+ m_xDoubleTypoCB->set_active(bool(nFlags & ACFlags::ChgQuotes));
+ m_xSingleTypoCB->set_active(bool(nFlags & ACFlags::ChgSglQuotes));
+ m_xDoubleTypoCB->save_state();
+ m_xSingleTypoCB->save_state();
+
+ cStartQuote = pAutoCorrect->GetStartDoubleQuote();
+ cEndQuote = pAutoCorrect->GetEndDoubleQuote();
+ cSglStartQuote = pAutoCorrect->GetStartSingleQuote();
+ cSglEndQuote = pAutoCorrect->GetEndSingleQuote();
+
+ m_xSglStartExFT->set_label(ChangeStringExt_Impl(cSglStartQuote));
+ m_xSglEndExFT->set_label(ChangeStringExt_Impl(cSglEndQuote));
+ m_xDblStartExFT->set_label(ChangeStringExt_Impl(cStartQuote));
+ m_xDblEndExFT->set_label(ChangeStringExt_Impl(cEndQuote));
+}
+
+#define SGL_START 0
+#define DBL_START 1
+#define SGL_END 2
+#define DBL_END 3
+
+
+IMPL_LINK(OfaQuoteTabPage, QuoteHdl, weld::Button&, rBtn, void)
+{
+ sal_uInt16 nMode = SGL_START;
+ if (&rBtn == m_xSglEndQuotePB.get())
+ nMode = SGL_END;
+ else if (&rBtn == m_xDblStartQuotePB.get())
+ nMode = DBL_START;
+ else if (&rBtn == m_xDblEndQuotePB.get())
+ nMode = DBL_END;
+ // start character selection dialog
+ SvxCharacterMap aMap(GetFrameWeld(), nullptr, nullptr);
+ aMap.SetCharFont( OutputDevice::GetDefaultFont(DefaultFontType::LATIN_TEXT,
+ LANGUAGE_ENGLISH_US, GetDefaultFontFlags::OnlyOne ));
+ aMap.set_title(nMode < SGL_END ? CuiResId(RID_CUISTR_STARTQUOTE) : CuiResId(RID_CUISTR_ENDQUOTE));
+ sal_UCS4 cDlg;
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ LanguageType eLang = Application::GetSettings().GetLanguageTag().getLanguageType();
+ switch( nMode )
+ {
+ case SGL_START:
+ cDlg = cSglStartQuote;
+ if(cDlg == 0)
+ cDlg = pAutoCorrect->GetQuote('\'', true, eLang);
+ break;
+ case SGL_END:
+ cDlg = cSglEndQuote;
+ if(cDlg == 0)
+ cDlg = pAutoCorrect->GetQuote('\'', false, eLang);
+ break;
+ case DBL_START:
+ cDlg = cStartQuote;
+ if(cDlg == 0)
+ cDlg = pAutoCorrect->GetQuote('\"', true, eLang);
+ break;
+ case DBL_END:
+ cDlg = cEndQuote;
+ if(cDlg == 0)
+ cDlg = pAutoCorrect->GetQuote('\"', false, eLang);
+ break;
+ default:
+ OSL_FAIL("svx::OfaQuoteTabPage::QuoteHdl(), how to initialize cDlg?" );
+ cDlg = 0;
+ break;
+
+ }
+ aMap.SetChar( cDlg );
+ aMap.DisableFontSelection();
+ if (aMap.run() != RET_OK)
+ return;
+
+ sal_UCS4 cNewChar = aMap.GetChar();
+ switch( nMode )
+ {
+ case SGL_START:
+ cSglStartQuote = cNewChar;
+ m_xSglStartExFT->set_label(ChangeStringExt_Impl(cNewChar));
+ break;
+ case SGL_END:
+ cSglEndQuote = cNewChar;
+ m_xSglEndExFT->set_label(ChangeStringExt_Impl(cNewChar));
+ break;
+ case DBL_START:
+ cStartQuote = cNewChar;
+ m_xDblStartExFT->set_label(ChangeStringExt_Impl(cNewChar));
+ break;
+ case DBL_END:
+ cEndQuote = cNewChar;
+ m_xDblEndExFT->set_label(ChangeStringExt_Impl(cNewChar));
+ break;
+ }
+}
+
+IMPL_LINK(OfaQuoteTabPage, StdQuoteHdl, weld::Button&, rBtn, void)
+{
+ if (&rBtn == m_xDblStandardPB.get())
+ {
+ cStartQuote = 0;
+ m_xDblStartExFT->set_label(ChangeStringExt_Impl(0));
+ cEndQuote = 0;
+ m_xDblEndExFT->set_label(ChangeStringExt_Impl(0));
+
+ }
+ else
+ {
+ cSglStartQuote = 0;
+ m_xSglStartExFT->set_label(ChangeStringExt_Impl(0));
+ cSglEndQuote = 0;
+ m_xSglEndExFT->set_label(ChangeStringExt_Impl(0));
+ }
+}
+
+OUString OfaQuoteTabPage::ChangeStringExt_Impl( sal_UCS4 cChar )
+{
+ if (!cChar)
+ return m_sStandard;
+
+ // convert codepoint value to unicode-hex string
+ sal_UCS4 aStrCodes[32] = { 0, ' ', '(', 'U', '+', '0' };
+ aStrCodes[0] = cChar;
+ int nFullLen = 5;
+ int nHexLen = 4;
+ while( (cChar >> (4*nHexLen)) != 0 )
+ ++nHexLen;
+ for( int i = nHexLen; --i >= 0;)
+ {
+ sal_UCS4 cHexDigit = ((cChar >> (4*i)) & 0x0f) + '0';
+ if( cHexDigit > '9' )
+ cHexDigit += 'A' - ('9' + 1);
+ aStrCodes[ nFullLen++ ] = cHexDigit;
+ }
+ aStrCodes[ nFullLen++ ] = ')';
+ // using the new UCS4 constructor
+ OUString aOUStr( aStrCodes, nFullLen );
+ return aOUStr;
+}
+
+OfaAutoCompleteTabPage::OfaAutoCompleteTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/wordcompletionpage.ui",
+ "WordCompletionPage", &rSet)
+ , m_pAutoCompleteList(nullptr)
+ , m_nAutoCmpltListCnt(0)
+ , m_xCBActiv(m_xBuilder->weld_check_button("enablewordcomplete"))
+ , m_xCBAppendSpace(m_xBuilder->weld_check_button("appendspace"))
+ , m_xCBAsTip(m_xBuilder->weld_check_button("showastip"))
+ , m_xCBCollect(m_xBuilder->weld_check_button("collectwords"))
+ , m_xCBRemoveList(m_xBuilder->weld_check_button("whenclosing"))
+ , m_xDCBExpandKey(m_xBuilder->weld_combo_box("acceptwith"))
+ , m_xNFMinWordlen(m_xBuilder->weld_spin_button("minwordlen"))
+ , m_xNFMaxEntries(m_xBuilder->weld_spin_button("maxentries"))
+ , m_xLBEntries(m_xBuilder->weld_tree_view("entries"))
+ , m_xPBEntries(m_xBuilder->weld_button("delete"))
+{
+ //fdo#65595, we need height-for-width support here, but for now we can
+ //bodge it
+ Size aPrefSize(m_xCBRemoveList->get_preferred_size());
+ int nMaxWidth = m_xCBRemoveList->get_approximate_digit_width() * 40;
+ if (aPrefSize.Width() > nMaxWidth)
+ {
+ m_xCBRemoveList->set_label_wrap(true);
+ m_xCBRemoveList->set_size_request(nMaxWidth, -1);
+ }
+
+ m_xLBEntries->set_size_request(m_xLBEntries->get_approximate_digit_width() * 30,
+ m_xLBEntries->get_height_rows(10));
+ m_xLBEntries->set_selection_mode(SelectionMode::Multiple);
+
+ // the defined KEYs
+ static const sal_uInt16 aKeyCodes[] = {
+ KEY_END,
+ KEY_RETURN,
+ KEY_SPACE,
+ KEY_RIGHT,
+ KEY_TAB,
+ 0
+ };
+
+ for( const sal_uInt16* pKeys = aKeyCodes; *pKeys; ++pKeys )
+ {
+ vcl::KeyCode aKCode(*pKeys);
+ m_xDCBExpandKey->append(OUString::number(static_cast<sal_Int32>(*pKeys)), aKCode.GetName());
+ if (KEY_RETURN == *pKeys) // default to RETURN
+ m_xDCBExpandKey->set_active(std::distance(aKeyCodes, pKeys));
+ }
+
+ m_xPBEntries->connect_clicked(LINK(this, OfaAutoCompleteTabPage, DeleteHdl));
+ m_xCBActiv->connect_toggled(LINK(this, OfaAutoCompleteTabPage, CheckHdl));
+ m_xCBCollect->connect_toggled(LINK(this, OfaAutoCompleteTabPage, CheckHdl));
+ m_xLBEntries->connect_key_release(LINK(this, OfaAutoCompleteTabPage, KeyReleaseHdl));
+}
+
+OfaAutoCompleteTabPage::~OfaAutoCompleteTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> OfaAutoCompleteTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rSet)
+{
+ return std::make_unique<OfaAutoCompleteTabPage>(pPage, pController, *rSet);
+}
+
+bool OfaAutoCompleteTabPage::FillItemSet( SfxItemSet* )
+{
+ bool bModified = false, bCheck;
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
+
+ bCheck = m_xCBActiv->get_active();
+ bModified |= pOpt->bAutoCompleteWords != bCheck;
+ pOpt->bAutoCompleteWords = bCheck;
+ bCheck = m_xCBCollect->get_active();
+ bModified |= pOpt->bAutoCmpltCollectWords != bCheck;
+ pOpt->bAutoCmpltCollectWords = bCheck;
+ bCheck = !m_xCBRemoveList->get_active(); // inverted value!
+ bModified |= pOpt->bAutoCmpltKeepList != bCheck;
+ pOpt->bAutoCmpltKeepList = bCheck;
+ bCheck = m_xCBAppendSpace->get_active();
+ bModified |= pOpt->bAutoCmpltAppendBlank != bCheck;
+ pOpt->bAutoCmpltAppendBlank = bCheck;
+ bCheck = m_xCBAsTip->get_active();
+ bModified |= pOpt->bAutoCmpltShowAsTip != bCheck;
+ pOpt->bAutoCmpltShowAsTip = bCheck;
+
+ sal_uInt16 nVal = static_cast<sal_uInt16>(m_xNFMinWordlen->get_value());
+ bModified |= nVal != pOpt->nAutoCmpltWordLen;
+ pOpt->nAutoCmpltWordLen = nVal;
+
+ sal_uInt32 nList = static_cast<sal_uInt32>(m_xNFMaxEntries->get_value());
+ bModified |= nList != pOpt->nAutoCmpltListLen;
+ pOpt->nAutoCmpltListLen = nList;
+
+ const int nPos = m_xDCBExpandKey->get_active();
+ if (nPos != -1)
+ {
+ sal_Int32 nKey = m_xDCBExpandKey->get_id(nPos).toInt32();
+ bModified |= nKey != pOpt->nAutoCmpltExpandKey;
+ pOpt->nAutoCmpltExpandKey = static_cast<sal_uInt16>(nKey);
+ }
+
+ if (m_pAutoCompleteList && m_nAutoCmpltListCnt != m_xLBEntries->n_children())
+ {
+ bModified = true;
+ pOpt->m_pAutoCompleteList = m_pAutoCompleteList;
+ }
+ if( bModified )
+ {
+ SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
+ rCfg.SetModified();
+ rCfg.Commit();
+ }
+ return true;
+}
+
+void OfaAutoCompleteTabPage::Reset( const SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
+
+ m_xCBActiv->set_active( pOpt->bAutoCompleteWords );
+ m_xCBCollect->set_active( pOpt->bAutoCmpltCollectWords );
+ m_xCBRemoveList->set_active( !pOpt->bAutoCmpltKeepList ); //inverted value!
+ m_xCBAppendSpace->set_active( pOpt->bAutoCmpltAppendBlank );
+ m_xCBAsTip->set_active( pOpt->bAutoCmpltShowAsTip );
+
+ m_xNFMinWordlen->set_value( pOpt->nAutoCmpltWordLen );
+ m_xNFMaxEntries->set_value( pOpt->nAutoCmpltListLen );
+
+ // select the specific KeyCode:
+ {
+ sal_Int32 nKey = pOpt->nAutoCmpltExpandKey;
+ for (int n = 0, nCnt = m_xDCBExpandKey->get_count(); n < nCnt; ++n)
+ {
+ if (nKey == m_xDCBExpandKey->get_id(n).toInt32())
+ {
+ m_xDCBExpandKey->set_active(n);
+ break;
+ }
+ }
+ }
+
+ if (pOpt->m_pAutoCompleteList && !pOpt->m_pAutoCompleteList->empty())
+ {
+ m_pAutoCompleteList = const_cast<editeng::SortedAutoCompleteStrings*>(
+ pOpt->m_pAutoCompleteList);
+ pOpt->m_pAutoCompleteList = nullptr;
+ m_nAutoCmpltListCnt = m_pAutoCompleteList->size();
+ for (size_t n = 0; n < m_nAutoCmpltListCnt; ++n)
+ {
+ const OUString* pStr =
+ &(*m_pAutoCompleteList)[n]->GetAutoCompleteString();
+ OUString sId(weld::toId(pStr));
+ m_xLBEntries->append(sId, *pStr);
+ }
+ }
+ else
+ {
+ m_xLBEntries->set_sensitive(false);
+ m_xPBEntries->set_sensitive(false);
+ }
+
+ CheckHdl(*m_xCBActiv);
+ CheckHdl(*m_xCBCollect);
+}
+
+void OfaAutoCompleteTabPage::ActivatePage( const SfxItemSet& )
+{
+ static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage( false );
+}
+
+IMPL_LINK_NOARG(OfaAutoCompleteTabPage, DeleteHdl, weld::Button&, void)
+{
+ auto rows = m_xLBEntries->get_selected_rows();
+ std::sort(rows.begin(), rows.end());
+ while (!rows.empty())
+ {
+ sal_Int32 nPos = rows.back();
+ OUString* pStr = weld::fromId<OUString*>(m_xLBEntries->get_id(nPos));
+ m_xLBEntries->remove(nPos);
+ editeng::IAutoCompleteString hack(*pStr); // UGLY
+ m_pAutoCompleteList->erase(&hack);
+ rows.pop_back();
+ }
+}
+
+IMPL_LINK(OfaAutoCompleteTabPage, CheckHdl, weld::Toggleable&, rBox, void)
+{
+ bool bEnable = rBox.get_active();
+ if (&rBox == m_xCBActiv.get())
+ {
+ m_xCBAppendSpace->set_sensitive(bEnable);
+ m_xCBAppendSpace->set_sensitive(bEnable);
+ m_xCBAsTip->set_sensitive(bEnable);
+ m_xDCBExpandKey->set_sensitive(bEnable);
+ }
+ else if (&rBox == m_xCBCollect.get())
+ m_xCBRemoveList->set_sensitive(bEnable);
+}
+
+void OfaAutoCompleteTabPage::CopyToClipboard() const
+{
+ auto rows = m_xLBEntries->get_selected_rows();
+ if (!m_pAutoCompleteList || rows.empty())
+ return;
+
+ rtl::Reference<TransferDataContainer> pCntnr = new TransferDataContainer;
+
+ OStringBuffer sData;
+
+ rtl_TextEncoding nEncode = osl_getThreadTextEncoding();
+
+ for (auto a : rows)
+ {
+ sData.append(OUStringToOString(m_xLBEntries->get_text(a), nEncode) + SAL_NEWLINE_STRING);
+ }
+ pCntnr->CopyByteString( SotClipboardFormatId::STRING, sData.makeStringAndClear() );
+ pCntnr->CopyToClipboard(m_xLBEntries->get_clipboard());
+}
+
+IMPL_LINK(OfaAutoCompleteTabPage, KeyReleaseHdl, const KeyEvent&, rEvent, bool)
+{
+ bool bHandled = false;
+ const vcl::KeyCode& rKeyCode = rEvent.GetKeyCode();
+ switch (rKeyCode.GetModifier() | rKeyCode.GetCode())
+ {
+ case KEY_DELETE:
+ DeleteHdl(*m_xPBEntries);
+ bHandled = true;
+ break;
+ default:
+ if (KeyFuncType::COPY == rKeyCode.GetFunction())
+ {
+ CopyToClipboard();
+ bHandled = true;
+ }
+ break;
+ }
+ return bHandled;
+}
+
+// class OfaSmartTagOptionsTabPage ---------------------------------------------
+
+OfaSmartTagOptionsTabPage::OfaSmartTagOptionsTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet )
+ : SfxTabPage(pPage, pController, "cui/ui/smarttagoptionspage.ui", "SmartTagOptionsPage", &rSet)
+ , m_xMainCB(m_xBuilder->weld_check_button("main"))
+ , m_xSmartTagTypesLB(m_xBuilder->weld_tree_view("list"))
+ , m_xPropertiesPB(m_xBuilder->weld_button("properties"))
+{
+ m_xSmartTagTypesLB->set_size_request(m_xSmartTagTypesLB->get_approximate_digit_width() * 50,
+ m_xSmartTagTypesLB->get_height_rows(6));
+
+ m_xSmartTagTypesLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
+
+ // set the handlers:
+ m_xMainCB->connect_toggled(LINK(this, OfaSmartTagOptionsTabPage, CheckHdl));
+ m_xPropertiesPB->connect_clicked(LINK(this, OfaSmartTagOptionsTabPage, ClickHdl));
+ m_xSmartTagTypesLB->connect_changed(LINK(this, OfaSmartTagOptionsTabPage, SelectHdl));
+}
+
+OfaSmartTagOptionsTabPage::~OfaSmartTagOptionsTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> OfaSmartTagOptionsTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<OfaSmartTagOptionsTabPage>(pPage, pController, *rSet);
+}
+
+namespace {
+
+/** This struct is used to associate list box entries with smart tag data
+*/
+struct ImplSmartTagLBUserData
+{
+ OUString maSmartTagType;
+ uno::Reference< smarttags::XSmartTagRecognizer > mxRec;
+ sal_Int32 mnSmartTagIdx;
+
+ ImplSmartTagLBUserData( OUString aSmartTagType,
+ uno::Reference< smarttags::XSmartTagRecognizer > xRec,
+ sal_Int32 nSmartTagIdx ) :
+ maSmartTagType(std::move( aSmartTagType )),
+ mxRec(std::move( xRec )),
+ mnSmartTagIdx( nSmartTagIdx ) {}
+};
+
+}
+
+/** Clears m_xSmartTagTypesLB
+*/
+void OfaSmartTagOptionsTabPage::ClearListBox()
+{
+ const int nCount = m_xSmartTagTypesLB->n_children();
+ for (int i = 0; i < nCount; ++i)
+ {
+ const ImplSmartTagLBUserData* pUserData = weld::fromId<ImplSmartTagLBUserData*>(m_xSmartTagTypesLB->get_id(i));
+ delete pUserData;
+ }
+
+ m_xSmartTagTypesLB->clear();
+}
+
+/** Inserts items into m_xSmartTagTypesLB
+*/
+void OfaSmartTagOptionsTabPage::FillListBox( const SmartTagMgr& rSmartTagMgr )
+{
+ // first we have to clear the list box:
+ ClearListBox();
+
+ // fill list box:
+ const sal_uInt32 nNumberOfRecognizers = rSmartTagMgr.NumberOfRecognizers();
+ const lang::Locale aLocale( LanguageTag::convertToLocale( eLastDialogLanguage ) );
+
+ for ( sal_uInt32 i = 0; i < nNumberOfRecognizers; ++i )
+ {
+ const uno::Reference< smarttags::XSmartTagRecognizer >& xRec = rSmartTagMgr.GetRecognizer(i);
+
+ const OUString aName = xRec->getName( aLocale );
+ const sal_Int32 nNumberOfSupportedSmartTags = xRec->getSmartTagCount();
+
+ for ( sal_Int32 j = 0; j < nNumberOfSupportedSmartTags; ++j )
+ {
+ const OUString aSmartTagType = xRec->getSmartTagName(j);
+ OUString aSmartTagCaption = rSmartTagMgr.GetSmartTagCaption( aSmartTagType, aLocale );
+
+ if ( aSmartTagCaption.isEmpty() )
+ aSmartTagCaption = aSmartTagType;
+
+ const OUString aLBEntry = aSmartTagCaption + " (" + aName + ")";
+
+ m_xSmartTagTypesLB->append();
+ const int nRow = m_xSmartTagTypesLB->n_children() - 1;
+ const bool bCheck = rSmartTagMgr.IsSmartTagTypeEnabled( aSmartTagType );
+ m_xSmartTagTypesLB->set_toggle(nRow, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xSmartTagTypesLB->set_text(nRow, aLBEntry, 0);
+ m_xSmartTagTypesLB->set_id(nRow, weld::toId(new ImplSmartTagLBUserData(aSmartTagType, xRec, j)));
+ }
+ }
+}
+
+/** Handler for the push button
+*/
+IMPL_LINK_NOARG(OfaSmartTagOptionsTabPage, ClickHdl, weld::Button&, void)
+{
+ const int nPos = m_xSmartTagTypesLB->get_selected_index();
+ const ImplSmartTagLBUserData* pUserData = weld::fromId<ImplSmartTagLBUserData*>(m_xSmartTagTypesLB->get_id(nPos));
+ uno::Reference< smarttags::XSmartTagRecognizer > xRec = pUserData->mxRec;
+ const sal_Int32 nSmartTagIdx = pUserData->mnSmartTagIdx;
+
+ const lang::Locale aLocale( LanguageTag::convertToLocale( eLastDialogLanguage ) );
+ if ( xRec->hasPropertyPage( nSmartTagIdx, aLocale ) )
+ xRec->displayPropertyPage( nSmartTagIdx, aLocale );
+}
+
+/** Handler for the check box
+*/
+IMPL_LINK_NOARG(OfaSmartTagOptionsTabPage, CheckHdl, weld::Toggleable&, void)
+{
+ const bool bEnable = m_xMainCB->get_active();
+ m_xSmartTagTypesLB->set_sensitive(bEnable);
+ m_xPropertiesPB->set_sensitive(false);
+
+ // if the controls are currently enabled, we still have to check
+ // if the properties button should be disabled because the currently
+ // selected smart tag type does not have a properties dialog.
+ // We do this by calling SelectHdl:
+ if (bEnable)
+ SelectHdl(*m_xSmartTagTypesLB);
+}
+
+/** Handler for the list box
+*/
+IMPL_LINK_NOARG(OfaSmartTagOptionsTabPage, SelectHdl, weld::TreeView&, void)
+{
+ const int nPos = m_xSmartTagTypesLB->get_selected_index();
+ if (nPos == -1)
+ return;
+ const ImplSmartTagLBUserData* pUserData = weld::fromId<ImplSmartTagLBUserData*>(m_xSmartTagTypesLB->get_id(nPos));
+ uno::Reference< smarttags::XSmartTagRecognizer > xRec = pUserData->mxRec;
+ const sal_Int32 nSmartTagIdx = pUserData->mnSmartTagIdx;
+
+ const lang::Locale aLocale( LanguageTag::convertToLocale( eLastDialogLanguage ) );
+ if ( xRec->hasPropertyPage( nSmartTagIdx, aLocale ) )
+ m_xPropertiesPB->set_sensitive(true);
+ else
+ m_xPropertiesPB->set_sensitive(false);
+}
+
+/** Propagates the current settings to the smart tag manager.
+*/
+bool OfaSmartTagOptionsTabPage::FillItemSet( SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
+ SmartTagMgr* pSmartTagMgr = pOpt->pSmartTagMgr;
+
+ // robust!
+ if ( !pSmartTagMgr )
+ return false;
+
+ bool bModifiedSmartTagTypes = false;
+ std::vector< OUString > aDisabledSmartTagTypes;
+
+ const int nCount = m_xSmartTagTypesLB->n_children();
+
+ for (int i = 0; i < nCount; ++i)
+ {
+ const ImplSmartTagLBUserData* pUserData = weld::fromId<ImplSmartTagLBUserData*>(m_xSmartTagTypesLB->get_id(i));
+ const bool bChecked = m_xSmartTagTypesLB->get_toggle(i) == TRISTATE_TRUE;
+ const bool bIsCurrentlyEnabled = pSmartTagMgr->IsSmartTagTypeEnabled( pUserData->maSmartTagType );
+
+ bModifiedSmartTagTypes = bModifiedSmartTagTypes || ( !bChecked != !bIsCurrentlyEnabled );
+
+ if ( !bChecked )
+ aDisabledSmartTagTypes.push_back( pUserData->maSmartTagType );
+
+ delete pUserData;
+ }
+
+ const bool bModifiedRecognize = ( !m_xMainCB->get_active() != !pSmartTagMgr->IsLabelTextWithSmartTags() );
+ if ( bModifiedSmartTagTypes || bModifiedRecognize )
+ {
+ bool bLabelTextWithSmartTags = m_xMainCB->get_active();
+ pSmartTagMgr->WriteConfiguration( bModifiedRecognize ? &bLabelTextWithSmartTags : nullptr,
+ bModifiedSmartTagTypes ? &aDisabledSmartTagTypes : nullptr );
+ }
+
+ return true;
+}
+
+/** Sets the controls based on the current settings at SmartTagMgr.
+*/
+void OfaSmartTagOptionsTabPage::Reset( const SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
+ const SmartTagMgr* pSmartTagMgr = pOpt->pSmartTagMgr;
+
+ // robust, should not happen!
+ if ( !pSmartTagMgr )
+ return;
+
+ FillListBox(*pSmartTagMgr);
+ m_xSmartTagTypesLB->select(0);
+ m_xMainCB->set_active(pSmartTagMgr->IsLabelTextWithSmartTags());
+ CheckHdl(*m_xMainCB);
+}
+
+void OfaSmartTagOptionsTabPage::ActivatePage( const SfxItemSet& )
+{
+ static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage( false );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/backgrnd.cxx b/cui/source/tabpages/backgrnd.cxx
new file mode 100644
index 0000000000..56bccfacdf
--- /dev/null
+++ b/cui/source/tabpages/backgrnd.cxx
@@ -0,0 +1,336 @@
+/* -*- 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 <memory>
+#include <sfx2/objsh.hxx>
+#include <svx/svxids.hrc>
+#include <editeng/colritem.hxx>
+#include <backgrnd.hxx>
+#include <svx/drawitem.hxx>
+#include <svx/xfillit0.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/flagsdef.hxx>
+#include <svl/intitem.hxx>
+#include <svx/unobrushitemhelper.hxx>
+
+using namespace css;
+
+// table background
+#define TBL_DEST_CELL 0
+#define TBL_DEST_ROW 1
+#define TBL_DEST_TBL 2
+
+const WhichRangesContainer SvxBkgTabPage::pBkgRanges(svl::Items<
+ SID_ATTR_BRUSH, SID_ATTR_BRUSH,
+ SID_ATTR_BRUSH_CHAR, SID_ATTR_BRUSH_CHAR
+>);
+
+static sal_uInt16 lcl_GetTableDestSlot(sal_Int32 nTblDest)
+{
+ switch (nTblDest)
+ {
+ default:
+ case TBL_DEST_CELL:
+ {
+ return SID_ATTR_BRUSH;
+ }
+ case TBL_DEST_ROW:
+ {
+ return SID_ATTR_BRUSH_ROW;
+ }
+ case TBL_DEST_TBL:
+ {
+ return SID_ATTR_BRUSH_TABLE;
+ }
+ }
+}
+
+SvxBkgTabPage::SvxBkgTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SvxAreaTabPage(pPage, pController, rInAttrs),
+ m_aAttrSet(*rInAttrs.GetPool(),
+ rInAttrs.GetRanges().MergeRange(XATTR_FILL_FIRST, XATTR_FILL_LAST))
+{
+ m_xBtnGradient->hide();
+ m_xBtnHatch->hide();
+ m_xBtnBitmap->hide();
+ m_xBtnPattern->hide();
+}
+
+SvxBkgTabPage::~SvxBkgTabPage()
+{
+ m_xTblLBox.reset();
+}
+
+void SvxBkgTabPage::ActivatePage( const SfxItemSet& )
+{
+ SvxAreaTabPage::ActivatePage(m_aAttrSet);
+}
+
+DeactivateRC SvxBkgTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if (DeactivateRC::KeepPage == SvxAreaTabPage::DeactivatePage(&m_aAttrSet))
+ return DeactivateRC::KeepPage;
+
+ if ( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+void SvxBkgTabPage::Reset(const SfxItemSet* pItemSet)
+{
+ if (m_xTblLBox && m_xTblLBox->get_visible())
+ {
+ if (m_nActPos == -1) // initial reset
+ {
+ m_nActPos = 0;
+ if (const SfxUInt16Item* pDestItem = pItemSet->GetItemIfSet(SID_BACKGRND_DESTINATION, false))
+ m_nActPos = pDestItem->GetValue();
+ m_xTblLBox->set_active(m_nActPos);
+ }
+ SetActiveTableDestinationBrushItem();
+ return;
+ }
+ else if (m_bCharBackColor)
+ {
+ sal_uInt16 nWhich(pItemSet->GetPool()->GetWhich(SID_ATTR_CHAR_BACK_COLOR));
+ Color aBackColor(static_cast<const SvxColorItem&>(pItemSet->Get(nWhich)).GetValue());
+ SvxBrushItem aBrushItem(SvxBrushItem(aBackColor, SID_ATTR_BRUSH_CHAR));
+ setSvxBrushItemAsFillAttributesToTargetSet(aBrushItem, m_aAttrSet);
+ }
+ else
+ {
+ sal_uInt16 nWhich(pItemSet->GetPool()->GetWhich(m_bHighlighting ? SID_ATTR_BRUSH_CHAR : SID_ATTR_BRUSH));
+ SvxBrushItem aBrushItem(static_cast<const SvxBrushItem&>(pItemSet->Get(nWhich)));
+ setSvxBrushItemAsFillAttributesToTargetSet(aBrushItem, m_aAttrSet);
+ }
+ SvxAreaTabPage::Reset(&m_aAttrSet);
+}
+
+bool SvxBkgTabPage::FillItemSet(SfxItemSet* pCoreSet)
+{
+ sal_uInt16 nSlot = SID_ATTR_BRUSH;
+ if (m_xTblLBox && m_xTblLBox->get_visible())
+ nSlot = lcl_GetTableDestSlot(m_xTblLBox->get_active());
+ else if (m_bHighlighting)
+ nSlot = SID_ATTR_BRUSH_CHAR;
+ else if (m_bCharBackColor)
+ nSlot = SID_ATTR_CHAR_BACK_COLOR;
+
+ sal_uInt16 nWhich = GetWhich(nSlot);
+
+ drawing::FillStyle eFillType = m_aAttrSet.Get(XATTR_FILLSTYLE).GetValue();
+ switch( eFillType )
+ {
+ case drawing::FillStyle_NONE:
+ {
+ if ( IsBtnClicked() )
+ {
+ if ( SID_ATTR_CHAR_BACK_COLOR == nSlot )
+ {
+ pCoreSet->Put(SvxColorItem(COL_TRANSPARENT, nWhich));
+ }
+ else
+ {
+ pCoreSet->Put(SvxBrushItem(COL_TRANSPARENT, nWhich));
+ }
+ }
+ break;
+ }
+ case drawing::FillStyle_SOLID:
+ {
+ XFillColorItem aColorItem(m_aAttrSet.Get(XATTR_FILLCOLOR));
+
+ // tdf#157801 - don't change direct formatting when color is unchanged
+ if (const SfxPoolItem* pOldItem = GetOldItem(*pCoreSet, nSlot))
+ {
+ const SvxBrushItem* pOldBrushItem = static_cast<const SvxBrushItem*>(pOldItem);
+ if (pOldBrushItem->GetColor() == aColorItem.GetColorValue())
+ break;
+ }
+
+ if ( SID_ATTR_CHAR_BACK_COLOR == nSlot )
+ {
+ pCoreSet->Put(SvxColorItem(aColorItem.GetColorValue(), aColorItem.getComplexColor(), nWhich));
+ }
+ else
+ {
+ pCoreSet->Put(SvxBrushItem(aColorItem.GetColorValue(), aColorItem.getComplexColor(), nWhich));
+ }
+ break;
+ }
+ case drawing::FillStyle_BITMAP:
+ {
+ std::unique_ptr<SvxBrushItem> aBrushItem(getSvxBrushItemFromSourceSet(m_aAttrSet, nWhich));
+ if ( GraphicType::NONE != aBrushItem->GetGraphicObject()->GetType() )
+ pCoreSet->Put(std::move(aBrushItem));
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (!m_xTblLBox || !m_xTblLBox->get_visible())
+ return true;
+
+ pCoreSet->Put(SfxUInt16Item(SID_BACKGRND_DESTINATION, m_xTblLBox->get_active()));
+
+ // *Put* in the core set all table brushes that are *SET* in the m_aAttrSet
+ if (nSlot != SID_ATTR_BRUSH)
+ {
+ nWhich = m_aAttrSet.GetPool()->GetWhich(SID_ATTR_BRUSH);
+ if (SfxItemState::SET == m_aAttrSet.GetItemState(nWhich))
+ {
+ SvxBrushItem aBrushItem(static_cast<const SvxBrushItem&>(m_aAttrSet.Get(nWhich)));
+ pCoreSet->Put(aBrushItem);
+ }
+ }
+ if (nSlot != SID_ATTR_BRUSH_ROW)
+ {
+ if (SfxItemState::SET == m_aAttrSet.GetItemState(SID_ATTR_BRUSH_ROW))
+ {
+ SvxBrushItem aBrushItem(m_aAttrSet.Get(SID_ATTR_BRUSH_ROW));
+ pCoreSet->Put(aBrushItem);
+ }
+ }
+ if (nSlot != SID_ATTR_BRUSH_TABLE)
+ {
+ if (SfxItemState::SET == m_aAttrSet.GetItemState(SID_ATTR_BRUSH_TABLE))
+ {
+ SvxBrushItem aBrushItem(m_aAttrSet.Get(SID_ATTR_BRUSH_TABLE));
+ pCoreSet->Put(aBrushItem);
+ }
+ }
+
+ return true;
+}
+
+std::unique_ptr<SfxTabPage> SvxBkgTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrs)
+{
+ auto xRet = std::make_unique<SvxBkgTabPage>(pPage, pController, *rAttrs);
+ xRet->SetOptimalSize(pController);
+ return xRet;
+}
+
+void SvxBkgTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxUInt32Item* pFlagItem = aSet.GetItem<SfxUInt32Item>(SID_FLAG_TYPE, false);
+ if (pFlagItem)
+ {
+ SvxBackgroundTabFlags nFlags = static_cast<SvxBackgroundTabFlags>(pFlagItem->GetValue());
+ if ( nFlags & SvxBackgroundTabFlags::SHOW_TBLCTL )
+ {
+ m_xBtnBitmap->show();
+ m_xTblLBox = m_xBuilder->weld_combo_box("tablelb");
+ m_xTblLBox->connect_changed(LINK(this, SvxBkgTabPage, TblDestinationHdl_Impl));
+ m_xTblLBox->show();
+ }
+ if ((nFlags & SvxBackgroundTabFlags::SHOW_HIGHLIGHTING) ||
+ (nFlags & SvxBackgroundTabFlags::SHOW_CHAR_BKGCOLOR))
+ {
+ m_bHighlighting = bool(nFlags & SvxBackgroundTabFlags::SHOW_HIGHLIGHTING);
+ m_bCharBackColor = bool(nFlags & SvxBackgroundTabFlags::SHOW_CHAR_BKGCOLOR);
+ }
+ if (nFlags & SvxBackgroundTabFlags::SHOW_SELECTOR)
+ m_xBtnBitmap->show();
+ SetOptimalSize(GetDialogController());
+ }
+
+ SfxObjectShell* pObjSh = SfxObjectShell::Current();
+
+ // we always have the color page
+ XColorListRef xColorTable;
+ if (pObjSh)
+ {
+ const SvxColorListItem* pItem = pObjSh->GetItem(SID_COLOR_TABLE);
+ if (pItem)
+ xColorTable = pItem->GetColorList();
+ }
+ if (!xColorTable.is())
+ xColorTable = XColorList::CreateStdColorList();
+ SetColorList(xColorTable);
+
+ // sometimes we have the bitmap page
+ if (m_xBtnBitmap->get_visible())
+ {
+ XBitmapListRef xBitmapList;
+ if (pObjSh)
+ if (const SvxBitmapListItem* pItem = pObjSh->GetItem(SID_BITMAP_LIST))
+ xBitmapList = pItem->GetBitmapList();
+ SetBitmapList(xBitmapList);
+ }
+}
+
+IMPL_LINK(SvxBkgTabPage, TblDestinationHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ sal_Int32 nSelPos = rBox.get_active();
+
+ if (m_nActPos == nSelPos)
+ return;
+
+ // Fill the local item set with XATTR_FILL settings gathered from the tab page, convert to
+ // SvxBrushItem and store in table destination slot Which. Do this so cell, row, and table
+ // brush items can be set together.
+ SvxAreaTabPage::FillItemSet(&m_aAttrSet);
+ m_aAttrSet.Put(getSvxBrushItemFromSourceSet(m_aAttrSet, GetWhich(lcl_GetTableDestSlot(m_nActPos))));
+
+ m_nActPos = nSelPos;
+
+ SetActiveTableDestinationBrushItem();
+}
+
+void SvxBkgTabPage::SetActiveTableDestinationBrushItem()
+{
+ // set the table destination (cell, row, table) brush item as a fill item in the local item set
+ sal_uInt16 nWhich = GetWhich(lcl_GetTableDestSlot(m_nActPos));
+ if (SfxItemState::SET == GetItemSet().GetItemState(nWhich))
+ {
+ SvxBrushItem aBrushItem(static_cast<const SvxBrushItem&>(GetItemSet().Get(nWhich)));
+ setSvxBrushItemAsFillAttributesToTargetSet(aBrushItem, m_aAttrSet);
+ }
+ else
+ {
+ SelectFillType(*m_xBtnNone, &m_aAttrSet);
+ return;
+ }
+
+ XFillStyleItem aFillStyleItem(m_aAttrSet.Get(m_aAttrSet.GetPool()->GetWhich(XATTR_FILLSTYLE)));
+ drawing::FillStyle eXFS = aFillStyleItem.GetValue();
+ switch(eXFS)
+ {
+ default:
+ case drawing::FillStyle_NONE:
+ {
+ SelectFillType(*m_xBtnNone, &m_aAttrSet);
+ break;
+ }
+ case drawing::FillStyle_SOLID:
+ {
+ SelectFillType(*m_xBtnColor, &m_aAttrSet);
+ break;
+ }
+ case drawing::FillStyle_BITMAP:
+ {
+ SelectFillType(*m_xBtnBitmap, &m_aAttrSet);
+ break;
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/bbdlg.cxx b/cui/source/tabpages/bbdlg.cxx
new file mode 100644
index 0000000000..9fc5960447
--- /dev/null
+++ b/cui/source/tabpages/bbdlg.cxx
@@ -0,0 +1,89 @@
+/* -*- 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 <bbdlg.hxx>
+#include <border.hxx>
+#include <backgrnd.hxx>
+#include <svx/svxids.hrc>
+#include <svl/intitem.hxx>
+#include <cuitabarea.hxx>
+
+SvxBorderBackgroundDlg::SvxBorderBackgroundDlg(weld::Window *pParent,
+ const SfxItemSet& rCoreSet,
+ bool bEnableSelector,
+ bool bEnableDrawingLayerFillStyles)
+ : SfxTabDialogController(pParent,
+ bEnableDrawingLayerFillStyles
+ ? OUString("cui/ui/borderareatransparencydialog.ui")
+ : OUString("cui/ui/borderbackgrounddialog.ui"),
+ bEnableDrawingLayerFillStyles
+ ? OUString("BorderAreaTransparencyDialog")
+ : OUString("BorderBackgroundDialog"),
+ &rCoreSet)
+ , mbEnableBackgroundSelector(bEnableSelector)
+{
+ AddTabPage("borders", SvxBorderTabPage::Create, nullptr );
+ if (bEnableDrawingLayerFillStyles)
+ {
+ // Here we want full DrawingLayer FillStyle access, so add Area and Transparency TabPages
+ AddTabPage("area", SvxAreaTabPage::Create, nullptr);
+ AddTabPage("transparence", SvxTransparenceTabPage::Create, nullptr);
+ }
+ else
+ {
+ AddTabPage("background", SvxBkgTabPage::Create, nullptr );
+ }
+}
+
+void SvxBorderBackgroundDlg::PageCreated(const OUString& rPageId, SfxTabPage& rTabPage)
+{
+ if (rPageId == "background")
+ {
+ SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool()));
+ // allow switching between Color/graphic
+ if (mbEnableBackgroundSelector)
+ aSet.Put(SfxUInt32Item(SID_FLAG_TYPE, static_cast<sal_uInt32>(SvxBackgroundTabFlags::SHOW_SELECTOR)));
+ rTabPage.PageCreated(aSet);
+ }
+ // inits for Area and Transparency TabPages
+ // The selection attribute lists (XPropertyList derivates, e.g. XColorList for
+ // the color table) need to be added as items (e.g. SvxColorTableItem) to make
+ // these pages find the needed attributes for fill style suggestions.
+ // These are added in SwDocStyleSheet::GetItemSet() for the SfxStyleFamily::Para on
+ // demand, but could also be directly added from the DrawModel.
+ else if (rPageId == "area")
+ {
+ SfxItemSetFixed<SID_COLOR_TABLE, SID_PATTERN_LIST,
+ SID_OFFER_IMPORT, SID_OFFER_IMPORT>
+ aNew(*GetInputSetImpl()->GetPool());
+
+ aNew.Put(*GetInputSetImpl());
+
+ // add flag for direct graphic content selection
+ aNew.Put(SfxBoolItem(SID_OFFER_IMPORT, true));
+
+ rTabPage.PageCreated(aNew);
+ }
+ else if (rPageId == "transparence")
+ {
+ rTabPage.PageCreated(*GetInputSetImpl());
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/border.cxx b/cui/source/tabpages/border.cxx
new file mode 100644
index 0000000000..ca2b7d61e2
--- /dev/null
+++ b/cui/source/tabpages/border.cxx
@@ -0,0 +1,1700 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <sfx2/objsh.hxx>
+#include <svx/strings.hrc>
+#include <svx/svxids.hrc>
+
+#include <strings.hrc>
+#include <bitmaps.hlst>
+
+#include <editeng/boxitem.hxx>
+#include <editeng/lineitem.hxx>
+#include <border.hxx>
+#include <svx/dlgutil.hxx>
+#include <dialmgr.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <vcl/fieldvalues.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <svx/dialmgr.hxx>
+#include <svx/flagsdef.hxx>
+#include <svl/grabbagitem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/ilstitem.hxx>
+#include <svl/int64item.hxx>
+#include <sal/macros.h>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <comphelper/lok.hxx>
+#include <svtools/unitconv.hxx>
+
+using namespace ::editeng;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::lang::XServiceInfo;
+using ::com::sun::star::uno::UNO_QUERY;
+
+
+/*
+ * [Description:]
+ * TabPage for setting the border attributes.
+ * Needs
+ * a SvxShadowItem: shadow
+ * a SvxBoxItem: lines left, right, top, bottom,
+ * a SvxBoxInfo: lines vertical, horizontal, distance, flags
+ *
+ * Lines can have three conditions:
+ * 1. Show ( -> valid values )
+ * 2. Hide ( -> NULL-Pointer )
+ * 3. DontCare ( -> special Valid-Flags in the InfoItem )
+ */
+
+// static ----------------------------------------------------------------
+
+const WhichRangesContainer SvxBorderTabPage::pRanges(
+ svl::Items<
+ SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_SHADOW,
+ SID_ATTR_ALIGN_MARGIN, SID_ATTR_ALIGN_MARGIN,
+ SID_ATTR_BORDER_CONNECT, SID_ATTR_BORDER_CONNECT,
+ SID_SW_COLLAPSING_BORDERS, SID_SW_COLLAPSING_BORDERS,
+ SID_ATTR_BORDER_DIAG_TLBR, SID_ATTR_BORDER_DIAG_BLTR>);
+
+namespace
+{
+constexpr int twipsToPt100(sal_Int64 nTwips)
+{
+ return o3tl::convert(nTwips * 100, o3tl::Length::twip, o3tl::Length::pt);
+}
+constexpr int s_LineWidths[] = { twipsToPt100(SvxBorderLineWidth::Hairline),
+ twipsToPt100(SvxBorderLineWidth::VeryThin),
+ twipsToPt100(SvxBorderLineWidth::Thin),
+ twipsToPt100(SvxBorderLineWidth::Medium),
+ twipsToPt100(SvxBorderLineWidth::Thick),
+ twipsToPt100(SvxBorderLineWidth::ExtraThick),
+ -1 };
+}
+
+static void lcl_SetDecimalDigitsTo1(weld::MetricSpinButton& rField)
+{
+ auto nMin = rField.denormalize(rField.get_min(FieldUnit::TWIP));
+ rField.set_digits(1);
+ rField.set_min(rField.normalize(nMin), FieldUnit::TWIP);
+}
+
+// returns in pt
+static sal_Int64 lcl_GetMinLineWidth(SvxBorderLineStyle aStyle)
+{
+ switch (aStyle)
+ {
+ case SvxBorderLineStyle::NONE:
+ return 0;
+
+ case SvxBorderLineStyle::SOLID:
+ case SvxBorderLineStyle::DOTTED:
+ case SvxBorderLineStyle::DASHED:
+ case SvxBorderLineStyle::FINE_DASHED:
+ case SvxBorderLineStyle::DASH_DOT:
+ case SvxBorderLineStyle::DASH_DOT_DOT:
+ return 15;
+
+ // Double lines
+ case SvxBorderLineStyle::DOUBLE: return 15;
+ case SvxBorderLineStyle::DOUBLE_THIN: return 15;
+ case SvxBorderLineStyle::THINTHICK_SMALLGAP: return 20;
+ case SvxBorderLineStyle::THINTHICK_MEDIUMGAP: return 15;
+ case SvxBorderLineStyle::THINTHICK_LARGEGAP: return 15;
+ case SvxBorderLineStyle::THICKTHIN_SMALLGAP: return 20;
+ case SvxBorderLineStyle::THICKTHIN_MEDIUMGAP: return 15;
+ case SvxBorderLineStyle::THICKTHIN_LARGEGAP: return 15;
+
+ case SvxBorderLineStyle::EMBOSSED: return 15;
+ case SvxBorderLineStyle::ENGRAVED: return 15;
+
+ case SvxBorderLineStyle::OUTSET: return 10;
+ case SvxBorderLineStyle::INSET: return 10;
+
+ default:
+ return 15;
+ }
+}
+
+// number of preset images to show
+const sal_uInt16 BORDER_PRESET_COUNT = 5;
+
+// number of shadow images to show
+const sal_uInt16 BORDER_SHADOW_COUNT = 5;
+
+ShadowControlsWrapper::ShadowControlsWrapper(ValueSet& rVsPos, weld::MetricSpinButton& rMfSize, ColorListBox& rLbColor)
+ : mrVsPos(rVsPos)
+ , mrMfSize(rMfSize)
+ , mrLbColor(rLbColor)
+{
+}
+
+SvxShadowItem ShadowControlsWrapper::GetControlValue(const SvxShadowItem& rItem) const
+{
+ SvxShadowItem aItem(rItem);
+ if (!mrVsPos.IsNoSelection())
+ {
+ switch (mrVsPos.GetSelectedItemId())
+ {
+ case 1:
+ aItem.SetLocation(SvxShadowLocation::NONE);
+ break;
+ case 2:
+ aItem.SetLocation(SvxShadowLocation::BottomRight);
+ break;
+ case 3:
+ aItem.SetLocation(SvxShadowLocation::TopRight);
+ break;
+ case 4:
+ aItem.SetLocation(SvxShadowLocation::BottomLeft);
+ break;
+ case 5:
+ aItem.SetLocation(SvxShadowLocation::TopLeft);
+ break;
+ default:
+ aItem.SetLocation(SvxShadowLocation::NONE);
+ break;
+ }
+ }
+ // Default value was saved; so don't change the aItem's width if the control
+ // has not changed its value, to avoid round-trip errors (like twip->cm->twip)
+ // E.g., initial 100 twip will become 0.18 cm, which will return as 102 twip
+ if (mrMfSize.get_value_changed_from_saved())
+ aItem.SetWidth(mrMfSize.denormalize(mrMfSize.get_value(FieldUnit::TWIP)));
+ if (!mrLbColor.IsNoSelection())
+ aItem.SetColor(mrLbColor.GetSelectEntryColor());
+ return aItem;
+}
+
+void ShadowControlsWrapper::SetControlValue(const SvxShadowItem& rItem)
+{
+ switch (rItem.GetLocation())
+ {
+ case SvxShadowLocation::NONE:
+ mrVsPos.SelectItem(1);
+ break;
+ case SvxShadowLocation::BottomRight:
+ mrVsPos.SelectItem(2);
+ break;
+ case SvxShadowLocation::TopRight:
+ mrVsPos.SelectItem(3);
+ break;
+ case SvxShadowLocation::BottomLeft:
+ mrVsPos.SelectItem(4);
+ break;
+ case SvxShadowLocation::TopLeft:
+ mrVsPos.SelectItem(5);
+ break;
+ default:
+ mrVsPos.SetNoSelection();
+ break;
+ }
+ mrVsPos.SaveValue();
+ mrMfSize.set_value(mrMfSize.normalize(rItem.GetWidth()), FieldUnit::TWIP);
+ mrMfSize.save_value();
+ mrLbColor.SelectEntry(rItem.GetColor());
+ mrLbColor.SaveValue();
+}
+
+bool ShadowControlsWrapper::get_value_changed_from_saved() const
+{
+ return mrVsPos.IsValueChangedFromSaved() ||
+ mrMfSize.get_value_changed_from_saved() ||
+ mrLbColor.IsValueChangedFromSaved();
+}
+
+void ShadowControlsWrapper::SetControlDontKnow()
+{
+ mrVsPos.SetNoSelection();
+ mrMfSize.set_text("");
+ mrLbColor.SetNoSelection();
+}
+
+MarginControlsWrapper::MarginControlsWrapper(weld::MetricSpinButton& rMfLeft, weld::MetricSpinButton& rMfRight,
+ weld::MetricSpinButton& rMfTop, weld::MetricSpinButton& rMfBottom)
+ : mrLeftWrp(rMfLeft)
+ , mrRightWrp(rMfRight)
+ , mrTopWrp(rMfTop)
+ , mrBottomWrp(rMfBottom)
+{
+}
+
+SvxMarginItem MarginControlsWrapper::GetControlValue(const SvxMarginItem &rItem) const
+{
+ SvxMarginItem aItem(rItem);
+ if (mrLeftWrp.get_sensitive())
+ aItem.SetLeftMargin(mrLeftWrp.denormalize(mrLeftWrp.get_value(FieldUnit::TWIP)));
+ if (mrRightWrp.get_sensitive())
+ aItem.SetRightMargin(mrRightWrp.denormalize(mrRightWrp.get_value(FieldUnit::TWIP)));
+ if (mrTopWrp.get_sensitive())
+ aItem.SetTopMargin(mrTopWrp.denormalize(mrTopWrp.get_value(FieldUnit::TWIP)));
+ if (mrBottomWrp.get_sensitive())
+ aItem.SetBottomMargin(mrBottomWrp.denormalize(mrBottomWrp.get_value(FieldUnit::TWIP)));
+ return aItem;
+}
+
+bool MarginControlsWrapper::get_value_changed_from_saved() const
+{
+ return mrLeftWrp.get_value_changed_from_saved() ||
+ mrRightWrp.get_value_changed_from_saved() ||
+ mrTopWrp.get_value_changed_from_saved() ||
+ mrBottomWrp.get_value_changed_from_saved();
+}
+
+void MarginControlsWrapper::SetControlValue(const SvxMarginItem& rItem)
+{
+ mrLeftWrp.set_value(mrLeftWrp.normalize(rItem.GetLeftMargin()), FieldUnit::TWIP);
+ mrRightWrp.set_value(mrRightWrp.normalize(rItem.GetRightMargin()), FieldUnit::TWIP);
+ mrTopWrp.set_value(mrTopWrp.normalize(rItem.GetTopMargin()), FieldUnit::TWIP);
+ mrBottomWrp.set_value(mrBottomWrp.normalize(rItem.GetBottomMargin()), FieldUnit::TWIP);
+ mrLeftWrp.save_value();
+ mrRightWrp.save_value();
+ mrTopWrp.save_value();
+ mrBottomWrp.save_value();
+}
+
+void MarginControlsWrapper::SetControlDontKnow()
+{
+ const OUString sEmpty;
+ mrLeftWrp.set_text(sEmpty);
+ mrRightWrp.set_text(sEmpty);
+ mrTopWrp.set_text(sEmpty);
+ mrBottomWrp.set_text(sEmpty);
+}
+
+SvxBorderTabPage::SvxBorderTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/borderpage.ui", "BorderPage", &rCoreAttrs)
+ , nMinValue(0)
+ , nSWMode(SwBorderModes::NONE)
+ , mnBoxSlot(SID_ATTR_BORDER_OUTER)
+ , mnShadowSlot(SID_ATTR_BORDER_SHADOW)
+ , mbHorEnabled(false)
+ , mbVerEnabled(false)
+ , mbTLBREnabled(false)
+ , mbBLTREnabled(false)
+ , mbUseMarginItem(false)
+ , mbLeftModified(false)
+ , mbRightModified(false)
+ , mbTopModified(false)
+ , mbBottomModified(false)
+ , mbSync(true)
+ , mbRemoveAdjacentCellBorders(false)
+ , bIsCalcDoc(false)
+ , m_xWndPresets(new ValueSet(nullptr))
+ , m_xWndPresetsWin(new weld::CustomWeld(*m_xBuilder, "presets", *m_xWndPresets))
+ , m_xUserDefFT(m_xBuilder->weld_label("userdefft"))
+ , m_xFrameSelWin(new weld::CustomWeld(*m_xBuilder, "framesel", m_aFrameSel))
+ , m_xLbLineStyle(new SvtLineListBox(m_xBuilder->weld_menu_button("linestylelb")))
+ , m_xLbLineColor(new ColorListBox(m_xBuilder->weld_menu_button("linecolorlb"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xLineWidthLB(m_xBuilder->weld_combo_box("linewidthlb"))
+ , m_xLineWidthMF(m_xBuilder->weld_metric_spin_button("linewidthmf", FieldUnit::POINT))
+ , m_xSpacingFrame(m_xBuilder->weld_container("spacing"))
+ , m_xLeftFT(m_xBuilder->weld_label("leftft"))
+ , m_xLeftMF(m_xBuilder->weld_metric_spin_button("leftmf", FieldUnit::MM))
+ , m_xRightFT(m_xBuilder->weld_label("rightft"))
+ , m_xRightMF(m_xBuilder->weld_metric_spin_button("rightmf", FieldUnit::MM))
+ , m_xTopFT(m_xBuilder->weld_label("topft"))
+ , m_xTopMF(m_xBuilder->weld_metric_spin_button("topmf", FieldUnit::MM))
+ , m_xBottomFT(m_xBuilder->weld_label("bottomft"))
+ , m_xBottomMF(m_xBuilder->weld_metric_spin_button("bottommf", FieldUnit::MM))
+ , m_xSynchronizeCB(m_xBuilder->weld_check_button("sync"))
+ , m_xShadowFrame(m_xBuilder->weld_container("shadow"))
+ , m_xWndShadows(new ValueSet(nullptr))
+ , m_xWndShadowsWin(new weld::CustomWeld(*m_xBuilder, "shadows", *m_xWndShadows))
+ , m_xFtShadowSize(m_xBuilder->weld_label("distanceft"))
+ , m_xEdShadowSize(m_xBuilder->weld_metric_spin_button("distancemf", FieldUnit::MM))
+ , m_xFtShadowColor(m_xBuilder->weld_label("shadowcolorft"))
+ , m_xLbShadowColor(new ColorListBox(m_xBuilder->weld_menu_button("shadowcolorlb"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xPropertiesFrame(m_xBuilder->weld_container("properties"))
+ , m_xMergeWithNextCB(m_xBuilder->weld_check_button("mergewithnext"))
+ , m_xMergeAdjacentBordersCB(m_xBuilder->weld_check_button("mergeadjacent"))
+ , m_xRemoveAdjacentCellBordersCB(m_xBuilder->weld_check_button("rmadjcellborders"))
+ , m_xRemoveAdjacentCellBordersFT(m_xBuilder->weld_label("rmadjcellbordersft"))
+{
+ static std::vector<OUString> aBorderImageIds;
+
+ if (aBorderImageIds.empty())
+ {
+ if (comphelper::LibreOfficeKit::isActive())
+ {
+ aBorderImageIds.insert(aBorderImageIds.end(), {
+ RID_SVXBMP_CELL_NONE_32,
+ RID_SVXBMP_CELL_ALL_32,
+ RID_SVXBMP_CELL_LR_32,
+ RID_SVXBMP_CELL_TB_32,
+ RID_SVXBMP_CELL_L_32,
+ RID_SVXBMP_CELL_DIAG_32
+ });
+ }
+ else
+ {
+ aBorderImageIds.insert(aBorderImageIds.end(), {
+ RID_SVXBMP_CELL_NONE,
+ RID_SVXBMP_CELL_ALL,
+ RID_SVXBMP_CELL_LR,
+ RID_SVXBMP_CELL_TB,
+ RID_SVXBMP_CELL_L,
+ RID_SVXBMP_CELL_DIAG
+ });
+ }
+ aBorderImageIds.insert(aBorderImageIds.end(), {
+ RID_SVXBMP_HOR_NONE,
+ RID_SVXBMP_HOR_OUTER,
+ RID_SVXBMP_HOR_HOR,
+ RID_SVXBMP_HOR_ALL,
+ RID_SVXBMP_HOR_OUTER2,
+ RID_SVXBMP_VER_NONE,
+ RID_SVXBMP_VER_OUTER,
+ RID_SVXBMP_VER_VER,
+ RID_SVXBMP_VER_ALL,
+ RID_SVXBMP_VER_OUTER2,
+ RID_SVXBMP_TABLE_NONE,
+ RID_SVXBMP_TABLE_OUTER,
+ RID_SVXBMP_TABLE_OUTERH,
+ RID_SVXBMP_TABLE_ALL,
+ RID_SVXBMP_TABLE_OUTER2
+ });
+ }
+
+ for (auto const & rImageId : aBorderImageIds)
+ m_aBorderImgVec.emplace_back(StockImage::Yes, rImageId);
+
+ static std::vector<OUString> aShadowImageIds;
+ if (aShadowImageIds.empty())
+ {
+ if (comphelper::LibreOfficeKit::isActive())
+ {
+ aShadowImageIds.insert(aShadowImageIds.end(), {
+ RID_SVXBMP_SHADOWNONE_32,
+ RID_SVXBMP_SHADOW_BOT_RIGHT_32,
+ RID_SVXBMP_SHADOW_TOP_RIGHT_32,
+ RID_SVXBMP_SHADOW_BOT_LEFT_32,
+ RID_SVXBMP_SHADOW_TOP_LEFT_32
+ });
+ }
+ else
+ {
+ aShadowImageIds.insert(aShadowImageIds.end(), {
+ RID_SVXBMP_SHADOWNONE,
+ RID_SVXBMP_SHADOW_BOT_RIGHT,
+ RID_SVXBMP_SHADOW_TOP_RIGHT,
+ RID_SVXBMP_SHADOW_BOT_LEFT,
+ RID_SVXBMP_SHADOW_TOP_LEFT
+ });
+ }
+ }
+
+ for (auto const & rImageId : aShadowImageIds)
+ m_aShadowImgVec.emplace_back(StockImage::Yes, rImageId);
+
+ assert(m_aShadowImgVec.size() == BORDER_SHADOW_COUNT);
+
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ /* Use SvxMarginItem instead of margins from SvxBoxItem, if present.
+ -> Remember this state in mbUseMarginItem, because other special handling
+ is needed across various functions... */
+ mbUseMarginItem = rCoreAttrs.GetItemState(GetWhich(SID_ATTR_ALIGN_MARGIN)) != SfxItemState::UNKNOWN;
+
+ if (const SfxIntegerListItem* p = rCoreAttrs.GetItemIfSet(SID_ATTR_BORDER_STYLES))
+ {
+ std::vector<sal_Int32> aUsedStyles = p->GetList();
+ for (int aUsedStyle : aUsedStyles)
+ maUsedBorderStyles.insert(static_cast<SvxBorderLineStyle>(aUsedStyle));
+ }
+
+ if (const SfxInt64Item* p = rCoreAttrs.GetItemIfSet(SID_ATTR_BORDER_DEFAULT_WIDTH))
+ {
+ // The caller specifies default line width. Honor it.
+ SetLineWidth(p->GetValue());
+ }
+
+ // set metric
+ FieldUnit eFUnit = GetModuleFieldUnit( rCoreAttrs );
+
+ if( mbUseMarginItem )
+ {
+ // copied from SvxAlignmentTabPage
+ switch ( eFUnit )
+ {
+ // #103396# the default value (1pt) can't be accurately represented in
+ // inches or pica with two decimals, so point is used instead.
+ case FieldUnit::PICA:
+ case FieldUnit::INCH:
+ case FieldUnit::FOOT:
+ case FieldUnit::MILE:
+ eFUnit = FieldUnit::POINT;
+ break;
+
+ case FieldUnit::CM:
+ case FieldUnit::M:
+ case FieldUnit::KM:
+ eFUnit = FieldUnit::MM;
+ break;
+ default: ;//prevent warning
+ }
+ }
+ else
+ {
+ switch ( eFUnit )
+ {
+ case FieldUnit::M:
+ case FieldUnit::KM:
+ eFUnit = FieldUnit::MM;
+ break;
+ default: ; //prevent warning
+ }
+ }
+
+ SetFieldUnit(*m_xEdShadowSize, eFUnit);
+
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_BORDER_INNER, false );
+ bool bIsDontCare = true;
+
+ if ( rCoreAttrs.GetItemState( nWhich ) >= SfxItemState::DEFAULT )
+ {
+ // paragraph or table
+ const SvxBoxInfoItem* pBoxInfo =
+ static_cast<const SvxBoxInfoItem*>(&( rCoreAttrs.Get( nWhich ) ));
+
+ mbHorEnabled = pBoxInfo->IsHorEnabled();
+ mbVerEnabled = pBoxInfo->IsVerEnabled();
+ mbTLBREnabled = rCoreAttrs.GetItemState(GetWhich(SID_ATTR_BORDER_DIAG_TLBR)) != SfxItemState::UNKNOWN;
+ mbBLTREnabled = rCoreAttrs.GetItemState(GetWhich(SID_ATTR_BORDER_DIAG_BLTR)) != SfxItemState::UNKNOWN;
+
+ if(pBoxInfo->IsDist())
+ {
+ SetFieldUnit(*m_xLeftMF, eFUnit);
+ SetFieldUnit(*m_xRightMF, eFUnit);
+ SetFieldUnit(*m_xTopMF, eFUnit);
+ SetFieldUnit(*m_xBottomMF, eFUnit);
+ m_xSynchronizeCB->connect_toggled(LINK(this, SvxBorderTabPage, SyncHdl_Impl));
+ m_xLeftMF->connect_value_changed(LINK(this, SvxBorderTabPage, ModifyDistanceHdl_Impl));
+ m_xRightMF->connect_value_changed(LINK(this, SvxBorderTabPage, ModifyDistanceHdl_Impl));
+ m_xTopMF->connect_value_changed(LINK(this, SvxBorderTabPage, ModifyDistanceHdl_Impl));
+ m_xBottomMF->connect_value_changed(LINK(this, SvxBorderTabPage, ModifyDistanceHdl_Impl));
+ }
+ else
+ {
+ m_xSpacingFrame->hide();
+ }
+ bIsDontCare = !pBoxInfo->IsValid( SvxBoxInfoItemValidFlags::DISABLE );
+ }
+ if(!mbUseMarginItem && eFUnit == FieldUnit::MM && MapUnit::MapTwip == rCoreAttrs.GetPool()->GetMetric( GetWhich( SID_ATTR_BORDER_INNER ) ))
+ {
+ //#i91548# changing the number of decimal digits changes the minimum values, too
+ lcl_SetDecimalDigitsTo1(*m_xLeftMF);
+ lcl_SetDecimalDigitsTo1(*m_xRightMF);
+ lcl_SetDecimalDigitsTo1(*m_xTopMF);
+ lcl_SetDecimalDigitsTo1(*m_xBottomMF);
+ lcl_SetDecimalDigitsTo1(*m_xEdShadowSize);
+ }
+
+ FrameSelFlags nFlags = FrameSelFlags::Outer;
+ if( mbHorEnabled )
+ nFlags |= FrameSelFlags::InnerHorizontal;
+ if( mbVerEnabled )
+ nFlags |= FrameSelFlags::InnerVertical;
+ if( mbTLBREnabled )
+ nFlags |= FrameSelFlags::DiagonalTLBR;
+ if( mbBLTREnabled )
+ nFlags |= FrameSelFlags::DiagonalBLTR;
+ if( bIsDontCare )
+ nFlags |= FrameSelFlags::DontCare;
+ m_aFrameSel.Initialize( nFlags );
+
+ m_aFrameSel.SetSelectHdl(LINK(this, SvxBorderTabPage, LinesChanged_Impl));
+ m_xLbLineStyle->SetSelectHdl( LINK( this, SvxBorderTabPage, SelStyleHdl_Impl ) );
+ m_xLbLineColor->SetSelectHdl( LINK( this, SvxBorderTabPage, SelColHdl_Impl ) );
+ m_xLineWidthLB->connect_changed(LINK(this, SvxBorderTabPage, ModifyWidthLBHdl_Impl));
+ m_xLineWidthMF->connect_value_changed(LINK(this, SvxBorderTabPage, ModifyWidthMFHdl_Impl));
+ m_xWndPresets->SetSelectHdl( LINK( this, SvxBorderTabPage, SelPreHdl_Impl ) );
+ m_xWndShadows->SetSelectHdl( LINK( this, SvxBorderTabPage, SelSdwHdl_Impl ) );
+
+ FillValueSets();
+ FillLineListBox_Impl();
+
+ // Reapply line width: probably one of predefined values should be selected
+ SetLineWidth(m_xLineWidthMF->get_value(FieldUnit::NONE));
+
+ // connections
+ const SfxPoolItem* pItem = nullptr;
+ if (rCoreAttrs.HasItem(GetWhich(SID_ATTR_PARA_GRABBAG), &pItem))
+ {
+ const SfxGrabBagItem* pGrabBag = static_cast<const SfxGrabBagItem*>(pItem);
+ auto it = pGrabBag->GetGrabBag().find("DialogUseCharAttr");
+ if (it != pGrabBag->GetGrabBag().end())
+ {
+ bool bDialogUseCharAttr = false;
+ it->second >>= bDialogUseCharAttr;
+ if (bDialogUseCharAttr)
+ {
+ mnShadowSlot = SID_ATTR_CHAR_SHADOW;
+ mnBoxSlot = SID_ATTR_CHAR_BOX;
+ }
+ }
+ }
+
+ bool bSupportsShadow = !SfxItemPool::IsSlot(GetWhich(mnShadowSlot));
+ if( bSupportsShadow )
+ m_xShadowControls.reset(new ShadowControlsWrapper(*m_xWndShadows, *m_xEdShadowSize, *m_xLbShadowColor));
+ else
+ HideShadowControls();
+
+ if (mbUseMarginItem)
+ m_xMarginControls.reset(new MarginControlsWrapper(*m_xLeftMF, *m_xRightMF, *m_xTopMF, *m_xBottomMF));
+
+ // checkbox "Merge with next paragraph" only visible for Writer dialog format.paragraph
+ m_xMergeWithNextCB->hide();
+ // checkbox "Merge adjacent line styles" only visible for Writer dialog format.table
+ m_xMergeAdjacentBordersCB->hide();
+
+ if (SfxObjectShell* pDocSh = SfxObjectShell::Current())
+ {
+ Reference< XServiceInfo > xSI( pDocSh->GetModel(), UNO_QUERY );
+ if ( xSI.is() )
+ bIsCalcDoc = xSI->supportsService("com.sun.star.sheet.SpreadsheetDocument");
+ }
+ if( bIsCalcDoc )
+ {
+ m_xRemoveAdjacentCellBordersCB->connect_toggled(LINK(this, SvxBorderTabPage, RemoveAdjacentCellBorderHdl_Impl));
+ m_xRemoveAdjacentCellBordersCB->show();
+ m_xRemoveAdjacentCellBordersCB->set_sensitive(false);
+ }
+ else
+ {
+ m_xRemoveAdjacentCellBordersCB->hide();
+ m_xRemoveAdjacentCellBordersFT->hide();
+ }
+}
+
+SvxBorderTabPage::~SvxBorderTabPage()
+{
+ m_xLbShadowColor.reset();
+ m_xWndShadowsWin.reset();
+ m_xWndShadows.reset();
+ m_xLbLineColor.reset();
+ m_xLbLineStyle.reset();
+ m_xFrameSelWin.reset();
+ m_xWndPresetsWin.reset();
+ m_xWndPresets.reset();
+}
+
+std::unique_ptr<SfxTabPage> SvxBorderTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxBorderTabPage>(pPage, pController, *rAttrSet);
+}
+
+void SvxBorderTabPage::ResetFrameLine_Impl( svx::FrameBorderType eBorder, const SvxBorderLine* pCoreLine, bool bValid )
+{
+ if( m_aFrameSel.IsBorderEnabled( eBorder ) )
+ {
+ if( bValid )
+ m_aFrameSel.ShowBorder( eBorder, pCoreLine );
+ else
+ m_aFrameSel.SetBorderDontCare( eBorder );
+ }
+}
+
+bool SvxBorderTabPage::IsBorderLineStyleAllowed( SvxBorderLineStyle nStyle ) const
+{
+ if (maUsedBorderStyles.empty())
+ // All border styles are allowed.
+ return true;
+
+ return maUsedBorderStyles.count(nStyle) > 0;
+}
+
+void SvxBorderTabPage::Reset( const SfxItemSet* rSet )
+{
+ SfxItemPool* pPool = rSet->GetPool();
+
+ if (m_aFrameSel.IsBorderEnabled(svx::FrameBorderType::TLBR))
+ {
+ sal_uInt16 nBorderDiagId = pPool->GetWhich(SID_ATTR_BORDER_DIAG_TLBR);
+ if (const SvxLineItem* pLineItem = static_cast<const SvxLineItem*>(rSet->GetItem(nBorderDiagId)))
+ m_aFrameSel.ShowBorder(svx::FrameBorderType::TLBR, pLineItem->GetLine());
+ else
+ m_aFrameSel.SetBorderDontCare(svx::FrameBorderType::TLBR);
+ }
+
+ if (m_aFrameSel.IsBorderEnabled(svx::FrameBorderType::BLTR))
+ {
+ sal_uInt16 nBorderDiagId = pPool->GetWhich(SID_ATTR_BORDER_DIAG_BLTR);
+ if (const SvxLineItem* pLineItem = static_cast<const SvxLineItem*>(rSet->GetItem(nBorderDiagId)))
+ m_aFrameSel.ShowBorder(svx::FrameBorderType::BLTR, pLineItem->GetLine());
+ else
+ m_aFrameSel.SetBorderDontCare(svx::FrameBorderType::BLTR);
+ }
+
+ if (m_xShadowControls)
+ {
+ sal_uInt16 nShadowId = pPool->GetWhich(mnShadowSlot);
+ const SfxPoolItem* pItem = rSet->GetItem(nShadowId);
+ if (pItem)
+ m_xShadowControls->SetControlValue(*static_cast<const SvxShadowItem*>(pItem));
+ else
+ m_xShadowControls->SetControlDontKnow();
+ }
+
+ if (m_xMarginControls)
+ {
+ sal_uInt16 nAlignMarginId = pPool->GetWhich(SID_ATTR_ALIGN_MARGIN);
+ const SfxPoolItem* pItem = rSet->GetItem(nAlignMarginId);
+ if (pItem)
+ m_xMarginControls->SetControlValue(*static_cast<const SvxMarginItem*>(pItem));
+ else
+ m_xMarginControls->SetControlDontKnow();
+ }
+
+ sal_uInt16 nMergeAdjacentBordersId = pPool->GetWhich(SID_SW_COLLAPSING_BORDERS);
+ const SfxBoolItem *pMergeAdjacentBorders = static_cast<const SfxBoolItem*>(rSet->GetItem(nMergeAdjacentBordersId));
+ if (!pMergeAdjacentBorders)
+ m_xMergeAdjacentBordersCB->set_state(TRISTATE_INDET);
+ else
+ m_xMergeAdjacentBordersCB->set_active(pMergeAdjacentBorders->GetValue());
+ m_xMergeAdjacentBordersCB->save_state();
+
+ sal_uInt16 nMergeWithNextId = pPool->GetWhich(SID_ATTR_BORDER_CONNECT);
+ const SfxBoolItem *pMergeWithNext = static_cast<const SfxBoolItem*>(rSet->GetItem(nMergeWithNextId));
+ if (!pMergeWithNext)
+ m_xMergeWithNextCB->set_state(TRISTATE_INDET);
+ else
+ m_xMergeWithNextCB->set_active(pMergeWithNext->GetValue());
+ m_xMergeWithNextCB->save_state();
+
+ const SvxBoxItem* pBoxItem;
+ const SvxBoxInfoItem* pBoxInfoItem;
+ sal_uInt16 nWhichBox = GetWhich(mnBoxSlot);
+ MapUnit eCoreUnit;
+
+ pBoxItem = static_cast<const SvxBoxItem*>(GetItem( *rSet, mnBoxSlot ));
+
+ pBoxInfoItem = GetItem( *rSet, SID_ATTR_BORDER_INNER, false );
+
+ eCoreUnit = pPool->GetMetric( nWhichBox );
+
+ if ( pBoxItem && pBoxInfoItem ) // -> Don't Care
+ {
+ ResetFrameLine_Impl( svx::FrameBorderType::Left, pBoxItem->GetLeft(), pBoxInfoItem->IsValid( SvxBoxInfoItemValidFlags::LEFT ) );
+ ResetFrameLine_Impl( svx::FrameBorderType::Right, pBoxItem->GetRight(), pBoxInfoItem->IsValid( SvxBoxInfoItemValidFlags::RIGHT ) );
+ ResetFrameLine_Impl( svx::FrameBorderType::Top, pBoxItem->GetTop(), pBoxInfoItem->IsValid( SvxBoxInfoItemValidFlags::TOP ) );
+ ResetFrameLine_Impl( svx::FrameBorderType::Bottom, pBoxItem->GetBottom(), pBoxInfoItem->IsValid( SvxBoxInfoItemValidFlags::BOTTOM ) );
+ ResetFrameLine_Impl( svx::FrameBorderType::Vertical, pBoxInfoItem->GetVert(), pBoxInfoItem->IsValid( SvxBoxInfoItemValidFlags::VERT ) );
+ ResetFrameLine_Impl( svx::FrameBorderType::Horizontal, pBoxInfoItem->GetHori(), pBoxInfoItem->IsValid( SvxBoxInfoItemValidFlags::HORI ) );
+
+
+ // distance inside
+
+ if( !mbUseMarginItem )
+ {
+ if (m_xLeftMF->get_visible())
+ {
+ SetMetricValue(*m_xLeftMF, pBoxInfoItem->GetDefDist(), eCoreUnit);
+ SetMetricValue(*m_xRightMF, pBoxInfoItem->GetDefDist(), eCoreUnit);
+ SetMetricValue(*m_xTopMF, pBoxInfoItem->GetDefDist(), eCoreUnit);
+ SetMetricValue(*m_xBottomMF, pBoxInfoItem->GetDefDist(), eCoreUnit);
+
+ nMinValue = m_xLeftMF->get_value(FieldUnit::NONE);
+
+ if ( pBoxInfoItem->IsDist() )
+ {
+ if( rSet->GetItemState( nWhichBox ) >= SfxItemState::DEFAULT )
+ {
+ bool bIsAnyBorderVisible = m_aFrameSel.IsAnyBorderVisible();
+ if( !bIsAnyBorderVisible || !pBoxInfoItem->IsMinDist() )
+ {
+ m_xLeftMF->set_min(0, FieldUnit::NONE);
+ m_xRightMF->set_min(0, FieldUnit::NONE);
+ m_xTopMF->set_min(0, FieldUnit::NONE);
+ m_xBottomMF->set_min(0, FieldUnit::NONE);
+ }
+ tools::Long nLeftDist = pBoxItem->GetDistance( SvxBoxItemLine::LEFT);
+ SetMetricValue(*m_xLeftMF, nLeftDist, eCoreUnit);
+ tools::Long nRightDist = pBoxItem->GetDistance( SvxBoxItemLine::RIGHT);
+ SetMetricValue(*m_xRightMF, nRightDist, eCoreUnit);
+ tools::Long nTopDist = pBoxItem->GetDistance( SvxBoxItemLine::TOP);
+ SetMetricValue( *m_xTopMF, nTopDist, eCoreUnit );
+ tools::Long nBottomDist = pBoxItem->GetDistance( SvxBoxItemLine::BOTTOM);
+ SetMetricValue( *m_xBottomMF, nBottomDist, eCoreUnit );
+
+ // if the distance is set with no active border line
+ // or it is null with an active border line
+ // no automatic changes should be made
+ const tools::Long nDefDist = bIsAnyBorderVisible ? pBoxInfoItem->GetDefDist() : 0;
+ bool bDiffDist = (nDefDist != nLeftDist ||
+ nDefDist != nRightDist ||
+ nDefDist != nTopDist ||
+ nDefDist != nBottomDist);
+ if ((pBoxItem->GetSmallestDistance() || bIsAnyBorderVisible) && bDiffDist )
+ {
+ mbLeftModified = true;
+ mbRightModified = true;
+ mbTopModified = true;
+ mbBottomModified = true;
+ }
+ }
+ else
+ {
+ // #106224# different margins -> do not fill the edits
+ m_xLeftMF->set_text( OUString() );
+ m_xRightMF->set_text( OUString() );
+ m_xTopMF->set_text( OUString() );
+ m_xBottomMF->set_text( OUString() );
+ }
+ }
+ m_xLeftMF->save_value();
+ m_xRightMF->save_value();
+ m_xTopMF->save_value();
+ m_xBottomMF->save_value();
+ }
+ }
+ }
+ else
+ {
+ // avoid ResetFrameLine-calls:
+ m_aFrameSel.HideAllBorders();
+ }
+
+ if( !m_aFrameSel.IsAnyBorderVisible() )
+ m_aFrameSel.DeselectAllBorders();
+
+ // depict line (color) in controllers if unambiguous:
+
+ {
+ // Do all visible lines show the same line widths?
+ tools::Long nWidth;
+ SvxBorderLineStyle nStyle;
+ bool bWidthEq = m_aFrameSel.GetVisibleWidth( nWidth, nStyle );
+ if( bWidthEq )
+ {
+ // Determine the width first as some styles can be missing depending on it
+ sal_Int64 nWidthPt = static_cast<sal_Int64>(vcl::ConvertDoubleValue(
+ sal_Int64( nWidth ), m_xLineWidthMF->get_digits(),
+ MapUnit::MapTwip, FieldUnit::POINT ));
+ SetLineWidth(nWidthPt);
+ m_xLbLineStyle->SetWidth(nWidth);
+
+ // then set the style
+ m_xLbLineStyle->SelectEntry( nStyle );
+ }
+ else
+ m_xLbLineStyle->SelectEntry(SvxBorderLineStyle::SOLID);
+
+ // Do all visible lines show the same line color?
+ Color aColor;
+ bool bColorEq = m_aFrameSel.GetVisibleColor( aColor );
+ if( !bColorEq )
+ aColor = COL_BLACK;
+
+ m_xLbLineColor->SelectEntry(aColor);
+ auto nTextColor = Application::GetSettings().GetStyleSettings().GetWindowTextColor();
+ m_xLbLineStyle->SetColor(nTextColor);
+
+ // Select all visible lines, if they are all equal.
+ if( bWidthEq && bColorEq )
+ m_aFrameSel.SelectAllVisibleBorders();
+
+ // set the current style and color (caches style in control even if nothing is selected)
+ SelStyleHdl_Impl(*m_xLbLineStyle);
+ SelColHdl_Impl(*m_xLbLineColor);
+ }
+
+ bool bEnable = m_xWndShadows->GetSelectedItemId() > 1 ;
+ m_xFtShadowSize->set_sensitive(bEnable);
+ m_xEdShadowSize->set_sensitive(bEnable);
+ m_xFtShadowColor->set_sensitive(bEnable);
+ m_xLbShadowColor->set_sensitive(bEnable);
+
+ m_xWndPresets->SetNoSelection();
+
+ // - no line - should not be selected
+
+ if (m_xLbLineStyle->GetSelectEntryStyle() == SvxBorderLineStyle::NONE)
+ {
+ m_xLbLineStyle->SelectEntry(SvxBorderLineStyle::SOLID);
+ SelStyleHdl_Impl(*m_xLbLineStyle);
+ }
+
+ const SfxUInt16Item* pHtmlModeItem = rSet->GetItemIfSet(SID_HTML_MODE, false);
+ if(!pHtmlModeItem)
+ {
+ if (SfxObjectShell* pShell = SfxObjectShell::Current())
+ pHtmlModeItem = pShell->GetItem(SID_HTML_MODE);
+ }
+ if(pHtmlModeItem)
+ {
+ sal_uInt16 nHtmlMode = pHtmlModeItem->GetValue();
+ if(nHtmlMode & HTMLMODE_ON)
+ {
+ // there are no shadows in Html-mode and only complete borders
+ m_xShadowFrame->set_sensitive(false);
+
+ if( !(nSWMode & SwBorderModes::TABLE) )
+ {
+ m_xUserDefFT->set_sensitive(false);
+ m_xFrameSelWin->set_sensitive(false);
+ m_xWndPresets->RemoveItem(3);
+ m_xWndPresets->RemoveItem(4);
+ m_xWndPresets->RemoveItem(5);
+ }
+ }
+ }
+
+ LinesChanged_Impl( nullptr );
+ if (m_xLeftMF->get_value(FieldUnit::NONE) == m_xRightMF->get_value(FieldUnit::NONE) &&
+ m_xTopMF->get_value(FieldUnit::NONE) == m_xBottomMF->get_value(FieldUnit::NONE) &&
+ m_xTopMF->get_value(FieldUnit::NONE) == m_xLeftMF->get_value(FieldUnit::NONE))
+ {
+ mbSync = true;
+ }
+ else
+ mbSync = false;
+ m_xSynchronizeCB->set_active(mbSync);
+
+ mbRemoveAdjacentCellBorders = false;
+ m_xRemoveAdjacentCellBordersCB->set_active(false);
+ m_xRemoveAdjacentCellBordersCB->set_sensitive(false);
+}
+
+void SvxBorderTabPage::ChangesApplied()
+{
+ m_xLeftMF->save_value();
+ m_xRightMF->save_value();
+ m_xTopMF->save_value();
+ m_xBottomMF->save_value();
+ m_xMergeWithNextCB->save_state();
+ m_xMergeAdjacentBordersCB->save_state();
+}
+
+DeactivateRC SvxBorderTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if ( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+bool SvxBorderTabPage::FillItemSet( SfxItemSet* rCoreAttrs )
+{
+ bool bAttrsChanged = false;
+
+ SfxItemPool* pPool = rCoreAttrs->GetPool();
+
+ if (m_aFrameSel.IsBorderEnabled(svx::FrameBorderType::TLBR) &&
+ m_aFrameSel.GetFrameBorderState(svx::FrameBorderType::TLBR) != svx::FrameBorderState::DontCare)
+ {
+ if (const SfxPoolItem* pOldItem = GetOldItem(*rCoreAttrs, SID_ATTR_BORDER_DIAG_TLBR))
+ {
+ SvxLineItem aLineItem(*static_cast<const SvxLineItem*>(pOldItem));
+ aLineItem.SetLine(m_aFrameSel.GetFrameBorderStyle(svx::FrameBorderType::TLBR));
+ rCoreAttrs->Put(aLineItem);
+ bAttrsChanged = true;
+ }
+ }
+
+ if (m_aFrameSel.IsBorderEnabled(svx::FrameBorderType::BLTR) &&
+ m_aFrameSel.GetFrameBorderState(svx::FrameBorderType::BLTR) != svx::FrameBorderState::DontCare)
+ {
+ if (const SfxPoolItem* pOldItem = GetOldItem(*rCoreAttrs, SID_ATTR_BORDER_DIAG_BLTR))
+ {
+ SvxLineItem aLineItem(*static_cast<const SvxLineItem*>(pOldItem));
+ aLineItem.SetLine(m_aFrameSel.GetFrameBorderStyle(svx::FrameBorderType::BLTR));
+ rCoreAttrs->Put(aLineItem);
+ bAttrsChanged = true;
+ }
+ }
+
+ if (m_xShadowControls && m_xShadowControls->get_value_changed_from_saved())
+ {
+ if (const SfxPoolItem* pOldItem = GetOldItem(*rCoreAttrs, mnShadowSlot))
+ {
+ const SvxShadowItem& rOldShadowItem = *static_cast<const SvxShadowItem*>(pOldItem);
+ rCoreAttrs->Put(m_xShadowControls->GetControlValue(rOldShadowItem));
+ bAttrsChanged = true;
+ }
+ }
+
+ if (m_xMarginControls && m_xMarginControls->get_value_changed_from_saved())
+ {
+ if (const SfxPoolItem* pOldItem = GetOldItem(*rCoreAttrs, SID_ATTR_ALIGN_MARGIN))
+ {
+ const SvxMarginItem& rOldMarginItem = *static_cast<const SvxMarginItem*>(pOldItem);
+ rCoreAttrs->Put(m_xMarginControls->GetControlValue(rOldMarginItem));
+ bAttrsChanged = true;
+ }
+ }
+
+ if (m_xMergeAdjacentBordersCB->get_state_changed_from_saved())
+ {
+ auto nState = m_xMergeAdjacentBordersCB->get_state();
+ if (nState == TRISTATE_INDET)
+ {
+ sal_uInt16 nMergeAdjacentBordersId = pPool->GetWhich(SID_SW_COLLAPSING_BORDERS);
+ rCoreAttrs->ClearItem(nMergeAdjacentBordersId);
+ }
+ else
+ {
+ if (const SfxPoolItem* pOldItem = GetOldItem(*rCoreAttrs, SID_SW_COLLAPSING_BORDERS))
+ {
+ std::unique_ptr<SfxBoolItem> xNewItem(static_cast<SfxBoolItem*>(pOldItem->Clone()));
+ xNewItem->SetValue(static_cast<bool>(nState));
+ rCoreAttrs->Put(std::move(xNewItem));
+ }
+ }
+ bAttrsChanged = true;
+ }
+
+ if (m_xMergeWithNextCB->get_state_changed_from_saved())
+ {
+ auto nState = m_xMergeWithNextCB->get_state();
+ if (nState == TRISTATE_INDET)
+ {
+ sal_uInt16 nMergeWithNextId = pPool->GetWhich(SID_ATTR_BORDER_CONNECT);
+ rCoreAttrs->ClearItem(nMergeWithNextId);
+ }
+ else
+ {
+ if (const SfxPoolItem* pOldItem = GetOldItem(*rCoreAttrs, SID_ATTR_BORDER_CONNECT))
+ {
+ std::unique_ptr<SfxBoolItem> xNewItem(static_cast<SfxBoolItem*>(pOldItem->Clone()));
+ xNewItem->SetValue(static_cast<bool>(nState));
+ rCoreAttrs->Put(std::move(xNewItem));
+ }
+ }
+ bAttrsChanged = true;
+ }
+
+ bool bPut = true;
+ sal_uInt16 nBoxWhich = GetWhich( mnBoxSlot );
+ sal_uInt16 nBoxInfoWhich = pPool->GetWhich( SID_ATTR_BORDER_INNER, false );
+ const SfxItemSet& rOldSet = GetItemSet();
+ SvxBoxItem aBoxItem ( nBoxWhich );
+ SvxBoxInfoItem aBoxInfoItem ( nBoxInfoWhich );
+ const SvxBoxItem* pOldBoxItem = static_cast<const SvxBoxItem*>(GetOldItem( *rCoreAttrs, mnBoxSlot ));
+
+ MapUnit eCoreUnit = rOldSet.GetPool()->GetMetric( nBoxWhich );
+
+
+ // outer border:
+
+ std::pair<svx::FrameBorderType,SvxBoxItemLine> eTypes1[] = {
+ { svx::FrameBorderType::Top,SvxBoxItemLine::TOP },
+ { svx::FrameBorderType::Bottom,SvxBoxItemLine::BOTTOM },
+ { svx::FrameBorderType::Left,SvxBoxItemLine::LEFT },
+ { svx::FrameBorderType::Right,SvxBoxItemLine::RIGHT },
+ };
+
+ for (std::pair<svx::FrameBorderType,SvxBoxItemLine> const & i : eTypes1)
+ aBoxItem.SetLine( m_aFrameSel.GetFrameBorderStyle( i.first ), i.second );
+
+
+ aBoxItem.SetRemoveAdjacentCellBorder( mbRemoveAdjacentCellBorders );
+ // border hor/ver and TableFlag
+
+ std::pair<svx::FrameBorderType,SvxBoxInfoItemLine> eTypes2[] = {
+ { svx::FrameBorderType::Horizontal,SvxBoxInfoItemLine::HORI },
+ { svx::FrameBorderType::Vertical,SvxBoxInfoItemLine::VERT }
+ };
+ for (std::pair<svx::FrameBorderType,SvxBoxInfoItemLine> const & j : eTypes2)
+ aBoxInfoItem.SetLine( m_aFrameSel.GetFrameBorderStyle( j.first ), j.second );
+
+ aBoxInfoItem.EnableHor( mbHorEnabled );
+ aBoxInfoItem.EnableVer( mbVerEnabled );
+
+
+ // inner distance
+
+ if (m_xLeftMF->get_visible())
+ {
+ // #i40405# enable distance controls for next dialog call
+ aBoxInfoItem.SetDist( true );
+
+ if( !mbUseMarginItem )
+ {
+ // #106224# all edits empty: do nothing
+ if( !m_xLeftMF->get_text().isEmpty() || !m_xRightMF->get_text().isEmpty() ||
+ !m_xTopMF->get_text().isEmpty() || !m_xBottomMF->get_text().isEmpty() )
+ {
+ const SvxBoxInfoItem* pOldBoxInfoItem = GetOldItem( *rCoreAttrs, SID_ATTR_BORDER_INNER );
+ if (
+ !pOldBoxItem ||
+ m_xLeftMF->get_value_changed_from_saved() ||
+ m_xRightMF->get_value_changed_from_saved() ||
+ m_xTopMF->get_value_changed_from_saved() ||
+ m_xBottomMF->get_value_changed_from_saved() ||
+ nMinValue == m_xLeftMF->get_value(FieldUnit::NONE) ||
+ nMinValue == m_xRightMF->get_value(FieldUnit::NONE) ||
+ nMinValue == m_xTopMF->get_value(FieldUnit::NONE) ||
+ nMinValue == m_xBottomMF->get_value(FieldUnit::NONE) ||
+ (pOldBoxInfoItem && !pOldBoxInfoItem->IsValid(SvxBoxInfoItemValidFlags::DISTANCE))
+ )
+ {
+ aBoxItem.SetDistance( static_cast<sal_uInt16>(GetCoreValue(*m_xLeftMF, eCoreUnit )), SvxBoxItemLine::LEFT );
+ aBoxItem.SetDistance( static_cast<sal_uInt16>(GetCoreValue(*m_xRightMF, eCoreUnit )), SvxBoxItemLine::RIGHT );
+ aBoxItem.SetDistance( static_cast<sal_uInt16>(GetCoreValue(*m_xTopMF, eCoreUnit )), SvxBoxItemLine::TOP );
+ aBoxItem.SetDistance( static_cast<sal_uInt16>(GetCoreValue(*m_xBottomMF, eCoreUnit )), SvxBoxItemLine::BOTTOM);
+ }
+ else
+ {
+ aBoxItem.SetDistance(pOldBoxItem->GetDistance(SvxBoxItemLine::LEFT ), SvxBoxItemLine::LEFT);
+ aBoxItem.SetDistance(pOldBoxItem->GetDistance(SvxBoxItemLine::RIGHT), SvxBoxItemLine::RIGHT);
+ aBoxItem.SetDistance(pOldBoxItem->GetDistance(SvxBoxItemLine::TOP ), SvxBoxItemLine::TOP);
+ aBoxItem.SetDistance(pOldBoxItem->GetDistance(SvxBoxItemLine::BOTTOM), SvxBoxItemLine::BOTTOM);
+ }
+ aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::DISTANCE );
+ }
+ }
+ }
+
+
+ // note Don't Care Status in the Info-Item:
+
+ aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::TOP, m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Top ) != svx::FrameBorderState::DontCare );
+ aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::BOTTOM, m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Bottom ) != svx::FrameBorderState::DontCare );
+ aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::LEFT, m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Left ) != svx::FrameBorderState::DontCare );
+ aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::RIGHT, m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Right ) != svx::FrameBorderState::DontCare );
+ aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::HORI, m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Horizontal ) != svx::FrameBorderState::DontCare );
+ aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::VERT, m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Vertical ) != svx::FrameBorderState::DontCare );
+
+
+ // Put or Clear of the border?
+
+ bPut = true;
+
+ if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nBoxWhich, false ))
+ {
+ bPut = aBoxItem != static_cast<const SvxBoxItem&>(rOldSet.Get(nBoxWhich));
+ }
+ if( SfxItemState::DEFAULT == rOldSet.GetItemState( nBoxInfoWhich, false ) )
+ {
+ const SvxBoxInfoItem& rOldBoxInfo = static_cast<const SvxBoxInfoItem&>(
+ rOldSet.Get(nBoxInfoWhich));
+
+ aBoxInfoItem.SetMinDist( rOldBoxInfo.IsMinDist() );
+ aBoxInfoItem.SetDefDist( rOldBoxInfo.GetDefDist() );
+ bPut |= (aBoxInfoItem != rOldBoxInfo );
+ }
+
+ if ( bPut )
+ {
+ if ( !pOldBoxItem || *pOldBoxItem != aBoxItem )
+ {
+ rCoreAttrs->Put( aBoxItem );
+ bAttrsChanged = true;
+ }
+ const SfxPoolItem* pOld = GetOldItem( *rCoreAttrs, SID_ATTR_BORDER_INNER, false );
+
+ if ( !pOld || *static_cast<const SvxBoxInfoItem*>(pOld) != aBoxInfoItem )
+ {
+ rCoreAttrs->Put( aBoxInfoItem );
+ bAttrsChanged = true;
+ }
+ }
+ else
+ {
+ rCoreAttrs->ClearItem( nBoxWhich );
+ rCoreAttrs->ClearItem( nBoxInfoWhich );
+ }
+
+ return bAttrsChanged;
+}
+
+void SvxBorderTabPage::HideShadowControls()
+{
+ m_xShadowFrame->hide();
+}
+
+#define IID_PRE_CELL_NONE 1
+#define IID_PRE_CELL_ALL 2
+#define IID_PRE_CELL_LR 3
+#define IID_PRE_CELL_TB 4
+#define IID_PRE_CELL_L 5
+#define IID_PRE_CELL_DIAG 6
+#define IID_PRE_HOR_NONE 7
+#define IID_PRE_HOR_OUTER 8
+#define IID_PRE_HOR_HOR 9
+#define IID_PRE_HOR_ALL 10
+#define IID_PRE_HOR_OUTER2 11
+#define IID_PRE_VER_NONE 12
+#define IID_PRE_VER_OUTER 13
+#define IID_PRE_VER_VER 14
+#define IID_PRE_VER_ALL 15
+#define IID_PRE_VER_OUTER2 16
+#define IID_PRE_TABLE_NONE 17
+#define IID_PRE_TABLE_OUTER 18
+#define IID_PRE_TABLE_OUTERH 19
+#define IID_PRE_TABLE_ALL 20
+#define IID_PRE_TABLE_OUTER2 21
+
+IMPL_LINK_NOARG(SvxBorderTabPage, SelPreHdl_Impl, ValueSet*, void)
+{
+ const svx::FrameBorderState SHOW = svx::FrameBorderState::Show;
+ const svx::FrameBorderState HIDE = svx::FrameBorderState::Hide;
+ const svx::FrameBorderState DONT = svx::FrameBorderState::DontCare;
+
+ static const svx::FrameBorderState ppeStates[][ svx::FRAMEBORDERTYPE_COUNT ] =
+ { /* Left Right Top Bot Hor Ver TLBR BLTR */
+/* ---------------------+--------------------------------------------------- */
+/* IID_PRE_CELL_NONE */ { HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_CELL_ALL */ { SHOW, SHOW, SHOW, SHOW, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_CELL_LR */ { SHOW, SHOW, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_CELL_TB */ { HIDE, HIDE, SHOW, SHOW, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_CELL_L */ { SHOW, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_CELL_DIAG */ { HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, SHOW, SHOW },
+/* IID_PRE_HOR_NONE */ { HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_HOR_OUTER */ { SHOW, SHOW, SHOW, SHOW, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_HOR_HOR */ { HIDE, HIDE, SHOW, SHOW, SHOW, HIDE, HIDE, HIDE },
+/* IID_PRE_HOR_ALL */ { SHOW, SHOW, SHOW, SHOW, SHOW, HIDE, HIDE, HIDE },
+/* IID_PRE_HOR_OUTER2 */ { SHOW, SHOW, SHOW, SHOW, DONT, HIDE, HIDE, HIDE },
+/* IID_PRE_VER_NONE */ { HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_VER_OUTER */ { SHOW, SHOW, SHOW, SHOW, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_VER_VER */ { SHOW, SHOW, HIDE, HIDE, HIDE, SHOW, HIDE, HIDE },
+/* IID_PRE_VER_ALL */ { SHOW, SHOW, SHOW, SHOW, HIDE, SHOW, HIDE, HIDE },
+/* IID_PRE_VER_OUTER2 */ { SHOW, SHOW, SHOW, SHOW, HIDE, DONT, HIDE, HIDE },
+/* IID_PRE_TABLE_NONE */ { HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_TABLE_OUTER */ { SHOW, SHOW, SHOW, SHOW, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_TABLE_OUTERH */ { SHOW, SHOW, SHOW, SHOW, SHOW, HIDE, HIDE, HIDE },
+/* IID_PRE_TABLE_ALL */ { SHOW, SHOW, SHOW, SHOW, SHOW, SHOW, HIDE, HIDE },
+/* IID_PRE_TABLE_OUTER2 */ { SHOW, SHOW, SHOW, SHOW, DONT, DONT, HIDE, HIDE }
+ };
+
+ // first hide and deselect all frame borders
+ m_aFrameSel.HideAllBorders();
+ m_aFrameSel.DeselectAllBorders();
+
+ // Using image ID to find correct line in table above.
+ sal_uInt16 nLine = GetPresetImageId( m_xWndPresets->GetSelectedItemId() ) - 1;
+
+ // Apply all styles from the table
+ for( int nBorder = 0; nBorder < svx::FRAMEBORDERTYPE_COUNT; ++nBorder )
+ {
+ svx::FrameBorderType eBorder = svx::GetFrameBorderTypeFromIndex( nBorder );
+ switch( ppeStates[ nLine ][ nBorder ] )
+ {
+ case SHOW: m_aFrameSel.SelectBorder( eBorder ); break;
+ case HIDE: /* nothing to do */ break;
+ case DONT: m_aFrameSel.SetBorderDontCare( eBorder ); break;
+ }
+ }
+
+ // Show all lines that have been selected above
+ if( m_aFrameSel.IsAnyBorderSelected() )
+ {
+ // any visible style, but "no-line" in line list box? -> use hair-line
+ if (m_xLbLineStyle->GetSelectEntryStyle() == SvxBorderLineStyle::NONE)
+ m_xLbLineStyle->SelectEntry(SvxBorderLineStyle::SOLID);
+
+ // set current style to all previously selected lines
+ SelStyleHdl_Impl(*m_xLbLineStyle);
+ SelColHdl_Impl(*m_xLbLineColor);
+ }
+
+ // Presets ValueSet does not show a selection (used as push buttons).
+ m_xWndPresets->SetNoSelection();
+
+ LinesChanged_Impl( nullptr );
+ UpdateRemoveAdjCellBorderCB( nLine + 1 );
+}
+
+IMPL_LINK_NOARG(SvxBorderTabPage, SelSdwHdl_Impl, ValueSet*, void)
+{
+ bool bEnable = m_xWndShadows->GetSelectedItemId() > 1;
+ m_xFtShadowSize->set_sensitive(bEnable);
+ m_xEdShadowSize->set_sensitive(bEnable);
+ m_xFtShadowColor->set_sensitive(bEnable);
+ m_xLbShadowColor->set_sensitive(bEnable);
+}
+
+IMPL_LINK(SvxBorderTabPage, SelColHdl_Impl, ColorListBox&, rColorBox, void)
+{
+ NamedColor aNamedColor = rColorBox.GetSelectedEntry();
+ m_aFrameSel.SetColorToSelection(aNamedColor.m_aColor, aNamedColor.getComplexColor());
+}
+
+IMPL_LINK_NOARG(SvxBorderTabPage, ModifyWidthLBHdl_Impl, weld::ComboBox&, void)
+{
+ sal_Int32 nPos = m_xLineWidthLB->get_active();
+ sal_Int32 nRemovedType = 0;
+ if (m_xLineWidthLB->get_values_changed_from_saved()) {
+ nRemovedType = std::size(s_LineWidths) - m_xLineWidthLB->get_count();
+ }
+
+ SetLineWidth(s_LineWidths[nPos + nRemovedType], nRemovedType);
+
+ // Call the spinner handler to trigger all related modifications
+ ModifyWidthMFHdl_Impl(*m_xLineWidthMF);
+}
+
+IMPL_LINK_NOARG(SvxBorderTabPage, ModifyWidthMFHdl_Impl, weld::MetricSpinButton&, void)
+{
+ sal_Int64 nVal = m_xLineWidthMF->get_value(FieldUnit::NONE);
+
+ // for DOUBLE_THIN line style we cannot allow thinner line width then 1.10pt
+ if (m_xLbLineStyle->GetSelectEntryStyle() == SvxBorderLineStyle::DOUBLE_THIN)
+ m_xLineWidthMF->set_min(110, FieldUnit::NONE);
+ else
+ m_xLineWidthMF->set_min(5, FieldUnit::NONE);
+
+ nVal = static_cast<sal_Int64>(vcl::ConvertDoubleValue(
+ nVal,
+ m_xLineWidthMF->get_digits(),
+ FieldUnit::POINT, MapUnit::MapTwip ));
+ m_xLbLineStyle->SetWidth( nVal );
+
+ m_aFrameSel.SetStyleToSelection( nVal,
+ m_xLbLineStyle->GetSelectEntryStyle() );
+}
+
+IMPL_LINK_NOARG(SvxBorderTabPage, SelStyleHdl_Impl, SvtLineListBox&, void)
+{
+ sal_Int64 nOldWidth = m_xLineWidthMF->get_value(FieldUnit::NONE);
+
+ // for DOUBLE_THIN line style we cannot allow thinner line width then 1.10pt
+ if (m_xLbLineStyle->GetSelectEntryStyle() == SvxBorderLineStyle::DOUBLE_THIN)
+ m_xLineWidthMF->set_min(110, FieldUnit::NONE);
+ else
+ m_xLineWidthMF->set_min(5, FieldUnit::NONE);
+
+ nOldWidth = static_cast<sal_Int64>(vcl::ConvertDoubleValue(
+ nOldWidth,
+ m_xLineWidthMF->get_digits(),
+ FieldUnit::POINT,
+ MapUnit::MapTwip));
+
+ const sal_Int64 nOldMinWidth = lcl_GetMinLineWidth(m_aFrameSel.getCurrentStyleLineStyle());
+ const sal_Int64 nNewMinWidth = lcl_GetMinLineWidth(m_xLbLineStyle->GetSelectEntryStyle());
+
+ // auto change line-width if it doesn't correspond to minimal value
+ // let's change only in case when user has not changed the line-width into some custom value
+ sal_Int64 nNewWidth = (nOldMinWidth == nOldWidth) ? nNewMinWidth : nOldWidth;
+
+ // if we had selected a predefined border width under SvxBorderLineWidth::Medium set the Medium as default
+ // otherwise if we had a custom border width under 1.10pt then set the spinner to the maximum allowed value for double border styles
+ bool bNewDoubleHairline = m_xLbLineStyle->GetSelectEntryStyle() == SvxBorderLineStyle::DOUBLE_THIN && !m_xLineWidthMF->get_visible() &&
+ (nOldWidth == SvxBorderLineWidth::Hairline || nOldWidth == SvxBorderLineWidth::VeryThin || nOldWidth == SvxBorderLineWidth::Thin);
+ if (bNewDoubleHairline && nNewWidth < SvxBorderLineWidth::Medium)
+ nNewWidth = SvxBorderLineWidth::Medium;
+
+ // set value inside edit box
+ if (nOldWidth != nNewWidth)
+ {
+ const sal_Int64 nNewWidthPt = static_cast<sal_Int64>(vcl::ConvertDoubleValue(
+ nNewWidth,
+ m_xLineWidthMF->get_digits(),
+ MapUnit::MapTwip,
+ FieldUnit::POINT));
+ SetLineWidth(nNewWidthPt);
+ }
+
+ if (m_xLbLineStyle->GetSelectEntryStyle() == SvxBorderLineStyle::DOUBLE_THIN)
+ {
+ for (size_t i = 0; i < 3; i++)
+ {
+ m_xLineWidthLB->save_values_by_id(OUString::number(i));
+ m_xLineWidthLB->remove_id(OUString::number(i));
+ }
+ if (m_xLineWidthLB->get_active_id().isEmpty())
+ m_xLineWidthLB->set_active_id("3");
+ }
+ else
+ {
+ if (m_xLineWidthLB->get_values_changed_from_saved())
+ {
+ for (size_t i = 0; i < 3; i++)
+ m_xLineWidthLB->append(i, OUString::number(i), m_xLineWidthLB->get_saved_values(i));
+ m_xLineWidthLB->removeSavedValues();
+ }
+ }
+
+ // set value inside style box
+ m_aFrameSel.SetStyleToSelection( nNewWidth,
+ m_xLbLineStyle->GetSelectEntryStyle() );
+}
+
+
+// ValueSet handling
+sal_uInt16 SvxBorderTabPage::GetPresetImageId( sal_uInt16 nValueSetIdx ) const
+{
+ // table with all sets of predefined border styles
+ static const sal_uInt16 ppnImgIds[][ BORDER_PRESET_COUNT ] =
+ {
+ // simple cell without diagonal frame borders
+ { IID_PRE_CELL_NONE, IID_PRE_CELL_ALL, IID_PRE_CELL_LR, IID_PRE_CELL_TB, IID_PRE_CELL_L },
+ // simple cell with diagonal frame borders
+ { IID_PRE_CELL_NONE, IID_PRE_CELL_ALL, IID_PRE_CELL_LR, IID_PRE_CELL_TB, IID_PRE_CELL_DIAG },
+ // with horizontal inner frame border
+ { IID_PRE_HOR_NONE, IID_PRE_HOR_OUTER, IID_PRE_HOR_HOR, IID_PRE_HOR_ALL, IID_PRE_HOR_OUTER2 },
+ // with vertical inner frame border
+ { IID_PRE_VER_NONE, IID_PRE_VER_OUTER, IID_PRE_VER_VER, IID_PRE_VER_ALL, IID_PRE_VER_OUTER2 },
+ // with horizontal and vertical inner frame borders
+ { IID_PRE_TABLE_NONE, IID_PRE_TABLE_OUTER, IID_PRE_TABLE_OUTERH, IID_PRE_TABLE_ALL, IID_PRE_TABLE_OUTER2 }
+ };
+
+ // find correct set of presets
+ int nLine = 0;
+ if( !mbHorEnabled && !mbVerEnabled )
+ nLine = (mbTLBREnabled || mbBLTREnabled) ? 1 : 0;
+ else if( mbHorEnabled && !mbVerEnabled )
+ nLine = 2;
+ else if( !mbHorEnabled && mbVerEnabled )
+ nLine = 3;
+ else
+ nLine = 4;
+
+ DBG_ASSERT( (1 <= nValueSetIdx) && (nValueSetIdx <= BORDER_PRESET_COUNT),
+ "SvxBorderTabPage::GetPresetImageId - wrong index" );
+ return ppnImgIds[ nLine ][ nValueSetIdx - 1 ];
+}
+
+TranslateId SvxBorderTabPage::GetPresetStringId( sal_uInt16 nValueSetIdx ) const
+{
+ // string resource IDs for each image (in order of the IID_PRE_* image IDs)
+ static const TranslateId pnStrIds[] =
+ {
+ RID_SVXSTR_TABLE_PRESET_NONE,
+ RID_SVXSTR_PARA_PRESET_ALL,
+ RID_SVXSTR_PARA_PRESET_LEFTRIGHT,
+ RID_SVXSTR_PARA_PRESET_TOPBOTTOM,
+ RID_SVXSTR_PARA_PRESET_ONLYLEFT,
+ RID_SVXSTR_PARA_PRESET_DIAGONAL,
+
+ RID_SVXSTR_TABLE_PRESET_NONE,
+ RID_SVXSTR_TABLE_PRESET_ONLYOUTER,
+ RID_SVXSTR_HOR_PRESET_ONLYHOR,
+ RID_SVXSTR_TABLE_PRESET_OUTERALL,
+ RID_SVXSTR_TABLE_PRESET_OUTERINNER,
+
+ RID_SVXSTR_TABLE_PRESET_NONE,
+ RID_SVXSTR_TABLE_PRESET_ONLYOUTER,
+ RID_SVXSTR_VER_PRESET_ONLYVER,
+ RID_SVXSTR_TABLE_PRESET_OUTERALL,
+ RID_SVXSTR_TABLE_PRESET_OUTERINNER,
+
+ RID_SVXSTR_TABLE_PRESET_NONE,
+ RID_SVXSTR_TABLE_PRESET_ONLYOUTER,
+ RID_SVXSTR_TABLE_PRESET_OUTERHORI,
+ RID_SVXSTR_TABLE_PRESET_OUTERALL,
+ RID_SVXSTR_TABLE_PRESET_OUTERINNER
+ };
+ return pnStrIds[ GetPresetImageId( nValueSetIdx ) - 1 ];
+}
+
+void SvxBorderTabPage::FillPresetVS()
+{
+ // basic initialization of the ValueSet
+ m_xWndPresets->SetStyle( m_xWndPresets->GetStyle() | WB_ITEMBORDER | WB_DOUBLEBORDER );
+ m_xWndPresets->SetColCount( BORDER_PRESET_COUNT );
+
+ // insert images and help texts
+ for( sal_uInt16 nVSIdx = 1; nVSIdx <= BORDER_PRESET_COUNT; ++nVSIdx )
+ {
+ m_xWndPresets->InsertItem( nVSIdx );
+ m_xWndPresets->SetItemImage(nVSIdx, m_aBorderImgVec[GetPresetImageId(nVSIdx) - 1]);
+ m_xWndPresets->SetItemText( nVSIdx, SvxResId( GetPresetStringId( nVSIdx ) ) );
+ }
+
+ // show the control
+ m_xWndPresets->SetNoSelection();
+ m_xWndPresets->SetOptimalSize();
+ m_xWndPresets->Show();
+}
+
+void SvxBorderTabPage::FillShadowVS()
+{
+ // basic initialization of the ValueSet
+ m_xWndShadows->SetStyle( m_xWndShadows->GetStyle() | WB_ITEMBORDER | WB_DOUBLEBORDER );
+ m_xWndShadows->SetColCount( BORDER_SHADOW_COUNT );
+
+ // string resource IDs for each image
+ static const TranslateId pnStrIds[ BORDER_SHADOW_COUNT ] =
+ { RID_CUISTR_SHADOW_STYLE_NONE, RID_CUISTR_SHADOW_STYLE_BOTTOMRIGHT, RID_CUISTR_SHADOW_STYLE_TOPRIGHT, RID_CUISTR_SHADOW_STYLE_BOTTOMLEFT, RID_CUISTR_SHADOW_STYLE_TOPLEFT };
+
+ // insert images and help texts
+ for( sal_uInt16 nVSIdx = 1; nVSIdx <= BORDER_SHADOW_COUNT; ++nVSIdx )
+ {
+ m_xWndShadows->InsertItem( nVSIdx );
+ m_xWndShadows->SetItemImage(nVSIdx, m_aShadowImgVec[nVSIdx-1]);
+ m_xWndShadows->SetItemText( nVSIdx, CuiResId( pnStrIds[ nVSIdx - 1 ] ) );
+ }
+
+ // show the control
+ m_xWndShadows->SelectItem( 1 );
+ m_xWndShadows->SetOptimalSize();
+ m_xWndShadows->Show();
+}
+
+
+void SvxBorderTabPage::FillValueSets()
+{
+ FillPresetVS();
+ FillShadowVS();
+}
+
+void SvxBorderTabPage::SetLineWidth( sal_Int64 nWidth, sal_Int32 nRemovedType )
+{
+ if ( nWidth >= 0 )
+ m_xLineWidthMF->set_value( nWidth, FieldUnit::POINT );
+
+ auto it = std::find( std::begin(s_LineWidths), std::end(s_LineWidths), nWidth );
+
+ if ( it != std::end(s_LineWidths) && *it >= 0 )
+ {
+ // Select predefined value in combobox
+ m_xLineWidthMF->hide();
+ m_xLineWidthLB->set_active(std::distance(std::begin(s_LineWidths), it) - nRemovedType);
+ }
+ else
+ {
+ // This is not one of predefined values. Show spinner
+ m_xLineWidthLB->set_active(std::size(s_LineWidths) - nRemovedType -1);
+ m_xLineWidthMF->show();
+ }
+}
+
+static Color lcl_mediumColor( Color aMain, Color /*aDefault*/ )
+{
+ return SvxBorderLine::threeDMediumColor( aMain );
+}
+
+void SvxBorderTabPage::FillLineListBox_Impl()
+{
+ using namespace ::com::sun::star::table::BorderLineStyle;
+
+ static struct {
+ SvxBorderLineStyle mnStyle;
+ SvtLineListBox::ColorFunc mpColor1Fn;
+ SvtLineListBox::ColorFunc mpColor2Fn;
+ SvtLineListBox::ColorDistFunc mpColorDistFn;
+ } const aLines[] = {
+ // Simple lines
+ { SvxBorderLineStyle::SOLID, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::DOTTED, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::DASHED, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::FINE_DASHED, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::DASH_DOT, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::DASH_DOT_DOT, &sameColor, &sameColor, &sameDistColor },
+
+ // Double lines
+ { SvxBorderLineStyle::DOUBLE, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::DOUBLE_THIN, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::THINTHICK_SMALLGAP, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::THINTHICK_MEDIUMGAP, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::THINTHICK_LARGEGAP, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::THICKTHIN_SMALLGAP, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::THICKTHIN_MEDIUMGAP, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::THICKTHIN_LARGEGAP, &sameColor, &sameColor, &sameDistColor },
+
+ { SvxBorderLineStyle::EMBOSSED, &SvxBorderLine::threeDLightColor, &SvxBorderLine::threeDDarkColor, &lcl_mediumColor },
+ { SvxBorderLineStyle::ENGRAVED, &SvxBorderLine::threeDDarkColor, &SvxBorderLine::threeDLightColor, &lcl_mediumColor },
+
+ { SvxBorderLineStyle::OUTSET, &SvxBorderLine::lightColor, &SvxBorderLine::darkColor, &sameDistColor },
+ { SvxBorderLineStyle::INSET, &SvxBorderLine::darkColor, &SvxBorderLine::lightColor, &sameDistColor }
+ };
+
+ m_xLbLineStyle->SetSourceUnit( FieldUnit::TWIP );
+
+ for (size_t i = 0; i < std::size(aLines); ++i)
+ {
+ if (!IsBorderLineStyleAllowed(aLines[i].mnStyle))
+ continue;
+
+ m_xLbLineStyle->InsertEntry(
+ SvxBorderLine::getWidthImpl(aLines[i].mnStyle),
+ aLines[i].mnStyle,
+ lcl_GetMinLineWidth(aLines[i].mnStyle),
+ aLines[i].mpColor1Fn,
+ aLines[i].mpColor2Fn,
+ aLines[i].mpColorDistFn);
+ }
+
+ sal_Int64 nVal = m_xLineWidthMF->get_value(FieldUnit::NONE);
+ nVal = static_cast<sal_Int64>(vcl::ConvertDoubleValue(nVal, m_xLineWidthMF->get_digits(),
+ m_xLineWidthMF->get_unit(), MapUnit::MapTwip));
+ m_xLbLineStyle->SetWidth( nVal );
+}
+
+
+IMPL_LINK_NOARG(SvxBorderTabPage, LinesChanged_Impl, LinkParamNone*, void)
+{
+ if (!mbUseMarginItem && m_xLeftMF->get_visible())
+ {
+ bool bLineSet = m_aFrameSel.IsAnyBorderVisible();
+ bool bSpaceModified = mbLeftModified ||
+ mbRightModified ||
+ mbTopModified ||
+ mbBottomModified;
+
+ if(bLineSet)
+ {
+ if(!bSpaceModified)
+ {
+ m_xLeftMF->set_value(nMinValue, FieldUnit::NONE);
+ m_xRightMF->set_value(nMinValue, FieldUnit::NONE);
+ m_xTopMF->set_value(nMinValue, FieldUnit::NONE);
+ m_xBottomMF->set_value(nMinValue, FieldUnit::NONE);
+ }
+ }
+ else
+ {
+ m_xLeftMF->set_min(0, FieldUnit::NONE);
+ m_xRightMF->set_min(0, FieldUnit::NONE);
+ m_xTopMF->set_min(0, FieldUnit::NONE);
+ m_xBottomMF->set_min(0, FieldUnit::NONE);
+ }
+ // for tables everything is allowed
+ SvxBoxInfoItemValidFlags nValid = SvxBoxInfoItemValidFlags::TOP|SvxBoxInfoItemValidFlags::BOTTOM|SvxBoxInfoItemValidFlags::LEFT|SvxBoxInfoItemValidFlags::RIGHT;
+
+ m_xLeftFT->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::LEFT) );
+ m_xRightFT->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::RIGHT) );
+ m_xTopFT->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::TOP) );
+ m_xBottomFT->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::BOTTOM) );
+ m_xLeftMF->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::LEFT) );
+ m_xRightMF->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::RIGHT) );
+ m_xTopMF->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::TOP) );
+ m_xBottomMF->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::BOTTOM) );
+ m_xSynchronizeCB->set_sensitive(m_xRightMF->get_sensitive() || m_xTopMF->get_sensitive() ||
+ m_xBottomMF->get_sensitive() || m_xLeftMF->get_sensitive());
+ }
+ UpdateRemoveAdjCellBorderCB( SAL_MAX_UINT16 );
+}
+
+
+IMPL_LINK( SvxBorderTabPage, ModifyDistanceHdl_Impl, weld::MetricSpinButton&, rField, void)
+{
+ if (&rField == m_xLeftMF.get())
+ mbLeftModified = true;
+ else if (&rField == m_xRightMF.get())
+ mbRightModified = true;
+ else if (&rField == m_xTopMF.get())
+ mbTopModified = true;
+ else if (&rField == m_xBottomMF.get())
+ mbBottomModified = true;
+
+ if (mbSync)
+ {
+ const auto nVal = rField.get_value(FieldUnit::NONE);
+ if (&rField != m_xLeftMF.get())
+ m_xLeftMF->set_value(nVal, FieldUnit::NONE);
+ if (&rField != m_xRightMF.get())
+ m_xRightMF->set_value(nVal, FieldUnit::NONE);
+ if (&rField != m_xTopMF.get())
+ m_xTopMF->set_value(nVal, FieldUnit::NONE);
+ if (&rField != m_xBottomMF.get())
+ m_xBottomMF->set_value(nVal, FieldUnit::NONE);
+ }
+}
+
+IMPL_LINK( SvxBorderTabPage, SyncHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ mbSync = rBox.get_active();
+}
+
+IMPL_LINK( SvxBorderTabPage, RemoveAdjacentCellBorderHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ mbRemoveAdjacentCellBorders = rBox.get_active();
+}
+
+void SvxBorderTabPage::UpdateRemoveAdjCellBorderCB( sal_uInt16 nPreset )
+{
+ if( !bIsCalcDoc )
+ return;
+ const SfxItemSet& rOldSet = GetItemSet();
+ const SvxBoxInfoItem* pOldBoxInfoItem = GetOldItem( rOldSet, SID_ATTR_BORDER_INNER );
+ const SvxBoxItem* pOldBoxItem = static_cast<const SvxBoxItem*>(GetOldItem( rOldSet, mnBoxSlot ));
+ if( !pOldBoxInfoItem || !pOldBoxItem )
+ return;
+ std::pair<svx::FrameBorderType, SvxBoxInfoItemValidFlags> eTypes1[] = {
+ { svx::FrameBorderType::Top,SvxBoxInfoItemValidFlags::TOP },
+ { svx::FrameBorderType::Bottom,SvxBoxInfoItemValidFlags::BOTTOM },
+ { svx::FrameBorderType::Left,SvxBoxInfoItemValidFlags::LEFT },
+ { svx::FrameBorderType::Right,SvxBoxInfoItemValidFlags::RIGHT },
+ };
+ SvxBoxItemLine const eTypes2[] = {
+ SvxBoxItemLine::TOP,
+ SvxBoxItemLine::BOTTOM,
+ SvxBoxItemLine::LEFT,
+ SvxBoxItemLine::RIGHT,
+ };
+
+ // Check if current selection involves deletion of at least one border
+ bool bBorderDeletionReq = false;
+ for ( size_t i=0; i < std::size( eTypes1 ); ++i )
+ {
+ if( pOldBoxItem->GetLine( eTypes2[i] ) || !( pOldBoxInfoItem->IsValid( eTypes1[i].second ) ) )
+ {
+ if( m_aFrameSel.GetFrameBorderState( eTypes1[i].first ) == svx::FrameBorderState::Hide )
+ {
+ bBorderDeletionReq = true;
+ break;
+ }
+ }
+ }
+
+ if( !bBorderDeletionReq && ( nPreset == IID_PRE_CELL_NONE || nPreset == IID_PRE_TABLE_NONE ) )
+ bBorderDeletionReq = true;
+
+ m_xRemoveAdjacentCellBordersCB->set_sensitive(bBorderDeletionReq);
+
+ if( !bBorderDeletionReq )
+ {
+ mbRemoveAdjacentCellBorders = false;
+ m_xRemoveAdjacentCellBordersCB->set_active(false);
+ }
+}
+
+void SvxBorderTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxUInt16Item* pSWModeItem = aSet.GetItem<SfxUInt16Item>(SID_SWMODE_TYPE, false);
+ const SfxUInt32Item* pFlagItem = aSet.GetItem<SfxUInt32Item>(SID_FLAG_TYPE, false);
+ if (pSWModeItem)
+ {
+ nSWMode = static_cast<SwBorderModes>(pSWModeItem->GetValue());
+ // #i43593#
+ // show checkbox <m_xMergeWithNextCB> for format.paragraph
+ if ( nSWMode == SwBorderModes::PARA )
+ {
+ m_xMergeWithNextCB->show();
+ m_xPropertiesFrame->show();
+ }
+ // show checkbox <m_xMergeAdjacentBordersCB> for format.paragraph
+ else if ( nSWMode == SwBorderModes::TABLE )
+ {
+ m_xMergeAdjacentBordersCB->show();
+ m_xPropertiesFrame->show();
+ }
+ }
+ if (pFlagItem)
+ if ( ( pFlagItem->GetValue() & SVX_HIDESHADOWCTL ) == SVX_HIDESHADOWCTL )
+ HideShadowControls();
+}
+
+void SvxBorderTabPage::SetTableMode()
+{
+ nSWMode = SwBorderModes::TABLE;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/chardlg.cxx b/cui/source/tabpages/chardlg.cxx
new file mode 100644
index 0000000000..e851816c17
--- /dev/null
+++ b/cui/source/tabpages/chardlg.cxx
@@ -0,0 +1,3238 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <vcl/svapp.hxx>
+#include <vcl/idle.hxx>
+#include <svtools/ctrltool.hxx>
+#include <sfx2/objsh.hxx>
+#include <svx/svxids.hrc>
+#include <svtools/unitconv.hxx>
+#include <svl/cjkoptions.hxx>
+#include <svl/ctloptions.hxx>
+#include <chardlg.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/crossedoutitem.hxx>
+#include <editeng/contouritem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/escapementitem.hxx>
+#include <editeng/wrlmitem.hxx>
+#include <editeng/cmapitem.hxx>
+#include <editeng/kernitem.hxx>
+#include <editeng/flstitem.hxx>
+#include <editeng/autokernitem.hxx>
+#include <editeng/colritem.hxx>
+#include <dialmgr.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <cui/cuicharmap.hxx>
+#include "chardlg.h"
+#include <editeng/emphasismarkitem.hxx>
+#include <editeng/charreliefitem.hxx>
+#include <editeng/twolinesitem.hxx>
+#include <editeng/charhiddenitem.hxx>
+#include <editeng/charscaleitem.hxx>
+#include <editeng/charrotateitem.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <strings.hrc>
+#include <twolines.hrc>
+#include <svl/intitem.hxx>
+#include <svx/flagsdef.hxx>
+#include <FontFeatures.hxx>
+#include <FontFeaturesDialog.hxx>
+#include <sal/log.hxx>
+#include <osl/diagnose.h>
+#include <o3tl/unit_conversion.hxx>
+#include <o3tl/string_view.hxx>
+
+using namespace ::com::sun::star;
+
+// static ----------------------------------------------------------------
+
+const WhichRangesContainer SvxCharNamePage::pNameRanges(svl::Items<
+ SID_ATTR_CHAR_FONT, SID_ATTR_CHAR_WEIGHT,
+ SID_ATTR_CHAR_FONTHEIGHT, SID_ATTR_CHAR_FONTHEIGHT,
+ SID_ATTR_CHAR_COLOR, SID_ATTR_CHAR_COLOR,
+ SID_ATTR_CHAR_LANGUAGE, SID_ATTR_CHAR_LANGUAGE,
+ SID_ATTR_CHAR_CJK_FONT, SID_ATTR_CHAR_CJK_WEIGHT,
+ SID_ATTR_CHAR_CTL_FONT, SID_ATTR_CHAR_CTL_WEIGHT
+>);
+
+const WhichRangesContainer SvxCharEffectsPage::pEffectsRanges(svl::Items<
+ SID_ATTR_CHAR_SHADOWED, SID_ATTR_CHAR_UNDERLINE,
+ SID_ATTR_CHAR_COLOR, SID_ATTR_CHAR_COLOR,
+ SID_ATTR_CHAR_CASEMAP, SID_ATTR_CHAR_CASEMAP,
+ SID_ATTR_FLASH, SID_ATTR_FLASH,
+ SID_ATTR_CHAR_EMPHASISMARK, SID_ATTR_CHAR_EMPHASISMARK,
+ SID_ATTR_CHAR_RELIEF, SID_ATTR_CHAR_RELIEF,
+ SID_ATTR_CHAR_HIDDEN, SID_ATTR_CHAR_HIDDEN,
+ SID_ATTR_CHAR_OVERLINE, SID_ATTR_CHAR_OVERLINE
+>);
+
+const WhichRangesContainer SvxCharPositionPage::pPositionRanges(svl::Items<
+ SID_ATTR_CHAR_KERNING, SID_ATTR_CHAR_KERNING,
+ SID_ATTR_CHAR_ESCAPEMENT, SID_ATTR_CHAR_ESCAPEMENT,
+ SID_ATTR_CHAR_AUTOKERN, SID_ATTR_CHAR_AUTOKERN,
+ SID_ATTR_CHAR_ROTATED, SID_ATTR_CHAR_SCALEWIDTH,
+ SID_ATTR_CHAR_WIDTH_FIT_TO_LINE, SID_ATTR_CHAR_WIDTH_FIT_TO_LINE
+>);
+
+const WhichRangesContainer SvxCharTwoLinesPage::pTwoLinesRanges(svl::Items<
+ SID_ATTR_CHAR_TWO_LINES, SID_ATTR_CHAR_TWO_LINES
+>);
+
+// C-Function ------------------------------------------------------------
+
+static bool StateToAttr( TriState aState )
+{
+ return ( TRISTATE_TRUE == aState );
+}
+
+namespace
+{
+ void setPrevFontEscapement(SvxFont& _rFont,sal_uInt8 nProp, sal_uInt8 nEscProp, short nEsc )
+ {
+ _rFont.SetPropr( nProp );
+ _rFont.SetProprRel( nEscProp );
+ _rFont.SetEscapement( nEsc );
+ }
+}
+
+inline SvxFont& SvxCharBasePage::GetPreviewFont()
+{
+ return m_aPreviewWin.GetFont();
+}
+
+inline SvxFont& SvxCharBasePage::GetPreviewCJKFont()
+{
+ return m_aPreviewWin.GetCJKFont();
+}
+
+inline SvxFont& SvxCharBasePage::GetPreviewCTLFont()
+{
+ return m_aPreviewWin.GetCTLFont();
+}
+
+SvxCharBasePage::SvxCharBasePage(weld::Container* pPage, weld::DialogController* pController, const OUString& rUIXMLDescription, const OUString& rID, const SfxItemSet& rItemset)
+ : SfxTabPage(pPage, pController, rUIXMLDescription, rID, &rItemset)
+ , m_bPreviewBackgroundToCharacter( false )
+{
+}
+
+SvxCharBasePage::~SvxCharBasePage()
+{
+}
+
+void SvxCharBasePage::ActivatePage(const SfxItemSet& rSet)
+{
+ m_aPreviewWin.SetFromItemSet(rSet, m_bPreviewBackgroundToCharacter);
+}
+
+void SvxCharBasePage::SetPrevFontWidthScale( const SfxItemSet& rSet )
+{
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_SCALEWIDTH );
+ if (rSet.GetItemState(nWhich)>=SfxItemState::DEFAULT)
+ {
+ const SvxCharScaleWidthItem &rItem = static_cast<const SvxCharScaleWidthItem&>( rSet.Get( nWhich ) );
+ m_aPreviewWin.SetFontWidthScale(rItem.GetValue());
+ }
+}
+
+void SvxCharBasePage::SetPrevFontEscapement( sal_uInt8 nProp, sal_uInt8 nEscProp, short nEsc )
+{
+ setPrevFontEscapement(GetPreviewFont(),nProp,nEscProp,nEsc);
+ setPrevFontEscapement(GetPreviewCJKFont(),nProp,nEscProp,nEsc);
+ setPrevFontEscapement(GetPreviewCTLFont(),nProp,nEscProp,nEsc);
+ m_aPreviewWin.Invalidate();
+}
+
+
+// SvxCharNamePage_Impl --------------------------------------------------
+
+struct SvxCharNamePage_Impl
+{
+ Idle m_aUpdateIdle { "cui SvxCharNamePage_Impl m_aUpdateIdle" };
+ OUString m_aNoStyleText;
+ std::unique_ptr<FontList> m_pFontList;
+ int m_nExtraEntryPos;
+ bool m_bInSearchMode;
+
+ SvxCharNamePage_Impl()
+ : m_nExtraEntryPos(std::numeric_limits<int>::max())
+ , m_bInSearchMode(false)
+
+ {
+ m_aUpdateIdle.SetPriority( TaskPriority::LOWEST );
+ }
+};
+
+// class SvxCharNamePage -------------------------------------------------
+
+SvxCharNamePage::SvxCharNamePage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInSet)
+ : SvxCharBasePage(pPage, pController, "cui/ui/charnamepage.ui", "CharNamePage", rInSet)
+ , m_pImpl(new SvxCharNamePage_Impl)
+ // Western
+ , m_xWestern(m_xBuilder->weld_notebook("nbWestern"))
+ , m_xWestFontNameFT(m_xBuilder->weld_label("lbWestFontname"))
+ , m_xWestFontStyleFT(m_xBuilder->weld_label("lbWestStyle"))
+ , m_xWestFontStyleLB(new FontStyleBox(m_xBuilder->weld_combo_box("cbWestStyle")))
+ , m_xWestFontSizeFT(m_xBuilder->weld_label("lbWestSize"))
+ , m_xWestFontSizeLB(new FontSizeBox(m_xBuilder->weld_combo_box("cbWestSize")))
+ , m_xWestFontLanguageFT(m_xBuilder->weld_label("lbWestLanguage"))
+ , m_xWestFontLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("cbWestLanguage")))
+ , m_xWestFontFeaturesButton(m_xBuilder->weld_button("btnWestFeatures"))
+ , m_xWestFontTypeFT(m_xBuilder->weld_label("lbWestFontinfo"))
+ , m_xCJK_CTL(m_xBuilder->weld_notebook("nbCJKCTL"))
+ // CJK
+ , m_xEastFontNameFT(m_xBuilder->weld_label("lbCJKFontname"))
+ , m_xEastFontStyleFT(m_xBuilder->weld_label("lbCJKStyle"))
+ , m_xEastFontStyleLB(new FontStyleBox(m_xBuilder->weld_combo_box("cbCJKStyle")))
+ , m_xEastFontSizeFT(m_xBuilder->weld_label("lbCJKSize"))
+ , m_xEastFontSizeLB(new FontSizeBox(m_xBuilder->weld_combo_box("cbCJKSize")))
+ , m_xEastFontLanguageFT(m_xBuilder->weld_label("lbCJKLanguage"))
+ , m_xEastFontLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("cbCJKLanguage")))
+ , m_xEastFontFeaturesButton(m_xBuilder->weld_button("btnCJKFeatures"))
+ , m_xEastFontTypeFT(m_xBuilder->weld_label("lbCJKFontinfo"))
+ // CTL
+ , m_xCTLFontNameFT(m_xBuilder->weld_label("lbCTLFontname"))
+ // tree
+ , m_xCTLFontStyleFT(m_xBuilder->weld_label("lbCTLStyle"))
+ , m_xCTLFontStyleLB(new FontStyleBox(m_xBuilder->weld_combo_box("cbCTLStyle")))
+ , m_xCTLFontSizeFT(m_xBuilder->weld_label("lbCTLSize"))
+ , m_xCTLFontSizeLB(new FontSizeBox(m_xBuilder->weld_combo_box("cbCTLSize")))
+ , m_xCTLFontLanguageFT(m_xBuilder->weld_label("lbCTLLanguage"))
+ , m_xCTLFontLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("cbCTLLanguage")))
+ , m_xCTLFontFeaturesButton(m_xBuilder->weld_button("btnCTLFeatures"))
+ , m_xCTLFontTypeFT(m_xBuilder->weld_label("lbCTLFontinfo"))
+
+ , m_xVDev(*Application::GetDefaultDevice(), DeviceFormat::WITH_ALPHA)
+{
+ m_xPreviewWin.reset(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWin));
+#ifdef IOS
+ m_xPreviewWin->hide();
+#endif
+ m_pImpl->m_aNoStyleText = CuiResId( RID_CUISTR_CHARNAME_NOSTYLE );
+
+ std::unique_ptr<weld::EntryTreeView> xWestFontName = m_xBuilder->weld_entry_tree_view("gdWestern", "edWestFontName", "trWestFontName");
+ std::unique_ptr<weld::EntryTreeView> xCJKFontName = m_xBuilder->weld_entry_tree_view("gdCJK", "edCJKFontName", "trCJKFontName");
+ std::unique_ptr<weld::EntryTreeView> xCTLFontName = m_xBuilder->weld_entry_tree_view("gdCTL", "edCTLFontName", "trCTLFontName");
+
+ // 7 lines in the treeview
+ xWestFontName->set_height_request_by_rows(7);
+ xCJKFontName->set_height_request_by_rows(7);
+ xCTLFontName->set_height_request_by_rows(7);
+
+ m_xWestFontNameLB = std::move(xWestFontName);
+ m_xEastFontNameLB = std::move(xCJKFontName);
+ m_xCTLFontNameLB = std::move(xCTLFontName);
+
+ bool bShowCJK = SvtCJKOptions::IsCJKFontEnabled();
+ bool bShowCTL = SvtCTLOptions::IsCTLFontEnabled();
+ bool bShowNonWestern = bShowCJK || bShowCTL;
+ if (!bShowNonWestern)
+ {
+ m_xCJK_CTL->hide();
+ m_xWestern->set_show_tabs(false); //hide single tab in case of Western only
+ }
+ else if (!bShowCJK) m_xCJK_CTL->remove_page("nbCJK");
+ else if (!bShowCTL) m_xCJK_CTL->remove_page("nbCTL");
+
+
+ //In MacOSX the standard dialogs name font-name, font-style as
+ //Family, Typeface
+ //In GNOME the standard dialogs name font-name, font-style as
+ //Family, Style
+ //In Windows the standard dialogs name font-name, font-style as
+ //Font, Style
+#ifdef _WIN32
+ OUString sFontFamilyString(CuiResId(RID_CUISTR_CHARNAME_FONT));
+#else
+ OUString sFontFamilyString(CuiResId(RID_CUISTR_CHARNAME_FAMILY));
+#endif
+ m_xWestFontNameFT->set_label(sFontFamilyString);
+ m_xCTLFontNameFT->set_label(sFontFamilyString);
+ m_xEastFontNameFT->set_label(sFontFamilyString);
+
+#ifdef MACOSX
+ OUString sFontStyleString(CuiResId(RID_CUISTR_CHARNAME_TYPEFACE));
+#else
+ OUString sFontStyleString(CuiResId(RID_CUISTR_CHARNAME_STYLE));
+#endif
+ m_xWestFontStyleFT->set_label(sFontStyleString);
+ m_xEastFontStyleFT->set_label(sFontStyleString);
+ m_xCTLFontStyleFT->set_label(sFontStyleString);
+
+ m_xWestFontLanguageLB->SetLanguageList(SvxLanguageListFlags::WESTERN, true, false, true, true,
+ LANGUAGE_SYSTEM, css::i18n::ScriptType::LATIN);
+ m_xEastFontLanguageLB->SetLanguageList(SvxLanguageListFlags::CJK, true, false, true, true,
+ LANGUAGE_SYSTEM, css::i18n::ScriptType::ASIAN);
+ m_xCTLFontLanguageLB->SetLanguageList(SvxLanguageListFlags::CTL, true, false, true, true,
+ LANGUAGE_SYSTEM, css::i18n::ScriptType::COMPLEX);
+ int nVisibleChars = 15;
+ // read-only combobox / HasEntry asserts on set_width_char()
+ m_xWestFontLanguageLB->set_width_chars(nVisibleChars);
+ m_xEastFontLanguageLB->set_width_chars(nVisibleChars);
+ m_xCTLFontLanguageLB->set_width_chars(nVisibleChars);
+
+ Initialize();
+}
+
+SvxCharNamePage::~SvxCharNamePage()
+{
+ m_pImpl.reset();
+ m_xCTLFontStyleLB.reset();
+ m_xEastFontLanguageLB.reset();
+ m_xWestFontStyleLB.reset();
+ m_xCTLFontSizeLB.reset();
+ m_xEastFontSizeLB.reset();
+ m_xWestFontSizeLB.reset();
+ m_xWestFontLanguageLB.reset();
+ m_xPreviewWin.reset();
+ m_xCTLFontLanguageLB.reset();
+ m_xEastFontLanguageLB.reset();
+}
+
+void SvxCharNamePage::Initialize()
+{
+ // to handle the changes of the other pages
+ SetExchangeSupport();
+
+ Link<weld::ComboBox&,void> aLink = LINK(this, SvxCharNamePage, FontModifyComboBoxHdl_Impl);
+ m_xWestFontNameLB->connect_changed(aLink);
+ m_xWestFontStyleLB->connect_changed(aLink);
+ m_xWestFontSizeLB->connect_changed(aLink);
+ m_xWestFontLanguageLB->connect_changed(aLink);
+
+ m_xWestFontFeaturesButton->connect_clicked(LINK(this, SvxCharNamePage, FontFeatureButtonClicked));
+
+ m_xEastFontNameLB->connect_changed(aLink);
+ m_xEastFontStyleLB->connect_changed(aLink);
+ m_xEastFontSizeLB->connect_changed(aLink);
+ m_xEastFontLanguageLB->connect_changed(aLink);
+ m_xEastFontFeaturesButton->connect_clicked(LINK(this, SvxCharNamePage, FontFeatureButtonClicked));
+
+ m_xCTLFontNameLB->connect_changed(aLink);
+ m_xCTLFontStyleLB->connect_changed(aLink);
+ m_xCTLFontSizeLB->connect_changed(aLink);
+ m_xCTLFontLanguageLB->connect_changed(aLink);
+ m_xCTLFontFeaturesButton->connect_clicked(LINK(this, SvxCharNamePage, FontFeatureButtonClicked));
+
+ m_pImpl->m_aUpdateIdle.SetInvokeHandler( LINK( this, SvxCharNamePage, UpdateHdl_Impl ) );
+}
+
+const FontList* SvxCharNamePage::GetFontList() const
+{
+ if ( !m_pImpl->m_pFontList )
+ {
+ /* #110771# SvxFontListItem::GetFontList can return NULL */
+ if (SfxObjectShell* pDocSh = SfxObjectShell::Current())
+ {
+ const SfxPoolItem* pItem = pDocSh->GetItem( SID_ATTR_CHAR_FONTLIST );
+ if ( pItem != nullptr )
+ {
+ DBG_ASSERT(nullptr != static_cast<const SvxFontListItem*>(pItem)->GetFontList(),
+ "Where is the font list?");
+ m_pImpl->m_pFontList = static_cast<const SvxFontListItem*>(pItem )->GetFontList()->Clone();
+ }
+ }
+ if(!m_pImpl->m_pFontList)
+ {
+ m_pImpl->m_pFontList.reset(new FontList( Application::GetDefaultDevice() ));
+ }
+ }
+
+ return m_pImpl->m_pFontList.get();
+}
+
+
+namespace
+{
+ FontMetric calcFontMetrics( SvxFont& _rFont,
+ SvxCharNamePage const * _pPage,
+ const weld::ComboBox* _pFontNameLB,
+ const FontStyleBox* _pFontStyleLB,
+ const FontSizeBox* _pFontSizeLB,
+ const SvxLanguageBox* _pLanguageLB,
+ const FontList* _pFontList,
+ sal_uInt16 _nFontWhich,
+ sal_uInt16 _nFontHeightWhich)
+ {
+ Size aSize = _rFont.GetFontSize();
+ aSize.setWidth( 0 );
+ FontMetric aFontMetrics;
+ OUString sFontName(_pFontNameLB->get_active_text());
+ bool bFontAvailable = _pFontList->IsAvailable( sFontName );
+ if (bFontAvailable || _pFontNameLB->get_value_changed_from_saved())
+ aFontMetrics = _pFontList->Get(sFontName, _pFontStyleLB->get_active_text());
+ else
+ {
+ //get the font from itemset
+ SfxItemState eState = _pPage->GetItemSet().GetItemState( _nFontWhich );
+ if ( eState >= SfxItemState::DEFAULT )
+ {
+ const SvxFontItem* pFontItem = static_cast<const SvxFontItem*>(&( _pPage->GetItemSet().Get( _nFontWhich ) ));
+ aFontMetrics.SetFamilyName(pFontItem->GetFamilyName());
+ aFontMetrics.SetStyleName(pFontItem->GetStyleName());
+ aFontMetrics.SetFamily(pFontItem->GetFamily());
+ aFontMetrics.SetPitch(pFontItem->GetPitch());
+ aFontMetrics.SetCharSet(pFontItem->GetCharSet());
+ }
+ }
+ if ( _pFontSizeLB->IsRelative() )
+ {
+ DBG_ASSERT( _pPage->GetItemSet().GetParent(), "No parent set" );
+ const SvxFontHeightItem& rOldItem = static_cast<const SvxFontHeightItem&>(_pPage->GetItemSet().GetParent()->Get( _nFontHeightWhich ));
+
+ // old value, scaled
+ tools::Long nHeight;
+ if ( _pFontSizeLB->IsPtRelative() )
+ nHeight = rOldItem.GetHeight()
+ + o3tl::convert(_pFontSizeLB->get_value(), o3tl::Length::pt,
+ o3tl::Length::twip) / 10;
+ else
+ nHeight = static_cast<tools::Long>(rOldItem.GetHeight() * _pFontSizeLB->get_value() / 100);
+
+ // conversion twips for the example-window
+ aSize.setHeight(
+ ItemToControl( nHeight, _pPage->GetItemSet().GetPool()->GetMetric( _nFontHeightWhich ), FieldUnit::TWIP ) );
+ }
+ else if ( !_pFontSizeLB->get_active_text().isEmpty() )
+ aSize.setHeight(o3tl::convert(_pFontSizeLB->get_value(), o3tl::Length::pt,
+ o3tl::Length::twip) / 10);
+ else
+ aSize.setHeight( 200 ); // default 10pt
+ aFontMetrics.SetFontSize( aSize );
+
+ _rFont.SetLanguage(_pLanguageLB->get_active_id());
+
+ _rFont.SetFamily( aFontMetrics.GetFamilyType() );
+ _rFont.SetFamilyName( aFontMetrics.GetFamilyName() );
+ _rFont.SetStyleName( aFontMetrics.GetStyleName() );
+ _rFont.SetPitch( aFontMetrics.GetPitch() );
+ _rFont.SetCharSet( aFontMetrics.GetCharSet() );
+ _rFont.SetWeight( aFontMetrics.GetWeight() );
+ _rFont.SetItalic( aFontMetrics.GetItalic() );
+ _rFont.SetFontSize( aFontMetrics.GetFontSize() );
+
+ return aFontMetrics;
+ }
+}
+
+
+void SvxCharNamePage::UpdatePreview_Impl()
+{
+ SvxFont& rFont = GetPreviewFont();
+ SvxFont& rCJKFont = GetPreviewCJKFont();
+ SvxFont& rCTLFont = GetPreviewCTLFont();
+ // Font
+ const FontList* pFontList = GetFontList();
+
+ FontMetric aWestFontMetric = calcFontMetrics(rFont, this, m_xWestFontNameLB.get(),
+ m_xWestFontStyleLB.get(), m_xWestFontSizeLB.get(), m_xWestFontLanguageLB.get(),
+ pFontList, GetWhich(SID_ATTR_CHAR_FONT),
+ GetWhich(SID_ATTR_CHAR_FONTHEIGHT));
+
+ m_xWestFontTypeFT->set_label(pFontList->GetFontMapText(aWestFontMetric));
+
+ FontMetric aEastFontMetric = calcFontMetrics(rCJKFont, this, m_xEastFontNameLB.get(),
+ m_xEastFontStyleLB.get(), m_xEastFontSizeLB.get(), m_xEastFontLanguageLB.get(),
+ pFontList, GetWhich(SID_ATTR_CHAR_CJK_FONT),
+ GetWhich(SID_ATTR_CHAR_CJK_FONTHEIGHT));
+
+ m_xEastFontTypeFT->set_label(pFontList->GetFontMapText(aEastFontMetric));
+
+ FontMetric aCTLFontMetric = calcFontMetrics(rCTLFont,
+ this, m_xCTLFontNameLB.get(), m_xCTLFontStyleLB.get(), m_xCTLFontSizeLB.get(),
+ m_xCTLFontLanguageLB.get(), pFontList, GetWhich(SID_ATTR_CHAR_CTL_FONT),
+ GetWhich(SID_ATTR_CHAR_CTL_FONTHEIGHT));
+
+ m_xCTLFontTypeFT->set_label(pFontList->GetFontMapText(aCTLFontMetric));
+
+ m_aPreviewWin.Invalidate();
+}
+void SvxCharNamePage::EnableFeatureButton(const weld::Widget& rNameBox)
+{
+ OUString sFontName;
+ weld::Button* pButton= nullptr;
+ if (m_xWestFontNameLB.get() == &rNameBox)
+ {
+ sFontName = m_xWestFontNameLB->get_active_text();
+ pButton= m_xWestFontFeaturesButton.get();
+ }
+ else if (m_xEastFontNameLB.get() == &rNameBox)
+ {
+ sFontName = m_xEastFontNameLB->get_active_text();
+ pButton=m_xEastFontFeaturesButton.get();
+ }
+ else if (m_xCTLFontNameLB.get() == &rNameBox)
+ {
+ sFontName = m_xCTLFontNameLB->get_active_text();
+ pButton= m_xCTLFontFeaturesButton.get();
+ }
+ else
+ {
+ SAL_WARN( "cui.tabpages", "invalid font name box" );
+ return;
+ }
+
+ bool bEnable = !getFontFeatureList(sFontName, *m_xVDev).empty();
+
+ pButton->set_sensitive(bEnable);
+}
+
+void SvxCharNamePage::FillStyleBox_Impl(const weld::Widget& rNameBox)
+{
+ const FontList* pFontList = GetFontList();
+ DBG_ASSERT( pFontList, "no fontlist" );
+
+ FontStyleBox* pStyleBox = nullptr;
+ OUString sFontName;
+
+ if (m_xWestFontNameLB.get() == &rNameBox)
+ {
+ pStyleBox = m_xWestFontStyleLB.get();
+ sFontName = m_xWestFontNameLB->get_active_text();
+ }
+ else if (m_xEastFontNameLB.get() == &rNameBox)
+ {
+ pStyleBox = m_xEastFontStyleLB.get();
+ sFontName = m_xEastFontStyleLB->get_active_text();
+ }
+ else if (m_xCTLFontNameLB.get() == &rNameBox)
+ {
+ pStyleBox = m_xCTLFontStyleLB.get();
+ sFontName = m_xCTLFontNameLB->get_active_text();
+ }
+ else
+ {
+ SAL_WARN( "cui.tabpages", "invalid font name box" );
+ return;
+ }
+
+ pStyleBox->Fill(sFontName, pFontList);
+
+ if ( !m_pImpl->m_bInSearchMode )
+ return;
+
+ // additional entries for the search:
+ // "not bold" and "not italic"
+ OUString aEntry = m_pImpl->m_aNoStyleText;
+ const char sS[] = "%1";
+ aEntry = aEntry.replaceFirst( sS, pFontList->GetBoldStr() );
+ m_pImpl->m_nExtraEntryPos = pStyleBox->get_count();
+ pStyleBox->append_text( aEntry );
+ aEntry = m_pImpl->m_aNoStyleText;
+ aEntry = aEntry.replaceFirst( sS, pFontList->GetItalicStr() );
+ pStyleBox->append_text(aEntry);
+}
+
+void SvxCharNamePage::FillSizeBox_Impl(const weld::Widget& rNameBox)
+{
+ const FontList* pFontList = GetFontList();
+ DBG_ASSERT( pFontList, "no fontlist" );
+
+ FontSizeBox* pSizeBox = nullptr;
+
+ if (m_xWestFontNameLB.get() == &rNameBox)
+ {
+ pSizeBox = m_xWestFontSizeLB.get();
+ }
+ else if (m_xEastFontNameLB.get() == &rNameBox)
+ {
+ pSizeBox = m_xEastFontSizeLB.get();
+ }
+ else if (m_xCTLFontNameLB.get() == &rNameBox)
+ {
+ pSizeBox = m_xCTLFontSizeLB.get();
+ }
+ else
+ {
+ SAL_WARN( "cui.tabpages", "invalid font name box" );
+ return;
+ }
+
+ pSizeBox->Fill( pFontList );
+}
+
+namespace
+{
+ void FillFontNames(weld::ComboBox& rBox, const FontList& rList)
+ {
+ // insert fonts
+ sal_uInt16 nFontCount = rList.GetFontNameCount();
+ std::vector<weld::ComboBoxEntry> aVector;
+ aVector.reserve(nFontCount);
+ for (sal_uInt16 i = 0; i < nFontCount; ++i)
+ {
+ const FontMetric& rFontMetric = rList.GetFontName(i);
+ aVector.emplace_back(rFontMetric.GetFamilyName());
+ }
+ rBox.insert_vector(aVector, false);
+ }
+}
+
+void SvxCharNamePage::Reset_Impl( const SfxItemSet& rSet, LanguageGroup eLangGrp )
+{
+ weld::ComboBox* pNameBox = nullptr;
+ weld::Label* pStyleLabel = nullptr;
+ FontStyleBox* pStyleBox = nullptr;
+ weld::Label* pSizeLabel = nullptr;
+ FontSizeBox* pSizeBox = nullptr;
+ weld::Label* pLangFT = nullptr;
+ SvxLanguageBox* pLangBox = nullptr;
+ sal_uInt16 nWhich = 0;
+
+ switch ( eLangGrp )
+ {
+ case Western :
+ pNameBox = m_xWestFontNameLB.get();
+ pStyleLabel = m_xWestFontStyleFT.get();
+ pStyleBox = m_xWestFontStyleLB.get();
+ pSizeLabel = m_xWestFontSizeFT.get();
+ pSizeBox = m_xWestFontSizeLB.get();
+ pLangFT = m_xWestFontLanguageFT.get();
+ pLangBox = m_xWestFontLanguageLB.get();
+ nWhich = GetWhich( SID_ATTR_CHAR_FONT );
+ break;
+
+ case Asian :
+ pNameBox = m_xEastFontNameLB.get();
+ pStyleLabel = m_xEastFontStyleFT.get();
+ pStyleBox = m_xEastFontStyleLB.get();
+ pSizeLabel = m_xEastFontSizeFT.get();
+ pSizeBox = m_xEastFontSizeLB.get();
+ pLangFT = m_xEastFontLanguageFT.get();
+ pLangBox = m_xEastFontLanguageLB.get();
+ nWhich = GetWhich( SID_ATTR_CHAR_CJK_FONT );
+ break;
+
+ case Ctl :
+ pNameBox = m_xCTLFontNameLB.get();
+ pStyleLabel = m_xCTLFontStyleFT.get();
+ pStyleBox = m_xCTLFontStyleLB.get();
+ pSizeLabel = m_xCTLFontSizeFT.get();
+ pSizeBox = m_xCTLFontSizeLB.get();
+ pLangFT = m_xCTLFontLanguageFT.get();
+ pLangBox = m_xCTLFontLanguageLB.get();
+ nWhich = GetWhich( SID_ATTR_CHAR_CTL_FONT );
+ break;
+ }
+
+ const FontList* pFontList = GetFontList();
+ FillFontNames(*pNameBox, *pFontList);
+
+ const SvxFontItem* pFontItem = nullptr;
+ SfxItemState eState = rSet.GetItemState( nWhich );
+
+ if ( eState >= SfxItemState::DEFAULT )
+ {
+ pFontItem = static_cast<const SvxFontItem*>(&( rSet.Get( nWhich ) ));
+ const OUString &rName = pFontItem->GetFamilyName();
+ int nIndex = pNameBox->find_text(rName);
+ pNameBox->set_active(nIndex);
+ // tdf#122992 if it didn't exist in the list, set the entry text to it anyway
+ if (nIndex == -1)
+ pNameBox->set_entry_text(rName);
+ }
+ else
+ {
+ pNameBox->set_active_text( OUString() );
+ }
+
+ FillStyleBox_Impl(*pNameBox);
+
+ bool bStyle = false;
+ bool bStyleAvailable = true;
+ FontItalic eItalic = ITALIC_NONE;
+ FontWeight eWeight = WEIGHT_NORMAL;
+ switch ( eLangGrp )
+ {
+ case Western : nWhich = GetWhich( SID_ATTR_CHAR_POSTURE ); break;
+ case Asian : nWhich = GetWhich( SID_ATTR_CHAR_CJK_POSTURE ); break;
+ case Ctl : nWhich = GetWhich( SID_ATTR_CHAR_CTL_POSTURE ); break;
+ }
+ eState = rSet.GetItemState( nWhich );
+
+ if ( eState >= SfxItemState::DEFAULT )
+ {
+ const SvxPostureItem& rItem = static_cast<const SvxPostureItem&>(rSet.Get( nWhich ));
+ eItalic = rItem.GetValue();
+ bStyle = true;
+ }
+ bStyleAvailable = bStyleAvailable && (eState >= SfxItemState::DONTCARE);
+
+ switch ( eLangGrp )
+ {
+ case Western : nWhich = GetWhich( SID_ATTR_CHAR_WEIGHT ); break;
+ case Asian : nWhich = GetWhich( SID_ATTR_CHAR_CJK_WEIGHT ); break;
+ case Ctl : nWhich = GetWhich( SID_ATTR_CHAR_CTL_WEIGHT ); break;
+ }
+ eState = rSet.GetItemState( nWhich );
+
+ if ( eState >= SfxItemState::DEFAULT )
+ {
+ const SvxWeightItem& rItem = static_cast<const SvxWeightItem&>(rSet.Get( nWhich ));
+ eWeight = rItem.GetValue();
+ }
+ else
+ bStyle = false;
+ bStyleAvailable = bStyleAvailable && (eState >= SfxItemState::DONTCARE);
+
+ // currently chosen font
+ if ( bStyle && pFontItem )
+ {
+ FontMetric aFontMetric = pFontList->Get( pFontItem->GetFamilyName(), eWeight, eItalic );
+ pStyleBox->set_active_text( pFontList->GetStyleName( aFontMetric ) );
+ }
+ else if ( !m_pImpl->m_bInSearchMode || !bStyle )
+ {
+ pStyleBox->set_active_text( OUString() );
+ }
+ else if ( bStyle )
+ {
+ FontMetric aFontMetric = pFontList->Get( OUString(), eWeight, eItalic );
+ pStyleBox->set_active_text( pFontList->GetStyleName( aFontMetric ) );
+ }
+ if (!bStyleAvailable)
+ {
+ pStyleBox->set_sensitive(false);
+ pStyleLabel->set_sensitive(false);
+ }
+
+ FillSizeBox_Impl(*pNameBox);
+ switch ( eLangGrp )
+ {
+ case Western : nWhich = GetWhich( SID_ATTR_CHAR_FONTHEIGHT ); break;
+ case Asian : nWhich = GetWhich( SID_ATTR_CHAR_CJK_FONTHEIGHT ); break;
+ case Ctl : nWhich = GetWhich( SID_ATTR_CHAR_CTL_FONTHEIGHT ); break;
+ }
+ eState = rSet.GetItemState( nWhich );
+
+ if ( pSizeBox->IsRelativeMode() )
+ {
+ MapUnit eUnit = rSet.GetPool()->GetMetric( nWhich );
+ const SvxFontHeightItem& rItem = static_cast<const SvxFontHeightItem&>(rSet.Get( nWhich ));
+
+ if( rItem.GetProp() != 100 || MapUnit::MapRelative != rItem.GetPropUnit() )
+ {
+ bool bPtRel = MapUnit::MapPoint == rItem.GetPropUnit();
+ pSizeBox->SetPtRelative( bPtRel );
+ pSizeBox->set_value( bPtRel ? static_cast<short>(rItem.GetProp()) * 10 : rItem.GetProp() );
+ }
+ else
+ {
+ pSizeBox->SetRelative(false);
+ pSizeBox->set_value( CalcToPoint( rItem.GetHeight(), eUnit, 10 ) );
+ }
+ }
+ else if ( eState >= SfxItemState::DEFAULT )
+ {
+ MapUnit eUnit = rSet.GetPool()->GetMetric( nWhich );
+ const SvxFontHeightItem& rItem = static_cast<const SvxFontHeightItem&>(rSet.Get( nWhich ));
+ pSizeBox->set_value( CalcToPoint( rItem.GetHeight(), eUnit, 10 ) );
+ }
+ else
+ {
+ pSizeBox->set_active_or_entry_text(OUString());
+ if ( eState <= SfxItemState::DISABLED )
+ {
+ pSizeBox->set_sensitive(false);
+ pSizeLabel->set_sensitive(false);
+ }
+ }
+
+ switch ( eLangGrp )
+ {
+ case Western : nWhich = GetWhich( SID_ATTR_CHAR_LANGUAGE ); break;
+ case Asian : nWhich = GetWhich( SID_ATTR_CHAR_CJK_LANGUAGE ); break;
+ case Ctl : nWhich = GetWhich( SID_ATTR_CHAR_CTL_LANGUAGE ); break;
+ }
+ pLangBox->set_active(-1);
+ eState = rSet.GetItemState( nWhich );
+
+ switch ( eState )
+ {
+ case SfxItemState::UNKNOWN:
+ pLangFT->hide();
+ pLangBox->hide();
+ break;
+
+ case SfxItemState::DISABLED:
+ pLangFT->set_sensitive(false);
+ pLangBox->set_sensitive(false);
+ break;
+
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxLanguageItem& rItem = static_cast<const SvxLanguageItem&>(rSet.Get( nWhich ));
+ LanguageType eLangType = rItem.GetValue();
+ DBG_ASSERT( eLangType != LANGUAGE_SYSTEM, "LANGUAGE_SYSTEM not allowed" );
+ if (eLangType != LANGUAGE_DONTKNOW)
+ pLangBox->set_active_id(eLangType);
+ break;
+ }
+ case SfxItemState::DONTCARE:
+ break;
+ }
+
+ OUString sMapText(pFontList->GetFontMapText(
+ pFontList->Get(pNameBox->get_active_text(), pStyleBox->get_active_text())));
+
+ switch (eLangGrp)
+ {
+ case Western:
+ m_xWestFontTypeFT->set_label(sMapText);
+ break;
+ case Asian:
+ m_xEastFontTypeFT->set_label(sMapText);
+ break;
+ case Ctl:
+ m_xCTLFontTypeFT->set_label(sMapText);
+ break;
+ }
+
+ EnableFeatureButton(*pNameBox);
+
+ // save these settings
+ pNameBox->save_value();
+ pStyleBox->save_value();
+ pSizeBox->save_value();
+ pLangBox->save_active_id();
+}
+
+bool SvxCharNamePage::FillItemSet_Impl( SfxItemSet& rSet, LanguageGroup eLangGrp )
+{
+ bool bModified = false;
+
+ weld::ComboBox* pNameBox = nullptr;
+ FontStyleBox* pStyleBox = nullptr;
+ FontSizeBox* pSizeBox = nullptr;
+ SvxLanguageBox* pLangBox = nullptr;
+ sal_uInt16 nWhich = 0;
+ sal_uInt16 nSlot = 0;
+
+ switch ( eLangGrp )
+ {
+ case Western :
+ pNameBox = m_xWestFontNameLB.get();
+ pStyleBox = m_xWestFontStyleLB.get();
+ pSizeBox = m_xWestFontSizeLB.get();
+ pLangBox = m_xWestFontLanguageLB.get();
+ nSlot = SID_ATTR_CHAR_FONT;
+ break;
+
+ case Asian :
+ pNameBox = m_xEastFontNameLB.get();
+ pStyleBox = m_xEastFontStyleLB.get();
+ pSizeBox = m_xEastFontSizeLB.get();
+ pLangBox = m_xEastFontLanguageLB.get();
+ nSlot = SID_ATTR_CHAR_CJK_FONT;
+ break;
+
+ case Ctl :
+ pNameBox = m_xCTLFontNameLB.get();
+ pStyleBox = m_xCTLFontStyleLB.get();
+ pSizeBox = m_xCTLFontSizeLB.get();
+ pLangBox = m_xCTLFontLanguageLB.get();
+ nSlot = SID_ATTR_CHAR_CTL_FONT;
+ break;
+ }
+
+ nWhich = GetWhich( nSlot );
+ const SfxPoolItem* pItem = nullptr;
+ const SfxItemSet& rOldSet = GetItemSet();
+ const SfxPoolItem* pOld = nullptr;
+
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+
+ bool bChanged = true;
+ const OUString& rFontName = pNameBox->get_active_text();
+ const FontList* pFontList = GetFontList();
+ OUString aStyleBoxText = pStyleBox->get_active_text();
+ int nEntryPos = pStyleBox->find_text(aStyleBoxText);
+ if (nEntryPos >= m_pImpl->m_nExtraEntryPos)
+ aStyleBoxText.clear();
+ FontMetric aInfo( pFontList->Get( rFontName, aStyleBoxText ) );
+ SvxFontItem aFontItem( aInfo.GetFamilyType(), aInfo.GetFamilyName(), aInfo.GetStyleName(),
+ aInfo.GetPitch(), aInfo.GetCharSet(), nWhich );
+ pOld = GetOldItem( rSet, nSlot );
+
+ if ( pOld )
+ {
+ const SvxFontItem& rItem = *static_cast<const SvxFontItem*>(pOld);
+
+ if ( rItem.GetFamilyName() == aFontItem.GetFamilyName() )
+ bChanged = false;
+ }
+
+ if ( !bChanged )
+ bChanged = pNameBox->get_saved_value().isEmpty();
+
+ if ( !bChanged && pExampleSet &&
+ pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
+ static_cast<const SvxFontItem*>(pItem)->GetFamilyName() != aFontItem.GetFamilyName() )
+ bChanged = true;
+
+ if ( bChanged && !rFontName.isEmpty() )
+ {
+ rSet.Put( aFontItem );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet.ClearItem( nWhich );
+
+
+ bChanged = true;
+ switch ( eLangGrp )
+ {
+ case Western : nSlot = SID_ATTR_CHAR_WEIGHT; break;
+ case Asian : nSlot = SID_ATTR_CHAR_CJK_WEIGHT; break;
+ case Ctl : nSlot = SID_ATTR_CHAR_CTL_WEIGHT; break;
+ }
+ nWhich = GetWhich( nSlot );
+ FontWeight eWeight = aInfo.GetWeight();
+ if ( nEntryPos >= m_pImpl->m_nExtraEntryPos )
+ eWeight = WEIGHT_NORMAL;
+ SvxWeightItem aWeightItem( eWeight, nWhich );
+ pOld = GetOldItem( rSet, nSlot );
+
+ if ( pOld )
+ {
+ const SvxWeightItem& rItem = *static_cast<const SvxWeightItem*>(pOld);
+
+ if ( rItem.GetValue() == aWeightItem.GetValue() )
+ bChanged = false;
+ }
+
+ if ( !bChanged )
+ {
+ bChanged = pStyleBox->get_saved_value().isEmpty();
+
+ if ( m_pImpl->m_bInSearchMode && bChanged &&
+ aInfo.GetWeight() == WEIGHT_NORMAL && aInfo.GetItalic() != ITALIC_NONE )
+ bChanged = false;
+ }
+
+ if ( !bChanged && pExampleSet &&
+ pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
+ static_cast<const SvxWeightItem*>(pItem)->GetValue() != aWeightItem.GetValue() )
+ bChanged = true;
+
+ if ( nEntryPos >= m_pImpl->m_nExtraEntryPos )
+ bChanged = ( nEntryPos == m_pImpl->m_nExtraEntryPos );
+
+ OUString aText( pStyleBox->get_active_text() ); // Tristate, then text empty
+
+ if ( bChanged && !aText.isEmpty() )
+ {
+ rSet.Put( aWeightItem );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet.InvalidateItem(nWhich);
+
+ bChanged = true;
+ switch ( eLangGrp )
+ {
+ case Western : nSlot = SID_ATTR_CHAR_POSTURE; break;
+ case Asian : nSlot = SID_ATTR_CHAR_CJK_POSTURE; break;
+ case Ctl : nSlot = SID_ATTR_CHAR_CTL_POSTURE; break;
+ }
+ nWhich = GetWhich( nSlot );
+ FontItalic eItalic = aInfo.GetItalic();
+ if ( nEntryPos >= m_pImpl->m_nExtraEntryPos )
+ eItalic = ITALIC_NONE;
+ SvxPostureItem aPostureItem( eItalic, nWhich );
+ pOld = GetOldItem( rSet, nSlot );
+
+ if ( pOld )
+ {
+ const SvxPostureItem& rItem = *static_cast<const SvxPostureItem*>(pOld);
+
+ if ( rItem.GetValue() == aPostureItem.GetValue() )
+ bChanged = false;
+ }
+
+ if ( !bChanged )
+ {
+ bChanged = pStyleBox->get_saved_value().isEmpty();
+
+ if ( m_pImpl->m_bInSearchMode && bChanged &&
+ aInfo.GetItalic() == ITALIC_NONE && aInfo.GetWeight() != WEIGHT_NORMAL )
+ bChanged = false;
+ }
+
+ if ( !bChanged && pExampleSet &&
+ pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
+ static_cast<const SvxPostureItem*>(pItem)->GetValue() != aPostureItem.GetValue() )
+ bChanged = true;
+
+ if ( nEntryPos >= m_pImpl->m_nExtraEntryPos )
+ bChanged = ( nEntryPos == ( m_pImpl->m_nExtraEntryPos + 1 ) );
+
+ if ( bChanged && !aText.isEmpty() )
+ {
+ rSet.Put( aPostureItem );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet.InvalidateItem(nWhich);
+
+ // FontSize
+ tools::Long nSize = pSizeBox->get_value();
+
+ if ( pSizeBox->get_active_text().isEmpty() ) // GetValue() returns the min-value
+ nSize = 0;
+ tools::Long nSavedSize = pSizeBox->get_saved_value();
+ const bool bRel = pSizeBox->IsRelative();
+
+ switch ( eLangGrp )
+ {
+ case Western : nSlot = SID_ATTR_CHAR_FONTHEIGHT; break;
+ case Asian : nSlot = SID_ATTR_CHAR_CJK_FONTHEIGHT; break;
+ case Ctl : nSlot = SID_ATTR_CHAR_CTL_FONTHEIGHT; break;
+ }
+ nWhich = GetWhich( nSlot );
+ const SvxFontHeightItem* pOldHeight = static_cast<const SvxFontHeightItem*>(GetOldItem( rSet, nSlot ));
+ bChanged = ( nSize != nSavedSize );
+
+ if ( !bChanged && pExampleSet &&
+ pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET )
+ {
+ float fSize = static_cast<float>(nSize) / 10;
+ tools::Long nVal = CalcToUnit( fSize, rSet.GetPool()->GetMetric( nWhich ) );
+ if ( static_cast<const SvxFontHeightItem*>(pItem)->GetHeight() != static_cast<sal_uInt32>(nVal) )
+ bChanged = true;
+ }
+
+ if ( bChanged || !pOldHeight ||
+ bRel != ( MapUnit::MapRelative != pOldHeight->GetPropUnit() || 100 != pOldHeight->GetProp() ) )
+ {
+ MapUnit eUnit = rSet.GetPool()->GetMetric( nWhich );
+ if ( pSizeBox->IsRelative() )
+ {
+ DBG_ASSERT( GetItemSet().GetParent(), "No parent set" );
+ const SvxFontHeightItem& rOldItem =
+ static_cast<const SvxFontHeightItem&>(GetItemSet().GetParent()->Get( nWhich ));
+
+ SvxFontHeightItem aHeight( 240, 100, nWhich );
+ if ( pSizeBox->IsPtRelative() )
+ aHeight.SetHeight( rOldItem.GetHeight(), static_cast<sal_uInt16>( nSize / 10 ), MapUnit::MapPoint, eUnit );
+ else
+ aHeight.SetHeight( rOldItem.GetHeight(), static_cast<sal_uInt16>(nSize) );
+ rSet.Put( aHeight );
+ }
+ else
+ {
+ float fSize = static_cast<float>(nSize) / 10;
+ rSet.Put( SvxFontHeightItem( CalcToUnit( fSize, eUnit ), 100, nWhich ) );
+ }
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet.InvalidateItem(nWhich);
+
+ bChanged = true;
+ switch ( eLangGrp )
+ {
+ case Western : nSlot = SID_ATTR_CHAR_LANGUAGE; break;
+ case Asian : nSlot = SID_ATTR_CHAR_CJK_LANGUAGE; break;
+ case Ctl : nSlot = SID_ATTR_CHAR_CTL_LANGUAGE; break;
+ }
+
+ // For language list boxes acting as ComboBox, check for, add and select an
+ // edited entry.
+ switch (pLangBox->GetEditedAndValid())
+ {
+ case SvxLanguageBox::EditedAndValid::No:
+ ; // nothing to do
+ break;
+ case SvxLanguageBox::EditedAndValid::Valid:
+ {
+ SvxLanguageBox* ppBoxes[3]
+ = {m_xWestFontLanguageLB.get(), m_xEastFontLanguageLB.get(), m_xCTLFontLanguageLB.get()};
+ SvxLanguageBox* pBox = pLangBox->SaveEditedAsEntry(ppBoxes);
+ if (pBox != pLangBox)
+ {
+ // Get item from corresponding slot.
+ if (pBox == m_xWestFontLanguageLB.get())
+ nSlot = SID_ATTR_CHAR_LANGUAGE;
+ else if (pBox == m_xEastFontLanguageLB.get())
+ nSlot = SID_ATTR_CHAR_CJK_LANGUAGE;
+ else if (pBox == m_xCTLFontLanguageLB.get())
+ nSlot = SID_ATTR_CHAR_CTL_LANGUAGE;
+ pLangBox = pBox;
+ }
+ }
+ break;
+ case SvxLanguageBox::EditedAndValid::Invalid:
+ pLangBox->set_active_id(pLangBox->get_saved_active_id());
+ break;
+ }
+
+ nWhich = GetWhich( nSlot );
+ pOld = GetOldItem( rSet, nSlot );
+
+ int nLangPos = pLangBox->get_active();
+ LanguageType eLangType = pLangBox->get_active_id();
+
+ if (pOld)
+ {
+ const SvxLanguageItem& rItem = *static_cast<const SvxLanguageItem*>(pOld);
+ if (nLangPos == -1 || eLangType == rItem.GetValue())
+ bChanged = false;
+ }
+
+ if (!bChanged)
+ bChanged = pLangBox->get_active_id_changed_from_saved();
+
+ if (bChanged && nLangPos != -1)
+ {
+ rSet.Put(SvxLanguageItem(eLangType, nWhich));
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet.InvalidateItem(nWhich);
+
+ return bModified;
+}
+
+IMPL_LINK_NOARG(SvxCharNamePage, UpdateHdl_Impl, Timer *, void)
+{
+ UpdatePreview_Impl();
+}
+
+IMPL_LINK(SvxCharNamePage, FontModifyComboBoxHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ FontModifyHdl_Impl(rBox);
+}
+
+IMPL_LINK(SvxCharNamePage, FontFeatureButtonClicked, weld::Button&, rButton, void)
+{
+ OUString sFontName;
+ weld::ComboBox* pNameBox = nullptr;
+
+ if (&rButton == m_xWestFontFeaturesButton.get())
+ {
+ pNameBox = m_xWestFontNameLB.get();
+ sFontName = GetPreviewFont().GetFamilyName();
+ }
+ else if (&rButton == m_xEastFontFeaturesButton.get())
+ {
+ pNameBox = m_xEastFontNameLB.get();
+ sFontName = GetPreviewCJKFont().GetFamilyName();
+ }
+ else if (&rButton == m_xCTLFontFeaturesButton.get())
+ {
+ pNameBox = m_xCTLFontNameLB.get();
+ sFontName = GetPreviewCTLFont().GetFamilyName();
+ }
+
+ if (!sFontName.isEmpty() && pNameBox)
+ {
+ cui::FontFeaturesDialog aDialog(GetFrameWeld(), sFontName);
+ if (aDialog.run() == RET_OK)
+ {
+ pNameBox->set_entry_text(aDialog.getResultFontName());
+ UpdatePreview_Impl();
+ }
+ }
+}
+
+void SvxCharNamePage::FontModifyHdl_Impl(const weld::Widget& rNameBox)
+{
+ m_pImpl->m_aUpdateIdle.Start();
+
+ if (m_xWestFontNameLB.get() == &rNameBox || m_xEastFontNameLB.get() == &rNameBox || m_xCTLFontNameLB.get() == &rNameBox)
+ {
+ FillStyleBox_Impl(rNameBox);
+ FillSizeBox_Impl(rNameBox);
+ EnableFeatureButton(rNameBox);
+ }
+}
+
+void SvxCharNamePage::ActivatePage( const SfxItemSet& rSet )
+{
+ SvxCharBasePage::ActivatePage( rSet );
+
+ UpdatePreview_Impl(); // instead of asynchronous calling in ctor
+}
+
+DeactivateRC SvxCharNamePage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if ( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+std::unique_ptr<SfxTabPage> SvxCharNamePage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxCharNamePage>(pPage, pController, *rSet );
+}
+
+void SvxCharNamePage::Reset( const SfxItemSet* rSet )
+{
+ Reset_Impl( *rSet, Western );
+ Reset_Impl( *rSet, Asian );
+ Reset_Impl( *rSet, Ctl );
+
+ SetPrevFontWidthScale( *rSet );
+ UpdatePreview_Impl();
+}
+
+void SvxCharNamePage::ChangesApplied()
+{
+ m_xWestFontNameLB->save_value();
+ m_xWestFontStyleLB->save_value();
+ m_xWestFontSizeLB->save_value();
+ m_xWestFontLanguageLB->save_active_id();
+ m_xEastFontNameLB->save_value();
+ m_xEastFontStyleLB->save_value();
+ m_xEastFontSizeLB->save_value();
+ m_xEastFontLanguageLB->save_active_id();
+ m_xCTLFontNameLB->save_value();
+ m_xCTLFontStyleLB->save_value();
+ m_xCTLFontSizeLB->save_value();
+ m_xCTLFontLanguageLB->save_active_id();
+}
+
+bool SvxCharNamePage::FillItemSet( SfxItemSet* rSet )
+{
+ bool bModified = FillItemSet_Impl( *rSet, Western );
+ bModified |= FillItemSet_Impl( *rSet, Asian );
+ bModified |= FillItemSet_Impl( *rSet, Ctl );
+ return bModified;
+}
+
+void SvxCharNamePage::SetFontList( const SvxFontListItem& rItem )
+{
+ m_pImpl->m_pFontList = rItem.GetFontList()->Clone();
+}
+
+namespace
+{
+ void enableRelativeMode( SvxCharNamePage const * _pPage, FontSizeBox* _pFontSizeLB, sal_uInt16 _nHeightWhich )
+ {
+ _pFontSizeLB->EnableRelativeMode( 5, 995 ); // min 5%, max 995%, step 5
+
+ const SvxFontHeightItem& rHeightItem =
+ static_cast<const SvxFontHeightItem&>(_pPage->GetItemSet().GetParent()->Get( _nHeightWhich ));
+ MapUnit eUnit = _pPage->GetItemSet().GetPool()->GetMetric( _nHeightWhich );
+ short nCurHeight =
+ static_cast< short >( CalcToPoint( rHeightItem.GetHeight(), eUnit, 1 ) * 10 );
+
+ // based on the current height:
+ // - negative until minimum of 2 pt
+ // - positive until maximum of 999 pt
+ _pFontSizeLB->EnablePtRelativeMode( sal::static_int_cast< short >(-(nCurHeight - 20)), (9999 - nCurHeight) );
+ }
+}
+
+void SvxCharNamePage::EnableRelativeMode()
+{
+ DBG_ASSERT( GetItemSet().GetParent(), "RelativeMode, but no ParentSet!" );
+ enableRelativeMode(this,m_xWestFontSizeLB.get(),GetWhich( SID_ATTR_CHAR_FONTHEIGHT ));
+ enableRelativeMode(this,m_xEastFontSizeLB.get(),GetWhich( SID_ATTR_CHAR_CJK_FONTHEIGHT ));
+ enableRelativeMode(this,m_xCTLFontSizeLB.get(),GetWhich( SID_ATTR_CHAR_CTL_FONTHEIGHT ));
+}
+
+void SvxCharNamePage::EnableSearchMode()
+{
+ m_pImpl->m_bInSearchMode = true;
+}
+
+void SvxCharNamePage::DisableControls( sal_uInt16 nDisable )
+{
+ if ( DISABLE_HIDE_LANGUAGE & nDisable )
+ {
+ if ( m_xWestFontLanguageFT ) m_xWestFontLanguageFT->hide();
+ if ( m_xWestFontLanguageLB ) m_xWestFontLanguageLB->hide();
+ if ( m_xEastFontLanguageFT ) m_xEastFontLanguageFT->hide();
+ if ( m_xEastFontLanguageLB ) m_xEastFontLanguageLB->hide();
+ if ( m_xCTLFontLanguageFT ) m_xCTLFontLanguageFT->hide();
+ if ( m_xCTLFontLanguageLB ) m_xCTLFontLanguageLB->hide();
+ }
+}
+
+void SvxCharNamePage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SvxFontListItem* pFontListItem = aSet.GetItem<SvxFontListItem>(SID_ATTR_CHAR_FONTLIST, false);
+ const SfxUInt32Item* pFlagItem = aSet.GetItem<SfxUInt32Item>(SID_FLAG_TYPE, false);
+ const SfxUInt16Item* pDisableItem = aSet.GetItem<SfxUInt16Item>(SID_DISABLE_CTL, false);
+ if (pFontListItem)
+ SetFontList(*pFontListItem);
+
+ if (pFlagItem)
+ {
+ sal_uInt32 nFlags=pFlagItem->GetValue();
+ if ( ( nFlags & SVX_RELATIVE_MODE ) == SVX_RELATIVE_MODE )
+ EnableRelativeMode();
+ if ( ( nFlags & SVX_PREVIEW_CHARACTER ) == SVX_PREVIEW_CHARACTER )
+ // the writer uses SID_ATTR_BRUSH as font background
+ m_bPreviewBackgroundToCharacter = true;
+ }
+ if (pDisableItem)
+ DisableControls(pDisableItem->GetValue());
+}
+// class SvxCharEffectsPage ----------------------------------------------
+
+SvxCharEffectsPage::SvxCharEffectsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInSet)
+ : SvxCharBasePage(pPage, pController, "cui/ui/effectspage.ui", "EffectsPage", rInSet)
+ , m_bOrigFontColor(false)
+ , m_bNewFontColor(false)
+ , m_bEnableNoneFontColor(false)
+ , m_xFontColorFT(m_xBuilder->weld_label("fontcolorft"))
+ , m_xFontColorLB(new ColorListBox(m_xBuilder->weld_menu_button("fontcolorlb"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xFontTransparencyFT(m_xBuilder->weld_label("fonttransparencyft"))
+ , m_xFontTransparencyMtr(
+ m_xBuilder->weld_metric_spin_button("fonttransparencymtr", FieldUnit::PERCENT))
+ , m_xEffectsFT(m_xBuilder->weld_label("effectsft"))
+ , m_xEffectsLB(m_xBuilder->weld_combo_box("effectslb"))
+ , m_xReliefFT(m_xBuilder->weld_label("reliefft"))
+ , m_xReliefLB(m_xBuilder->weld_combo_box("relieflb"))
+ , m_xOutlineBtn(m_xBuilder->weld_check_button("outlinecb"))
+ , m_xShadowBtn(m_xBuilder->weld_check_button("shadowcb"))
+ , m_xHiddenBtn(m_xBuilder->weld_check_button("hiddencb"))
+ , m_xOverlineLB(m_xBuilder->weld_combo_box("overlinelb"))
+ , m_xOverlineColorFT(m_xBuilder->weld_label("overlinecolorft"))
+ , m_xOverlineColorLB(new ColorListBox(m_xBuilder->weld_menu_button("overlinecolorlb"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xStrikeoutLB(m_xBuilder->weld_combo_box("strikeoutlb"))
+ , m_xUnderlineLB(m_xBuilder->weld_combo_box("underlinelb"))
+ , m_xUnderlineColorFT(m_xBuilder->weld_label("underlinecolorft"))
+ , m_xUnderlineColorLB(new ColorListBox(m_xBuilder->weld_menu_button("underlinecolorlb"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xIndividualWordsBtn(m_xBuilder->weld_check_button("individualwordscb"))
+ , m_xEmphasisFT(m_xBuilder->weld_label("emphasisft"))
+ , m_xEmphasisLB(m_xBuilder->weld_combo_box("emphasislb"))
+ , m_xPositionFT(m_xBuilder->weld_label("positionft"))
+ , m_xPositionLB(m_xBuilder->weld_combo_box("positionlb"))
+ , m_xA11yWarningFT(m_xBuilder->weld_label("a11ywarning"))
+{
+ m_xPreviewWin.reset(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWin));
+#ifdef IOS
+ m_xPreviewWin->hide();
+#endif
+ m_xFontColorLB->SetSlotId(SID_ATTR_CHAR_COLOR);
+ m_xOverlineColorLB->SetSlotId(SID_ATTR_CHAR_COLOR);
+ m_xUnderlineColorLB->SetSlotId(SID_ATTR_CHAR_COLOR);
+ Initialize();
+}
+
+void SvxCharEffectsPage::EnableNoneFontColor()
+{
+ m_xFontColorLB->SetSlotId(SID_ATTR_CHAR_COLOR, true);
+ m_bEnableNoneFontColor = true;
+}
+
+SvxCharEffectsPage::~SvxCharEffectsPage()
+{
+ m_xUnderlineColorLB.reset();
+ m_xOverlineColorLB.reset();
+ m_xFontTransparencyMtr.reset();
+ m_xFontColorLB.reset();
+}
+
+void SvxCharEffectsPage::Initialize()
+{
+ // to handle the changes of the other pages
+ SetExchangeSupport();
+
+ // HTML-Mode
+ const SfxUInt16Item* pHtmlModeItem = GetItemSet().GetItemIfSet( SID_HTML_MODE, false );
+ if ( !pHtmlModeItem)
+ {
+ if (SfxObjectShell* pShell = SfxObjectShell::Current())
+ pHtmlModeItem = pShell->GetItem( SID_HTML_MODE );
+ }
+ if (pHtmlModeItem)
+ {
+ sal_uInt16 nHtmlMode = pHtmlModeItem->GetValue();
+ if ( ( nHtmlMode & HTMLMODE_ON ) == HTMLMODE_ON )
+ {
+ //!!! hide some controls please
+ }
+ }
+
+ m_xFontColorLB->SetSelectHdl(LINK(this, SvxCharEffectsPage, ColorBoxSelectHdl_Impl));
+ m_xFontTransparencyMtr->connect_value_changed(
+ LINK(this, SvxCharEffectsPage, ModifyFontTransparencyHdl_Impl));
+
+ // handler
+ Link<weld::ComboBox&,void> aLink = LINK( this, SvxCharEffectsPage, SelectListBoxHdl_Impl );
+ m_xUnderlineLB->connect_changed( aLink );
+ m_xUnderlineColorLB->SetSelectHdl(LINK(this, SvxCharEffectsPage, ColorBoxSelectHdl_Impl));
+ m_xOverlineLB->connect_changed( aLink );
+ m_xOverlineColorLB->SetSelectHdl(LINK(this, SvxCharEffectsPage, ColorBoxSelectHdl_Impl));
+ m_xStrikeoutLB->connect_changed( aLink );
+ m_xEmphasisLB->connect_changed( aLink );
+ m_xPositionLB->connect_changed( aLink );
+ m_xEffectsLB->connect_changed( aLink );
+ m_xReliefLB->connect_changed( aLink );
+
+ m_xUnderlineLB->set_active( 0 );
+ m_xOverlineLB->set_active( 0 );
+ m_xStrikeoutLB->set_active( 0 );
+ m_xEmphasisLB->set_active( 0 );
+ m_xPositionLB->set_active( 0 );
+ SelectHdl_Impl(nullptr);
+ SelectHdl_Impl(m_xEmphasisLB.get());
+
+ m_xEffectsLB->set_active( 0 );
+
+ m_xHiddenBtn->connect_toggled(LINK(this, SvxCharEffectsPage, HiddenBtnClickHdl));
+ m_xIndividualWordsBtn->connect_toggled(LINK(this, SvxCharEffectsPage, CbClickHdl_Impl));
+ m_xOutlineBtn->connect_toggled(LINK(this, SvxCharEffectsPage, OutlineBtnClickHdl));
+ m_xShadowBtn->connect_toggled(LINK(this, SvxCharEffectsPage, ShadowBtnClickHdl));
+
+ if ( !SvtCJKOptions::IsAsianTypographyEnabled() )
+ {
+ m_xEmphasisFT->hide();
+ m_xEmphasisLB->hide();
+ m_xPositionFT->hide();
+ m_xPositionLB->hide();
+ }
+
+ m_xA11yWarningFT->set_visible(officecfg::Office::Common::Accessibility::IsAutomaticFontColor::get());
+}
+
+void SvxCharEffectsPage::UpdatePreview_Impl()
+{
+ SvxFont& rFont = GetPreviewFont();
+ SvxFont& rCJKFont = GetPreviewCJKFont();
+ SvxFont& rCTLFont = GetPreviewCTLFont();
+
+ const Color& rSelectedColor = m_xFontColorLB->GetSelectEntryColor();
+ rFont.SetColor(rSelectedColor);
+ rCJKFont.SetColor(rSelectedColor);
+ rCTLFont.SetColor(rSelectedColor);
+ m_aPreviewWin.AutoCorrectFontColor(); // handle color COL_AUTO
+
+ FontLineStyle eUnderline = static_cast<FontLineStyle>(m_xUnderlineLB->get_active_id().toInt32());
+ FontLineStyle eOverline = static_cast<FontLineStyle>(m_xOverlineLB->get_active_id().toInt32());
+ FontStrikeout eStrikeout = static_cast<FontStrikeout>(m_xStrikeoutLB->get_active_id().toInt32());
+ rFont.SetUnderline( eUnderline );
+ rCJKFont.SetUnderline( eUnderline );
+ rCTLFont.SetUnderline( eUnderline );
+ m_aPreviewWin.SetTextLineColor( m_xUnderlineColorLB->GetSelectEntryColor() );
+ rFont.SetOverline( eOverline );
+ rCJKFont.SetOverline( eOverline );
+ rCTLFont.SetOverline( eOverline );
+ m_aPreviewWin.SetOverlineColor( m_xOverlineColorLB->GetSelectEntryColor() );
+ rFont.SetStrikeout( eStrikeout );
+ rCJKFont.SetStrikeout( eStrikeout );
+ rCTLFont.SetStrikeout( eStrikeout );
+
+ auto nEmphasis = m_xEmphasisLB->get_active();
+ if (nEmphasis != -1)
+ {
+ bool bUnder = (CHRDLG_POSITION_UNDER == m_xPositionLB->get_active_id().toInt32());
+ FontEmphasisMark eMark = static_cast<FontEmphasisMark>(nEmphasis);
+ eMark |= bUnder ? FontEmphasisMark::PosBelow : FontEmphasisMark::PosAbove;
+ rFont.SetEmphasisMark( eMark );
+ rCJKFont.SetEmphasisMark( eMark );
+ rCTLFont.SetEmphasisMark( eMark );
+ }
+
+ auto nRelief = m_xReliefLB->get_active();
+ if (nRelief != -1)
+ {
+ rFont.SetRelief( static_cast<FontRelief>(nRelief) );
+ rCJKFont.SetRelief( static_cast<FontRelief>(nRelief) );
+ rCTLFont.SetRelief( static_cast<FontRelief>(nRelief) );
+ }
+
+ rFont.SetOutline( StateToAttr( m_xOutlineBtn->get_state() ) );
+ rCJKFont.SetOutline( rFont.IsOutline() );
+ rCTLFont.SetOutline( rFont.IsOutline() );
+
+ rFont.SetShadow( StateToAttr( m_xShadowBtn->get_state() ) );
+ rCJKFont.SetShadow( rFont.IsShadow() );
+ rCTLFont.SetShadow( rFont.IsShadow() );
+
+ auto nCapsPos = m_xEffectsLB->get_active();
+ if (nCapsPos != -1)
+ {
+ SvxCaseMap eCaps = static_cast<SvxCaseMap>(nCapsPos);
+ rFont.SetCaseMap( eCaps );
+ rCJKFont.SetCaseMap( eCaps );
+ // #i78474# small caps do not exist in CTL fonts
+ rCTLFont.SetCaseMap( eCaps == SvxCaseMap::SmallCaps ? SvxCaseMap::NotMapped : eCaps );
+ }
+
+ bool bWordLine = StateToAttr( m_xIndividualWordsBtn->get_state() );
+ rFont.SetWordLineMode( bWordLine );
+ rCJKFont.SetWordLineMode( bWordLine );
+ rCTLFont.SetWordLineMode( bWordLine );
+
+ m_aPreviewWin.Invalidate();
+}
+
+void SvxCharEffectsPage::SetCaseMap_Impl( SvxCaseMap eCaseMap )
+{
+ if ( SvxCaseMap::End > eCaseMap )
+ m_xEffectsLB->set_active(
+ sal::static_int_cast< sal_Int32 >( eCaseMap ) );
+ else
+ {
+ // not mapped
+ m_xEffectsLB->set_active(-1);
+ }
+
+ UpdatePreview_Impl();
+}
+
+void SvxCharEffectsPage::ResetColor_Impl( const SfxItemSet& rSet )
+{
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_COLOR );
+ SfxItemState eState = rSet.GetItemState( nWhich );
+
+ m_bOrigFontColor = false;
+ switch ( eState )
+ {
+ case SfxItemState::UNKNOWN:
+ m_xFontColorFT->hide();
+ m_xFontColorLB->hide();
+ break;
+
+ case SfxItemState::DISABLED:
+ m_xFontColorFT->set_sensitive(false);
+ m_xFontColorLB->set_sensitive(false);
+ break;
+
+ case SfxItemState::DONTCARE:
+ //Related: tdf#106080 if there is no font color, then allow "none"
+ //as a color so the listbox can display that state.
+ EnableNoneFontColor();
+ m_xFontColorLB->SetNoSelection();
+ break;
+
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ SvxFont& rFont = GetPreviewFont();
+ SvxFont& rCJKFont = GetPreviewCJKFont();
+ SvxFont& rCTLFont = GetPreviewCTLFont();
+
+ const SvxColorItem& rItem = static_cast<const SvxColorItem&>(rSet.Get( nWhich ));
+ Color aColor = rItem.GetValue();
+ rFont.SetColor(aColor);
+ rCJKFont.SetColor(aColor);
+ rCTLFont.SetColor(aColor);
+ m_aPreviewWin.AutoCorrectFontColor(); // handle color COL_AUTO
+
+ m_aPreviewWin.Invalidate();
+
+ Color aRGBColor = aColor;
+ if (aRGBColor.IsTransparent() && aColor != COL_AUTO)
+ {
+ aRGBColor.SetAlpha(255);
+ }
+ m_xFontColorLB->SelectEntry(aRGBColor);
+
+ if (m_xFontTransparencyMtr->get_visible() && aColor != COL_AUTO)
+ {
+ double fTransparency = (255 - aColor.GetAlpha()) * 100.0 / 255;
+ m_xFontTransparencyMtr->set_value(basegfx::fround(fTransparency),
+ FieldUnit::PERCENT);
+ }
+
+ m_aOrigFontColor = aColor;
+ m_bOrigFontColor = true;
+ break;
+ }
+ }
+ m_bNewFontColor = false;
+}
+
+bool SvxCharEffectsPage::FillItemSetColor_Impl( SfxItemSet& rSet )
+{
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_COLOR );
+ const SfxItemSet& rOldSet = GetItemSet();
+
+ NamedColor aSelectedColor;
+ bool bChanged = m_bNewFontColor;
+
+ if (bChanged)
+ {
+ aSelectedColor = m_xFontColorLB->GetSelectedEntryThemedColor();
+
+ if (m_xFontTransparencyMtr->get_value_changed_from_saved())
+ {
+ double fTransparency
+ = m_xFontTransparencyMtr->get_value(FieldUnit::PERCENT) * 255.0 / 100;
+ aSelectedColor.m_aColor.SetAlpha(255 - static_cast<sal_uInt8>(basegfx::fround(fTransparency)));
+ }
+
+ if (m_bOrigFontColor)
+ bChanged = aSelectedColor.m_aColor != m_aOrigFontColor;
+ if (m_bEnableNoneFontColor && bChanged && aSelectedColor.m_aColor == COL_NONE_COLOR)
+ bChanged = false;
+ }
+
+ if (bChanged)
+ {
+ SvxColorItem aItem(aSelectedColor.m_aColor, aSelectedColor.getComplexColor(), nWhich);
+ rSet.Put(aItem);
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet.InvalidateItem(nWhich);
+
+ return bChanged;
+}
+
+IMPL_LINK( SvxCharEffectsPage, SelectListBoxHdl_Impl, weld::ComboBox&, rBox, void )
+{
+ SelectHdl_Impl(&rBox);
+}
+
+void SvxCharEffectsPage::SelectHdl_Impl(const weld::ComboBox* pBox)
+{
+ if (m_xEmphasisLB.get() == pBox)
+ {
+ auto nEPos = m_xEmphasisLB->get_active();
+ bool bEnable = nEPos > 0;
+ m_xPositionFT->set_sensitive( bEnable );
+ m_xPositionLB->set_sensitive( bEnable );
+ }
+ else if (m_xReliefLB.get() == pBox)
+ {
+ bool bEnable = ( pBox->get_active() == 0 );
+ m_xOutlineBtn->set_sensitive( bEnable );
+ m_xShadowBtn->set_sensitive( bEnable );
+ }
+ else if (m_xPositionLB.get() != pBox)
+ {
+ auto nUPos = m_xUnderlineLB->get_active();
+ bool bUEnable = nUPos > 0;
+ m_xUnderlineColorFT->set_sensitive(bUEnable);
+ m_xUnderlineColorLB->set_sensitive(bUEnable);
+
+ auto nOPos = m_xOverlineLB->get_active();
+ bool bOEnable = nOPos > 0;
+ m_xOverlineColorFT->set_sensitive(bOEnable);
+ m_xOverlineColorLB->set_sensitive(bOEnable);
+
+ auto nSPos = m_xStrikeoutLB->get_active();
+ m_xIndividualWordsBtn->set_sensitive( bUEnable || bOEnable || nSPos > 0);
+ }
+ UpdatePreview_Impl();
+}
+
+IMPL_LINK(SvxCharEffectsPage, CbClickHdl_Impl, weld::Toggleable&, rToggle, void)
+{
+ m_aIndividualWordsState.ButtonToggled(rToggle);
+ UpdatePreview_Impl();
+ UpdatePreview_Impl();
+}
+
+IMPL_LINK(SvxCharEffectsPage, ColorBoxSelectHdl_Impl, ColorListBox&, rBox, void)
+{
+ if (m_xFontColorLB.get() == &rBox)
+ m_bNewFontColor = true;
+ UpdatePreview_Impl();
+}
+
+IMPL_LINK_NOARG(SvxCharEffectsPage, ModifyFontTransparencyHdl_Impl, weld::MetricSpinButton&, void)
+{
+ m_bNewFontColor = true;
+}
+
+DeactivateRC SvxCharEffectsPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if ( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+std::unique_ptr<SfxTabPage> SvxCharEffectsPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet )
+{
+ return std::make_unique<SvxCharEffectsPage>( pPage, pController, *rSet );
+}
+
+void SvxCharEffectsPage::Reset( const SfxItemSet* rSet )
+{
+ SvxFont& rFont = GetPreviewFont();
+ SvxFont& rCJKFont = GetPreviewCJKFont();
+ SvxFont& rCTLFont = GetPreviewCTLFont();
+
+ bool bEnable = false;
+
+ // Underline
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_UNDERLINE );
+ rFont.SetUnderline( LINESTYLE_NONE );
+ rCJKFont.SetUnderline( LINESTYLE_NONE );
+ rCTLFont.SetUnderline( LINESTYLE_NONE );
+
+ m_xUnderlineLB->set_active( 0 );
+ SfxItemState eState = rSet->GetItemState( nWhich );
+
+ if ( eState >= SfxItemState::DONTCARE )
+ {
+ if ( eState == SfxItemState::DONTCARE )
+ m_xUnderlineLB->set_active(-1);
+ else
+ {
+ const SvxUnderlineItem& rItem = static_cast<const SvxUnderlineItem&>(rSet->Get( nWhich ));
+ FontLineStyle eUnderline = rItem.GetValue();
+ rFont.SetUnderline( eUnderline );
+ rCJKFont.SetUnderline( eUnderline );
+ rCTLFont.SetUnderline( eUnderline );
+
+ if ( eUnderline != LINESTYLE_NONE )
+ {
+ auto nPos = m_xUnderlineLB->find_id(OUString::number(eUnderline));
+ if (nPos != -1)
+ {
+ m_xUnderlineLB->set_active(nPos);
+ bEnable = true;
+ }
+ Color aColor = rItem.GetColor();
+ m_xUnderlineColorLB->SelectEntry(aColor);
+ }
+ else
+ {
+ m_xUnderlineColorLB->SelectEntry(COL_AUTO);
+ m_xUnderlineColorLB->set_sensitive(false);
+ }
+ }
+ }
+
+ // Overline
+ nWhich = GetWhich( SID_ATTR_CHAR_OVERLINE );
+ rFont.SetOverline( LINESTYLE_NONE );
+ rCJKFont.SetOverline( LINESTYLE_NONE );
+ rCTLFont.SetOverline( LINESTYLE_NONE );
+
+ m_xOverlineLB->set_active( 0 );
+ eState = rSet->GetItemState( nWhich );
+
+ if ( eState >= SfxItemState::DONTCARE )
+ {
+ if ( eState == SfxItemState::DONTCARE )
+ m_xOverlineLB->set_active(-1);
+ else
+ {
+ const SvxOverlineItem& rItem = static_cast<const SvxOverlineItem&>(rSet->Get( nWhich ));
+ FontLineStyle eOverline = rItem.GetValue();
+ rFont.SetOverline( eOverline );
+ rCJKFont.SetOverline( eOverline );
+ rCTLFont.SetOverline( eOverline );
+
+ if ( eOverline != LINESTYLE_NONE )
+ {
+ auto nPos = m_xOverlineLB->find_id(OUString::number(eOverline));
+ if (nPos != -1)
+ {
+ m_xOverlineLB->set_active(nPos);
+ bEnable = true;
+ }
+ Color aColor = rItem.GetColor();
+ m_xOverlineColorLB->SelectEntry(aColor);
+ }
+ else
+ {
+ m_xOverlineColorLB->SelectEntry(COL_AUTO);
+ m_xOverlineColorLB->set_sensitive(false);
+ }
+ }
+ }
+
+ // Strikeout
+ nWhich = GetWhich( SID_ATTR_CHAR_STRIKEOUT );
+ rFont.SetStrikeout( STRIKEOUT_NONE );
+ rCJKFont.SetStrikeout( STRIKEOUT_NONE );
+ rCTLFont.SetStrikeout( STRIKEOUT_NONE );
+
+ m_xStrikeoutLB->set_active( 0 );
+ eState = rSet->GetItemState( nWhich );
+
+ if ( eState >= SfxItemState::DONTCARE )
+ {
+ if ( eState == SfxItemState::DONTCARE )
+ m_xStrikeoutLB->set_active(-1);
+ else
+ {
+ const SvxCrossedOutItem& rItem = static_cast<const SvxCrossedOutItem&>(rSet->Get( nWhich ));
+ FontStrikeout eStrikeout = rItem.GetValue();
+ rFont.SetStrikeout( eStrikeout );
+ rCJKFont.SetStrikeout( eStrikeout );
+ rCTLFont.SetStrikeout( eStrikeout );
+
+ if ( eStrikeout != STRIKEOUT_NONE )
+ {
+ auto nPos = m_xStrikeoutLB->find_id(OUString::number(eStrikeout));
+ if (nPos != -1)
+ {
+ m_xStrikeoutLB->set_active(nPos);
+ bEnable = true;
+ }
+ }
+ }
+ }
+
+ // WordLineMode
+ nWhich = GetWhich( SID_ATTR_CHAR_WORDLINEMODE );
+ eState = rSet->GetItemState( nWhich );
+
+ switch ( eState )
+ {
+ case SfxItemState::UNKNOWN:
+ m_aIndividualWordsState.bTriStateEnabled = false;
+ m_xIndividualWordsBtn->hide();
+ break;
+
+ case SfxItemState::DISABLED:
+ m_aIndividualWordsState.bTriStateEnabled = false;
+ m_xIndividualWordsBtn->set_sensitive(false);
+ break;
+
+ case SfxItemState::DONTCARE:
+ m_aIndividualWordsState.bTriStateEnabled = true;
+ m_xIndividualWordsBtn->set_state( TRISTATE_INDET );
+ break;
+
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxWordLineModeItem& rItem = static_cast<const SvxWordLineModeItem&>(rSet->Get( nWhich ));
+ rFont.SetWordLineMode( rItem.GetValue() );
+ rCJKFont.SetWordLineMode( rItem.GetValue() );
+ rCTLFont.SetWordLineMode( rItem.GetValue() );
+
+ m_aIndividualWordsState.bTriStateEnabled = false;
+ m_xIndividualWordsBtn->set_active(rItem.GetValue());
+ m_xIndividualWordsBtn->set_sensitive(bEnable);
+ break;
+ }
+ }
+
+ // Emphasis
+ nWhich = GetWhich( SID_ATTR_CHAR_EMPHASISMARK );
+ eState = rSet->GetItemState( nWhich );
+
+ if ( eState >= SfxItemState::DEFAULT )
+ {
+ const SvxEmphasisMarkItem& rItem = static_cast<const SvxEmphasisMarkItem&>(rSet->Get( nWhich ));
+ FontEmphasisMark eMark = rItem.GetEmphasisMark();
+ rFont.SetEmphasisMark( eMark );
+ rCJKFont.SetEmphasisMark( eMark );
+ rCTLFont.SetEmphasisMark( eMark );
+
+ m_xEmphasisLB->set_active( static_cast<sal_Int32>(FontEmphasisMark( eMark & FontEmphasisMark::Style )) );
+ eMark &= ~FontEmphasisMark::Style;
+ int nEntryData = ( eMark == FontEmphasisMark::PosAbove )
+ ? CHRDLG_POSITION_OVER
+ : ( eMark == FontEmphasisMark::PosBelow ) ? CHRDLG_POSITION_UNDER : 0;
+
+ auto nPos = m_xPositionLB->find_id(OUString::number(nEntryData));
+ if (nPos != -1)
+ m_xPositionLB->set_active(nPos);
+ }
+ else if ( eState == SfxItemState::DONTCARE )
+ m_xEmphasisLB->set_active(-1);
+ else if ( eState == SfxItemState::UNKNOWN )
+ {
+ m_xEmphasisFT->hide();
+ m_xEmphasisLB->hide();
+ }
+ else // SfxItemState::DISABLED
+ {
+ m_xEmphasisFT->set_sensitive(false);
+ m_xEmphasisLB->set_sensitive(false);
+ }
+
+ // the select handler for the underline/overline/strikeout list boxes
+ SelectHdl_Impl(m_xUnderlineLB.get());
+
+ // the select handler for the emphasis listbox
+ SelectHdl_Impl(m_xEmphasisLB.get());
+
+ // Effects
+ SvxCaseMap eCaseMap = SvxCaseMap::End;
+ nWhich = GetWhich( SID_ATTR_CHAR_CASEMAP );
+ eState = rSet->GetItemState( nWhich );
+ switch ( eState )
+ {
+ case SfxItemState::UNKNOWN:
+ m_xEffectsFT->hide();
+ m_xEffectsLB->hide();
+ break;
+
+ case SfxItemState::DISABLED:
+ m_xEffectsFT->set_sensitive(false);
+ m_xEffectsLB->set_sensitive(false);
+ break;
+
+ case SfxItemState::DONTCARE:
+ m_xEffectsLB->set_active(-1);
+ break;
+
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxCaseMapItem& rItem = static_cast<const SvxCaseMapItem&>(rSet->Get( nWhich ));
+ eCaseMap = rItem.GetValue();
+ break;
+ }
+ }
+ SetCaseMap_Impl( eCaseMap );
+
+ //Relief
+ nWhich = GetWhich(SID_ATTR_CHAR_RELIEF);
+ eState = rSet->GetItemState( nWhich );
+ switch ( eState )
+ {
+ case SfxItemState::UNKNOWN:
+ m_xReliefFT->hide();
+ m_xReliefLB->hide();
+ break;
+
+ case SfxItemState::DISABLED:
+ m_xReliefFT->set_sensitive(false);
+ m_xReliefLB->set_sensitive(false);
+ break;
+
+ case SfxItemState::DONTCARE:
+ m_xReliefLB->set_active(-1);
+ break;
+
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxCharReliefItem& rItem = static_cast<const SvxCharReliefItem&>(rSet->Get( nWhich ));
+ m_xReliefLB->set_active(static_cast<sal_Int32>(rItem.GetValue()));
+ SelectHdl_Impl(m_xReliefLB.get());
+ break;
+ }
+ }
+
+ // Outline
+ nWhich = GetWhich( SID_ATTR_CHAR_CONTOUR );
+ eState = rSet->GetItemState( nWhich );
+ switch ( eState )
+ {
+ case SfxItemState::UNKNOWN:
+ m_aOutlineState.bTriStateEnabled = false;
+ m_xOutlineBtn->hide();
+ break;
+
+ case SfxItemState::DISABLED:
+ m_aOutlineState.bTriStateEnabled = false;
+ m_xOutlineBtn->set_sensitive(false);
+ break;
+
+ case SfxItemState::DONTCARE:
+ m_aOutlineState.bTriStateEnabled = true;
+ m_xOutlineBtn->set_state(TRISTATE_INDET);
+ break;
+
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxContourItem& rItem = static_cast<const SvxContourItem&>(rSet->Get( nWhich ));
+ m_aOutlineState.bTriStateEnabled = false;
+ m_xOutlineBtn->set_state(static_cast<TriState>(rItem.GetValue()));
+ break;
+ }
+ }
+
+ // Shadow
+ nWhich = GetWhich( SID_ATTR_CHAR_SHADOWED );
+ eState = rSet->GetItemState( nWhich );
+
+ switch ( eState )
+ {
+ case SfxItemState::UNKNOWN:
+ m_aShadowState.bTriStateEnabled = false;
+ m_xShadowBtn->hide();
+ break;
+
+ case SfxItemState::DISABLED:
+ m_aShadowState.bTriStateEnabled = false;
+ m_xShadowBtn->set_sensitive(false);
+ break;
+
+ case SfxItemState::DONTCARE:
+ m_aShadowState.bTriStateEnabled = true;
+ m_xShadowBtn->set_state( TRISTATE_INDET );
+ break;
+
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxShadowedItem& rItem = static_cast<const SvxShadowedItem&>(rSet->Get( nWhich ));
+ m_aShadowState.bTriStateEnabled = false;
+ m_xShadowBtn->set_state( static_cast<TriState>(rItem.GetValue()) );
+ break;
+ }
+ }
+
+ // Hidden
+ nWhich = GetWhich( SID_ATTR_CHAR_HIDDEN );
+ eState = rSet->GetItemState( nWhich );
+
+ switch ( eState )
+ {
+ case SfxItemState::UNKNOWN:
+ m_aHiddenState.bTriStateEnabled = false;
+ m_xHiddenBtn->hide();
+ break;
+
+ case SfxItemState::DISABLED:
+ m_aHiddenState.bTriStateEnabled = false;
+ m_xHiddenBtn->set_sensitive(false);
+ break;
+
+ case SfxItemState::DONTCARE:
+ m_aHiddenState.bTriStateEnabled = true;
+ m_xHiddenBtn->set_state(TRISTATE_INDET);
+ break;
+
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxCharHiddenItem& rItem = static_cast<const SvxCharHiddenItem&>(rSet->Get( nWhich ));
+ m_aHiddenState.bTriStateEnabled = false;
+ m_xHiddenBtn->set_state(static_cast<TriState>(rItem.GetValue()));
+ break;
+ }
+ }
+
+ SetPrevFontWidthScale( *rSet );
+ ResetColor_Impl( *rSet );
+
+ // preview update
+ m_aPreviewWin.Invalidate();
+
+ // save this settings
+ ChangesApplied();
+}
+
+IMPL_LINK(SvxCharEffectsPage, HiddenBtnClickHdl, weld::Toggleable&, rToggle, void)
+{
+ m_aHiddenState.ButtonToggled(rToggle);
+}
+
+IMPL_LINK(SvxCharEffectsPage, OutlineBtnClickHdl, weld::Toggleable&, rToggle, void)
+{
+ m_aOutlineState.ButtonToggled(rToggle);
+ UpdatePreview_Impl();
+}
+
+IMPL_LINK(SvxCharEffectsPage, ShadowBtnClickHdl, weld::Toggleable&, rToggle, void)
+{
+ m_aShadowState.ButtonToggled(rToggle);
+ UpdatePreview_Impl();
+}
+
+void SvxCharEffectsPage::ChangesApplied()
+{
+ m_xUnderlineLB->save_value();
+ m_xOverlineLB->save_value();
+ m_xStrikeoutLB->save_value();
+ m_xIndividualWordsBtn->save_state();
+ m_xEmphasisLB->save_value();
+ m_xPositionLB->save_value();
+ m_xEffectsLB->save_value();
+ m_xReliefLB->save_value();
+ m_xOutlineBtn->save_state();
+ m_xShadowBtn->save_state();
+ m_xHiddenBtn->save_state();
+ m_xFontTransparencyMtr->save_value();
+}
+
+bool SvxCharEffectsPage::FillItemSet( SfxItemSet* rSet )
+{
+ const SfxPoolItem* pOld = nullptr;
+ const SfxItemSet& rOldSet = GetItemSet();
+ bool bModified = false;
+ bool bChanged = true;
+
+ // Underline
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_UNDERLINE );
+ pOld = GetOldItem( *rSet, SID_ATTR_CHAR_UNDERLINE );
+ auto nPos = m_xUnderlineLB->get_active();
+ FontLineStyle eUnder = static_cast<FontLineStyle>(m_xUnderlineLB->get_active_id().toInt32());
+
+ if ( pOld )
+ {
+ //! if there are different underline styles in the selection the
+ //! item-state in the 'rOldSet' will be invalid. In this case
+ //! changing the underline style will be allowed if a style is
+ //! selected in the listbox.
+ bool bAllowChange = nPos != -1 &&
+ SfxItemState::DEFAULT > rOldSet.GetItemState( nWhich );
+
+ const SvxUnderlineItem& rItem = *static_cast<const SvxUnderlineItem*>(pOld);
+ if (rItem.GetValue() == eUnder &&
+ (LINESTYLE_NONE == eUnder || (rItem.GetColor() == m_xUnderlineColorLB->GetSelectEntryColor() &&
+ rItem.getComplexColor() == m_xUnderlineColorLB->GetSelectedEntry().getComplexColor())) &&
+ !bAllowChange)
+ {
+ bChanged = false;
+ }
+ }
+
+ if ( bChanged )
+ {
+ SvxUnderlineItem aNewItem( eUnder, nWhich );
+ auto aNamedColor = m_xUnderlineColorLB->GetSelectedEntry();
+ aNewItem.SetColor(aNamedColor.m_aColor);
+ aNewItem.setComplexColor(aNamedColor.getComplexColor());
+ rSet->Put(aNewItem);
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ bChanged = true;
+
+ // Overline
+ nWhich = GetWhich( SID_ATTR_CHAR_OVERLINE );
+ pOld = GetOldItem( *rSet, SID_ATTR_CHAR_OVERLINE );
+ nPos = m_xOverlineLB->get_active();
+ FontLineStyle eOver = static_cast<FontLineStyle>(m_xOverlineLB->get_active_id().toInt32());
+
+ if ( pOld )
+ {
+ //! if there are different underline styles in the selection the
+ //! item-state in the 'rOldSet' will be invalid. In this case
+ //! changing the underline style will be allowed if a style is
+ //! selected in the listbox.
+ bool bAllowChange = nPos != -1 &&
+ SfxItemState::DEFAULT > rOldSet.GetItemState( nWhich );
+
+ const SvxOverlineItem& rItem = *static_cast<const SvxOverlineItem*>(pOld);
+ if (rItem.GetValue() == eOver &&
+ (LINESTYLE_NONE == eOver || (rItem.GetColor() == m_xOverlineColorLB->GetSelectEntryColor() &&
+ rItem.getComplexColor() == m_xOverlineColorLB->GetSelectedEntry().getComplexColor())) &&
+ !bAllowChange)
+ {
+ bChanged = false;
+ }
+ }
+
+ if ( bChanged )
+ {
+ SvxOverlineItem aNewItem( eOver, nWhich );
+ auto aNamedColor = m_xOverlineColorLB->GetSelectedEntry();
+ aNewItem.SetColor(aNamedColor.m_aColor);
+ aNewItem.setComplexColor(aNamedColor.getComplexColor());
+ rSet->Put(aNewItem);
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ bChanged = true;
+
+ // Strikeout
+ nWhich = GetWhich( SID_ATTR_CHAR_STRIKEOUT );
+ pOld = GetOldItem( *rSet, SID_ATTR_CHAR_STRIKEOUT );
+ nPos = m_xStrikeoutLB->get_active();
+ FontStrikeout eStrike = static_cast<FontStrikeout>(m_xStrikeoutLB->get_active_id().toInt32());
+
+ if ( pOld )
+ {
+ //! if there are different strikeout styles in the selection the
+ //! item-state in the 'rOldSet' will be invalid. In this case
+ //! changing the strikeout style will be allowed if a style is
+ //! selected in the listbox.
+ bool bAllowChg = nPos != -1 &&
+ SfxItemState::DEFAULT > rOldSet.GetItemState( nWhich );
+
+ const SvxCrossedOutItem& rItem = *static_cast<const SvxCrossedOutItem*>(pOld);
+ if ( !m_xStrikeoutLB->get_sensitive()
+ || (rItem.GetValue() == eStrike && !bAllowChg) )
+ bChanged = false;
+ }
+
+ if ( bChanged )
+ {
+ rSet->Put( SvxCrossedOutItem( eStrike, nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ bChanged = true;
+
+ // Individual words
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ nWhich = GetWhich( SID_ATTR_CHAR_WORDLINEMODE );
+ pOld = GetOldItem( *rSet, SID_ATTR_CHAR_WORDLINEMODE );
+ TriState eState = m_xIndividualWordsBtn->get_state();
+ const SfxPoolItem* pItem;
+
+ if ( pOld )
+ {
+ const SvxWordLineModeItem& rItem = *static_cast<const SvxWordLineModeItem*>(pOld);
+ if ( rItem.GetValue() == StateToAttr( eState ) && m_xIndividualWordsBtn->get_saved_state() == eState )
+ bChanged = false;
+ }
+
+ if ( !bChanged && pExampleSet && pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
+ !StateToAttr( eState ) && static_cast<const SvxWordLineModeItem*>(pItem)->GetValue() )
+ bChanged = true;
+
+ if ( bChanged && eState != TRISTATE_INDET )
+ {
+ rSet->Put( SvxWordLineModeItem( StateToAttr( eState ), nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ bChanged = true;
+
+ // Emphasis
+ nWhich = GetWhich( SID_ATTR_CHAR_EMPHASISMARK );
+ pOld = GetOldItem( *rSet, SID_ATTR_CHAR_EMPHASISMARK );
+ int nMarkPos = m_xEmphasisLB->get_active();
+ OUString sMarkPos = m_xEmphasisLB->get_active_text();
+ OUString sPosPos = m_xPositionLB->get_active_text();
+ FontEmphasisMark eMark = static_cast<FontEmphasisMark>(nMarkPos);
+ if (m_xPositionLB->get_sensitive())
+ {
+ eMark |= (CHRDLG_POSITION_UNDER == m_xPositionLB->get_active_id().toInt32())
+ ? FontEmphasisMark::PosBelow : FontEmphasisMark::PosAbove;
+ }
+
+ if ( pOld )
+ {
+ if( rOldSet.GetItemState( nWhich ) != SfxItemState::DONTCARE )
+ {
+ const SvxEmphasisMarkItem& rItem = *static_cast<const SvxEmphasisMarkItem*>(pOld);
+ if ( rItem.GetEmphasisMark() == eMark )
+ bChanged = false;
+ }
+ }
+
+ if (rOldSet.GetItemState( nWhich ) == SfxItemState::DONTCARE &&
+ m_xEmphasisLB->get_saved_value() == sMarkPos && m_xPositionLB->get_saved_value() == sPosPos)
+ {
+ bChanged = false;
+ }
+
+ if (bChanged)
+ {
+ rSet->Put( SvxEmphasisMarkItem( eMark, TypedWhichId<SvxEmphasisMarkItem>(nWhich) ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ bChanged = true;
+
+ // Effects
+ nWhich = GetWhich( SID_ATTR_CHAR_CASEMAP );
+ pOld = GetOldItem( *rSet, SID_ATTR_CHAR_CASEMAP );
+ SvxCaseMap eCaseMap = SvxCaseMap::NotMapped;
+ bool bChecked = false;
+ auto nCapsPos = m_xEffectsLB->get_active();
+ if (nCapsPos != -1)
+ {
+ eCaseMap = static_cast<SvxCaseMap>(nCapsPos);
+ bChecked = true;
+ }
+
+ if ( pOld )
+ {
+ //! if there are different effect styles in the selection the
+ //! item-state in the 'rOldSet' will be invalid. In this case
+ //! changing the effect style will be allowed if a style is
+ //! selected in the listbox.
+ bool bAllowChg = nPos != -1 &&
+ SfxItemState::DEFAULT > rOldSet.GetItemState( nWhich );
+
+ const SvxCaseMapItem& rItem = *static_cast<const SvxCaseMapItem*>(pOld);
+ if ( rItem.GetValue() == eCaseMap && !bAllowChg )
+ bChanged = false;
+ }
+
+ if ( bChanged && bChecked )
+ {
+ rSet->Put( SvxCaseMapItem( eCaseMap, nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ bChanged = true;
+
+ //Relief
+ nWhich = GetWhich(SID_ATTR_CHAR_RELIEF);
+ if (m_xReliefLB->get_value_changed_from_saved())
+ {
+ m_xReliefLB->save_value();
+ SvxCharReliefItem aRelief(static_cast<FontRelief>(m_xReliefLB->get_active()), nWhich);
+ rSet->Put(aRelief);
+ }
+
+ // Outline
+ nWhich = GetWhich( SID_ATTR_CHAR_CONTOUR );
+ pOld = GetOldItem( *rSet, SID_ATTR_CHAR_CONTOUR );
+ eState = m_xOutlineBtn->get_state();
+
+ if ( pOld )
+ {
+ const SvxContourItem& rItem = *static_cast<const SvxContourItem*>(pOld);
+ if ( rItem.GetValue() == StateToAttr( eState ) && m_xOutlineBtn->get_saved_state() == eState )
+ bChanged = false;
+ }
+
+ if ( !bChanged && pExampleSet && pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
+ !StateToAttr( eState ) && static_cast<const SvxContourItem*>(pItem)->GetValue() )
+ bChanged = true;
+
+ if ( bChanged && eState != TRISTATE_INDET )
+ {
+ rSet->Put( SvxContourItem( StateToAttr( eState ), nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ bChanged = true;
+
+ // Shadow
+ nWhich = GetWhich( SID_ATTR_CHAR_SHADOWED );
+ pOld = GetOldItem( *rSet, SID_ATTR_CHAR_SHADOWED );
+ eState = m_xShadowBtn->get_state();
+
+ if ( pOld )
+ {
+ const SvxShadowedItem& rItem = *static_cast<const SvxShadowedItem*>(pOld);
+ if ( rItem.GetValue() == StateToAttr( eState ) && m_xShadowBtn->get_saved_state() == eState )
+ bChanged = false;
+ }
+
+ if ( !bChanged && pExampleSet && pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
+ !StateToAttr( eState ) && static_cast<const SvxShadowedItem*>(pItem)->GetValue() )
+ bChanged = true;
+
+ if ( bChanged && eState != TRISTATE_INDET )
+ {
+ rSet->Put( SvxShadowedItem( StateToAttr( eState ), nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ bChanged = true;
+
+ // Hidden
+ nWhich = GetWhich( SID_ATTR_CHAR_HIDDEN );
+ pOld = GetOldItem( *rSet, SID_ATTR_CHAR_HIDDEN );
+ eState = m_xHiddenBtn->get_state();
+ bChanged = true;
+
+ if ( pOld )
+ {
+ const SvxCharHiddenItem& rItem = *static_cast<const SvxCharHiddenItem*>(pOld);
+ if ( rItem.GetValue() == StateToAttr( eState ) && m_xHiddenBtn->get_saved_state() == eState )
+ bChanged = false;
+ }
+
+ if ( !bChanged && pExampleSet && pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
+ !StateToAttr( eState ) && static_cast<const SvxCharHiddenItem*>(pItem)->GetValue() )
+ bChanged = true;
+
+ if ( bChanged && eState != TRISTATE_INDET )
+ {
+ rSet->Put( SvxCharHiddenItem( StateToAttr( eState ), nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ bModified |= FillItemSetColor_Impl( *rSet );
+
+ return bModified;
+}
+
+void SvxCharEffectsPage::DisableControls( sal_uInt16 nDisable )
+{
+ if ( ( DISABLE_CASEMAP & nDisable ) == DISABLE_CASEMAP )
+ {
+ m_xEffectsFT->set_sensitive(false);
+ m_xEffectsLB->set_sensitive(false);
+ }
+}
+
+void SvxCharEffectsPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxUInt16Item* pDisableCtlItem = aSet.GetItem<SfxUInt16Item>(SID_DISABLE_CTL, false);
+ const SfxUInt32Item* pFlagItem = aSet.GetItem<SfxUInt32Item>(SID_FLAG_TYPE, false);
+ if (pDisableCtlItem)
+ DisableControls(pDisableCtlItem->GetValue());
+
+ sal_uInt32 nFlags = pFlagItem ? pFlagItem->GetValue() : 0;
+ if ( ( nFlags & SVX_PREVIEW_CHARACTER ) == SVX_PREVIEW_CHARACTER )
+ // the writer uses SID_ATTR_BRUSH as font background
+ m_bPreviewBackgroundToCharacter = true;
+ if ((nFlags & SVX_ENABLE_CHAR_TRANSPARENCY) != SVX_ENABLE_CHAR_TRANSPARENCY)
+ {
+ // Only show these in case client code explicitly wants this.
+ m_xFontTransparencyFT->hide();
+ m_xFontTransparencyMtr->hide();
+ }
+}
+
+// class SvxCharPositionPage ---------------------------------------------
+
+SvxCharPositionPage::SvxCharPositionPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInSet)
+ : SvxCharBasePage(pPage, pController, "cui/ui/positionpage.ui", "PositionPage", rInSet)
+ , m_nSuperEsc(short(DFLT_ESC_SUPER))
+ , m_nSubEsc(short(DFLT_ESC_SUB))
+ , m_nScaleWidthItemSetVal(100)
+ , m_nScaleWidthInitialVal(100)
+ , m_nSuperProp(sal_uInt8(DFLT_ESC_PROP))
+ , m_nSubProp(sal_uInt8(DFLT_ESC_PROP))
+ , m_xHighPosBtn(m_xBuilder->weld_radio_button("superscript"))
+ , m_xNormalPosBtn(m_xBuilder->weld_radio_button("normal"))
+ , m_xLowPosBtn(m_xBuilder->weld_radio_button("subscript"))
+ , m_xHighLowFT(m_xBuilder->weld_label("raiselower"))
+ , m_xHighLowMF(m_xBuilder->weld_metric_spin_button("raiselowersb", FieldUnit::PERCENT))
+ , m_xHighLowRB(m_xBuilder->weld_check_button("automatic"))
+ , m_xFontSizeFT(m_xBuilder->weld_label("relativefontsize"))
+ , m_xFontSizeMF(m_xBuilder->weld_metric_spin_button("fontsizesb", FieldUnit::PERCENT))
+ , m_xRotationContainer(m_xBuilder->weld_widget("rotationcontainer"))
+ , m_xScalingFT(m_xBuilder->weld_label("scale"))
+ , m_xScalingAndRotationFT(m_xBuilder->weld_label("rotateandscale"))
+ , m_x0degRB(m_xBuilder->weld_radio_button("0deg"))
+ , m_x90degRB(m_xBuilder->weld_radio_button("90deg"))
+ , m_x270degRB(m_xBuilder->weld_radio_button("270deg"))
+ , m_xFitToLineCB(m_xBuilder->weld_check_button("fittoline"))
+ , m_xScaleWidthMF(m_xBuilder->weld_metric_spin_button("scalewidthsb", FieldUnit::PERCENT))
+ , m_xKerningMF(m_xBuilder->weld_metric_spin_button("kerningsb", FieldUnit::POINT))
+ , m_xPairKerningBtn(m_xBuilder->weld_check_button("pairkerning"))
+{
+ m_xPreviewWin.reset(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWin));
+#ifdef IOS
+ m_xPreviewWin->hide();
+#endif
+ Initialize();
+}
+
+SvxCharPositionPage::~SvxCharPositionPage()
+{
+}
+
+
+void SvxCharPositionPage::Initialize()
+{
+ // to handle the changes of the other pages
+ SetExchangeSupport();
+
+ GetPreviewFont().SetFontSize( Size( 0, 240 ) );
+ GetPreviewCJKFont().SetFontSize( Size( 0, 240 ) );
+ GetPreviewCTLFont().SetFontSize( Size( 0, 240 ) );
+
+ m_xNormalPosBtn->set_active(true);
+ PositionHdl_Impl(*m_xNormalPosBtn);
+
+ Link<weld::Toggleable&,void> aLink2 = LINK(this, SvxCharPositionPage, PositionHdl_Impl);
+ m_xHighPosBtn->connect_toggled(aLink2);
+ m_xNormalPosBtn->connect_toggled(aLink2);
+ m_xLowPosBtn->connect_toggled(aLink2);
+
+ aLink2 = LINK( this, SvxCharPositionPage, RotationHdl_Impl );
+ m_x0degRB->connect_toggled(aLink2);
+ m_x90degRB->connect_toggled(aLink2);
+ m_x270degRB->connect_toggled(aLink2);
+
+ Link<weld::MetricSpinButton&,void> aLink3 = LINK(this, SvxCharPositionPage, ValueChangedHdl_Impl);
+ m_xHighLowMF->connect_value_changed(aLink3);
+ m_xFontSizeMF->connect_value_changed(aLink3);
+
+ m_xHighLowRB->connect_toggled(LINK(this, SvxCharPositionPage, AutoPositionHdl_Impl));
+ m_xFitToLineCB->connect_toggled(LINK(this, SvxCharPositionPage, FitToLineHdl_Impl));
+ m_xKerningMF->connect_value_changed(LINK(this, SvxCharPositionPage, KerningModifyHdl_Impl));
+ m_xScaleWidthMF->connect_value_changed(LINK(this, SvxCharPositionPage, ScaleWidthModifyHdl_Impl));
+}
+
+void SvxCharPositionPage::UpdatePreview_Impl( sal_uInt8 nProp, sal_uInt8 nEscProp, short nEsc )
+{
+ SetPrevFontEscapement( nProp, nEscProp, nEsc );
+}
+
+
+void SvxCharPositionPage::SetEscapement_Impl( SvxEscapement nEsc )
+{
+ SvxEscapementItem aEscItm( nEsc, SID_ATTR_CHAR_ESCAPEMENT );
+
+ if ( SvxEscapement::Superscript == nEsc )
+ {
+ aEscItm.GetEsc() = m_nSuperEsc;
+ aEscItm.GetProportionalHeight() = m_nSuperProp;
+ }
+ else if ( SvxEscapement::Subscript == nEsc )
+ {
+ aEscItm.GetEsc() = m_nSubEsc;
+ aEscItm.GetProportionalHeight() = m_nSubProp;
+ }
+
+ short nFac = aEscItm.GetEsc() < 0 ? -1 : 1;
+
+ m_xHighLowMF->set_value(aEscItm.GetEsc() * nFac, FieldUnit::PERCENT);
+ m_xFontSizeMF->set_value(aEscItm.GetProportionalHeight(), FieldUnit::PERCENT);
+
+ if ( SvxEscapement::Off == nEsc )
+ {
+ m_xHighLowFT->set_sensitive(false);
+ m_xHighLowMF->set_sensitive(false);
+ m_xFontSizeFT->set_sensitive(false);
+ m_xFontSizeMF->set_sensitive(false);
+ m_xHighLowRB->set_sensitive(false);
+ }
+ else
+ {
+ m_xFontSizeFT->set_sensitive(true);
+ m_xFontSizeMF->set_sensitive(true);
+ m_xHighLowRB->set_sensitive(true);
+
+ if (!m_xHighLowRB->get_active())
+ {
+ m_xHighLowFT->set_sensitive(true);
+ m_xHighLowMF->set_sensitive(true);
+ }
+ else
+ AutoPositionHdl_Impl(*m_xHighLowRB);
+ }
+
+ UpdatePreview_Impl( 100, aEscItm.GetProportionalHeight(), aEscItm.GetEsc() );
+}
+
+
+IMPL_LINK_NOARG(SvxCharPositionPage, PositionHdl_Impl, weld::Toggleable&, void)
+{
+ SvxEscapement nEsc = SvxEscapement::Off; // also when pBtn == NULL
+
+ if (m_xHighPosBtn->get_active())
+ nEsc = SvxEscapement::Superscript;
+ else if (m_xLowPosBtn->get_active())
+ nEsc = SvxEscapement::Subscript;
+
+ SetEscapement_Impl( nEsc );
+}
+
+IMPL_LINK_NOARG(SvxCharPositionPage, RotationHdl_Impl, weld::Toggleable&, void)
+{
+ bool bEnable = false;
+ if (m_x90degRB->get_active() || m_x270degRB->get_active())
+ bEnable = true;
+ else
+ OSL_ENSURE(m_x0degRB->get_active(), "unexpected button");
+ m_xFitToLineCB->set_sensitive(bEnable);
+}
+
+void SvxCharPositionPage::FontModifyHdl_Impl()
+{
+ sal_uInt8 nEscProp = static_cast<sal_uInt8>(m_xFontSizeMF->get_value(FieldUnit::PERCENT));
+ short nEsc = static_cast<short>(m_xHighLowMF->get_value(FieldUnit::PERCENT));
+ nEsc *= m_xLowPosBtn->get_active() ? -1 : 1;
+ UpdatePreview_Impl( 100, nEscProp, nEsc );
+}
+
+IMPL_LINK(SvxCharPositionPage, AutoPositionHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ if (rBox.get_active())
+ {
+ m_xHighLowFT->set_sensitive(false);
+ m_xHighLowMF->set_sensitive(false);
+ }
+ else
+ PositionHdl_Impl(m_xHighPosBtn->get_active() ? *m_xHighPosBtn
+ : m_xLowPosBtn->get_active() ? *m_xLowPosBtn
+ : *m_xNormalPosBtn);
+}
+
+IMPL_LINK_NOARG(SvxCharPositionPage, FitToLineHdl_Impl, weld::Toggleable&, void)
+{
+ sal_uInt16 nVal = m_nScaleWidthInitialVal;
+ if (m_xFitToLineCB->get_active())
+ nVal = m_nScaleWidthItemSetVal;
+ m_xScaleWidthMF->set_value(nVal, FieldUnit::PERCENT);
+ m_aPreviewWin.SetFontWidthScale( nVal );
+}
+
+IMPL_LINK_NOARG(SvxCharPositionPage, KerningModifyHdl_Impl, weld::MetricSpinButton&, void)
+{
+ tools::Long nVal = static_cast<tools::Long>(m_xKerningMF->get_value(FieldUnit::POINT));
+ nVal = o3tl::convert(nVal, o3tl::Length::pt, o3tl::Length::twip);
+
+ tools::Long nKern = static_cast<short>(m_xKerningMF->denormalize(nVal));
+
+ SvxFont& rFont = GetPreviewFont();
+ SvxFont& rCJKFont = GetPreviewCJKFont();
+ SvxFont& rCTLFont = GetPreviewCTLFont();
+
+ rFont.SetFixKerning( static_cast<short>(nKern) );
+ rCJKFont.SetFixKerning( static_cast<short>(nKern) );
+ rCTLFont.SetFixKerning( static_cast<short>(nKern) );
+ m_aPreviewWin.Invalidate();
+}
+
+IMPL_LINK(SvxCharPositionPage, ValueChangedHdl_Impl, weld::MetricSpinButton&, rField, void)
+{
+ bool bHigh = m_xHighPosBtn->get_active();
+ bool bLow = m_xLowPosBtn->get_active();
+ DBG_ASSERT( bHigh || bLow, "normal position is not valid" );
+
+ if (m_xHighLowMF.get() == &rField)
+ {
+ if ( bLow )
+ m_nSubEsc = static_cast<short>(m_xHighLowMF->get_value(FieldUnit::PERCENT)) * -1;
+ else
+ m_nSuperEsc = static_cast<short>(m_xHighLowMF->get_value(FieldUnit::PERCENT));
+ }
+ else if (m_xFontSizeMF.get() == &rField)
+ {
+ if ( bLow )
+ m_nSubProp = static_cast<sal_uInt8>(m_xFontSizeMF->get_value(FieldUnit::PERCENT));
+ else
+ m_nSuperProp = static_cast<sal_uInt8>(m_xFontSizeMF->get_value(FieldUnit::PERCENT));
+ }
+
+ FontModifyHdl_Impl();
+}
+
+IMPL_LINK_NOARG(SvxCharPositionPage, ScaleWidthModifyHdl_Impl, weld::MetricSpinButton&, void)
+{
+ m_aPreviewWin.SetFontWidthScale(sal_uInt16(m_xScaleWidthMF->get_value(FieldUnit::PERCENT)));
+}
+
+DeactivateRC SvxCharPositionPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if ( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+std::unique_ptr<SfxTabPage> SvxCharPositionPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxCharPositionPage>(pPage, pController, *rSet);
+}
+
+void SvxCharPositionPage::Reset( const SfxItemSet* rSet )
+{
+ OUString sUser = GetUserData();
+
+ if ( !sUser.isEmpty() )
+ {
+ sal_Int32 nIdx {0};
+ m_nSuperEsc = static_cast<short>(o3tl::toInt32(o3tl::getToken(sUser, 0, ';', nIdx )));
+ m_nSubEsc = static_cast<short>(o3tl::toInt32(o3tl::getToken(sUser, 0, ';', nIdx )));
+ m_nSuperProp = static_cast<sal_uInt8>(o3tl::toInt32(o3tl::getToken(sUser, 0, ';', nIdx )));
+ m_nSubProp = static_cast<sal_uInt8>(o3tl::toInt32(o3tl::getToken(sUser, 0, ';', nIdx )));
+
+ m_xHighLowMF->set_max(MAX_ESC_POS, FieldUnit::PERCENT);
+
+ //fdo#75307 validate all the entries and discard all of them if any are
+ //out of range
+ bool bValid = true;
+ if (m_nSuperEsc < m_xHighLowMF->get_min(FieldUnit::PERCENT) || m_nSuperEsc > m_xHighLowMF->get_max(FieldUnit::PERCENT))
+ bValid = false;
+ if (m_nSubEsc*-1 < m_xHighLowMF->get_min(FieldUnit::PERCENT) || m_nSubEsc*-1 > m_xHighLowMF->get_max(FieldUnit::PERCENT))
+ bValid = false;
+ if (m_nSuperProp < m_xFontSizeMF->get_min(FieldUnit::PERCENT) || m_nSuperProp > m_xFontSizeMF->get_max(FieldUnit::PERCENT))
+ bValid = false;
+ if (m_nSubProp < m_xFontSizeMF->get_min(FieldUnit::PERCENT) || m_nSubProp > m_xFontSizeMF->get_max(FieldUnit::PERCENT))
+ bValid = false;
+
+ if (!bValid)
+ {
+ m_nSuperEsc = DFLT_ESC_SUPER;
+ m_nSubEsc = DFLT_ESC_SUB;
+ m_nSuperProp = DFLT_ESC_PROP;
+ m_nSubProp = DFLT_ESC_PROP;
+ }
+ }
+
+ short nEsc = 0;
+ sal_uInt8 nEscProp = 100;
+
+ m_xHighLowFT->set_sensitive(false);
+ m_xHighLowMF->set_sensitive(false);
+ m_xFontSizeFT->set_sensitive(false);
+ m_xFontSizeMF->set_sensitive(false);
+
+ SvxFont& rFont = GetPreviewFont();
+ SvxFont& rCJKFont = GetPreviewCJKFont();
+ SvxFont& rCTLFont = GetPreviewCTLFont();
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_ESCAPEMENT );
+
+ if ( rSet->GetItemState( nWhich ) >= SfxItemState::DEFAULT )
+ {
+ const SvxEscapementItem& rItem = static_cast<const SvxEscapementItem&>(rSet->Get( nWhich ));
+ nEsc = rItem.GetEsc();
+ nEscProp = rItem.GetProportionalHeight();
+
+ if ( nEsc != 0 )
+ {
+ m_xHighLowFT->set_sensitive(true);
+ m_xHighLowMF->set_sensitive(true);
+ m_xFontSizeFT->set_sensitive(true);
+ m_xFontSizeMF->set_sensitive(true);
+
+ short nFac;
+ bool bAutomatic(false);
+
+ if ( nEsc > 0 )
+ {
+ nFac = 1;
+ m_xHighPosBtn->set_active(true);
+ if ( nEsc == DFLT_ESC_AUTO_SUPER )
+ {
+ nEsc = .8 * (100 - nEscProp); //approximation of actual percentage used
+ bAutomatic = true;
+ }
+ }
+ else
+ {
+ nFac = -1;
+ m_xLowPosBtn->set_active(true);
+ if ( nEsc == DFLT_ESC_AUTO_SUB )
+ {
+ nEsc = .2 * -(100 - nEscProp); //approximation of actual percentage used
+ bAutomatic = true;
+ }
+ }
+ if (!m_xHighLowRB->get_sensitive())
+ {
+ m_xHighLowRB->set_sensitive(true);
+ }
+ m_xHighLowRB->set_active(bAutomatic);
+
+ if (m_xHighLowRB->get_active())
+ {
+ m_xHighLowFT->set_sensitive(false);
+ m_xHighLowMF->set_sensitive(false);
+ }
+ m_xHighLowMF->set_value(m_xHighLowMF->normalize(nFac * nEsc), FieldUnit::PERCENT);
+ }
+ else
+ {
+ m_xNormalPosBtn->set_active(true);
+ m_xHighLowRB->set_active(true);
+ PositionHdl_Impl(*m_xNormalPosBtn);
+ }
+ //the height has to be set after the handler is called to keep the value also if the escapement is zero
+ m_xFontSizeMF->set_value(m_xFontSizeMF->normalize(nEscProp), FieldUnit::PERCENT);
+ }
+ else
+ {
+ m_xHighPosBtn->set_active(false);
+ m_xNormalPosBtn->set_active(false);
+ m_xLowPosBtn->set_active(false);
+
+ m_xHighLowRB->set_active(true);
+ }
+
+ // set BspFont
+ SetPrevFontEscapement( 100, nEscProp, nEsc );
+
+ // Kerning
+ nWhich = GetWhich( SID_ATTR_CHAR_KERNING );
+
+ if ( rSet->GetItemState( nWhich ) >= SfxItemState::DEFAULT )
+ {
+ const SvxKerningItem& rItem = static_cast<const SvxKerningItem&>(rSet->Get( nWhich ));
+ MapUnit eUnit = rSet->GetPool()->GetMetric( nWhich );
+ tools::Long nBig = static_cast<tools::Long>(m_xKerningMF->normalize( static_cast<tools::Long>(rItem.GetValue()) ));
+ tools::Long nKerning = OutputDevice::LogicToLogic(nBig, eUnit, MapUnit::MapPoint);
+
+ // set Kerning at the Font, convert into Twips before
+ tools::Long nKern = OutputDevice::LogicToLogic(rItem.GetValue(), eUnit, MapUnit::MapTwip);
+ rFont.SetFixKerning( static_cast<short>(nKern) );
+ rCJKFont.SetFixKerning( static_cast<short>(nKern) );
+ rCTLFont.SetFixKerning( static_cast<short>(nKern) );
+
+ //the attribute value must be displayed also if it's above/below the maximum allowed value
+ tools::Long nVal = static_cast<tools::Long>(m_xKerningMF->get_max(FieldUnit::POINT));
+ if(nVal < nKerning)
+ m_xKerningMF->set_max(nKerning, FieldUnit::POINT);
+ nVal = static_cast<tools::Long>(m_xKerningMF->get_min(FieldUnit::POINT));
+ if (nVal > nKerning)
+ m_xKerningMF->set_min(nKerning, FieldUnit::POINT);
+ m_xKerningMF->set_value(nKerning, FieldUnit::POINT);
+ }
+ else
+ m_xKerningMF->set_text(OUString());
+
+ // Pair kerning
+ nWhich = GetWhich( SID_ATTR_CHAR_AUTOKERN );
+
+ if ( rSet->GetItemState( nWhich ) >= SfxItemState::DEFAULT )
+ {
+ const SvxAutoKernItem& rItem = static_cast<const SvxAutoKernItem&>(rSet->Get( nWhich ));
+ m_xPairKerningBtn->set_active(rItem.GetValue());
+ }
+ else
+ m_xPairKerningBtn->set_active(false);
+
+ // Scale Width
+ nWhich = GetWhich( SID_ATTR_CHAR_SCALEWIDTH );
+ if ( rSet->GetItemState( nWhich ) >= SfxItemState::DEFAULT )
+ {
+ const SvxCharScaleWidthItem& rItem = static_cast<const SvxCharScaleWidthItem&>( rSet->Get( nWhich ) );
+ m_nScaleWidthInitialVal = rItem.GetValue();
+ m_xScaleWidthMF->set_value(m_nScaleWidthInitialVal, FieldUnit::PERCENT);
+ }
+ else
+ m_xScaleWidthMF->set_value(100, FieldUnit::PERCENT);
+
+ if ( rSet->GetItemState( SID_ATTR_CHAR_WIDTH_FIT_TO_LINE ) >= SfxItemState::DEFAULT )
+ m_nScaleWidthItemSetVal = rSet->Get( SID_ATTR_CHAR_WIDTH_FIT_TO_LINE ).GetValue();
+
+ // Rotation
+ nWhich = GetWhich( SID_ATTR_CHAR_ROTATED );
+ SfxItemState eState = rSet->GetItemState( nWhich );
+ if( SfxItemState::UNKNOWN == eState )
+ {
+ m_xRotationContainer->hide();
+ m_xScalingAndRotationFT->hide();
+ m_xScalingFT->show();
+ }
+ else
+ {
+ m_xRotationContainer->show();
+ m_xScalingAndRotationFT->show();
+ m_xScalingFT->hide();
+
+ if( eState >= SfxItemState::DEFAULT )
+ {
+ const SvxCharRotateItem& rItem =
+ static_cast<const SvxCharRotateItem&>( rSet->Get( nWhich ));
+ if (rItem.IsBottomToTop())
+ m_x90degRB->set_active(true);
+ else if (rItem.IsTopToBottom())
+ m_x270degRB->set_active(true);
+ else
+ {
+ DBG_ASSERT( 0_deg10 == rItem.GetValue(), "incorrect value" );
+ m_x0degRB->set_active(true);
+ }
+ m_xFitToLineCB->set_active(rItem.IsFitToLine());
+ }
+ else
+ {
+ if( eState == SfxItemState::DONTCARE )
+ {
+ m_x0degRB->set_active(false);
+ m_x90degRB->set_active(false);
+ m_x270degRB->set_active(false);
+ }
+ else
+ m_x0degRB->set_active(true);
+
+ m_xFitToLineCB->set_active(false);
+ }
+ m_xFitToLineCB->set_sensitive(!m_x0degRB->get_active());
+
+ // is this value set?
+ if( SfxItemState::UNKNOWN == rSet->GetItemState(
+ SID_ATTR_CHAR_WIDTH_FIT_TO_LINE ))
+ m_xFitToLineCB->hide();
+ }
+ ChangesApplied();
+}
+
+void SvxCharPositionPage::ChangesApplied()
+{
+ m_xHighPosBtn->save_state();
+ m_xNormalPosBtn->save_state();
+ m_xLowPosBtn->save_state();
+ m_xHighLowRB->save_state();
+ m_x0degRB->save_state();
+ m_x90degRB->save_state();
+ m_x270degRB->save_state();
+ m_xFitToLineCB->save_state();
+ m_xScaleWidthMF->save_value();
+ m_xKerningMF->save_value();
+ m_xPairKerningBtn->save_state();
+}
+
+bool SvxCharPositionPage::FillItemSet( SfxItemSet* rSet )
+{
+ // Position (high, normal or low)
+ const SfxItemSet& rOldSet = GetItemSet();
+ bool bModified = false, bChanged = true;
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_ESCAPEMENT );
+ const SfxPoolItem* pOld = GetOldItem( *rSet, SID_ATTR_CHAR_ESCAPEMENT );
+ const bool bHigh = m_xHighPosBtn->get_active();
+ short nEsc;
+ sal_uInt8 nEscProp;
+
+ if (bHigh || m_xLowPosBtn->get_active())
+ {
+ if (m_xHighLowRB->get_active())
+ nEsc = bHigh ? DFLT_ESC_AUTO_SUPER : DFLT_ESC_AUTO_SUB;
+ else
+ {
+ nEsc = static_cast<short>(m_xHighLowMF->denormalize(m_xHighLowMF->get_value(FieldUnit::PERCENT)));
+ nEsc *= (bHigh ? 1 : -1);
+ }
+ nEscProp = static_cast<sal_uInt8>(m_xFontSizeMF->denormalize(m_xFontSizeMF->get_value(FieldUnit::PERCENT)));
+ }
+ else
+ {
+ nEsc = 0;
+ nEscProp = 100;
+ }
+
+ if ( pOld )
+ {
+ const SvxEscapementItem& rItem = *static_cast<const SvxEscapementItem*>(pOld);
+ if (rItem.GetEsc() == nEsc && rItem.GetProportionalHeight() == nEscProp)
+ bChanged = false;
+ }
+
+ if ( !bChanged && !m_xHighPosBtn->get_saved_state() &&
+ !m_xNormalPosBtn->get_saved_state() && !m_xLowPosBtn->get_saved_state() )
+ bChanged = true;
+
+ if ( bChanged &&
+ ( m_xHighPosBtn->get_active() || m_xNormalPosBtn->get_active() || m_xLowPosBtn->get_active() ) )
+ {
+ rSet->Put( SvxEscapementItem( nEsc, nEscProp, nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ bChanged = true;
+
+ // Kerning
+ nWhich = GetWhich( SID_ATTR_CHAR_KERNING );
+ pOld = GetOldItem( *rSet, SID_ATTR_CHAR_KERNING );
+ short nKerning = 0;
+ MapUnit eUnit = rSet->GetPool()->GetMetric( nWhich );
+
+ tools::Long nTmp = static_cast<tools::Long>(m_xKerningMF->get_value(FieldUnit::POINT));
+ tools::Long nVal = OutputDevice::LogicToLogic(nTmp, MapUnit::MapPoint, eUnit);
+ nKerning = static_cast<short>(m_xKerningMF->denormalize( nVal ));
+
+ SfxItemState eOldKernState = rOldSet.GetItemState( nWhich, false );
+ if ( pOld )
+ {
+ const SvxKerningItem& rItem = *static_cast<const SvxKerningItem*>(pOld);
+ if ( (eOldKernState >= SfxItemState::DEFAULT || m_xKerningMF->get_text().isEmpty()) && rItem.GetValue() == nKerning )
+ bChanged = false;
+ }
+
+ if ( bChanged )
+ {
+ rSet->Put( SvxKerningItem( nKerning, nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == eOldKernState )
+ rSet->InvalidateItem(nWhich);
+
+ // Pair-Kerning
+ nWhich = GetWhich( SID_ATTR_CHAR_AUTOKERN );
+
+ if (m_xPairKerningBtn->get_state_changed_from_saved())
+ {
+ rSet->Put( SvxAutoKernItem( m_xPairKerningBtn->get_active(), nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ // Scale Width
+ nWhich = GetWhich( SID_ATTR_CHAR_SCALEWIDTH );
+ if (m_xScaleWidthMF->get_value_changed_from_saved())
+ {
+ rSet->Put(SvxCharScaleWidthItem(static_cast<sal_uInt16>(m_xScaleWidthMF->get_value(FieldUnit::PERCENT)), TypedWhichId<SvxCharScaleWidthItem>(nWhich)));
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ // Rotation
+ nWhich = GetWhich( SID_ATTR_CHAR_ROTATED );
+ if ( m_x0degRB->get_state_changed_from_saved() ||
+ m_x90degRB->get_state_changed_from_saved() ||
+ m_x270degRB->get_state_changed_from_saved() ||
+ m_xFitToLineCB->get_state_changed_from_saved() )
+ {
+ SvxCharRotateItem aItem( 0_deg10, m_xFitToLineCB->get_active(), TypedWhichId<SvxCharRotateItem>(nWhich) );
+ if (m_x90degRB->get_active())
+ aItem.SetBottomToTop();
+ else if (m_x270degRB->get_active())
+ aItem.SetTopToBottom();
+ rSet->Put( aItem );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ return bModified;
+}
+
+
+void SvxCharPositionPage::FillUserData()
+{
+ static constexpr OUString cTok( u";"_ustr );
+
+ OUString sUser = OUString::number( m_nSuperEsc ) + cTok +
+ OUString::number( m_nSubEsc ) + cTok +
+ OUString::number( m_nSuperProp ) + cTok +
+ OUString::number( m_nSubProp );
+ SetUserData( sUser );
+}
+
+
+void SvxCharPositionPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxUInt32Item* pFlagItem = aSet.GetItem<SfxUInt32Item>(SID_FLAG_TYPE, false);
+ if (pFlagItem)
+ {
+ sal_uInt32 nFlags=pFlagItem->GetValue();
+ if ( ( nFlags & SVX_PREVIEW_CHARACTER ) == SVX_PREVIEW_CHARACTER )
+ // the writer uses SID_ATTR_BRUSH as font background
+ m_bPreviewBackgroundToCharacter = true;
+ }
+}
+// class SvxCharTwoLinesPage ------------------------------------------------
+
+SvxCharTwoLinesPage::SvxCharTwoLinesPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInSet)
+ : SvxCharBasePage(pPage, pController, "cui/ui/twolinespage.ui", "TwoLinesPage", rInSet)
+ , m_nStartBracketPosition( 0 )
+ , m_nEndBracketPosition( 0 )
+ , m_xTwoLinesBtn(m_xBuilder->weld_check_button("twolines"))
+ , m_xEnclosingFrame(m_xBuilder->weld_widget("enclosing"))
+ , m_xStartBracketLB(m_xBuilder->weld_tree_view("startbracket"))
+ , m_xEndBracketLB(m_xBuilder->weld_tree_view("endbracket"))
+{
+ for (size_t i = 0; i < std::size(TWOLINE_OPEN); ++i)
+ m_xStartBracketLB->append(OUString::number(TWOLINE_OPEN[i].second), CuiResId(TWOLINE_OPEN[i].first));
+ for (size_t i = 0; i < std::size(TWOLINE_CLOSE); ++i)
+ m_xEndBracketLB->append(OUString::number(TWOLINE_CLOSE[i].second), CuiResId(TWOLINE_CLOSE[i].first));
+
+ m_xPreviewWin.reset(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWin));
+#ifdef IOS
+ m_xPreviewWin->hide();
+#endif
+ Initialize();
+}
+
+SvxCharTwoLinesPage::~SvxCharTwoLinesPage()
+{
+}
+
+void SvxCharTwoLinesPage::Initialize()
+{
+ m_xTwoLinesBtn->set_active(false);
+ TwoLinesHdl_Impl(*m_xTwoLinesBtn);
+
+ m_xTwoLinesBtn->connect_toggled(LINK(this, SvxCharTwoLinesPage, TwoLinesHdl_Impl));
+
+ Link<weld::TreeView&,void> aLink = LINK(this, SvxCharTwoLinesPage, CharacterMapHdl_Impl);
+ m_xStartBracketLB->connect_changed(aLink);
+ m_xEndBracketLB->connect_changed(aLink);
+
+ SvxFont& rFont = GetPreviewFont();
+ SvxFont& rCJKFont = GetPreviewCJKFont();
+ SvxFont& rCTLFont = GetPreviewCTLFont();
+ rFont.SetFontSize( Size( 0, 220 ) );
+ rCJKFont.SetFontSize( Size( 0, 220 ) );
+ rCTLFont.SetFontSize( Size( 0, 220 ) );
+}
+
+void SvxCharTwoLinesPage::SelectCharacter(weld::TreeView* pBox)
+{
+ bool bStart = pBox == m_xStartBracketLB.get();
+ SvxCharacterMap aDlg(GetFrameWeld(), nullptr, nullptr);
+ aDlg.DisableFontSelection();
+
+ if (aDlg.run() == RET_OK)
+ {
+ sal_Unicode cChar = static_cast<sal_Unicode>(aDlg.GetChar());
+ SetBracket( cChar, bStart );
+ }
+ else
+ {
+ pBox->select(bStart ? m_nStartBracketPosition : m_nEndBracketPosition);
+ }
+}
+
+
+void SvxCharTwoLinesPage::SetBracket( sal_Unicode cBracket, bool bStart )
+{
+ int nEntryPos = 0;
+ weld::TreeView* pBox = bStart ? m_xStartBracketLB.get() : m_xEndBracketLB.get();
+ if (cBracket == 0)
+ pBox->select(0);
+ else
+ {
+ bool bFound = false;
+ for (int i = 1; i < pBox->n_children(); ++i)
+ {
+ if (pBox->get_id(i).toInt32() != CHRDLG_ENCLOSE_SPECIAL_CHAR)
+ {
+ const sal_Unicode cChar = pBox->get_text(i)[0];
+ if (cChar == cBracket)
+ {
+ pBox->select(i);
+ nEntryPos = i;
+ bFound = true;
+ break;
+ }
+ }
+ }
+
+ if (!bFound)
+ {
+ pBox->append_text(OUString(cBracket));
+ nEntryPos = pBox->n_children() - 1;
+ pBox->select(nEntryPos);
+ }
+ }
+ if (bStart)
+ m_nStartBracketPosition = nEntryPos;
+ else
+ m_nEndBracketPosition = nEntryPos;
+}
+
+IMPL_LINK_NOARG(SvxCharTwoLinesPage, TwoLinesHdl_Impl, weld::Toggleable&, void)
+{
+ bool bChecked = m_xTwoLinesBtn->get_active();
+ m_xEnclosingFrame->set_sensitive(bChecked);
+ UpdatePreview_Impl();
+}
+
+IMPL_LINK(SvxCharTwoLinesPage, CharacterMapHdl_Impl, weld::TreeView&, rBox, void)
+{
+ int nPos = rBox.get_selected_index();
+ if (rBox.get_id(nPos).toInt32() == CHRDLG_ENCLOSE_SPECIAL_CHAR)
+ SelectCharacter( &rBox );
+ else
+ {
+ bool bStart = &rBox == m_xStartBracketLB.get();
+ if (bStart)
+ m_nStartBracketPosition = nPos;
+ else
+ m_nEndBracketPosition = nPos;
+ }
+ UpdatePreview_Impl();
+}
+
+void SvxCharTwoLinesPage::ActivatePage( const SfxItemSet& rSet )
+{
+ SvxCharBasePage::ActivatePage(rSet);
+}
+
+DeactivateRC SvxCharTwoLinesPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if ( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+std::unique_ptr<SfxTabPage> SvxCharTwoLinesPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxCharTwoLinesPage>(pPage, pController, *rSet);
+}
+
+void SvxCharTwoLinesPage::Reset( const SfxItemSet* rSet )
+{
+ m_xTwoLinesBtn->set_active(false);
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_TWO_LINES );
+ SfxItemState eState = rSet->GetItemState( nWhich );
+
+ if ( eState >= SfxItemState::DONTCARE )
+ {
+ const SvxTwoLinesItem& rItem = static_cast<const SvxTwoLinesItem&>(rSet->Get( nWhich ));
+ m_xTwoLinesBtn->set_active(rItem.GetValue());
+
+ if ( rItem.GetValue() )
+ {
+ SetBracket( rItem.GetStartBracket(), true );
+ SetBracket( rItem.GetEndBracket(), false );
+ }
+ }
+ TwoLinesHdl_Impl(*m_xTwoLinesBtn);
+
+ SetPrevFontWidthScale( *rSet );
+}
+
+bool SvxCharTwoLinesPage::FillItemSet( SfxItemSet* rSet )
+{
+ const SfxItemSet& rOldSet = GetItemSet();
+ bool bModified = false, bChanged = true;
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_TWO_LINES );
+ const SfxPoolItem* pOld = GetOldItem( *rSet, SID_ATTR_CHAR_TWO_LINES );
+ bool bOn = m_xTwoLinesBtn->get_active();
+ sal_Unicode cStart = ( bOn && m_xStartBracketLB->get_selected_index() > 0 )
+ ? m_xStartBracketLB->get_selected_text()[0] : 0;
+ sal_Unicode cEnd = ( bOn && m_xEndBracketLB->get_selected_index() > 0 )
+ ? m_xEndBracketLB->get_selected_text()[0] : 0;
+
+ if ( pOld )
+ {
+ const SvxTwoLinesItem& rItem = *static_cast<const SvxTwoLinesItem*>(pOld);
+ if ( rItem.GetValue() == bOn &&
+ ( !bOn || ( rItem.GetStartBracket() == cStart && rItem.GetEndBracket() == cEnd ) ) )
+ bChanged = false;
+ }
+
+ if ( bChanged )
+ {
+ rSet->Put( SvxTwoLinesItem( bOn, cStart, cEnd, nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ return bModified;
+}
+
+void SvxCharTwoLinesPage::UpdatePreview_Impl()
+{
+ sal_Unicode cStart = m_xStartBracketLB->get_selected_index() > 0
+ ? m_xStartBracketLB->get_selected_text()[0] : 0;
+ sal_Unicode cEnd = m_xEndBracketLB->get_selected_index() > 0
+ ? m_xEndBracketLB->get_selected_text()[0] : 0;
+ m_aPreviewWin.SetBrackets(cStart, cEnd);
+ m_aPreviewWin.SetTwoLines(m_xTwoLinesBtn->get_active());
+ m_aPreviewWin.Invalidate();
+}
+
+void SvxCharTwoLinesPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxUInt32Item* pFlagItem = aSet.GetItem<SfxUInt32Item>(SID_FLAG_TYPE, false);
+ if (pFlagItem)
+ {
+ sal_uInt32 nFlags=pFlagItem->GetValue();
+ if ( ( nFlags & SVX_PREVIEW_CHARACTER ) == SVX_PREVIEW_CHARACTER )
+ // the writer uses SID_ATTR_BRUSH as font background
+ m_bPreviewBackgroundToCharacter = true;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/chardlg.h b/cui/source/tabpages/chardlg.h
new file mode 100644
index 0000000000..4a52cb24b4
--- /dev/null
+++ b/cui/source/tabpages/chardlg.h
@@ -0,0 +1,26 @@
+/* -*- 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
+
+// define ----------------------------------------------------------------
+
+#define CHRDLG_POSITION_OVER 0
+#define CHRDLG_POSITION_UNDER 1
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/connect.cxx b/cui/source/tabpages/connect.cxx
new file mode 100644
index 0000000000..b69f17b551
--- /dev/null
+++ b/cui/source/tabpages/connect.cxx
@@ -0,0 +1,395 @@
+/* -*- 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 <strings.hrc>
+#include <dialmgr.hxx>
+
+#include <svx/connctrl.hxx>
+#include <svx/svxids.hrc>
+#include <svx/dlgutil.hxx>
+#include <svx/ofaitem.hxx>
+
+#include <svx/svdview.hxx>
+#include <svx/sxekitm.hxx>
+#include <svx/sxelditm.hxx>
+#include <svx/sxenditm.hxx>
+#include <svtools/unitconv.hxx>
+
+#include <connect.hxx>
+
+const WhichRangesContainer SvxConnectionPage::pRanges(
+ svl::Items<SDRATTR_EDGE_FIRST, SDRATTR_EDGE_LAST>);
+
+/*************************************************************************
+|*
+|* dialog for changing connectors
+|*
+\************************************************************************/
+SvxConnectionDialog::SvxConnectionDialog(weld::Window* pParent, const SfxItemSet& rInAttrs, const SdrView* pSdrView)
+ : SfxSingleTabDialogController(pParent, &rInAttrs)
+{
+ auto xPage = std::make_unique<SvxConnectionPage>(get_content_area(), this, rInAttrs);
+
+ xPage->SetView(pSdrView);
+ xPage->Construct();
+
+ SetTabPage(std::move(xPage));
+ m_xDialog->set_title(CuiResId(RID_CUISTR_CONNECTOR));
+}
+
+/*************************************************************************
+|*
+|* page for changing connectors
+|*
+\************************************************************************/
+
+SvxConnectionPage::SvxConnectionPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/connectortabpage.ui", "ConnectorTabPage", &rInAttrs)
+ , rOutAttrs(rInAttrs)
+ , aAttrSet(*rInAttrs.GetPool())
+ , pView(nullptr)
+ , m_xLbType(m_xBuilder->weld_combo_box("LB_TYPE"))
+ , m_xFtLine1(m_xBuilder->weld_label("FT_LINE_1"))
+ , m_xMtrFldLine1(m_xBuilder->weld_metric_spin_button("MTR_FLD_LINE_1", FieldUnit::CM))
+ , m_xFtLine2(m_xBuilder->weld_label("FT_LINE_2"))
+ , m_xMtrFldLine2(m_xBuilder->weld_metric_spin_button("MTR_FLD_LINE_2", FieldUnit::CM))
+ , m_xFtLine3(m_xBuilder->weld_label("FT_LINE_3"))
+ , m_xMtrFldLine3(m_xBuilder->weld_metric_spin_button("MTR_FLD_LINE_3", FieldUnit::CM))
+ , m_xMtrFldHorz1(m_xBuilder->weld_metric_spin_button("MTR_FLD_HORZ_1", FieldUnit::MM))
+ , m_xMtrFldVert1(m_xBuilder->weld_metric_spin_button("MTR_FLD_VERT_1", FieldUnit::MM))
+ , m_xMtrFldHorz2(m_xBuilder->weld_metric_spin_button("MTR_FLD_HORZ_2", FieldUnit::MM))
+ , m_xMtrFldVert2(m_xBuilder->weld_metric_spin_button("MTR_FLD_VERT_2", FieldUnit::MM))
+ , m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, "CTL_PREVIEW", m_aCtlPreview))
+{
+ SfxItemPool* pPool = rOutAttrs.GetPool();
+ DBG_ASSERT( pPool, "Where is the pool" );
+ eUnit = pPool->GetMetric( SDRATTR_EDGENODE1HORZDIST );
+
+ FillTypeLB();
+
+ const FieldUnit eFUnit = GetModuleFieldUnit( rInAttrs );
+ SetFieldUnit( *m_xMtrFldHorz1, eFUnit );
+ SetFieldUnit( *m_xMtrFldHorz2, eFUnit );
+ SetFieldUnit( *m_xMtrFldVert1, eFUnit );
+ SetFieldUnit( *m_xMtrFldVert2, eFUnit );
+ SetFieldUnit( *m_xMtrFldLine1, eFUnit );
+ SetFieldUnit( *m_xMtrFldLine2, eFUnit );
+ SetFieldUnit( *m_xMtrFldLine3, eFUnit );
+ if( eFUnit == FieldUnit::MM )
+ {
+ m_xMtrFldHorz1->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrFldHorz2->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrFldVert1->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrFldVert2->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrFldLine1->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrFldLine2->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrFldLine3->set_increments(50, 500, FieldUnit::NONE);
+ }
+
+ Link<weld::MetricSpinButton&,void> aLink(LINK(this, SvxConnectionPage, ChangeAttrEditHdl_Impl));
+ m_xMtrFldHorz1->connect_value_changed(aLink);
+ m_xMtrFldVert1->connect_value_changed(aLink);
+ m_xMtrFldHorz2->connect_value_changed(aLink);
+ m_xMtrFldVert2->connect_value_changed(aLink);
+ m_xMtrFldLine1->connect_value_changed(aLink);
+ m_xMtrFldLine2->connect_value_changed(aLink);
+ m_xMtrFldLine3->connect_value_changed(aLink);
+ m_xLbType->connect_changed(LINK(this, SvxConnectionPage, ChangeAttrListBoxHdl_Impl));
+}
+
+SvxConnectionPage::~SvxConnectionPage()
+{
+ m_xCtlPreview.reset();
+}
+
+template<class T>
+void SvxConnectionPage::SetMetricValueAndSave(const SfxItemSet* rAttrs, weld::MetricSpinButton& rField, TypedWhichId<T> nWhich)
+{
+ const SfxPoolItem* pItem = GetItem( *rAttrs, nWhich);
+ const SfxItemPool* pPool = rAttrs->GetPool();
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( nWhich );
+ SetMetricValue(rField, pItem->StaticWhichCast(nWhich).GetValue(), eUnit);
+ rField.save_value();
+}
+
+/*************************************************************************
+|*
+|* reads passed Item-Set
+|*
+\************************************************************************/
+
+void SvxConnectionPage::Reset( const SfxItemSet* rAttrs )
+{
+ const SfxPoolItem* pItem;
+ const SfxItemPool* pPool = rAttrs->GetPool();
+
+ // SdrEdgeNode1HorzDistItem
+ SetMetricValueAndSave(rAttrs, *m_xMtrFldHorz1, SDRATTR_EDGENODE1HORZDIST);
+
+ // SdrEdgeNode2HorzDistItem
+ SetMetricValueAndSave(rAttrs, *m_xMtrFldHorz2, SDRATTR_EDGENODE2HORZDIST);
+
+ // SdrEdgeNode1VertDistItem
+ SetMetricValueAndSave(rAttrs, *m_xMtrFldVert1, SDRATTR_EDGENODE1VERTDIST);
+
+ // SdrEdgeNode2VertDistItem
+ SetMetricValueAndSave(rAttrs, *m_xMtrFldVert2, SDRATTR_EDGENODE2VERTDIST);
+
+ // SdrEdgeLine1DeltaItem
+ SetMetricValueAndSave(rAttrs, *m_xMtrFldLine1, SDRATTR_EDGELINE1DELTA);
+
+ // SdrEdgeLine2DeltaItem
+ SetMetricValueAndSave(rAttrs, *m_xMtrFldLine2, SDRATTR_EDGELINE2DELTA);
+
+ // SdrEdgeLine3DeltaItem
+ SetMetricValueAndSave(rAttrs, *m_xMtrFldLine3, SDRATTR_EDGELINE3DELTA);
+
+ // SdrEdgeLineDeltaAnzItem
+ pItem = GetItem( *rAttrs, SDRATTR_EDGELINEDELTACOUNT );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_EDGELINEDELTACOUNT );
+ switch (pItem->StaticWhichCast(SDRATTR_EDGELINEDELTACOUNT).GetValue())
+ {
+ case 0:
+ m_xFtLine1->set_sensitive(false);
+ m_xMtrFldLine1->set_sensitive(false);
+ m_xMtrFldLine1->set_text("");
+ [[fallthrough]];
+ case 1:
+ m_xFtLine2->set_sensitive(false);
+ m_xMtrFldLine2->set_sensitive(false);
+ m_xMtrFldLine2->set_text("");
+ [[fallthrough]];
+ case 2:
+ m_xFtLine3->set_sensitive(false);
+ m_xMtrFldLine3->set_sensitive(false);
+ m_xMtrFldLine3->set_text("");
+ break;
+ }
+
+ // SdrEdgeKindItem
+ pItem = GetItem( *rAttrs, SDRATTR_EDGEKIND );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_EDGEKIND );
+ m_xLbType->set_active(
+ sal::static_int_cast<sal_uInt16>(pItem->StaticWhichCast(SDRATTR_EDGEKIND).GetValue()));
+ m_xLbType->save_value();
+}
+
+/*************************************************************************
+|*
+|* fills the passed Item-Set width Dialogbox attributes
+|*
+\************************************************************************/
+
+bool SvxConnectionPage::FillItemSet( SfxItemSet* rAttrs)
+{
+ bool bModified = false;
+ sal_Int32 nValue;
+
+ if (m_xMtrFldHorz1->get_value_changed_from_saved())
+ {
+ nValue = GetCoreValue(*m_xMtrFldHorz1, eUnit);
+ rAttrs->Put( SdrEdgeNode1HorzDistItem( nValue ) );
+ bModified = true;
+ }
+
+ if (m_xMtrFldHorz2->get_value_changed_from_saved())
+ {
+ nValue = GetCoreValue(*m_xMtrFldHorz2, eUnit);
+ rAttrs->Put( SdrEdgeNode2HorzDistItem( nValue ) );
+ bModified = true;
+ }
+
+ if (m_xMtrFldVert1->get_value_changed_from_saved())
+ {
+ nValue = GetCoreValue(*m_xMtrFldVert1, eUnit);
+ rAttrs->Put( SdrEdgeNode1VertDistItem( nValue ) );
+ bModified = true;
+ }
+
+ if (m_xMtrFldVert2->get_value_changed_from_saved())
+ {
+ nValue = GetCoreValue(*m_xMtrFldVert2, eUnit);
+ rAttrs->Put( SdrEdgeNode2VertDistItem( nValue ) );
+ bModified = true;
+ }
+
+ if (m_xMtrFldLine1->get_value_changed_from_saved())
+ {
+ nValue = GetCoreValue(*m_xMtrFldLine1, eUnit);
+ rAttrs->Put( makeSdrEdgeLine1DeltaItem( nValue ) );
+ bModified = true;
+ }
+
+ if (m_xMtrFldLine2->get_value_changed_from_saved())
+ {
+ nValue = GetCoreValue(*m_xMtrFldLine2, eUnit);
+ rAttrs->Put( makeSdrEdgeLine2DeltaItem( nValue ) );
+ bModified = true;
+ }
+
+ if (m_xMtrFldLine3->get_value_changed_from_saved())
+ {
+ nValue = GetCoreValue(*m_xMtrFldLine3, eUnit);
+ rAttrs->Put( makeSdrEdgeLine3DeltaItem( nValue ) );
+ bModified = true;
+ }
+
+ int nPos = m_xLbType->get_active();
+ if (m_xLbType->get_value_changed_from_saved())
+ {
+ if (nPos != -1)
+ {
+ rAttrs->Put( SdrEdgeKindItem( static_cast<SdrEdgeKind>(nPos) ) );
+ bModified = true;
+ }
+ }
+
+ return bModified;
+}
+
+void SvxConnectionPage::Construct()
+{
+ DBG_ASSERT( pView, "No valid View transfer!" );
+
+ m_aCtlPreview.SetView(pView);
+ m_aCtlPreview.Construct();
+}
+
+/*************************************************************************
+|*
+|* creates the page
+|*
+\************************************************************************/
+std::unique_ptr<SfxTabPage> SvxConnectionPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrs)
+{
+ return std::make_unique<SvxConnectionPage>(pPage, pController, *rAttrs);
+}
+
+IMPL_LINK_NOARG(SvxConnectionPage, ChangeAttrListBoxHdl_Impl, weld::ComboBox&, void)
+{
+ int nPos = m_xLbType->get_active();
+ if (nPos != -1)
+ {
+ aAttrSet.Put( SdrEdgeKindItem( static_cast<SdrEdgeKind>(nPos) ) );
+ }
+
+ m_aCtlPreview.SetAttributes(aAttrSet);
+
+ // get the number of line displacements
+ sal_uInt16 nCount = m_aCtlPreview.GetLineDeltaCount();
+
+ m_xFtLine3->set_sensitive( nCount > 2 );
+ m_xMtrFldLine3->set_sensitive( nCount > 2 );
+ if( nCount > 2 )
+ m_xMtrFldLine3->set_value(m_xMtrFldLine3->get_value(FieldUnit::NONE), FieldUnit::NONE);
+ else
+ m_xMtrFldLine3->set_text("");
+
+ m_xFtLine2->set_sensitive( nCount > 1 );
+ m_xMtrFldLine2->set_sensitive( nCount > 1 );
+ if( nCount > 1 )
+ m_xMtrFldLine2->set_value(m_xMtrFldLine2->get_value(FieldUnit::NONE), FieldUnit::NONE);
+ else
+ m_xMtrFldLine2->set_text("");
+
+ m_xFtLine1->set_sensitive( nCount > 0 );
+ m_xMtrFldLine1->set_sensitive( nCount > 0 );
+ if( nCount > 0 )
+ m_xMtrFldLine1->set_value(m_xMtrFldLine1->get_value(FieldUnit::NONE), FieldUnit::NONE);
+ else
+ m_xMtrFldLine1->set_text("");
+}
+
+IMPL_LINK(SvxConnectionPage, ChangeAttrEditHdl_Impl, weld::MetricSpinButton&, r, void)
+{
+ if (&r == m_xMtrFldHorz1.get())
+ {
+ sal_Int32 nValue = GetCoreValue(*m_xMtrFldHorz1, eUnit);
+ aAttrSet.Put( SdrEdgeNode1HorzDistItem( nValue ) );
+ }
+
+ if (&r == m_xMtrFldHorz2.get())
+ {
+ sal_Int32 nValue = GetCoreValue( *m_xMtrFldHorz2, eUnit );
+ aAttrSet.Put( SdrEdgeNode2HorzDistItem( nValue ) );
+ }
+
+ if (&r == m_xMtrFldVert1.get())
+ {
+ sal_Int32 nValue = GetCoreValue(*m_xMtrFldVert1, eUnit);
+ aAttrSet.Put( SdrEdgeNode1VertDistItem( nValue ) );
+ }
+
+ if (&r == m_xMtrFldVert2.get())
+ {
+ sal_Int32 nValue = GetCoreValue(*m_xMtrFldVert2, eUnit);
+ aAttrSet.Put( SdrEdgeNode2VertDistItem( nValue ) );
+ }
+
+ if (&r == m_xMtrFldLine1.get())
+ {
+ sal_Int32 nValue = GetCoreValue(*m_xMtrFldLine1, eUnit);
+ aAttrSet.Put( makeSdrEdgeLine1DeltaItem( nValue ) );
+ }
+
+ if (&r == m_xMtrFldLine2.get())
+ {
+ sal_Int32 nValue = GetCoreValue(*m_xMtrFldLine2, eUnit);
+ aAttrSet.Put( makeSdrEdgeLine2DeltaItem( nValue ) );
+ }
+
+ if (&r == m_xMtrFldLine3.get())
+ {
+ sal_Int32 nValue = GetCoreValue(*m_xMtrFldLine3, eUnit);
+ aAttrSet.Put( makeSdrEdgeLine3DeltaItem( nValue ) );
+ }
+
+ m_aCtlPreview.SetAttributes(aAttrSet);
+}
+
+void SvxConnectionPage::FillTypeLB()
+{
+ // fill ListBox with connector names
+ const SfxPoolItem* pItem = GetItem( rOutAttrs, SDRATTR_EDGEKIND );
+ const SfxItemPool* pPool = rOutAttrs.GetPool();
+
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_EDGEKIND );
+ const SdrEdgeKindItem* pEdgeKindItem = &pItem->StaticWhichCast(SDRATTR_EDGEKIND);
+ const sal_uInt16 nCount = pEdgeKindItem->GetValueCount();
+ for (sal_uInt16 i = 0; i < nCount; i++)
+ {
+ OUString aStr = SdrEdgeKindItem::GetValueTextByPos(i);
+ m_xLbType->append_text(aStr);
+ }
+}
+void SvxConnectionPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const OfaPtrItem* pOfaPtrItem = aSet.GetItem<OfaPtrItem>(SID_OBJECT_LIST, false);
+ if (pOfaPtrItem)
+ SetView( static_cast<SdrView *>(pOfaPtrItem->GetValue()) );
+
+ Construct();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/grfpage.cxx b/cui/source/tabpages/grfpage.cxx
new file mode 100644
index 0000000000..fac0bfb6ab
--- /dev/null
+++ b/cui/source/tabpages/grfpage.cxx
@@ -0,0 +1,832 @@
+/* -*- 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 <memory>
+#include <svl/eitem.hxx>
+#include <svl/stritem.hxx>
+#include <dialmgr.hxx>
+#include <svx/dlgutil.hxx>
+#include <editeng/sizeitem.hxx>
+#include <editeng/brushitem.hxx>
+#include <grfpage.hxx>
+#include <svx/grfcrop.hxx>
+#include <rtl/ustring.hxx>
+#include <tools/debug.hxx>
+#include <tools/fract.hxx>
+#include <svx/svxids.hrc>
+#include <strings.hrc>
+#include <vcl/fieldvalues.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <svtools/unitconv.hxx>
+#include <svtools/optionsdrawinglayer.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <o3tl/unit_conversion.hxx>
+
+constexpr auto CM_1_TO_TWIP = o3tl::convert(1, o3tl::Length::cm, o3tl::Length::twip); // 567
+
+
+static int lcl_GetValue(const weld::MetricSpinButton& rMetric, FieldUnit eUnit)
+{
+ return rMetric.denormalize(rMetric.get_value(eUnit));
+}
+
+/*--------------------------------------------------------------------
+ description: crop graphic
+ --------------------------------------------------------------------*/
+
+SvxGrfCropPage::SvxGrfCropPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/croppage.ui", "CropPage", &rSet)
+ , m_nOldWidth(0)
+ , m_nOldHeight(0)
+ , m_bSetOrigSize(false)
+ , m_aPreferredDPI(0)
+ , m_xCropFrame(m_xBuilder->weld_widget("cropframe"))
+ , m_xZoomConstRB(m_xBuilder->weld_radio_button("keepscale"))
+ , m_xSizeConstRB(m_xBuilder->weld_radio_button("keepsize"))
+ , m_xLeftMF(m_xBuilder->weld_metric_spin_button("left", FieldUnit::CM))
+ , m_xRightMF(m_xBuilder->weld_metric_spin_button("right", FieldUnit::CM))
+ , m_xTopMF(m_xBuilder->weld_metric_spin_button("top", FieldUnit::CM))
+ , m_xBottomMF(m_xBuilder->weld_metric_spin_button("bottom", FieldUnit::CM))
+ , m_xScaleFrame(m_xBuilder->weld_widget("scaleframe"))
+ , m_xWidthZoomMF(m_xBuilder->weld_metric_spin_button("widthzoom", FieldUnit::PERCENT))
+ , m_xHeightZoomMF(m_xBuilder->weld_metric_spin_button("heightzoom", FieldUnit::PERCENT))
+ , m_xSizeFrame(m_xBuilder->weld_widget("sizeframe"))
+ , m_xWidthMF(m_xBuilder->weld_metric_spin_button("width", FieldUnit::CM))
+ , m_xHeightMF(m_xBuilder->weld_metric_spin_button("height", FieldUnit::CM))
+ , m_xOrigSizeGrid(m_xBuilder->weld_widget("origsizegrid"))
+ , m_xOrigSizeFT(m_xBuilder->weld_label("origsizeft"))
+ , m_xOrigSizePB(m_xBuilder->weld_button("origsize"))
+ , m_xUncropPB(m_xBuilder->weld_button("uncrop"))
+ , m_xExampleWN(new weld::CustomWeld(*m_xBuilder, "preview", m_aExampleWN))
+{
+ SetExchangeSupport();
+
+ // set the correct metric
+ const FieldUnit eMetric = GetModuleFieldUnit( rSet );
+
+ SetFieldUnit( *m_xWidthMF, eMetric );
+ SetFieldUnit( *m_xHeightMF, eMetric );
+ SetFieldUnit( *m_xLeftMF, eMetric );
+ SetFieldUnit( *m_xRightMF, eMetric );
+ SetFieldUnit( *m_xTopMF , eMetric );
+ SetFieldUnit( *m_xBottomMF, eMetric );
+
+ Link<weld::MetricSpinButton&,void> aLk = LINK(this, SvxGrfCropPage, SizeHdl);
+ m_xWidthMF->connect_value_changed( aLk );
+ m_xHeightMF->connect_value_changed( aLk );
+
+ aLk = LINK(this, SvxGrfCropPage, ZoomHdl);
+ m_xWidthZoomMF->connect_value_changed( aLk );
+ m_xHeightZoomMF->connect_value_changed( aLk );
+
+ aLk = LINK(this, SvxGrfCropPage, CropModifyHdl);
+ m_xLeftMF->connect_value_changed( aLk );
+ m_xRightMF->connect_value_changed( aLk );
+ m_xTopMF->connect_value_changed( aLk );
+ m_xBottomMF->connect_value_changed( aLk );
+
+ m_xOrigSizePB->connect_clicked(LINK(this, SvxGrfCropPage, OrigSizeHdl));
+ m_xUncropPB->connect_clicked(LINK(this, SvxGrfCropPage, UncropHdl));
+}
+
+SvxGrfCropPage::~SvxGrfCropPage()
+{
+ m_xExampleWN.reset();
+}
+
+std::unique_ptr<SfxTabPage> SvxGrfCropPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rSet)
+{
+ return std::make_unique<SvxGrfCropPage>(pPage, pController, *rSet);
+}
+
+void SvxGrfCropPage::Reset( const SfxItemSet *rSet )
+{
+ const SfxPoolItem* pItem;
+ const SfxItemPool& rPool = *rSet->GetPool();
+
+ if(SfxItemState::SET == rSet->GetItemState( rPool.GetWhich(
+ SID_ATTR_GRAF_KEEP_ZOOM ), true, &pItem ))
+ {
+ if( static_cast<const SfxBoolItem*>(pItem)->GetValue() )
+ m_xZoomConstRB->set_active(true);
+ else
+ m_xSizeConstRB->set_active(true);
+ m_xZoomConstRB->save_state();
+ }
+
+ sal_uInt16 nW = rPool.GetWhich( SID_ATTR_GRAF_CROP );
+ if( SfxItemState::SET == rSet->GetItemState( nW, true, &pItem))
+ {
+ FieldUnit eUnit = MapToFieldUnit( rSet->GetPool()->GetMetric( nW ));
+
+ const SvxGrfCrop* pCrop = static_cast<const SvxGrfCrop*>(pItem);
+
+ m_aExampleWN.SetLeft(pCrop->GetLeft());
+ m_aExampleWN.SetRight(pCrop->GetRight());
+ m_aExampleWN.SetTop(pCrop->GetTop());
+ m_aExampleWN.SetBottom(pCrop->GetBottom());
+
+ m_xLeftMF->set_value( m_xLeftMF->normalize( pCrop->GetLeft()), eUnit );
+ m_xRightMF->set_value( m_xRightMF->normalize( pCrop->GetRight()), eUnit );
+ m_xTopMF->set_value( m_xTopMF->normalize( pCrop->GetTop()), eUnit );
+ m_xBottomMF->set_value( m_xBottomMF->normalize( pCrop->GetBottom()), eUnit );
+ }
+ else
+ {
+ m_xLeftMF->set_value(0, FieldUnit::NONE);
+ m_xRightMF->set_value(0, FieldUnit::NONE);
+ m_xTopMF->set_value(0, FieldUnit::NONE);
+ m_xBottomMF->set_value(0, FieldUnit::NONE);
+ }
+
+ m_xLeftMF->save_value();
+ m_xRightMF->save_value();
+ m_xTopMF->save_value();
+ m_xBottomMF->save_value();
+
+ nW = rPool.GetWhich( SID_ATTR_PAGE_SIZE );
+ if ( SfxItemState::SET == rSet->GetItemState( nW, false, &pItem ) )
+ {
+ // orientation and size from the PageItem
+ FieldUnit eUnit = MapToFieldUnit( rSet->GetPool()->GetMetric( nW ));
+
+ m_aPageSize = static_cast<const SvxSizeItem*>(pItem)->GetSize();
+
+ auto nMin = m_xWidthMF->normalize( 23 );
+ auto nMax = m_xHeightMF->normalize(m_aPageSize.Height());
+ m_xHeightMF->set_range(nMin, nMax, eUnit);
+ nMax = m_xWidthMF->normalize(m_aPageSize.Width());
+ m_xWidthMF->set_range(nMin, nMax, eUnit);
+ }
+ else
+ {
+ m_aPageSize = OutputDevice::LogicToLogic(
+ Size( CM_1_TO_TWIP, CM_1_TO_TWIP ),
+ MapMode( MapUnit::MapTwip ),
+ MapMode( rSet->GetPool()->GetMetric( nW ) ) );
+ }
+
+ bool bFound = false;
+ if( const SvxBrushItem* pGraphicItem = rSet->GetItemIfSet( SID_ATTR_GRAF_GRAPHIC, false ) )
+ {
+ OUString referer;
+ SfxStringItem const * it = rSet->GetItem(SID_REFERER);
+ if (it != nullptr) {
+ referer = it->GetValue();
+ }
+ const Graphic* pGrf = pGraphicItem->GetGraphic(referer);
+ if( pGrf )
+ {
+ m_aOrigSize = GetGrfOrigSize( *pGrf );
+ if (pGrf->GetType() == GraphicType::Bitmap && m_aOrigSize.Width() && m_aOrigSize.Height())
+ {
+ m_aOrigPixelSize = pGrf->GetSizePixel();
+ }
+
+ if( m_aOrigSize.Width() && m_aOrigSize.Height() )
+ {
+ CalcMinMaxBorder();
+ m_aExampleWN.SetGraphic( *pGrf );
+ m_aExampleWN.SetFrameSize( m_aOrigSize );
+
+ bFound = true;
+ if( !pGraphicItem->GetGraphicLink().isEmpty() )
+ m_aGraphicName = pGraphicItem->GetGraphicLink();
+ }
+ }
+ }
+
+ GraphicHasChanged( bFound );
+ ActivatePage( *rSet );
+}
+
+bool SvxGrfCropPage::FillItemSet(SfxItemSet *rSet)
+{
+ const SfxItemPool& rPool = *rSet->GetPool();
+ bool bModified = false;
+ if( m_xWidthMF->get_value_changed_from_saved() ||
+ m_xHeightMF->get_value_changed_from_saved() )
+ {
+ constexpr TypedWhichId<SvxSizeItem> nW = SID_ATTR_GRAF_FRMSIZE;
+ FieldUnit eUnit = MapToFieldUnit( rSet->GetPool()->GetMetric( nW ));
+
+ std::shared_ptr<SvxSizeItem> aSz(std::make_shared<SvxSizeItem>(nW));
+
+ // size could already have been set from another page
+ const SfxItemSet* pExSet = GetDialogExampleSet();
+ const SvxSizeItem* pSizeItem = nullptr;
+ if( pExSet && (pSizeItem = pExSet->GetItemIfSet( nW, false )) )
+ {
+ aSz.reset(pSizeItem->Clone());
+ }
+ else
+ {
+ aSz.reset(GetItemSet().Get(nW).Clone());
+ }
+
+ Size aTmpSz( aSz->GetSize() );
+ if( m_xWidthMF->get_value_changed_from_saved() )
+ aTmpSz.setWidth( lcl_GetValue( *m_xWidthMF, eUnit ) );
+ if( m_xHeightMF->get_value_changed_from_saved() )
+ aTmpSz.setHeight( lcl_GetValue( *m_xHeightMF, eUnit ) );
+ aSz->SetSize( aTmpSz );
+ m_xWidthMF->save_value();
+ m_xHeightMF->save_value();
+
+ bModified |= nullptr != rSet->Put( *aSz );
+
+ if (m_bSetOrigSize)
+ {
+ bModified |= nullptr != rSet->Put( SvxSizeItem( rPool.GetWhich(
+ SID_ATTR_GRAF_FRMSIZE_PERCENT ), Size( 0, 0 )) );
+ }
+ }
+ if( m_xLeftMF->get_value_changed_from_saved() || m_xRightMF->get_value_changed_from_saved() ||
+ m_xTopMF->get_value_changed_from_saved() || m_xBottomMF->get_value_changed_from_saved() )
+ {
+ sal_uInt16 nW = rPool.GetWhich( SID_ATTR_GRAF_CROP );
+ FieldUnit eUnit = MapToFieldUnit( rSet->GetPool()->GetMetric( nW ));
+ std::unique_ptr<SvxGrfCrop> pNew(static_cast<SvxGrfCrop*>(rSet->Get( nW ).Clone()));
+
+ pNew->SetLeft( lcl_GetValue( *m_xLeftMF, eUnit ) );
+ pNew->SetRight( lcl_GetValue( *m_xRightMF, eUnit ) );
+ pNew->SetTop( lcl_GetValue( *m_xTopMF, eUnit ) );
+ pNew->SetBottom( lcl_GetValue( *m_xBottomMF, eUnit ) );
+ bModified |= nullptr != rSet->Put( std::move(pNew) );
+ }
+
+ if( m_xZoomConstRB->get_state_changed_from_saved() )
+ {
+ bModified |= nullptr != rSet->Put( SfxBoolItem( rPool.GetWhich(
+ SID_ATTR_GRAF_KEEP_ZOOM), m_xZoomConstRB->get_active() ) );
+ }
+
+ return bModified;
+}
+
+void SvxGrfCropPage::ActivatePage(const SfxItemSet& rSet)
+{
+#ifdef DBG_UTIL
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+#endif
+
+ auto& aProperties = getAdditionalProperties();
+ auto aIterator = aProperties.find("PreferredDPI");
+ if (aIterator != aProperties.end())
+ m_aPreferredDPI = aIterator->second.get<sal_Int32>();
+
+ m_bSetOrigSize = false;
+
+ // Size
+ Size aSize;
+ if( const SvxSizeItem* pFrmSizeItem = rSet.GetItemIfSet( SID_ATTR_GRAF_FRMSIZE, false ) )
+ aSize = pFrmSizeItem->GetSize();
+
+ m_nOldWidth = aSize.Width();
+ m_nOldHeight = aSize.Height();
+
+ auto nWidth = m_xWidthMF->normalize(m_nOldWidth);
+ auto nHeight = m_xHeightMF->normalize(m_nOldHeight);
+
+ if (nWidth != m_xWidthMF->get_value(FieldUnit::TWIP))
+ m_xWidthMF->set_value(nWidth, FieldUnit::TWIP);
+ m_xWidthMF->save_value();
+
+ if (nHeight != m_xHeightMF->get_value(FieldUnit::TWIP))
+ m_xHeightMF->set_value(nHeight, FieldUnit::TWIP);
+ m_xHeightMF->save_value();
+
+ if( const SvxBrushItem* pBrushItem = rSet.GetItemIfSet( SID_ATTR_GRAF_GRAPHIC, false ) )
+ {
+ if( !pBrushItem->GetGraphicLink().isEmpty() &&
+ m_aGraphicName != pBrushItem->GetGraphicLink() )
+ m_aGraphicName = pBrushItem->GetGraphicLink();
+
+ OUString referer;
+ SfxStringItem const * it = rSet.GetItem(SID_REFERER);
+ if (it != nullptr) {
+ referer = it->GetValue();
+ }
+ const Graphic* pGrf = pBrushItem->GetGraphic(referer);
+ if( pGrf )
+ {
+ m_aExampleWN.SetGraphic( *pGrf );
+ m_aOrigSize = GetGrfOrigSize( *pGrf );
+ if (pGrf->GetType() == GraphicType::Bitmap && m_aOrigSize.Width() > 1 && m_aOrigSize.Height() > 1) {
+ m_aOrigPixelSize = pGrf->GetSizePixel();
+ }
+ m_aExampleWN.SetFrameSize(m_aOrigSize);
+ GraphicHasChanged( m_aOrigSize.Width() && m_aOrigSize.Height() );
+ CalcMinMaxBorder();
+ }
+ else
+ GraphicHasChanged( false );
+ }
+
+ CalcZoom();
+}
+
+DeactivateRC SvxGrfCropPage::DeactivatePage(SfxItemSet *_pSet)
+{
+ if ( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+/*--------------------------------------------------------------------
+ description: scale changed, adjust size
+ --------------------------------------------------------------------*/
+
+IMPL_LINK( SvxGrfCropPage, ZoomHdl, weld::MetricSpinButton&, rField, void )
+{
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
+ SID_ATTR_GRAF_CROP ) ) );
+
+ if (&rField == m_xWidthZoomMF.get())
+ {
+ tools::Long nLRBorders = lcl_GetValue(*m_xLeftMF, eUnit)
+ +lcl_GetValue(*m_xRightMF, eUnit);
+ m_xWidthMF->set_value( m_xWidthMF->normalize(
+ ((m_aOrigSize.Width() - nLRBorders) * rField.get_value(FieldUnit::NONE))/100),
+ eUnit);
+ }
+ else
+ {
+ tools::Long nULBorders = lcl_GetValue(*m_xTopMF, eUnit)
+ +lcl_GetValue(*m_xBottomMF, eUnit);
+ m_xHeightMF->set_value( m_xHeightMF->normalize(
+ ((m_aOrigSize.Height() - nULBorders ) * rField.get_value(FieldUnit::NONE))/100) ,
+ eUnit );
+ }
+}
+
+/*--------------------------------------------------------------------
+ description: change size, adjust scale
+ --------------------------------------------------------------------*/
+
+IMPL_LINK( SvxGrfCropPage, SizeHdl, weld::MetricSpinButton&, rField, void )
+{
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
+ SID_ATTR_GRAF_CROP ) ) );
+
+ Size aSize( lcl_GetValue(*m_xWidthMF, eUnit),
+ lcl_GetValue(*m_xHeightMF, eUnit) );
+
+ if(&rField == m_xWidthMF.get())
+ {
+ tools::Long nWidth = m_aOrigSize.Width() -
+ ( lcl_GetValue(*m_xLeftMF, eUnit) +
+ lcl_GetValue(*m_xRightMF, eUnit) );
+ if(!nWidth)
+ nWidth++;
+ sal_uInt16 nZoom = static_cast<sal_uInt16>( aSize.Width() * 100 / nWidth);
+ m_xWidthZoomMF->set_value(nZoom, FieldUnit::NONE);
+ }
+ else
+ {
+ tools::Long nHeight = m_aOrigSize.Height() -
+ ( lcl_GetValue(*m_xTopMF, eUnit) +
+ lcl_GetValue(*m_xBottomMF, eUnit));
+ if(!nHeight)
+ nHeight++;
+ sal_uInt16 nZoom = static_cast<sal_uInt16>( aSize.Height() * 100 / nHeight);
+ m_xHeightZoomMF->set_value(nZoom, FieldUnit::NONE);
+ }
+}
+
+/*--------------------------------------------------------------------
+ description: evaluate border
+ --------------------------------------------------------------------*/
+
+IMPL_LINK( SvxGrfCropPage, CropModifyHdl, weld::MetricSpinButton&, rField, void )
+{
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
+ SID_ATTR_GRAF_CROP ) ) );
+
+ bool bZoom = m_xZoomConstRB->get_active();
+ if (&rField == m_xLeftMF.get() || &rField == m_xRightMF.get())
+ {
+ tools::Long nLeft = lcl_GetValue( *m_xLeftMF, eUnit );
+ tools::Long nRight = lcl_GetValue( *m_xRightMF, eUnit );
+ tools::Long nWidthZoom = static_cast<tools::Long>(m_xWidthZoomMF->get_value(FieldUnit::NONE));
+ if (bZoom && nWidthZoom != 0 && ( ( ( m_aOrigSize.Width() - (nLeft + nRight )) * nWidthZoom )
+ / 100 >= m_aPageSize.Width() ) )
+ {
+ if (&rField == m_xLeftMF.get())
+ {
+ nLeft = m_aOrigSize.Width() -
+ ( m_aPageSize.Width() * 100 / nWidthZoom + nRight );
+ m_xLeftMF->set_value( m_xLeftMF->normalize( nLeft ), eUnit );
+ }
+ else
+ {
+ nRight = m_aOrigSize.Width() -
+ ( m_aPageSize.Width() * 100 / nWidthZoom + nLeft );
+ m_xRightMF->set_value( m_xRightMF->normalize( nRight ), eUnit );
+ }
+ }
+ if (AllSettings::GetLayoutRTL())
+ {
+ m_aExampleWN.SetLeft(nRight);
+ m_aExampleWN.SetRight(nLeft);
+ }
+ else
+ {
+ m_aExampleWN.SetLeft(nLeft);
+ m_aExampleWN.SetRight(nRight);
+ }
+ if(bZoom)
+ {
+ // scale stays, recompute width
+ ZoomHdl(*m_xWidthZoomMF);
+ }
+ }
+ else
+ {
+ tools::Long nTop = lcl_GetValue( *m_xTopMF, eUnit );
+ tools::Long nBottom = lcl_GetValue( *m_xBottomMF, eUnit );
+ tools::Long nHeightZoom = static_cast<tools::Long>(m_xHeightZoomMF->get_value(FieldUnit::NONE));
+ if(bZoom && ( ( ( m_aOrigSize.Height() - (nTop + nBottom )) * nHeightZoom)
+ / 100 >= m_aPageSize.Height()))
+ {
+ assert(nHeightZoom && "div-by-zero");
+ if(&rField == m_xTopMF.get())
+ {
+ nTop = m_aOrigSize.Height() -
+ ( m_aPageSize.Height() * 100 / nHeightZoom + nBottom);
+ m_xTopMF->set_value( m_xWidthMF->normalize( nTop ), eUnit );
+ }
+ else
+ {
+ nBottom = m_aOrigSize.Height() -
+ ( m_aPageSize.Height() * 100 / nHeightZoom + nTop);
+ m_xBottomMF->set_value( m_xWidthMF->normalize( nBottom ), eUnit );
+ }
+ }
+ m_aExampleWN.SetTop( nTop );
+ m_aExampleWN.SetBottom( nBottom );
+ if(bZoom)
+ {
+ // scale stays, recompute height
+ ZoomHdl(*m_xHeightZoomMF);
+ }
+ }
+ m_aExampleWN.Invalidate();
+ // size and border changed -> recompute scale
+ if(!bZoom)
+ CalcZoom();
+ CalcMinMaxBorder();
+}
+/*--------------------------------------------------------------------
+ description: set original size
+ --------------------------------------------------------------------*/
+
+IMPL_LINK_NOARG(SvxGrfCropPage, OrigSizeHdl, weld::Button&, void)
+{
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
+ SID_ATTR_GRAF_CROP ) ) );
+
+ tools::Long nWidth = m_aOrigSize.Width() -
+ lcl_GetValue( *m_xLeftMF, eUnit ) -
+ lcl_GetValue( *m_xRightMF, eUnit );
+ m_xWidthMF->set_value( m_xWidthMF->normalize( nWidth ), eUnit );
+ tools::Long nHeight = m_aOrigSize.Height() -
+ lcl_GetValue( *m_xTopMF, eUnit ) -
+ lcl_GetValue( *m_xBottomMF, eUnit );
+ m_xHeightMF->set_value( m_xHeightMF->normalize( nHeight ), eUnit );
+ m_xWidthZoomMF->set_value(100, FieldUnit::NONE);
+ m_xHeightZoomMF->set_value(100, FieldUnit::NONE);
+ m_bSetOrigSize = true;
+}
+
+/*--------------------------------------------------------------------
+ description: reset crop
+ --------------------------------------------------------------------*/
+
+IMPL_LINK_NOARG(SvxGrfCropPage, UncropHdl, weld::Button&, void)
+{
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+
+ m_xLeftMF->set_value(0, FieldUnit::NONE);
+ m_xRightMF->set_value(0, FieldUnit::NONE);
+ m_xTopMF->set_value(0, FieldUnit::NONE);
+ m_xBottomMF->set_value(0, FieldUnit::NONE);
+
+ m_aExampleWN.SetLeft(0);
+ m_aExampleWN.SetRight(0);
+ m_aExampleWN.SetTop(0);
+ m_aExampleWN.SetBottom(0);
+
+ m_aExampleWN.Invalidate();
+ CalcMinMaxBorder();
+
+}
+
+
+/*--------------------------------------------------------------------
+ description: compute scale
+ --------------------------------------------------------------------*/
+
+void SvxGrfCropPage::CalcZoom()
+{
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
+ SID_ATTR_GRAF_CROP ) ) );
+
+ tools::Long nWidth = lcl_GetValue( *m_xWidthMF, eUnit );
+ tools::Long nHeight = lcl_GetValue( *m_xHeightMF, eUnit );
+ tools::Long nLRBorders = lcl_GetValue( *m_xLeftMF, eUnit ) +
+ lcl_GetValue( *m_xRightMF, eUnit );
+ tools::Long nULBorders = lcl_GetValue( *m_xTopMF, eUnit ) +
+ lcl_GetValue( *m_xBottomMF, eUnit );
+ sal_uInt16 nZoom = 0;
+ tools::Long nDen;
+ if( (nDen = m_aOrigSize.Width() - nLRBorders) > 0)
+ nZoom = static_cast<sal_uInt16>((( nWidth * 1000 / nDen )+5)/10);
+ m_xWidthZoomMF->set_value(nZoom, FieldUnit::NONE);
+ if( (nDen = m_aOrigSize.Height() - nULBorders) > 0)
+ nZoom = static_cast<sal_uInt16>((( nHeight * 1000 / nDen )+5)/10);
+ else
+ nZoom = 0;
+ m_xHeightZoomMF->set_value(nZoom, FieldUnit::NONE);
+}
+
+/*--------------------------------------------------------------------
+ description: set minimum/maximum values for the margins
+ --------------------------------------------------------------------*/
+
+void SvxGrfCropPage::CalcMinMaxBorder()
+{
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
+ SID_ATTR_GRAF_CROP ) ) );
+ tools::Long nR = lcl_GetValue(*m_xRightMF, eUnit );
+ tools::Long nMinWidth = (m_aOrigSize.Width() * 10) /11;
+ tools::Long nMin = nMinWidth - (nR >= 0 ? nR : 0);
+ m_xLeftMF->set_max( m_xLeftMF->normalize(nMin), eUnit );
+
+ tools::Long nL = lcl_GetValue(*m_xLeftMF, eUnit );
+ nMin = nMinWidth - (nL >= 0 ? nL : 0);
+ m_xRightMF->set_max( m_xRightMF->normalize(nMin), eUnit );
+
+ tools::Long nUp = lcl_GetValue( *m_xTopMF, eUnit );
+ tools::Long nMinHeight = (m_aOrigSize.Height() * 10) /11;
+ nMin = nMinHeight - (nUp >= 0 ? nUp : 0);
+ m_xBottomMF->set_max( m_xBottomMF->normalize(nMin), eUnit );
+
+ tools::Long nLow = lcl_GetValue(*m_xBottomMF, eUnit );
+ nMin = nMinHeight - (nLow >= 0 ? nLow : 0);
+ m_xTopMF->set_max( m_xTopMF->normalize(nMin), eUnit );
+}
+/*--------------------------------------------------------------------
+ description: set spinsize to 1/20 of the original size,
+ fill FixedText with the original size
+ --------------------------------------------------------------------*/
+
+void SvxGrfCropPage::GraphicHasChanged( bool bFound )
+{
+ if( bFound )
+ {
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
+ SID_ATTR_GRAF_CROP ) ));
+
+ sal_Int64 nSpin = m_xLeftMF->normalize(m_aOrigSize.Width()) / 20;
+ nSpin = vcl::ConvertValue( nSpin, m_aOrigSize.Width(), 0,
+ eUnit, m_xLeftMF->get_unit());
+
+ // if the margin is too big, it is set to 1/3 on both pages
+ tools::Long nR = lcl_GetValue( *m_xRightMF, eUnit );
+ tools::Long nL = lcl_GetValue( *m_xLeftMF, eUnit );
+ if((nL + nR) < - m_aOrigSize.Width())
+ {
+ tools::Long nVal = m_aOrigSize.Width() / -3;
+ m_xRightMF->set_value( m_xRightMF->normalize( nVal ), eUnit );
+ m_xLeftMF->set_value( m_xLeftMF->normalize( nVal ), eUnit );
+ m_aExampleWN.SetLeft(nVal);
+ m_aExampleWN.SetRight(nVal);
+ }
+ tools::Long nUp = lcl_GetValue(*m_xTopMF, eUnit );
+ tools::Long nLow = lcl_GetValue(*m_xBottomMF, eUnit );
+ if((nUp + nLow) < - m_aOrigSize.Height())
+ {
+ tools::Long nVal = m_aOrigSize.Height() / -3;
+ m_xTopMF->set_value( m_xTopMF->normalize( nVal ), eUnit );
+ m_xBottomMF->set_value( m_xBottomMF->normalize( nVal ), eUnit );
+ m_aExampleWN.SetTop(nVal);
+ m_aExampleWN.SetBottom(nVal);
+ }
+
+ m_xLeftMF->set_increments(nSpin, nSpin * 10, FieldUnit::NONE);
+ m_xRightMF->set_increments(nSpin, nSpin * 10, FieldUnit::NONE);
+ nSpin = m_xTopMF->normalize(m_aOrigSize.Height()) / 20;
+ nSpin = vcl::ConvertValue( nSpin, m_aOrigSize.Width(), 0,
+ eUnit, m_xLeftMF->get_unit() );
+ m_xTopMF->set_increments(nSpin, nSpin * 10, FieldUnit::NONE);
+ m_xBottomMF->set_increments(nSpin, nSpin * 10, FieldUnit::NONE);
+
+ // display original size
+ const FieldUnit eMetric = GetModuleFieldUnit( GetItemSet() );
+
+ OUString sTemp;
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/spinbox.ui"));
+ std::unique_ptr<weld::Dialog> xTopLevel(xBuilder->weld_dialog("SpinDialog"));
+ std::unique_ptr<weld::MetricSpinButton> xFld(xBuilder->weld_metric_spin_button("spin", FieldUnit::CM));
+ SetFieldUnit( *xFld, eMetric );
+ xFld->set_digits(m_xWidthMF->get_digits());
+ xFld->set_max(INT_MAX - 1, FieldUnit::NONE);
+
+ xFld->set_value(xFld->normalize(m_aOrigSize.Width()), eUnit);
+ sTemp = xFld->get_text();
+ xFld->set_value(xFld->normalize(m_aOrigSize.Height()), eUnit);
+ // multiplication sign (U+00D7)
+ sTemp += u"\u00D7" + xFld->get_text();
+ }
+
+ if ( m_aOrigPixelSize.Width() && m_aOrigPixelSize.Height() ) {
+ sal_Int32 ax = 0.5 + m_aOrigPixelSize.Width() /
+ o3tl::convert<double>(m_aOrigSize.Width(), o3tl::Length::twip,
+ o3tl::Length::in);
+ sal_Int32 ay = 0.5 + m_aOrigPixelSize.Height() /
+ o3tl::convert<double>(m_aOrigSize.Height(), o3tl::Length::twip,
+ o3tl::Length::in);
+ OUString sPPI = OUString::number(ax);
+ if (abs(ax - ay) > 1) {
+ sPPI += u"\u00D7" + OUString::number(ay);
+ }
+ sTemp += " " + CuiResId(RID_CUISTR_PPI).replaceAll("%1", sPPI);
+ }
+ sTemp += "\n" + OUString::number(m_aOrigPixelSize.Width()) + u"\u00D7" + OUString::number(m_aOrigPixelSize.Height()) + " px";
+ m_xOrigSizeFT->set_label(sTemp);
+ }
+
+ m_xCropFrame->set_sensitive(bFound);
+ m_xScaleFrame->set_sensitive(bFound);
+ m_xSizeFrame->set_sensitive(bFound);
+ m_xOrigSizeGrid->set_sensitive(bFound);
+ m_xZoomConstRB->set_sensitive(bFound);
+}
+
+Size SvxGrfCropPage::GetGrfOrigSize(const Graphic& rGrf)
+{
+ Size aSize;
+
+ if (m_aPreferredDPI > 0)
+ {
+ Size aPixelSize = rGrf.GetSizePixel();
+ double fWidth = aPixelSize.Width() / double(m_aPreferredDPI);
+ double fHeight = aPixelSize.Height() / double(m_aPreferredDPI);
+ fWidth = o3tl::convert(fWidth, o3tl::Length::in, o3tl::Length::twip);
+ fHeight = o3tl::convert(fHeight, o3tl::Length::in, o3tl::Length::twip);
+ aSize = Size(fWidth, fHeight);
+ }
+ else
+ {
+ const MapMode aMapTwip( MapUnit::MapTwip );
+ aSize = rGrf.GetPrefSize();
+ if( MapUnit::MapPixel == rGrf.GetPrefMapMode().GetMapUnit() )
+ aSize = Application::GetDefaultDevice()->PixelToLogic(aSize, aMapTwip);
+ else
+ aSize = OutputDevice::LogicToLogic( aSize,
+ rGrf.GetPrefMapMode(), aMapTwip );
+ }
+ return aSize;
+}
+
+/*****************************************************************/
+
+SvxCropExample::SvxCropExample()
+ : m_aTopLeft(0, 0)
+ , m_aBottomRight(0, 0)
+{
+}
+
+void SvxCropExample::SetDrawingArea(weld::DrawingArea* pDrawingArea)
+{
+ CustomWidgetController::SetDrawingArea(pDrawingArea);
+ OutputDevice& rDevice = pDrawingArea->get_ref_device();
+ Size aSize(rDevice.LogicToPixel(Size(78, 78), MapMode(MapUnit::MapAppFont)));
+ pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
+
+ m_aMapMode = rDevice.GetMapMode();
+ m_aFrameSize = OutputDevice::LogicToLogic(
+ Size(CM_1_TO_TWIP / 2, CM_1_TO_TWIP / 2),
+ MapMode(MapUnit::MapTwip), m_aMapMode);
+}
+
+void SvxCropExample::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle&)
+{
+ rRenderContext.Push(vcl::PushFlags::MAPMODE);
+ rRenderContext.SetMapMode(m_aMapMode);
+
+ // Win BG
+ const Size aWinSize(rRenderContext.PixelToLogic(GetOutputSizePixel()));
+ rRenderContext.SetLineColor();
+ rRenderContext.SetFillColor(rRenderContext.GetSettings().GetStyleSettings().GetWindowColor());
+ rRenderContext.DrawRect(::tools::Rectangle(Point(), aWinSize));
+
+ // use AA, the Graphic may be a metafile/svg and would then look ugly
+ rRenderContext.SetAntialiasing(AntialiasingFlags::Enable);
+
+ // draw Graphic
+ ::tools::Rectangle aRect(
+ Point((aWinSize.Width() - m_aFrameSize.Width())/2, (aWinSize.Height() - m_aFrameSize.Height())/2),
+ m_aFrameSize);
+ m_aGrf.Draw(rRenderContext, aRect.TopLeft(), aRect.GetSize());
+
+ // Remove one more case that uses XOR paint (RasterOp::Invert).
+ // Get colors and logic DashLength from settings, use equal to
+ // PolygonMarkerPrimitive2D, may be changed to that primitive later.
+ // Use this to guarantee good visibility - that was the purpose of
+ // the former used XOR paint.
+ const Color aColA(SvtOptionsDrawinglayer::GetStripeColorA().getBColor());
+ const Color aColB(SvtOptionsDrawinglayer::GetStripeColorB().getBColor());
+ const double fStripeLength(SvtOptionsDrawinglayer::GetStripeLength());
+ const basegfx::B2DVector aDashVector(rRenderContext.GetInverseViewTransformation() * basegfx::B2DVector(fStripeLength, 0.0));
+ const double fLogicDashLength(aDashVector.getX());
+
+ // apply current crop settings
+ aRect.AdjustLeft(m_aTopLeft.Y());
+ aRect.AdjustTop(m_aTopLeft.X());
+ aRect.AdjustRight(-m_aBottomRight.Y());
+ aRect.AdjustBottom(-m_aBottomRight.X());
+
+ // apply dash with direct paint callbacks
+ basegfx::utils::applyLineDashing(
+ basegfx::utils::createPolygonFromRect(
+ basegfx::B2DRange(aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom())),
+ std::vector< double >(2, fLogicDashLength),
+ [&aColA,&rRenderContext](const basegfx::B2DPolygon& rSnippet)
+ {
+ rRenderContext.SetLineColor(aColA);
+ rRenderContext.DrawPolyLine(rSnippet);
+ },
+ [&aColB,&rRenderContext](const basegfx::B2DPolygon& rSnippet)
+ {
+ rRenderContext.SetLineColor(aColB);
+ rRenderContext.DrawPolyLine(rSnippet);
+ },
+ 2.0 * fLogicDashLength);
+
+ rRenderContext.Pop();
+}
+
+void SvxCropExample::Resize()
+{
+ SetFrameSize(m_aFrameSize);
+}
+
+void SvxCropExample::SetFrameSize( const Size& rSz )
+{
+ m_aFrameSize = rSz;
+ if (!m_aFrameSize.Width())
+ m_aFrameSize.setWidth( 1 );
+ if (!m_aFrameSize.Height())
+ m_aFrameSize.setHeight( 1 );
+ Size aWinSize( GetOutputSizePixel() );
+ Fraction aXScale( aWinSize.Width() * 4, m_aFrameSize.Width() * 5 );
+ Fraction aYScale( aWinSize.Height() * 4, m_aFrameSize.Height() * 5 );
+
+ if( aYScale < aXScale )
+ aXScale = aYScale;
+
+ m_aMapMode.SetScaleX(aXScale);
+ m_aMapMode.SetScaleY(aXScale);
+
+ Invalidate();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/labdlg.cxx b/cui/source/tabpages/labdlg.cxx
new file mode 100644
index 0000000000..c566158647
--- /dev/null
+++ b/cui/source/tabpages/labdlg.cxx
@@ -0,0 +1,507 @@
+/* -*- 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 <swpossizetabpage.hxx>
+#include <svtools/unitconv.hxx>
+
+#include <svx/svddef.hxx>
+#include <svx/sxcecitm.hxx>
+#include <svx/sxcgitm.hxx>
+#include <svx/sxcllitm.hxx>
+#include <svx/sxctitm.hxx>
+
+#include <svx/dlgutil.hxx>
+#include <labdlg.hxx>
+#include <transfrm.hxx>
+#include <bitmaps.hlst>
+
+// define ----------------------------------------------------------------
+
+#define EXT_OPTIMAL 0
+#define EXT_FROM_TOP 1
+#define EXT_FROM_LEFT 2
+#define EXT_HORIZONTAL 3
+#define EXT_VERTICAL 4
+
+#define POS_TOP 0
+#define POS_MIDDLE 1
+#define POS_BOTTOM 2
+
+#define BMP_CAPTTYPE_1 1
+#define BMP_CAPTTYPE_2 2
+#define BMP_CAPTTYPE_3 3
+
+// static ----------------------------------------------------------------
+
+const WhichRangesContainer SvxCaptionTabPage::pCaptionRanges(
+ svl::Items<
+ SDRATTR_CAPTIONTYPE, SDRATTR_CAPTIONFIXEDANGLE,
+ SDRATTR_CAPTIONANGLE, SDRATTR_CAPTIONGAP,
+ SDRATTR_CAPTIONESCDIR, SDRATTR_CAPTIONESCISREL,
+ SDRATTR_CAPTIONESCREL, SDRATTR_CAPTIONESCABS,
+ SDRATTR_CAPTIONLINELEN, SDRATTR_CAPTIONFITLINELEN>);
+
+SvxCaptionTabPage::SvxCaptionTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/calloutpage.ui", "CalloutPage", &rInAttrs)
+ , nCaptionType(SdrCaptionType::Type1)
+ , nGap(0)
+ , nEscDir(SdrCaptionEscDir::Horizontal)
+ , bEscRel(false)
+ , nEscAbs(0)
+ , nEscRel(0)
+ , nLineLen(0)
+ , bFitLineLen(false)
+ , nPosition(0)
+ , nExtension(0)
+ , rOutAttrs(rInAttrs)
+ , pView(nullptr)
+ , m_xMF_SPACING(m_xBuilder->weld_metric_spin_button("spacing", FieldUnit::MM))
+ , m_xLB_EXTENSION(m_xBuilder->weld_combo_box("extension"))
+ , m_xFT_BYFT(m_xBuilder->weld_label("byft"))
+ , m_xMF_BY(m_xBuilder->weld_metric_spin_button("by", FieldUnit::MM))
+ , m_xFT_POSITIONFT(m_xBuilder->weld_label("positionft"))
+ , m_xLB_POSITION(m_xBuilder->weld_combo_box("position"))
+ , m_xLineTypes(m_xBuilder->weld_combo_box("linetypes"))
+ , m_xFT_LENGTHFT(m_xBuilder->weld_label("lengthft"))
+ , m_xMF_LENGTH(m_xBuilder->weld_metric_spin_button("length", FieldUnit::MM))
+ , m_xCB_OPTIMAL(m_xBuilder->weld_check_button("optimal"))
+ , m_xCT_CAPTTYPE(new ValueSet(m_xBuilder->weld_scrolled_window("valuesetwin", true)))
+ , m_xCT_CAPTTYPEWin(new weld::CustomWeld(*m_xBuilder, "valueset", *m_xCT_CAPTTYPE))
+{
+ Size aSize(m_xCT_CAPTTYPE->GetDrawingArea()->get_ref_device().LogicToPixel(Size(187, 38), MapMode(MapUnit::MapAppFont)));
+ m_xCT_CAPTTYPEWin->set_size_request(aSize.Width(), aSize.Height());
+
+ assert(m_xLB_POSITION->get_count() == 6);
+ for (int i = 0; i < 3; ++i)
+ m_aStrHorzList.push_back(m_xLB_POSITION->get_text(i));
+ for (int i = 3; i < 6; ++i)
+ m_aStrVertList.push_back(m_xLB_POSITION->get_text(i));
+ m_xLB_POSITION->clear();
+
+ assert(m_xLineTypes->get_count() == 3);
+ std::vector<OUString> aLineTypes;
+ aLineTypes.reserve(3);
+ for (int i = 0; i < 3; ++i)
+ aLineTypes.push_back(m_xLineTypes->get_text(i));
+
+ static_assert(CAPTYPE_BITMAPS_COUNT == 3, "unexpected");
+ m_aBmpCapTypes[0] = Image(StockImage::Yes, RID_SVXBMP_LEGTYP1);
+ m_aBmpCapTypes[1] = Image(StockImage::Yes, RID_SVXBMP_LEGTYP2);
+ m_aBmpCapTypes[2] = Image(StockImage::Yes, RID_SVXBMP_LEGTYP3);
+
+ //------------install ValueSet--------------------------
+ m_xCT_CAPTTYPE->SetStyle( m_xCT_CAPTTYPE->GetStyle() | WB_ITEMBORDER | WB_DOUBLEBORDER | WB_NAMEFIELD );
+ m_xCT_CAPTTYPE->SetColCount(5);//XXX
+ m_xCT_CAPTTYPE->SetLineCount(1);
+ m_xCT_CAPTTYPE->SetSelectHdl(LINK( this, SvxCaptionTabPage, SelectCaptTypeHdl_Impl));
+
+ Image aImage;
+ m_xCT_CAPTTYPE->InsertItem(BMP_CAPTTYPE_1, aImage, aLineTypes[0]);
+ m_xCT_CAPTTYPE->InsertItem(BMP_CAPTTYPE_2, aImage, aLineTypes[1]);
+ m_xCT_CAPTTYPE->InsertItem(BMP_CAPTTYPE_3, aImage, aLineTypes[2]);
+
+ FillValueSet();
+
+ m_xLB_EXTENSION->connect_changed(LINK(this, SvxCaptionTabPage, ExtensionSelectHdl_Impl));
+ m_xLB_POSITION->connect_changed(LINK(this, SvxCaptionTabPage, PositionSelectHdl_Impl));
+ m_xCB_OPTIMAL->connect_toggled(LINK(this, SvxCaptionTabPage, LineOptHdl_Impl));
+}
+
+SvxCaptionTabPage::~SvxCaptionTabPage()
+{
+ m_xCT_CAPTTYPEWin.reset();
+ m_xCT_CAPTTYPE.reset();
+}
+
+void SvxCaptionTabPage::Construct()
+{
+ // set rectangle and working area
+ DBG_ASSERT( pView, "No valid View transferred!" );
+}
+
+bool SvxCaptionTabPage::FillItemSet( SfxItemSet* _rOutAttrs)
+{
+ SfxItemPool* pPool = _rOutAttrs->GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+
+ MapUnit eUnit;
+
+ nCaptionType = static_cast<SdrCaptionType>(m_xCT_CAPTTYPE->GetSelectedItemId()-1);
+
+ _rOutAttrs->Put( SdrCaptionTypeItem( nCaptionType ) );
+
+ if (m_xMF_SPACING->get_value_changed_from_saved())
+ {
+ eUnit = pPool->GetMetric( GetWhich( SDRATTR_CAPTIONGAP ) );
+ _rOutAttrs->Put( SdrCaptionGapItem( GetCoreValue(*m_xMF_SPACING, eUnit ) ) );
+ }
+
+ // special treatment!!! XXX
+ if( nCaptionType==SdrCaptionType::Type1 )
+ {
+ switch( nEscDir )
+ {
+ case SdrCaptionEscDir::Horizontal: nEscDir=SdrCaptionEscDir::Vertical;break;
+ case SdrCaptionEscDir::Vertical: nEscDir=SdrCaptionEscDir::Horizontal;break;
+ default: break;
+ }
+ }
+
+ _rOutAttrs->Put( SdrCaptionEscDirItem( nEscDir ) );
+
+ bEscRel = m_xLB_POSITION->get_visible();
+ _rOutAttrs->Put( SdrCaptionEscIsRelItem( bEscRel ) );
+
+ if( bEscRel )
+ {
+ tools::Long nVal = 0;
+
+ switch (m_xLB_POSITION->get_active())
+ {
+ case POS_TOP: nVal=0;break;
+ case POS_MIDDLE: nVal=5000;break;
+ case POS_BOTTOM: nVal=10000;break;
+ }
+ _rOutAttrs->Put( SdrCaptionEscRelItem( nVal ) );
+ }
+ else
+ {
+ if (m_xMF_BY->get_value_changed_from_saved())
+ {
+ eUnit = pPool->GetMetric( GetWhich( SDRATTR_CAPTIONESCABS ) );
+ _rOutAttrs->Put( SdrCaptionEscAbsItem( GetCoreValue(*m_xMF_BY, eUnit ) ) );
+ }
+ }
+
+ bFitLineLen = m_xCB_OPTIMAL->get_active();
+ _rOutAttrs->Put( SdrCaptionFitLineLenItem( bFitLineLen ) );
+
+ if( ! bFitLineLen )
+ {
+ if (m_xMF_LENGTH->get_value_changed_from_saved())
+ {
+ eUnit = pPool->GetMetric( GetWhich( SDRATTR_CAPTIONLINELEN ) );
+ _rOutAttrs->Put( SdrCaptionLineLenItem( GetCoreValue(*m_xMF_LENGTH, eUnit ) ) );
+ }
+ }
+
+//NYI-------------the angles have to be added here!!! XXX----------------------
+
+ return true;
+}
+
+void SvxCaptionTabPage::Reset( const SfxItemSet* )
+{
+
+ //------------set metric-----------------------------
+
+ FieldUnit eFUnit = GetModuleFieldUnit( rOutAttrs );
+
+ switch ( eFUnit )
+ {
+ case FieldUnit::CM:
+ case FieldUnit::M:
+ case FieldUnit::KM:
+ eFUnit = FieldUnit::MM;
+ break;
+ default: ;//prevent warning
+ }
+ SetFieldUnit( *m_xMF_SPACING, eFUnit );
+ SetFieldUnit( *m_xMF_BY, eFUnit );
+ SetFieldUnit( *m_xMF_LENGTH, eFUnit );
+
+ SfxItemPool* pPool = rOutAttrs.GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+
+ sal_uInt16 nWhich;
+ MapUnit eUnit;
+
+ nWhich = GetWhich( SDRATTR_CAPTIONESCABS );
+ eUnit = pPool->GetMetric( nWhich );
+ nEscAbs = static_cast<const SdrCaptionEscAbsItem&>( rOutAttrs.Get( nWhich ) ).GetValue();
+ SetMetricValue( *m_xMF_BY, nEscAbs, eUnit );
+ nEscAbs = m_xMF_BY->get_value(FieldUnit::NONE);
+
+ nWhich = GetWhich( SDRATTR_CAPTIONESCREL );
+ nEscRel = static_cast<tools::Long>(static_cast<const SdrCaptionEscRelItem&>( rOutAttrs.Get( nWhich ) ).GetValue());
+
+ //------- line length ----------
+ nWhich = GetWhich( SDRATTR_CAPTIONLINELEN );
+ eUnit = pPool->GetMetric( nWhich );
+ nLineLen = static_cast<const SdrCaptionLineLenItem&>( rOutAttrs.Get( nWhich ) ).GetValue();
+ SetMetricValue( *m_xMF_LENGTH, nLineLen, eUnit );
+ nLineLen = m_xMF_LENGTH->get_value(FieldUnit::NONE);
+
+ //------- distance to box ----------
+ nWhich = GetWhich( SDRATTR_CAPTIONGAP );
+ eUnit = pPool->GetMetric( nWhich );
+ nGap = static_cast<const SdrCaptionGapItem&>( rOutAttrs.Get( nWhich ) ).GetValue();
+ SetMetricValue( *m_xMF_SPACING, nGap, eUnit );
+ nGap = m_xMF_SPACING->get_value(FieldUnit::NONE);
+
+ nCaptionType = rOutAttrs.Get( GetWhich( SDRATTR_CAPTIONTYPE ) ).GetValue();
+ bFitLineLen = static_cast<const SfxBoolItem&>( rOutAttrs.Get( GetWhich( SDRATTR_CAPTIONFITLINELEN ) ) ).GetValue();
+ nEscDir = rOutAttrs.Get( GetWhich( SDRATTR_CAPTIONESCDIR ) ).GetValue();
+ bEscRel = static_cast<const SfxBoolItem&>( rOutAttrs.Get( GetWhich( SDRATTR_CAPTIONESCISREL ) ) ).GetValue();
+
+ // special treatment!!! XXX
+ if( nCaptionType==SdrCaptionType::Type1 )
+ {
+ switch( nEscDir )
+ {
+ case SdrCaptionEscDir::Horizontal: nEscDir=SdrCaptionEscDir::Vertical;break;
+ case SdrCaptionEscDir::Vertical: nEscDir=SdrCaptionEscDir::Horizontal;break;
+ default: break;
+ }
+ }
+
+ nPosition = POS_MIDDLE;
+ nExtension = EXT_OPTIMAL;
+
+ m_xMF_SPACING->set_value(nGap, FieldUnit::NONE);
+
+ if( nEscDir == SdrCaptionEscDir::Horizontal )
+ {
+ if( bEscRel )
+ {
+ if( nEscRel < 3333 )
+ nPosition = POS_TOP;
+ if( nEscRel > 6666 )
+ nPosition = POS_BOTTOM;
+ nExtension = EXT_HORIZONTAL;
+ }
+ else
+ {
+ nExtension = EXT_FROM_TOP;
+ m_xMF_BY->set_value(nEscAbs, FieldUnit::NONE);
+ }
+ }
+ else if( nEscDir == SdrCaptionEscDir::Vertical )
+ {
+ if( bEscRel )
+ {
+ if( nEscRel < 3333 )
+ nPosition = POS_TOP;
+ if( nEscRel > 6666 )
+ nPosition = POS_BOTTOM;
+ nExtension = EXT_VERTICAL;
+ }
+ else
+ {
+ nExtension = EXT_FROM_LEFT;
+ m_xMF_BY->set_value(nEscAbs, FieldUnit::NONE);
+ }
+ }
+ else if( nEscDir == SdrCaptionEscDir::BestFit )
+ {
+ nExtension = EXT_OPTIMAL;
+ }
+
+ m_xCB_OPTIMAL->set_active(bFitLineLen);
+ m_xMF_LENGTH->set_value(nLineLen, FieldUnit::NONE);
+
+ m_xLB_EXTENSION->set_active(nExtension);
+
+ SetupExtension_Impl( nExtension );
+ m_xCT_CAPTTYPE->SelectItem( static_cast<int>(nCaptionType)+1 ); // Enum starts at 0!
+ SetupType_Impl( nCaptionType );
+}
+
+std::unique_ptr<SfxTabPage> SvxCaptionTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rOutAttrs)
+{
+ return std::make_unique<SvxCaptionTabPage>(pPage, pController, *rOutAttrs);
+}
+
+void SvxCaptionTabPage::SetupExtension_Impl( sal_uInt16 nType )
+{
+ switch( nType )
+ {
+ case EXT_OPTIMAL:
+ m_xMF_BY->show();
+ m_xFT_BYFT->show();
+ m_xFT_POSITIONFT->hide();
+ m_xLB_POSITION->hide();
+ nEscDir = SdrCaptionEscDir::BestFit;
+ break;
+
+ case EXT_FROM_TOP:
+ m_xMF_BY->show();
+ m_xFT_BYFT->show();
+ m_xFT_POSITIONFT->hide();
+ m_xLB_POSITION->hide();
+ nEscDir = SdrCaptionEscDir::Horizontal;
+ break;
+
+ case EXT_FROM_LEFT:
+ m_xMF_BY->show();
+ m_xFT_BYFT->show();
+ m_xFT_POSITIONFT->hide();
+ m_xLB_POSITION->hide();
+ nEscDir = SdrCaptionEscDir::Vertical;
+ break;
+
+ case EXT_HORIZONTAL:
+ m_xLB_POSITION->clear();
+ for (const OUString & i : m_aStrHorzList)
+ m_xLB_POSITION->append_text(i);
+ m_xLB_POSITION->set_active(nPosition);
+
+ m_xMF_BY->hide();
+ m_xFT_BYFT->hide();
+ m_xFT_POSITIONFT->show();
+ m_xLB_POSITION->show();
+ nEscDir = SdrCaptionEscDir::Horizontal;
+ break;
+
+ case EXT_VERTICAL:
+ m_xLB_POSITION->clear();
+ for (const OUString & i : m_aStrVertList)
+ m_xLB_POSITION->append_text(i);
+ m_xLB_POSITION->set_active(nPosition);
+
+ m_xMF_BY->hide();
+ m_xFT_BYFT->hide();
+ m_xFT_POSITIONFT->show();
+ m_xLB_POSITION->show();
+ nEscDir = SdrCaptionEscDir::Vertical;
+ break;
+ }
+}
+
+IMPL_LINK(SvxCaptionTabPage, ExtensionSelectHdl_Impl, weld::ComboBox&, rListBox, void)
+{
+ if (&rListBox == m_xLB_EXTENSION.get())
+ {
+ SetupExtension_Impl(m_xLB_EXTENSION->get_active());
+ }
+}
+
+IMPL_LINK(SvxCaptionTabPage, PositionSelectHdl_Impl, weld::ComboBox&, rListBox, void)
+{
+ if (&rListBox == m_xLB_POSITION.get())
+ {
+ nPosition = m_xLB_POSITION->get_active();
+ }
+}
+
+IMPL_LINK( SvxCaptionTabPage, LineOptHdl_Impl, weld::Toggleable&, rButton, void )
+{
+ if (&rButton != m_xCB_OPTIMAL.get())
+ return;
+
+ if (m_xCB_OPTIMAL->get_active() || !m_xCB_OPTIMAL->get_sensitive())
+ {
+ m_xFT_LENGTHFT->set_sensitive(false);
+ m_xMF_LENGTH->set_sensitive(false);
+ }
+ else
+ {
+ m_xFT_LENGTHFT->set_sensitive(true);
+ m_xMF_LENGTH->set_sensitive(true);
+ }
+}
+
+IMPL_LINK_NOARG(SvxCaptionTabPage, SelectCaptTypeHdl_Impl, ValueSet*, void)
+{
+ SetupType_Impl( static_cast<SdrCaptionType>(m_xCT_CAPTTYPE->GetSelectedItemId()) );
+}
+
+void SvxCaptionTabPage::SetupType_Impl( SdrCaptionType nType )
+{
+ switch( nType )
+ {
+ case SdrCaptionType::Type1:
+ case SdrCaptionType::Type2:
+ m_xFT_LENGTHFT->set_sensitive(false);
+ m_xCB_OPTIMAL->set_sensitive(false);
+ LineOptHdl_Impl(*m_xCB_OPTIMAL);
+ break;
+ case SdrCaptionType::Type3:
+ case SdrCaptionType::Type4:
+ m_xFT_LENGTHFT->set_sensitive(true);
+ m_xCB_OPTIMAL->set_sensitive(true);
+ LineOptHdl_Impl(*m_xCB_OPTIMAL);
+ break;
+ }
+}
+
+void SvxCaptionTabPage::FillValueSet()
+{
+ m_xCT_CAPTTYPE->SetItemImage(BMP_CAPTTYPE_1, m_aBmpCapTypes[0] );
+ m_xCT_CAPTTYPE->SetItemImage(BMP_CAPTTYPE_2, m_aBmpCapTypes[1] );
+ m_xCT_CAPTTYPE->SetItemImage(BMP_CAPTTYPE_3, m_aBmpCapTypes[2] );
+}
+
+SvxCaptionTabDialog::SvxCaptionTabDialog(weld::Window* pParent, const SdrView* pSdrView,
+ SvxAnchorIds nAnchorTypes)
+ : SfxTabDialogController(pParent, "cui/ui/calloutdialog.ui", "CalloutDialog")
+ , pView(pSdrView)
+ , nAnchorCtrls(nAnchorTypes)
+{
+ assert(pView); // No valid View transferred!
+
+ //different positioning page in Writer
+ if (nAnchorCtrls & (SvxAnchorIds::Paragraph | SvxAnchorIds::Character | SvxAnchorIds::Page | SvxAnchorIds::Fly))
+ {
+ AddTabPage("RID_SVXPAGE_SWPOSSIZE", SvxSwPosSizeTabPage::Create,
+ SvxSwPosSizeTabPage::GetRanges );
+ RemoveTabPage("RID_SVXPAGE_POSITION_SIZE");
+ }
+ else
+ {
+ AddTabPage("RID_SVXPAGE_POSITION_SIZE", SvxPositionSizeTabPage::Create,
+ SvxPositionSizeTabPage::GetRanges );
+ RemoveTabPage("RID_SVXPAGE_SWPOSSIZE");
+ }
+ AddTabPage("RID_SVXPAGE_CAPTION", SvxCaptionTabPage::Create,
+ SvxCaptionTabPage::GetRanges );
+}
+
+void SvxCaptionTabDialog::PageCreated(const OUString& rId, SfxTabPage &rPage)
+{
+ if (rId == "RID_SVXPAGE_POSITION_SIZE")
+ {
+ static_cast<SvxPositionSizeTabPage&>( rPage ).SetView( pView );
+ static_cast<SvxPositionSizeTabPage&>( rPage ).Construct();
+ if( nAnchorCtrls & SvxAnchorIds::NoResize )
+ static_cast<SvxPositionSizeTabPage&>( rPage ).DisableResize();
+
+ if( nAnchorCtrls & SvxAnchorIds::NoProtect )
+ static_cast<SvxPositionSizeTabPage&>( rPage ).DisableProtect();
+ }
+ else if (rId == "RID_SVXPAGE_SWPOSSIZE")
+ {
+ SvxSwPosSizeTabPage& rSwPage = static_cast<SvxSwPosSizeTabPage&>(rPage);
+ rSwPage.EnableAnchorTypes(nAnchorCtrls);
+ rSwPage.SetValidateFramePosLink( aValidateLink );
+ }
+ else if (rId == "RID_SVXPAGE_CAPTION")
+ {
+ static_cast<SvxCaptionTabPage&>( rPage ).SetView( pView );
+ static_cast<SvxCaptionTabPage&>( rPage ).Construct();
+ }
+}
+
+void SvxCaptionTabDialog::SetValidateFramePosLink( const Link<SvxSwFrameValidation&,void>& rLink )
+{
+ aValidateLink = rLink;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/macroass.cxx b/cui/source/tabpages/macroass.cxx
new file mode 100644
index 0000000000..baff7c87b0
--- /dev/null
+++ b/cui/source/tabpages/macroass.cxx
@@ -0,0 +1,400 @@
+/* -*- 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 <macroass.hxx>
+#include <o3tl/safeint.hxx>
+#include <o3tl/string_view.hxx>
+#include <osl/diagnose.h>
+#include <comphelper/string.hxx>
+#include <comphelper/processfactory.hxx>
+#include <svl/macitem.hxx>
+#include <svx/svxids.hrc>
+#include <tools/debug.hxx>
+#include <vcl/idle.hxx>
+#include <cfgutil.hxx>
+#include <sfx2/evntconf.hxx>
+#include <headertablistbox.hxx>
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::frame::XFrame;
+
+class SfxMacroTabPage_Impl
+{
+public:
+ SfxMacroTabPage_Impl();
+
+ OUString m_aStaticMacroLBLabel;
+ std::unique_ptr<weld::Button> m_xAssignPB;
+ std::unique_ptr<weld::Button> m_xDeletePB;
+ std::unique_ptr<MacroEventListBox> m_xEventLB;
+ std::unique_ptr<weld::Widget> m_xGroupFrame;
+ std::unique_ptr<CuiConfigGroupListBox> m_xGroupLB;
+ std::unique_ptr<weld::Frame> m_xMacroFrame;
+ std::unique_ptr<CuiConfigFunctionListBox> m_xMacroLB;
+
+ Idle m_aFillGroupIdle { "cui SfxMacroTabPage m_aFillGroupIdle" };
+ bool m_bGotEvents;
+};
+
+SfxMacroTabPage_Impl::SfxMacroTabPage_Impl()
+ : m_bGotEvents(false)
+{
+}
+
+static sal_uInt16 aPageRg[] = {
+ SID_ATTR_MACROITEM, SID_ATTR_MACROITEM,
+ 0
+};
+
+static OUString ConvertToUIName_Impl( SvxMacro const *pMacro )
+{
+ OUString aName( pMacro->GetMacName() );
+ if ( pMacro->GetLanguage() != "JavaScript" )
+ {
+ const sal_Int32 nCount = comphelper::string::getTokenCount(aName, '.');
+ OUString aEntry = aName.getToken( nCount-1, '.' );
+ if ( nCount > 2 )
+ {
+ aEntry += OUString::Concat("(") + o3tl::getToken(aName, 0, '.' ) + "." + o3tl::getToken(aName, nCount-2, '.' ) + ")";
+ }
+ return aEntry;
+ }
+ else
+ return aName;
+}
+
+void SfxMacroTabPage::EnableButtons()
+{
+ // don't do anything as long as the eventbox is empty
+ weld::TreeView& rTreeView = mpImpl->m_xEventLB->GetListBox();
+ int nSelected = rTreeView.get_selected_index();
+ if (nSelected != -1)
+ {
+ // get bound macro
+ const SvxMacro* pM = aTbl.Get(static_cast<SvMacroItemId>(rTreeView.get_selected_id().toInt32()));
+ mpImpl->m_xDeletePB->set_sensitive(nullptr != pM);
+
+ OUString sEventMacro = rTreeView.get_text(nSelected, 1);
+
+ OUString sScriptURI = mpImpl->m_xMacroLB->GetSelectedScriptURI();
+ mpImpl->m_xAssignPB->set_sensitive(!sScriptURI.equalsIgnoreAsciiCase(sEventMacro));
+ }
+ else
+ mpImpl->m_xAssignPB->set_sensitive(false);
+}
+
+SfxMacroTabPage::SfxMacroTabPage(weld::Container* pPage, weld::DialogController* pController, const Reference< XFrame >& rxDocumentFrame, const SfxItemSet& rAttrSet )
+ : SfxTabPage(pPage, pController, "cui/ui/eventassignpage.ui", "EventAssignPage", &rAttrSet)
+{
+ mpImpl.reset(new SfxMacroTabPage_Impl);
+
+ mpImpl->m_aFillGroupIdle.SetInvokeHandler( LINK( this, SfxMacroTabPage, TimeOut_Impl ) );
+ mpImpl->m_aFillGroupIdle.SetPriority( TaskPriority::HIGHEST );
+
+ mpImpl->m_xEventLB.reset(new MacroEventListBox(m_xBuilder->weld_tree_view("assignments")));
+ mpImpl->m_xAssignPB = m_xBuilder->weld_button("assign");
+ mpImpl->m_xDeletePB = m_xBuilder->weld_button("delete");
+ mpImpl->m_xGroupFrame = m_xBuilder->weld_widget("groupframe");
+ mpImpl->m_xGroupLB.reset(new CuiConfigGroupListBox(m_xBuilder->weld_tree_view("libraries")));
+ mpImpl->m_xMacroFrame = m_xBuilder->weld_frame("macroframe");
+ mpImpl->m_aStaticMacroLBLabel = mpImpl->m_xMacroFrame->get_label();
+ mpImpl->m_xMacroLB.reset(new CuiConfigFunctionListBox(m_xBuilder->weld_tree_view("macros")));
+
+ SetFrame( rxDocumentFrame );
+
+ InitAndSetHandler();
+
+ ScriptChanged();
+}
+
+SfxMacroTabPage::~SfxMacroTabPage()
+{
+ mpImpl.reset();
+}
+
+void SfxMacroTabPage::AddEvent(const OUString& rEventName, SvMacroItemId nEventId)
+{
+ weld::TreeView& rTreeView = mpImpl->m_xEventLB->GetListBox();
+ rTreeView.append(OUString::number(static_cast<sal_Int32>(nEventId)), rEventName);
+
+ // if the table is valid already
+ SvxMacro* pM = aTbl.Get(nEventId);
+ if (pM)
+ {
+ OUString sNew(ConvertToUIName_Impl(pM));
+ rTreeView.set_text(rTreeView.n_children() - 1, sNew, 1);
+ }
+}
+
+void SfxMacroTabPage::ScriptChanged()
+{
+ // get new areas and their functions
+ mpImpl->m_xGroupFrame->show();
+ mpImpl->m_xMacroFrame->show();
+
+ EnableButtons();
+}
+
+bool SfxMacroTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ SvxMacroItem aItem( GetWhich( aPageRg[0] ) );
+ const_cast<SvxMacroTableDtor&>(aItem.GetMacroTable()) = aTbl;
+
+ const SfxPoolItem* pItem = nullptr;
+ SfxItemState eState = GetItemSet().GetItemState(aItem.Which(), true, &pItem);
+ if (eState == SfxItemState::DEFAULT && aTbl.empty())
+ {
+ // Don't touch the item set if there was no input and our table is empty.
+ return false;
+ }
+ if (SfxItemState::SET != eState || aItem != *static_cast<const SvxMacroItem*>(pItem))
+ {
+ rSet->Put( aItem );
+ return true;
+ }
+ return false;
+}
+
+void SfxMacroTabPage::LaunchFillGroup()
+{
+ if (! mpImpl->m_aFillGroupIdle.IsActive() )
+ mpImpl->m_aFillGroupIdle.Start();
+}
+
+void SfxMacroTabPage::ActivatePage( const SfxItemSet& )
+{
+ LaunchFillGroup();
+}
+
+void SfxMacroTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ if( mpImpl->m_bGotEvents )
+ return;
+ if( const SfxEventNamesItem* pEventsItem = aSet.GetItemIfSet( SID_EVENTCONFIG ) )
+ {
+ mpImpl->m_bGotEvents = true;
+ const SfxEventNamesList& rList = pEventsItem->GetEvents();
+ for ( size_t nNo = 0, nCnt = rList.size(); nNo < nCnt; ++nNo )
+ {
+ const SfxEventName &rOwn = rList.at(nNo);
+ AddEvent( rOwn.maUIName, rOwn.mnId );
+ }
+ }
+}
+
+void SfxMacroTabPage::Reset( const SfxItemSet* rSet )
+{
+ const SfxPoolItem* pItem;
+ if( SfxItemState::SET == rSet->GetItemState( GetWhich( aPageRg[0] ), true, &pItem ))
+ aTbl = static_cast<const SvxMacroItem*>(pItem)->GetMacroTable();
+
+ const SfxEventNamesItem* pEventsItem;
+ if( !mpImpl->m_bGotEvents && (pEventsItem = rSet->GetItemIfSet( SID_EVENTCONFIG ) ) )
+ {
+ mpImpl->m_bGotEvents = true;
+ const SfxEventNamesList& rList = pEventsItem->GetEvents();
+ for ( size_t nNo = 0, nCnt = rList.size(); nNo < nCnt; ++nNo )
+ {
+ const SfxEventName &rOwn = rList.at(nNo);
+ AddEvent( rOwn.maUIName, rOwn.mnId );
+ }
+ }
+
+ FillEvents();
+
+ weld::TreeView& rListBox = mpImpl->m_xEventLB->GetListBox();
+ std::unique_ptr<weld::TreeIter> xIter(rListBox.make_iterator());
+ if (rListBox.get_iter_first(*xIter))
+ {
+ rListBox.set_cursor(*xIter);
+ EnableButtons();
+ }
+}
+
+bool SfxMacroTabPage::IsReadOnly() const
+{
+ return false;
+}
+
+IMPL_LINK_NOARG(SfxMacroTabPage, SelectEvent_Impl, weld::TreeView&, void)
+{
+ weld::TreeView& rListBox = mpImpl->m_xEventLB->GetListBox();
+ int nSelected = rListBox.get_selected_index();
+ if (nSelected == -1)
+ {
+ DBG_ASSERT(nSelected != -1, "Where does the empty entry come from?");
+ return;
+ }
+
+ ScriptChanged();
+ EnableButtons();
+}
+
+IMPL_LINK_NOARG(SfxMacroTabPage, SelectGroup_Impl, weld::TreeView&, void)
+{
+ mpImpl->m_xGroupLB->GroupSelected();
+ const OUString sScriptURI = mpImpl->m_xMacroLB->GetSelectedScriptURI();
+ OUString aLabelText;
+ if( !sScriptURI.isEmpty() )
+ aLabelText = mpImpl->m_aStaticMacroLBLabel;
+ mpImpl->m_xMacroFrame->set_label( aLabelText );
+
+ EnableButtons();
+}
+
+IMPL_LINK_NOARG(SfxMacroTabPage, SelectMacro_Impl, weld::TreeView&, void)
+{
+ EnableButtons();
+}
+
+IMPL_LINK(SfxMacroTabPage, AssignDeleteClickHdl_Impl, weld::Button&, rBtn, void)
+{
+ AssignDeleteHdl(&rBtn);
+}
+
+IMPL_LINK(SfxMacroTabPage, AssignDeleteHdl_Impl, weld::TreeView&, rBtn, bool)
+{
+ AssignDeleteHdl(&rBtn);
+ return true;
+}
+
+void SfxMacroTabPage::AssignDeleteHdl(const weld::Widget* pBtn)
+{
+ weld::TreeView& rListBox = mpImpl->m_xEventLB->GetListBox();
+ int nSelected = rListBox.get_selected_index();
+ if (nSelected == -1)
+ {
+ DBG_ASSERT(nSelected != -1, "Where does the empty entry come from?");
+ return;
+ }
+
+ const bool bAssEnabled = pBtn != mpImpl->m_xDeletePB.get() && mpImpl->m_xAssignPB->get_sensitive();
+
+ // remove from the table
+ SvMacroItemId nEvent = static_cast<SvMacroItemId>(rListBox.get_selected_id().toInt32());
+ aTbl.Erase( nEvent );
+
+ OUString sScriptURI;
+ if( bAssEnabled )
+ {
+ sScriptURI = mpImpl->m_xMacroLB->GetSelectedScriptURI();
+ if( sScriptURI.startsWith( "vnd.sun.star.script:" ) )
+ {
+ aTbl.Insert(
+ nEvent, SvxMacro( sScriptURI, SVX_MACRO_LANGUAGE_SF ) );
+ }
+ else
+ {
+ OSL_ENSURE( false, "SfxMacroTabPage::AssignDeleteHdl_Impl: this branch is *not* dead? (out of interest: tell fs, please!)" );
+ aTbl.Insert(
+ nEvent, SvxMacro( sScriptURI, SVX_MACRO_LANGUAGE_STARBASIC ) );
+ }
+ }
+
+ rListBox.set_text(nSelected, sScriptURI, 1);
+
+ EnableButtons();
+}
+
+IMPL_LINK( SfxMacroTabPage, TimeOut_Impl, Timer*,, void )
+{
+ // FillMacroList() can take a long time -> show wait cursor and disable input
+ weld::Window* pDialog = GetFrameWeld();
+ // perhaps the tabpage is part of a SingleTabDialog then pDialog == nullptr
+ std::unique_ptr<weld::WaitObject> xWait(pDialog ? new weld::WaitObject(pDialog) : nullptr);
+ // fill macro list
+ mpImpl->m_xGroupLB->Init(comphelper::getProcessComponentContext(), GetFrame(),
+ OUString(), false);
+}
+
+void SfxMacroTabPage::InitAndSetHandler()
+{
+ weld::TreeView& rListBox = mpImpl->m_xEventLB->GetListBox();
+ Link<weld::TreeView&,bool> aLnk(LINK(this, SfxMacroTabPage, AssignDeleteHdl_Impl));
+ mpImpl->m_xMacroLB->connect_row_activated( aLnk);
+ mpImpl->m_xDeletePB->connect_clicked(LINK(this, SfxMacroTabPage, AssignDeleteClickHdl_Impl));
+ mpImpl->m_xAssignPB->connect_clicked(LINK(this, SfxMacroTabPage, AssignDeleteClickHdl_Impl));
+ rListBox.connect_row_activated(aLnk);
+
+ rListBox.connect_changed(LINK(this, SfxMacroTabPage, SelectEvent_Impl));
+ mpImpl->m_xGroupLB->connect_changed(LINK(this, SfxMacroTabPage, SelectGroup_Impl));
+ mpImpl->m_xMacroLB->connect_changed(LINK(this, SfxMacroTabPage, SelectMacro_Impl));
+
+ std::vector<int> aWidths
+ {
+ o3tl::narrowing<int>(rListBox.get_approximate_digit_width() * 35)
+ };
+ rListBox.set_column_fixed_widths(aWidths);
+
+ mpImpl->m_xEventLB->show();
+
+ mpImpl->m_xEventLB->set_sensitive(true);
+ mpImpl->m_xGroupLB->set_sensitive(true);
+ mpImpl->m_xMacroLB->set_sensitive(true);
+
+ mpImpl->m_xGroupLB->SetFunctionListBox(mpImpl->m_xMacroLB.get());
+}
+
+void SfxMacroTabPage::FillEvents()
+{
+ weld::TreeView& rListBox = mpImpl->m_xEventLB->GetListBox();
+
+ int nEntryCnt = rListBox.n_children();
+
+ // get events from the table and fill the EventListBox respectively
+ for (int n = 0 ; n < nEntryCnt; ++n)
+ {
+ OUString sOld = rListBox.get_text(n, 1);
+ OUString sNew;
+ SvMacroItemId nEventId = static_cast<SvMacroItemId>(rListBox.get_id(n).toInt32());
+ if (aTbl.IsKeyValid(nEventId))
+ sNew = ConvertToUIName_Impl(aTbl.Get(nEventId));
+
+ if (sOld == sNew)
+ continue;
+
+ rListBox.set_text(n, sNew, 1);
+ }
+}
+
+namespace
+{
+ std::unique_ptr<SfxMacroTabPage> CreateSfxMacroTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttrSet)
+ {
+ return std::make_unique<SfxMacroTabPage>( pPage, pController, nullptr, rAttrSet );
+ }
+}
+
+std::unique_ptr<SfxTabPage> SfxMacroTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+{
+ return CreateSfxMacroTabPage(pPage, pController, *rAttrSet);
+}
+
+SfxMacroAssignDlg::SfxMacroAssignDlg(weld::Widget* pParent,
+ const Reference< XFrame >& rxDocumentFrame, const SfxItemSet& rSet)
+ : SfxSingleTabDialogController(pParent, &rSet,"cui/ui/eventassigndialog.ui",
+ "EventAssignDialog")
+{
+ std::unique_ptr<SfxMacroTabPage> xPage = CreateSfxMacroTabPage(get_content_area(), this, rSet);
+ xPage->SetFrame(rxDocumentFrame);
+ SetTabPage(std::move(xPage));
+ GetTabPage()->LaunchFillGroup();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/measure.cxx b/cui/source/tabpages/measure.cxx
new file mode 100644
index 0000000000..fe61ed53ab
--- /dev/null
+++ b/cui/source/tabpages/measure.cxx
@@ -0,0 +1,755 @@
+/* -*- 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 <strings.hrc>
+#include <dialmgr.hxx>
+
+#include <svx/svxids.hrc>
+#include <svx/dlgutil.hxx>
+#include <svx/measctrl.hxx>
+#include <svx/ofaitem.hxx>
+#include <svx/strarray.hxx>
+#include <svx/svdview.hxx>
+#include <svx/sxmbritm.hxx>
+#include <svx/sxmlhitm.hxx>
+#include <svx/sxmtfitm.hxx>
+#include <svx/sxmtpitm.hxx>
+#include <svx/sxmtritm.hxx>
+#include <svx/sxmuitm.hxx>
+#include <svtools/unitconv.hxx>
+
+#include <measure.hxx>
+
+const WhichRangesContainer SvxMeasurePage::pRanges(
+ svl::Items<SDRATTR_MEASURE_FIRST, SDRATTR_MEASURE_LAST>);
+
+/*************************************************************************
+|*
+|* Dialog to change measure-attributes
+|*
+\************************************************************************/
+SvxMeasureDialog::SvxMeasureDialog(weld::Window* pParent, const SfxItemSet& rInAttrs,
+ const SdrView* pSdrView)
+ : SfxSingleTabDialogController(pParent, &rInAttrs)
+{
+ auto xPage = std::make_unique<SvxMeasurePage>(get_content_area(), this, rInAttrs);
+
+ xPage->SetView(pSdrView);
+ xPage->Construct();
+
+ SetTabPage(std::move(xPage));
+ m_xDialog->set_title(CuiResId(RID_CUISTR_DIMENSION_LINE));
+}
+
+/*************************************************************************
+|*
+|* Tabpage for changing measure-attributes
+|*
+\************************************************************************/
+
+SvxMeasurePage::SvxMeasurePage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SvxTabPage(pPage, pController, "cui/ui/dimensionlinestabpage.ui", "DimensionLinesTabPage", rInAttrs)
+ , rOutAttrs(rInAttrs)
+ , aAttrSet(*rInAttrs.GetPool())
+ , pView(nullptr)
+ , eUnit(MapUnit::Map100thMM)
+ , bPositionModified(false)
+ , m_aCtlPosition(this)
+ , m_xMtrFldLineDist(m_xBuilder->weld_metric_spin_button("MTR_LINE_DIST", FieldUnit::MM))
+ , m_xMtrFldHelplineOverhang(m_xBuilder->weld_metric_spin_button("MTR_FLD_HELPLINE_OVERHANG", FieldUnit::MM))
+ , m_xMtrFldHelplineDist(m_xBuilder->weld_metric_spin_button("MTR_FLD_HELPLINE_DIST", FieldUnit::MM))
+ , m_xMtrFldHelpline1Len(m_xBuilder->weld_metric_spin_button("MTR_FLD_HELPLINE1_LEN", FieldUnit::MM))
+ , m_xMtrFldHelpline2Len(m_xBuilder->weld_metric_spin_button("MTR_FLD_HELPLINE2_LEN", FieldUnit::MM))
+ , m_xTsbBelowRefEdge(m_xBuilder->weld_check_button("TSB_BELOW_REF_EDGE"))
+ , m_xMtrFldDecimalPlaces(m_xBuilder->weld_spin_button("MTR_FLD_DECIMALPLACES"))
+ , m_xTsbAutoPosV(m_xBuilder->weld_check_button("TSB_AUTOPOSV"))
+ , m_xTsbAutoPosH(m_xBuilder->weld_check_button("TSB_AUTOPOSH"))
+ , m_xTsbShowUnit(m_xBuilder->weld_check_button("TSB_SHOW_UNIT"))
+ , m_xLbUnit(m_xBuilder->weld_combo_box("LB_UNIT"))
+ , m_xTsbParallel(m_xBuilder->weld_check_button("TSB_PARALLEL"))
+ , m_xFtAutomatic(m_xBuilder->weld_label("STR_MEASURE_AUTOMATIC"))
+ , m_xCtlPosition(new weld::CustomWeld(*m_xBuilder, "CTL_POSITION", m_aCtlPosition))
+ , m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, "CTL_PREVIEW", m_aCtlPreview))
+{
+ m_aCtlPreview.SetAttributes(rInAttrs);
+
+ FillUnitLB();
+
+ const FieldUnit eFUnit = GetModuleFieldUnit( rInAttrs );
+ SetFieldUnit( *m_xMtrFldLineDist, eFUnit );
+ SetFieldUnit( *m_xMtrFldHelplineOverhang, eFUnit );
+ SetFieldUnit( *m_xMtrFldHelplineDist, eFUnit );
+ SetFieldUnit( *m_xMtrFldHelpline1Len, eFUnit );
+ SetFieldUnit( *m_xMtrFldHelpline2Len, eFUnit );
+ if( eFUnit == FieldUnit::MM )
+ {
+ m_xMtrFldLineDist->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrFldHelplineOverhang->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrFldHelplineDist->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrFldHelpline1Len->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrFldHelpline2Len->set_increments(50, 500, FieldUnit::NONE);
+ }
+
+ m_xTsbAutoPosV->connect_toggled(LINK( this, SvxMeasurePage, ClickAutoPosHdl_Impl));
+ m_xTsbAutoPosH->connect_toggled(LINK(this, SvxMeasurePage, ClickAutoPosHdl_Impl));
+
+ Link<weld::MetricSpinButton&,void> aLink(LINK(this, SvxMeasurePage, ChangeAttrEditHdl_Impl));
+ m_xMtrFldLineDist->set_range(-10000, 10000, FieldUnit::MM);
+ m_xMtrFldLineDist->connect_value_changed(aLink);
+ m_xMtrFldHelplineOverhang->connect_value_changed(aLink);
+ m_xMtrFldHelplineOverhang->set_range(-10000, 10000, FieldUnit::MM);
+ m_xMtrFldHelplineDist->connect_value_changed(aLink);
+ m_xMtrFldHelplineDist->set_range(-10000, 10000, FieldUnit::MM);
+ m_xMtrFldHelpline1Len->connect_value_changed(aLink);
+ m_xMtrFldHelpline1Len->set_range(-10000, 10000, FieldUnit::MM);
+ m_xMtrFldHelpline2Len->connect_value_changed(aLink);
+ m_xMtrFldHelpline2Len->set_range(-10000, 10000, FieldUnit::MM);
+ m_xMtrFldDecimalPlaces->connect_value_changed(LINK(this, SvxMeasurePage, ChangeAttrSpinHdl_Impl));
+ m_xTsbBelowRefEdge->connect_toggled(LINK(this, SvxMeasurePage, ChangeAttrClickHdl_Impl));
+ m_xTsbParallel->connect_toggled( LINK( this, SvxMeasurePage, ChangeAttrClickHdl_Impl));
+ m_xTsbShowUnit->connect_toggled(LINK(this, SvxMeasurePage, ChangeAttrClickHdl_Impl));
+ m_xLbUnit->connect_changed(LINK(this, SvxMeasurePage, ChangeAttrListBoxHdl_Impl));
+}
+
+SvxMeasurePage::~SvxMeasurePage()
+{
+ m_xCtlPreview.reset();
+ m_xCtlPosition.reset();
+}
+
+/*************************************************************************
+|*
+|* read the delivered Item-Set
+|*
+\************************************************************************/
+
+void SvxMeasurePage::Reset( const SfxItemSet* rAttrs )
+{
+ SfxItemPool* pPool = rAttrs->GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ eUnit = pPool->GetMetric( SDRATTR_MEASURELINEDIST );
+
+ const SfxPoolItem* pItem = GetItem( *rAttrs, SDRATTR_MEASURELINEDIST );
+
+ // SdrMeasureLineDistItem
+ if( pItem == nullptr )
+ pItem = &pPool->GetDefaultItem( SDRATTR_MEASURELINEDIST );
+ SetMetricValue(*m_xMtrFldLineDist, static_cast<const SdrMetricItem*>(pItem)->GetValue(), eUnit);
+ m_xMtrFldLineDist->save_value();
+
+ // SdrMeasureHelplineOverhangItem
+ pItem = GetItem( *rAttrs, SDRATTR_MEASUREHELPLINEOVERHANG );
+ if( pItem == nullptr )
+ pItem = &pPool->GetDefaultItem( SDRATTR_MEASUREHELPLINEOVERHANG );
+ SetMetricValue(*m_xMtrFldHelplineOverhang, static_cast<const SdrMetricItem*>(pItem)->GetValue(),
+ eUnit);
+ m_xMtrFldHelplineOverhang->save_value();
+
+ // SdrMeasureHelplineDistItem
+ pItem = GetItem( *rAttrs, SDRATTR_MEASUREHELPLINEDIST );
+ if( pItem == nullptr )
+ pItem = &pPool->GetDefaultItem( SDRATTR_MEASUREHELPLINEDIST );
+ SetMetricValue(*m_xMtrFldHelplineDist, static_cast<const SdrMetricItem*>(pItem)->GetValue(),
+ eUnit);
+ m_xMtrFldHelplineDist->save_value();
+
+ // SdrMeasureHelpline1LenItem
+ pItem = GetItem( *rAttrs, SDRATTR_MEASUREHELPLINE1LEN );
+ if( pItem == nullptr )
+ pItem = &pPool->GetDefaultItem( SDRATTR_MEASUREHELPLINE1LEN );
+ SetMetricValue(*m_xMtrFldHelpline1Len, static_cast<const SdrMetricItem*>(pItem)->GetValue(),
+ eUnit);
+ m_xMtrFldHelpline1Len->save_value();
+
+ // SdrMeasureHelpline2LenItem
+ pItem = GetItem( *rAttrs, SDRATTR_MEASUREHELPLINE2LEN );
+ if( pItem == nullptr )
+ pItem = &pPool->GetDefaultItem( SDRATTR_MEASUREHELPLINE2LEN );
+ SetMetricValue(*m_xMtrFldHelpline2Len, static_cast<const SdrMetricItem*>(pItem)->GetValue(),
+ eUnit);
+ m_xMtrFldHelpline2Len->save_value();
+
+ // SdrMeasureBelowRefEdgeItem
+ if( rAttrs->GetItemState( SDRATTR_MEASUREBELOWREFEDGE ) != SfxItemState::DONTCARE )
+ {
+ m_xTsbBelowRefEdge->set_state( rAttrs->Get( SDRATTR_MEASUREBELOWREFEDGE ).
+ GetValue() ? TRISTATE_TRUE : TRISTATE_FALSE );
+ }
+ else
+ {
+ m_xTsbBelowRefEdge->set_state( TRISTATE_INDET );
+ }
+ m_xTsbBelowRefEdge->save_state();
+
+ // SdrMeasureDecimalPlacesItem
+ pItem = GetItem( *rAttrs, SDRATTR_MEASUREDECIMALPLACES );
+ if( pItem == nullptr )
+ pItem = &pPool->GetDefaultItem( SDRATTR_MEASUREDECIMALPLACES );
+ m_xMtrFldDecimalPlaces->set_value(
+ static_cast<const SdrMeasureDecimalPlacesItem*>(pItem)->GetValue());
+ m_xMtrFldDecimalPlaces->save_value();
+
+ // SdrMeasureTextRota90Item
+ // Attention: negate !
+ if( rAttrs->GetItemState( SDRATTR_MEASURETEXTROTA90 ) != SfxItemState::DONTCARE )
+ {
+ m_xTsbParallel->set_state( rAttrs->Get( SDRATTR_MEASURETEXTROTA90 ).
+ GetValue() ? TRISTATE_FALSE : TRISTATE_TRUE );
+ }
+ else
+ {
+ m_xTsbParallel->set_state( TRISTATE_INDET );
+ }
+ m_xTsbParallel->save_state();
+
+ // SdrMeasureShowUnitItem
+ if( rAttrs->GetItemState( SDRATTR_MEASURESHOWUNIT ) != SfxItemState::DONTCARE )
+ {
+ m_xTsbShowUnit->set_state( rAttrs->Get( SDRATTR_MEASURESHOWUNIT ).
+ GetValue() ? TRISTATE_TRUE : TRISTATE_FALSE );
+ }
+ else
+ {
+ m_xTsbShowUnit->set_state( TRISTATE_INDET );
+ }
+ m_xTsbShowUnit->save_state();
+
+ // SdrMeasureUnitItem
+ if( rAttrs->GetItemState( SDRATTR_MEASUREUNIT ) != SfxItemState::DONTCARE )
+ {
+ tools::Long nFieldUnit = static_cast<tools::Long>(rAttrs->Get( SDRATTR_MEASUREUNIT ).GetValue());
+
+ for (sal_Int32 i = 0; i < m_xLbUnit->get_count(); ++i)
+ {
+ if (m_xLbUnit->get_id(i).toInt32() == nFieldUnit)
+ {
+ m_xLbUnit->set_active(i);
+ break;
+ }
+ }
+ }
+ else
+ {
+ m_xLbUnit->set_active(-1);
+ }
+ m_xLbUnit->save_value();
+
+ // Position
+ if ( rAttrs->GetItemState( SDRATTR_MEASURETEXTVPOS ) != SfxItemState::DONTCARE )
+ {
+ css::drawing::MeasureTextVertPos eVPos =
+ rAttrs->Get( SDRATTR_MEASURETEXTVPOS ).GetValue();
+ {
+ if ( rAttrs->GetItemState( SDRATTR_MEASURETEXTHPOS ) != SfxItemState::DONTCARE )
+ {
+ css::drawing::MeasureTextHorzPos eHPos =
+ rAttrs->Get( SDRATTR_MEASURETEXTHPOS ).GetValue();
+ RectPoint eRP = RectPoint::MM;
+ switch( eVPos )
+ {
+ case css::drawing::MeasureTextVertPos_EAST:
+ switch( eHPos )
+ {
+ case css::drawing::MeasureTextHorzPos_LEFTOUTSIDE: eRP = RectPoint::LT; break;
+ case css::drawing::MeasureTextHorzPos_INSIDE: eRP = RectPoint::MT; break;
+ case css::drawing::MeasureTextHorzPos_RIGHTOUTSIDE: eRP = RectPoint::RT; break;
+ case css::drawing::MeasureTextHorzPos_AUTO: eRP = RectPoint::MT; break;
+ default: break;
+ }
+ break;
+ case css::drawing::MeasureTextVertPos_CENTERED:
+ switch( eHPos )
+ {
+ case css::drawing::MeasureTextHorzPos_LEFTOUTSIDE: eRP = RectPoint::LM; break;
+ case css::drawing::MeasureTextHorzPos_INSIDE: eRP = RectPoint::MM; break;
+ case css::drawing::MeasureTextHorzPos_RIGHTOUTSIDE: eRP = RectPoint::RM; break;
+ case css::drawing::MeasureTextHorzPos_AUTO: eRP = RectPoint::MM; break;
+ default: break;
+ }
+ break;
+ case css::drawing::MeasureTextVertPos_WEST:
+ switch( eHPos )
+ {
+ case css::drawing::MeasureTextHorzPos_LEFTOUTSIDE: eRP = RectPoint::LB; break;
+ case css::drawing::MeasureTextHorzPos_INSIDE: eRP = RectPoint::MB; break;
+ case css::drawing::MeasureTextHorzPos_RIGHTOUTSIDE: eRP = RectPoint::RB; break;
+ case css::drawing::MeasureTextHorzPos_AUTO: eRP = RectPoint::MB; break;
+ default: break;
+ }
+ break;
+ case css::drawing::MeasureTextVertPos_AUTO:
+ switch( eHPos )
+ {
+ case css::drawing::MeasureTextHorzPos_LEFTOUTSIDE: eRP = RectPoint::LM; break;
+ case css::drawing::MeasureTextHorzPos_INSIDE: eRP = RectPoint::MM; break;
+ case css::drawing::MeasureTextHorzPos_RIGHTOUTSIDE: eRP = RectPoint::RM; break;
+ case css::drawing::MeasureTextHorzPos_AUTO: eRP = RectPoint::MM; break;
+ default: break;
+ }
+ break;
+ default: ;//prevent warning
+ }
+
+ CTL_STATE nState = CTL_STATE::NONE;
+
+ if (eHPos == css::drawing::MeasureTextHorzPos_AUTO)
+ {
+ m_xTsbAutoPosH->set_state( TRISTATE_TRUE );
+ nState = CTL_STATE::NOHORZ;
+ }
+
+ if (eVPos == css::drawing::MeasureTextVertPos_AUTO)
+ {
+ m_xTsbAutoPosV->set_state( TRISTATE_TRUE );
+ nState |= CTL_STATE::NOVERT;
+ }
+
+ m_aCtlPosition.SetState(nState);
+ m_aCtlPosition.SetActualRP(eRP);
+ }
+ }
+ }
+ else
+ {
+ m_aCtlPosition.Reset();
+ m_xTsbAutoPosV->set_state( TRISTATE_INDET );
+ m_xTsbAutoPosH->set_state( TRISTATE_INDET );
+ }
+
+ // put the attributes to the preview-control,
+ // otherwise the control don't know about
+ // the settings of the dialog (#67930)
+ ChangeAttrHdl_Impl(m_xTsbShowUnit.get());
+ m_aCtlPreview.SetAttributes(*rAttrs);
+
+ bPositionModified = false;
+}
+
+/*************************************************************************
+|*
+|* Fill the delivered Item-Set with dialogbox-attributes
+|*
+\************************************************************************/
+
+bool SvxMeasurePage::FillItemSet( SfxItemSet* rAttrs)
+{
+ bool bModified = false;
+ sal_Int32 nValue;
+ TriState eState;
+
+ if( m_xMtrFldLineDist->get_value_changed_from_saved() )
+ {
+ nValue = GetCoreValue( *m_xMtrFldLineDist, eUnit );
+ rAttrs->Put( makeSdrMeasureLineDistItem( nValue ) );
+ bModified = true;
+ }
+
+ if( m_xMtrFldHelplineOverhang->get_value_changed_from_saved() )
+ {
+ nValue = GetCoreValue( *m_xMtrFldHelplineOverhang, eUnit );
+ rAttrs->Put( makeSdrMeasureHelplineOverhangItem( nValue ) );
+ bModified = true;
+ }
+
+ if( m_xMtrFldHelplineDist->get_value_changed_from_saved() )
+ {
+ nValue = GetCoreValue( *m_xMtrFldHelplineDist, eUnit );
+ rAttrs->Put( makeSdrMeasureHelplineDistItem( nValue ) );
+ bModified = true;
+ }
+
+ if( m_xMtrFldHelpline1Len->get_value_changed_from_saved() )
+ {
+ nValue = GetCoreValue( *m_xMtrFldHelpline1Len, eUnit );
+ rAttrs->Put( makeSdrMeasureHelpline1LenItem( nValue ) );
+ bModified = true;
+ }
+
+ if( m_xMtrFldHelpline2Len->get_value_changed_from_saved() )
+ {
+ nValue = GetCoreValue( *m_xMtrFldHelpline2Len, eUnit );
+ rAttrs->Put( makeSdrMeasureHelpline2LenItem( nValue ) );
+ bModified = true;
+ }
+
+ eState = m_xTsbBelowRefEdge->get_state();
+ if( m_xTsbBelowRefEdge->get_state_changed_from_saved() )
+ {
+ rAttrs->Put( SdrMeasureBelowRefEdgeItem( TRISTATE_TRUE == eState ) );
+ bModified = true;
+ }
+
+ if( m_xMtrFldDecimalPlaces->get_value_changed_from_saved() )
+ {
+ nValue = m_xMtrFldDecimalPlaces->get_value();
+ rAttrs->Put(
+ SdrMeasureDecimalPlacesItem(
+ sal::static_int_cast< sal_Int16 >( nValue ) ) );
+ bModified = true;
+ }
+
+ eState = m_xTsbParallel->get_state();
+ if( m_xTsbParallel->get_state_changed_from_saved() )
+ {
+ rAttrs->Put( SdrMeasureTextRota90Item( TRISTATE_FALSE == eState ) );
+ bModified = true;
+ }
+
+ eState = m_xTsbShowUnit->get_state();
+ if( m_xTsbShowUnit->get_state_changed_from_saved() )
+ {
+ rAttrs->Put( SdrYesNoItem(SDRATTR_MEASURESHOWUNIT, TRISTATE_TRUE == eState ) );
+ bModified = true;
+ }
+
+ int nPos = m_xLbUnit->get_active();
+ if( m_xLbUnit->get_value_changed_from_saved() )
+ {
+ if (nPos != -1)
+ {
+ sal_uInt16 nFieldUnit = m_xLbUnit->get_id(nPos).toUInt32();
+ FieldUnit _eUnit = static_cast<FieldUnit>(nFieldUnit);
+ rAttrs->Put( SdrMeasureUnitItem( _eUnit ) );
+ bModified = true;
+ }
+ }
+
+ if( bPositionModified )
+ {
+ // Position
+ css::drawing::MeasureTextVertPos eVPos;
+ css::drawing::MeasureTextHorzPos eHPos;
+
+ RectPoint eRP = m_aCtlPosition.GetActualRP();
+ switch( eRP )
+ {
+ default:
+ case RectPoint::LT: eVPos = css::drawing::MeasureTextVertPos_EAST;
+ eHPos = css::drawing::MeasureTextHorzPos_LEFTOUTSIDE; break;
+ case RectPoint::LM: eVPos = css::drawing::MeasureTextVertPos_CENTERED;
+ eHPos = css::drawing::MeasureTextHorzPos_LEFTOUTSIDE; break;
+ case RectPoint::LB: eVPos = css::drawing::MeasureTextVertPos_WEST;
+ eHPos = css::drawing::MeasureTextHorzPos_LEFTOUTSIDE; break;
+ case RectPoint::MT: eVPos = css::drawing::MeasureTextVertPos_EAST;
+ eHPos = css::drawing::MeasureTextHorzPos_INSIDE; break;
+ case RectPoint::MM: eVPos = css::drawing::MeasureTextVertPos_CENTERED;
+ eHPos = css::drawing::MeasureTextHorzPos_INSIDE; break;
+ case RectPoint::MB: eVPos = css::drawing::MeasureTextVertPos_WEST;
+ eHPos = css::drawing::MeasureTextHorzPos_INSIDE; break;
+ case RectPoint::RT: eVPos = css::drawing::MeasureTextVertPos_EAST;
+ eHPos = css::drawing::MeasureTextHorzPos_RIGHTOUTSIDE; break;
+ case RectPoint::RM: eVPos = css::drawing::MeasureTextVertPos_CENTERED;
+ eHPos = css::drawing::MeasureTextHorzPos_RIGHTOUTSIDE; break;
+ case RectPoint::RB: eVPos = css::drawing::MeasureTextVertPos_WEST;
+ eHPos = css::drawing::MeasureTextHorzPos_RIGHTOUTSIDE; break;
+ }
+ if (m_xTsbAutoPosH->get_state() == TRISTATE_TRUE)
+ eHPos = css::drawing::MeasureTextHorzPos_AUTO;
+
+ if (m_xTsbAutoPosV->get_state() == TRISTATE_TRUE)
+ eVPos = css::drawing::MeasureTextVertPos_AUTO;
+
+ if ( rAttrs->GetItemState( SDRATTR_MEASURETEXTVPOS ) != SfxItemState::DONTCARE )
+ {
+ css::drawing::MeasureTextVertPos eOldVPos = rOutAttrs.Get(SDRATTR_MEASURETEXTVPOS).GetValue();
+ if( eOldVPos != eVPos )
+ {
+ rAttrs->Put( SdrMeasureTextVPosItem( eVPos ) );
+ bModified = true;
+ }
+ }
+ else
+ {
+ rAttrs->Put( SdrMeasureTextVPosItem( eVPos ) );
+ bModified = true;
+ }
+
+ if ( rAttrs->GetItemState( SDRATTR_MEASURETEXTHPOS ) != SfxItemState::DONTCARE )
+ {
+ css::drawing::MeasureTextHorzPos eOldHPos = rOutAttrs.Get( SDRATTR_MEASURETEXTHPOS ).GetValue();
+ if( eOldHPos != eHPos )
+ {
+ rAttrs->Put( SdrMeasureTextHPosItem( eHPos ) );
+ bModified = true;
+ }
+ }
+ else
+ {
+ rAttrs->Put( SdrMeasureTextHPosItem( eHPos ) );
+ bModified = true;
+ }
+ }
+
+ return bModified;
+}
+
+/*************************************************************************
+|*
+|* The View have to set at the measure-object to be able to notify
+|* unit and floatingpoint-values
+|*
+\************************************************************************/
+
+void SvxMeasurePage::Construct()
+{
+ DBG_ASSERT( pView, "No valid View transferred!" );
+
+ // TTTT
+ // pMeasureObj is member of SvxXMeasurePreview and can only be accessed due to
+ // SvxMeasurePage being a friend. It has its own SdrModel (also in SvxXMeasurePreview)
+ // and 'setting' the SdrModel is a hack. The comment above about 'notify unit and
+ // floatingpoint-values' is not clear, but has to be done another way - if needed.
+ // Checked on original aw080, is just commented out there, too.
+
+ m_aCtlPreview.Invalidate();
+}
+
+std::unique_ptr<SfxTabPage> SvxMeasurePage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrs)
+{
+ return std::make_unique<SvxMeasurePage>(pPage, pController, *rAttrs);
+}
+
+void SvxMeasurePage::PointChanged(weld::DrawingArea* pDrawingArea, RectPoint /*eRP*/)
+{
+ ChangeAttrHdl_Impl(pDrawingArea);
+}
+
+IMPL_LINK( SvxMeasurePage, ClickAutoPosHdl_Impl, weld::Toggleable&, rBox, void )
+{
+ if (m_xTsbAutoPosH->get_state() == TRISTATE_TRUE)
+ {
+ switch( m_aCtlPosition.GetActualRP() )
+ {
+ case RectPoint::LT:
+ case RectPoint::RT:
+ m_aCtlPosition.SetActualRP( RectPoint::MT );
+ break;
+
+ case RectPoint::LM:
+ case RectPoint::RM:
+ m_aCtlPosition.SetActualRP( RectPoint::MM );
+ break;
+
+ case RectPoint::LB:
+ case RectPoint::RB:
+ m_aCtlPosition.SetActualRP( RectPoint::MB );
+ break;
+ default: ;//prevent warning
+ }
+ }
+ if (m_xTsbAutoPosV->get_state() == TRISTATE_TRUE)
+ {
+ switch( m_aCtlPosition.GetActualRP() )
+ {
+ case RectPoint::LT:
+ case RectPoint::LB:
+ m_aCtlPosition.SetActualRP( RectPoint::LM );
+ break;
+
+ case RectPoint::MT:
+ case RectPoint::MB:
+ m_aCtlPosition.SetActualRP( RectPoint::MM );
+ break;
+
+ case RectPoint::RT:
+ case RectPoint::RB:
+ m_aCtlPosition.SetActualRP( RectPoint::RM );
+ break;
+ default: ;//prevent warning
+ }
+ }
+ ChangeAttrHdl_Impl(&rBox);
+}
+
+IMPL_LINK(SvxMeasurePage, ChangeAttrClickHdl_Impl, weld::Toggleable&, r, void)
+{
+ ChangeAttrHdl_Impl(&r);
+}
+
+IMPL_LINK(SvxMeasurePage, ChangeAttrListBoxHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ ChangeAttrHdl_Impl(&rBox);
+}
+
+IMPL_LINK(SvxMeasurePage, ChangeAttrEditHdl_Impl, weld::MetricSpinButton&, rBox, void)
+{
+ ChangeAttrHdl_Impl(&rBox);
+}
+
+IMPL_LINK( SvxMeasurePage, ChangeAttrSpinHdl_Impl, weld::SpinButton&, rBox, void )
+{
+ ChangeAttrHdl_Impl(&rBox);
+}
+
+void SvxMeasurePage::ChangeAttrHdl_Impl( void const * p )
+{
+ if (p == m_xMtrFldLineDist.get())
+ {
+ sal_Int32 nValue = GetCoreValue( *m_xMtrFldLineDist, eUnit );
+ aAttrSet.Put( makeSdrMeasureLineDistItem( nValue ) );
+ }
+
+ if (p == m_xMtrFldHelplineOverhang.get())
+ {
+ sal_Int32 nValue = GetCoreValue( *m_xMtrFldHelplineOverhang, eUnit );
+ aAttrSet.Put( makeSdrMeasureHelplineOverhangItem( nValue) );
+ }
+
+ if (p == m_xMtrFldHelplineDist.get())
+ {
+ sal_Int32 nValue = GetCoreValue( *m_xMtrFldHelplineDist, eUnit );
+ aAttrSet.Put( makeSdrMeasureHelplineDistItem( nValue) );
+ }
+
+ if (p == m_xMtrFldHelpline1Len.get())
+ {
+ sal_Int32 nValue = GetCoreValue( *m_xMtrFldHelpline1Len, eUnit );
+ aAttrSet.Put( makeSdrMeasureHelpline1LenItem( nValue ) );
+ }
+
+ if (p == m_xMtrFldHelpline2Len.get())
+ {
+ sal_Int32 nValue = GetCoreValue( *m_xMtrFldHelpline2Len, eUnit );
+ aAttrSet.Put( makeSdrMeasureHelpline2LenItem( nValue ) );
+ }
+
+ if (p == m_xTsbBelowRefEdge.get())
+ {
+ TriState eState = m_xTsbBelowRefEdge->get_state();
+ if( eState != TRISTATE_INDET )
+ aAttrSet.Put( SdrMeasureBelowRefEdgeItem( TRISTATE_TRUE == eState ) );
+ }
+
+ if (p == m_xMtrFldDecimalPlaces.get())
+ {
+ sal_Int16 nValue = sal::static_int_cast< sal_Int16 >(
+ m_xMtrFldDecimalPlaces->get_value() );
+ aAttrSet.Put( SdrMeasureDecimalPlacesItem( nValue ) );
+ }
+
+ if (p == m_xTsbParallel.get())
+ {
+ TriState eState = m_xTsbParallel->get_state();
+ if( eState != TRISTATE_INDET )
+ aAttrSet.Put( SdrMeasureTextRota90Item( TRISTATE_FALSE == eState ) );
+ }
+
+ if (p == m_xTsbShowUnit.get())
+ {
+ TriState eState = m_xTsbShowUnit->get_state();
+ if( eState != TRISTATE_INDET )
+ aAttrSet.Put( SdrYesNoItem( SDRATTR_MEASURESHOWUNIT, TRISTATE_TRUE == eState ) );
+ }
+
+ if (p == m_xLbUnit.get())
+ {
+ int nPos = m_xLbUnit->get_active();
+ if (nPos != -1)
+ {
+ sal_uInt16 nFieldUnit = m_xLbUnit->get_id(nPos).toUInt32();
+ FieldUnit _eUnit = static_cast<FieldUnit>(nFieldUnit);
+ aAttrSet.Put( SdrMeasureUnitItem( _eUnit ) );
+ }
+ }
+
+ if (p == m_xTsbAutoPosV.get() || p == m_xTsbAutoPosH.get() || p == m_aCtlPosition.GetDrawingArea())
+ {
+ bPositionModified = true;
+
+ // Position
+ RectPoint eRP = m_aCtlPosition.GetActualRP();
+ css::drawing::MeasureTextVertPos eVPos;
+ css::drawing::MeasureTextHorzPos eHPos;
+
+ switch( eRP )
+ {
+ default:
+ case RectPoint::LT: eVPos = css::drawing::MeasureTextVertPos_EAST;
+ eHPos = css::drawing::MeasureTextHorzPos_LEFTOUTSIDE; break;
+ case RectPoint::LM: eVPos = css::drawing::MeasureTextVertPos_CENTERED;
+ eHPos = css::drawing::MeasureTextHorzPos_LEFTOUTSIDE; break;
+ case RectPoint::LB: eVPos = css::drawing::MeasureTextVertPos_WEST;
+ eHPos = css::drawing::MeasureTextHorzPos_LEFTOUTSIDE; break;
+ case RectPoint::MT: eVPos = css::drawing::MeasureTextVertPos_EAST;
+ eHPos = css::drawing::MeasureTextHorzPos_INSIDE; break;
+ case RectPoint::MM: eVPos = css::drawing::MeasureTextVertPos_CENTERED;
+ eHPos = css::drawing::MeasureTextHorzPos_INSIDE; break;
+ case RectPoint::MB: eVPos = css::drawing::MeasureTextVertPos_WEST;
+ eHPos = css::drawing::MeasureTextHorzPos_INSIDE; break;
+ case RectPoint::RT: eVPos = css::drawing::MeasureTextVertPos_EAST;
+ eHPos = css::drawing::MeasureTextHorzPos_RIGHTOUTSIDE; break;
+ case RectPoint::RM: eVPos = css::drawing::MeasureTextVertPos_CENTERED;
+ eHPos = css::drawing::MeasureTextHorzPos_RIGHTOUTSIDE; break;
+ case RectPoint::RB: eVPos = css::drawing::MeasureTextVertPos_WEST;
+ eHPos = css::drawing::MeasureTextHorzPos_RIGHTOUTSIDE; break;
+ }
+
+ CTL_STATE nState = CTL_STATE::NONE;
+
+ if (m_xTsbAutoPosH->get_state() == TRISTATE_TRUE)
+ {
+ eHPos = css::drawing::MeasureTextHorzPos_AUTO;
+ nState = CTL_STATE::NOHORZ;
+ }
+
+ if (m_xTsbAutoPosV->get_state() == TRISTATE_TRUE)
+ {
+ eVPos = css::drawing::MeasureTextVertPos_AUTO;
+ nState |= CTL_STATE::NOVERT;
+ }
+
+ if (p == m_xTsbAutoPosV.get() || p == m_xTsbAutoPosH.get())
+ m_aCtlPosition.SetState( nState );
+
+ aAttrSet.Put( SdrMeasureTextVPosItem( eVPos ) );
+ aAttrSet.Put( SdrMeasureTextHPosItem( eHPos ) );
+ }
+
+ m_aCtlPreview.SetAttributes(aAttrSet);
+ m_aCtlPreview.Invalidate();
+}
+
+void SvxMeasurePage::FillUnitLB()
+{
+ // fill ListBox with metrics
+
+ FieldUnit nUnit = FieldUnit::NONE;
+ OUString aStrMetric(m_xFtAutomatic->get_label());
+ m_xLbUnit->append(OUString::number(sal_uInt32(nUnit)), aStrMetric);
+
+ for( sal_uInt32 i = 0; i < SvxFieldUnitTable::Count(); ++i )
+ {
+ aStrMetric = SvxFieldUnitTable::GetString(i);
+ nUnit = SvxFieldUnitTable::GetValue(i);
+ m_xLbUnit->append(OUString::number(sal_uInt32(nUnit)), aStrMetric);
+ }
+}
+
+void SvxMeasurePage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const OfaPtrItem* pOfaPtrItem = aSet.GetItem<OfaPtrItem>(SID_OBJECT_LIST, false);
+
+ if (pOfaPtrItem)
+ SetView( static_cast<SdrView *>(pOfaPtrItem->GetValue()));
+
+ Construct();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/numfmt.cxx b/cui/source/tabpages/numfmt.cxx
new file mode 100644
index 0000000000..21972673cc
--- /dev/null
+++ b/cui/source/tabpages/numfmt.cxx
@@ -0,0 +1,1771 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <o3tl/safeint.hxx>
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include <sfx2/objsh.hxx>
+#include <vcl/outdev.hxx>
+#include <i18nlangtag/lang.h>
+#include <svx/svxids.hrc>
+#include <svtools/colorcfg.hxx>
+
+#include <numcategories.hrc>
+#include <strings.hrc>
+
+#include <svx/numinf.hxx>
+
+#include <numfmt.hxx>
+#include <svx/numfmtsh.hxx>
+#include <dialmgr.hxx>
+#include <sfx2/basedlgs.hxx>
+#include <svx/flagsdef.hxx>
+#include <vector>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <limits>
+#include <memory>
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::lang::XServiceInfo;
+using ::com::sun::star::uno::UNO_QUERY;
+
+#define NUMKEY_UNDEFINED SAL_MAX_UINT32
+
+// static ----------------------------------------------------------------
+
+const WhichRangesContainer SvxNumberFormatTabPage::pRanges(
+ svl::Items<
+ SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_INFO, // 10085 - 10086
+ SID_ATTR_NUMBERFORMAT_ONE_AREA, SID_ATTR_NUMBERFORMAT_ONE_AREA, // 10580 - 10580
+ SID_ATTR_NUMBERFORMAT_NOLANGUAGE, SID_ATTR_NUMBERFORMAT_NOLANGUAGE, // 10700 - 10700
+ SID_ATTR_NUMBERFORMAT_SOURCE, SID_ATTR_NUMBERFORMAT_SOURCE>); // 10932 - 10932
+
+/*************************************************************************
+#* Method: SvxNumberPreview
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberPreview
+#* Function: Constructor of the class SvxNumberPreview
+#* Input: Window, Resource-ID
+#* Output: ---
+#*
+#************************************************************************/
+
+SvxNumberPreview::SvxNumberPreview()
+ : mnPos(-1)
+ , mnChar(0x0)
+{
+}
+
+/*************************************************************************
+#* Method: NotifyChange
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberPreview
+#* Function: Function for changing the preview string
+#* Input: String, color
+#* Output: ---
+#*
+#************************************************************************/
+
+void SvxNumberPreview::NotifyChange( const OUString& rPrevStr,
+ const Color* pColor )
+{
+ // detect and strip out '*' related placeholders
+ aPrevStr = rPrevStr;
+ mnPos = aPrevStr.indexOf( 0x1B );
+ if ( mnPos != -1 )
+ {
+ // Right during user input the star symbol is the very
+ // last character before the user enters another one.
+ if (mnPos < aPrevStr.getLength() - 1)
+ {
+ mnChar = aPrevStr[ mnPos + 1 ];
+ // delete placeholder and char to repeat
+ aPrevStr = aPrevStr.replaceAt( mnPos, 2, u"" );
+ }
+ else
+ {
+ // delete placeholder
+ aPrevStr = aPrevStr.replaceAt( mnPos, 1, u"" );
+ // do not attempt to draw a 0 fill character
+ mnPos = -1;
+ }
+ }
+ if (pColor)
+ aPrevCol = *pColor;
+ else
+ {
+ svtools::ColorConfig aColorConfig;
+ Color aFgColor = aColorConfig.GetColorValue(svtools::FONTCOLOR, false).nColor;
+ if (aFgColor == COL_AUTO)
+ {
+ Color aBgColor = aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor;
+ aFgColor = aBgColor.IsDark() ? COL_WHITE : COL_BLACK;
+ }
+ aPrevCol = aFgColor;
+ }
+ Invalidate();
+}
+
+/*************************************************************************
+#* Method: Paint
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberPreview
+#* Function: Function for repainting the window.
+#* Input: ---
+#* Output: ---
+#*
+#************************************************************************/
+
+void SvxNumberPreview::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle&)
+{
+ rRenderContext.Push(vcl::PushFlags::ALL);
+
+ svtools::ColorConfig aColorConfig;
+ Color aBgColor = aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor;
+ Color aFgColor = aColorConfig.GetColorValue(svtools::FONTCOLOR, false).nColor;
+ if (aFgColor == COL_AUTO)
+ aFgColor = aBgColor.IsDark() ? COL_WHITE : COL_BLACK;
+ rRenderContext.SetBackground(aBgColor);
+ rRenderContext.SetTextColor(aFgColor);
+ rRenderContext.Erase();
+
+ vcl::Font aDrawFont = rRenderContext.GetFont();
+ Size aSzWnd(GetOutputSizePixel());
+ OUString aTmpStr(aPrevStr);
+ tools::Long nLeadSpace = (aSzWnd.Width() - rRenderContext.GetTextWidth(aTmpStr)) / 2;
+
+ aDrawFont.SetTransparent(true);
+ aDrawFont.SetColor(aPrevCol);
+ rRenderContext.SetFont(aDrawFont);
+
+ if (mnPos != -1)
+ {
+ tools::Long nCharWidth = rRenderContext.GetTextWidth(OUString(mnChar));
+
+ int nNumCharsToInsert = 0;
+ if (nCharWidth > 0)
+ nNumCharsToInsert = nLeadSpace / nCharWidth;
+
+ if (nNumCharsToInsert > 0)
+ {
+ for (int i = 0; i < nNumCharsToInsert; ++i)
+ aTmpStr = aTmpStr.replaceAt(mnPos, 0, rtl::OUStringChar(mnChar));
+ }
+ }
+
+ tools::Long nX = 0;
+ if (mnPos == -1 && nLeadSpace > 0) //tdf#122120 if it won't fit anyway, then left align it
+ {
+ nX = nLeadSpace;
+ }
+
+ Point aPosText(nX, (aSzWnd.Height() - GetTextHeight()) / 2);
+ rRenderContext.DrawText(aPosText, aTmpStr);
+ rRenderContext.Pop();
+}
+
+// class SvxNumberFormatTabPage ------------------------------------------
+
+#define REMOVE_DONTKNOW() \
+ if (!m_xFtLanguage->get_sensitive()) \
+ { \
+ m_xFtLanguage->set_sensitive(true); \
+ m_xLbLanguage->set_sensitive(true); \
+ m_xLbLanguage->set_active_id(pNumFmtShell->GetCurLanguage()); \
+ }
+
+SvxNumberFormatTabPage::SvxNumberFormatTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rCoreAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/numberingformatpage.ui", "NumberingFormatPage", &rCoreAttrs)
+ , nInitFormat(std::numeric_limits<sal_uInt32>::max())
+ , m_nLbFormatSelPosEdComment(SELPOS_NONE)
+ , bLegacyAutomaticCurrency(false)
+ , sAutomaticLangEntry(CuiResId(RID_CUISTR_AUTO_ENTRY))
+ , m_xFtCategory(m_xBuilder->weld_label("categoryft"))
+ , m_xLbCategory(m_xBuilder->weld_tree_view("categorylb"))
+ , m_xFtFormat(m_xBuilder->weld_label("formatft"))
+ , m_xLbCurrency(m_xBuilder->weld_combo_box("currencylb"))
+ , m_xLbFormat(m_xBuilder->weld_tree_view("formatlb"))
+ , m_xFtLanguage(m_xBuilder->weld_label("languageft"))
+ , m_xCbSourceFormat(m_xBuilder->weld_check_button("sourceformat"))
+ , m_xFtOptions(m_xBuilder->weld_label("optionsft"))
+ , m_xFtDecimals(m_xBuilder->weld_label("decimalsft"))
+ , m_xEdDecimals(m_xBuilder->weld_spin_button("decimalsed"))
+ , m_xFtDenominator(m_xBuilder->weld_label("denominatorft"))
+ , m_xEdDenominator(m_xBuilder->weld_spin_button("denominatored"))
+ , m_xBtnNegRed(m_xBuilder->weld_check_button("negnumred"))
+ , m_xFtLeadZeroes(m_xBuilder->weld_label("leadzerosft"))
+ , m_xEdLeadZeroes(m_xBuilder->weld_spin_button("leadzerosed"))
+ , m_xBtnThousand(m_xBuilder->weld_check_button("thousands"))
+ , m_xBtnEngineering(m_xBuilder->weld_check_button("engineering"))
+ , m_xFormatCodeFrame(m_xBuilder->weld_widget("formatcode"))
+ , m_xEdFormat(m_xBuilder->weld_entry("formatted"))
+ , m_xIbAdd(m_xBuilder->weld_button("add"))
+ , m_xIbInfo(m_xBuilder->weld_button("edit"))
+ , m_xIbRemove(m_xBuilder->weld_button("delete"))
+ , m_xFtComment(m_xBuilder->weld_label("commentft"))
+ , m_xEdComment(m_xBuilder->weld_entry("commented"))
+ , m_xLbLanguage(new SvxLanguageBox(m_xBuilder->weld_combo_box("languagelb")))
+ , m_xWndPreview(new weld::CustomWeld(*m_xBuilder, "preview", m_aWndPreview))
+{
+ for (size_t i = 0; i < std::size(NUM_CATEGORIES); ++i)
+ m_xLbCategory->append_text(CuiResId(NUM_CATEGORIES[i]));
+
+ auto nWidth = m_xLbCategory->get_approximate_digit_width() * 22;
+ m_xLbCategory->set_size_request(nWidth, m_xLbCategory->get_height_rows(7));
+ m_xLbFormat->set_size_request(nWidth, m_xLbFormat->get_height_rows(5));
+ m_xLbCurrency->set_size_request(nWidth, -1); // force using (narrower) width of its LbFormat sibling
+
+ // Initially remove the "Automatically" entry.
+ m_xLbCurrency->set_active(-1); // First ensure that nothing is selected.
+ sAutomaticCurrencyEntry = m_xLbCurrency->get_text(0);
+ m_xLbCurrency->remove(0);
+
+ Init_Impl();
+ SetExchangeSupport(); // this page needs ExchangeSupport
+ nFixedCategory=-1;
+}
+
+SvxNumberFormatTabPage::~SvxNumberFormatTabPage()
+{
+ pNumFmtShell.reset();
+ pNumItem.reset();
+ m_xWndPreview.reset();
+ m_xLbLanguage.reset();
+}
+
+void SvxNumberFormatTabPage::Init_Impl()
+{
+ bNumItemFlag=true;
+ bOneAreaFlag=false;
+
+ m_xIbAdd->set_sensitive(false );
+ m_xIbRemove->set_sensitive(false );
+ m_xIbInfo->set_sensitive(false );
+
+ m_xEdComment->set_text(m_xLbCategory->get_text(1)); // string for user defined
+
+ m_xEdComment->hide();
+
+ m_xCbSourceFormat->set_active( false );
+ m_xCbSourceFormat->set_sensitive(false);
+ m_xCbSourceFormat->hide();
+
+ Link<weld::TreeView&,void> aLink2 = LINK(this, SvxNumberFormatTabPage, SelFormatTreeListBoxHdl_Impl);
+ Link<weld::ComboBox&,void> aLink3 = LINK(this, SvxNumberFormatTabPage, SelFormatListBoxHdl_Impl);
+ m_xLbCategory->connect_changed(aLink2);
+ m_xLbCategory->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xLbFormat->connect_changed(aLink2);
+ m_xLbFormat->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xLbLanguage->connect_changed(aLink3);
+ m_xLbLanguage->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xLbCurrency->connect_changed(aLink3);
+ m_xLbCurrency->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xCbSourceFormat->connect_toggled(LINK(this, SvxNumberFormatTabPage, SelFormatClickHdl_Impl));
+ m_xCbSourceFormat->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+
+ Link<weld::SpinButton&,void> aLink = LINK( this, SvxNumberFormatTabPage, OptEditHdl_Impl );
+
+ m_xEdDecimals->connect_value_changed(aLink);
+ m_xEdDecimals->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xEdDenominator->connect_value_changed(aLink);
+ m_xEdDenominator->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xEdLeadZeroes->connect_value_changed(aLink);
+ m_xEdLeadZeroes->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+
+ m_xBtnNegRed->connect_toggled(LINK(this, SvxNumberFormatTabPage, OptClickHdl_Impl));
+ m_xBtnNegRed->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xBtnThousand->connect_toggled(LINK(this, SvxNumberFormatTabPage, OptClickHdl_Impl));
+ m_xBtnThousand->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xBtnEngineering->connect_toggled(LINK(this, SvxNumberFormatTabPage, OptClickHdl_Impl));
+ m_xBtnEngineering->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xLbFormat->connect_row_activated(LINK(this, SvxNumberFormatTabPage, DoubleClickHdl_Impl));
+ m_xEdFormat->connect_changed(LINK(this, SvxNumberFormatTabPage, EditModifyHdl_Impl));
+ m_xEdFormat->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xIbAdd->connect_clicked(LINK(this, SvxNumberFormatTabPage, ClickHdl_Impl));
+ m_xIbAdd->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xIbRemove->connect_clicked(LINK(this, SvxNumberFormatTabPage, ClickHdl_Impl));
+ m_xIbRemove->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xIbInfo->connect_clicked(LINK(this, SvxNumberFormatTabPage, ClickHdl_Impl));
+ UpdateThousandEngineeringCheckBox();
+ UpdateDecimalsDenominatorEditBox();
+
+ // initialize language ListBox
+
+ m_xLbLanguage->SetLanguageList(SvxLanguageListFlags::ALL | SvxLanguageListFlags::ONLY_KNOWN,
+ false, false, false, true, LANGUAGE_SYSTEM,
+ css::i18n::ScriptType::WEAK);
+}
+
+std::unique_ptr<SfxTabPage> SvxNumberFormatTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxNumberFormatTabPage>(pPage, pController, *rAttrSet);
+}
+
+
+/*************************************************************************
+#* Method: Reset
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: The dialog's attributes are reset
+#* using the Itemset.
+#* Input: SfxItemSet
+#* Output: ---
+#*
+#************************************************************************/
+
+void SvxNumberFormatTabPage::set_active_currency(sal_Int32 nPos)
+{
+ static_assert(SELPOS_NONE == -1, "SELPOS_NONE was -1 at time of writing");
+ if (nPos == 0 && !bLegacyAutomaticCurrency)
+ {
+ // Insert "Automatically" if currently used so it is selectable.
+ m_xLbCurrency->insert_text(0, sAutomaticCurrencyEntry);
+ bLegacyAutomaticCurrency = true;
+ }
+ if (nPos != -1 && !bLegacyAutomaticCurrency)
+ --nPos;
+ m_xLbCurrency->set_active(nPos);
+}
+
+sal_uInt32 SvxNumberFormatTabPage::get_active_currency() const
+{
+ static_assert(SELPOS_NONE == -1, "SELPOS_NONE was -1 at time of writing");
+ sal_Int32 nCurrencyPos = m_xLbCurrency->get_active();
+ if (nCurrencyPos != -1 && !bLegacyAutomaticCurrency)
+ ++nCurrencyPos;
+ return nCurrencyPos;
+}
+
+void SvxNumberFormatTabPage::Reset( const SfxItemSet* rSet )
+{
+ const SfxUInt32Item* pValFmtAttr = nullptr;
+ const SfxPoolItem* pItem = nullptr;
+ const SfxBoolItem* pAutoEntryAttr = nullptr;
+
+ sal_uInt16 nCatLbSelPos = 0;
+ sal_uInt16 nFmtLbSelPos = 0;
+ LanguageType eLangType = LANGUAGE_DONTKNOW;
+ std::vector<OUString> aFmtEntryList;
+ SvxNumberValueType eValType = SvxNumberValueType::Undefined;
+ double nValDouble = 0;
+ OUString aValString;
+
+ if(const SfxBoolItem* pBoolLangItem = rSet->GetItemIfSet( SID_ATTR_NUMBERFORMAT_NOLANGUAGE ))
+ {
+ if(pBoolLangItem->GetValue())
+ {
+ HideLanguage();
+ }
+ else
+ {
+ HideLanguage(false);
+ }
+
+ }
+
+ SfxItemState eState = rSet->GetItemState( GetWhich( SID_ATTR_NUMBERFORMAT_INFO ),true,&pItem);
+
+ if(eState==SfxItemState::SET)
+ {
+ if(pNumItem==nullptr)
+ {
+ bNumItemFlag=true;
+ pNumItem.reset( static_cast<SvxNumberInfoItem *>(pItem->Clone()) );
+ }
+ else
+ {
+ bNumItemFlag=false;
+ }
+ }
+ else
+ {
+ bNumItemFlag=false;
+ }
+
+
+ eState = rSet->GetItemState( GetWhich( SID_ATTR_NUMBERFORMAT_ONE_AREA ));
+
+ if(eState==SfxItemState::SET)
+ {
+ const SfxBoolItem* pBoolItem = GetItem( *rSet, SID_ATTR_NUMBERFORMAT_ONE_AREA);
+
+ if(pBoolItem!=nullptr)
+ {
+ bOneAreaFlag= pBoolItem->GetValue();
+ }
+ }
+
+ eState = rSet->GetItemState( SID_ATTR_NUMBERFORMAT_SOURCE );
+
+ if ( eState == SfxItemState::SET )
+ {
+ const SfxBoolItem* pBoolItem =
+ GetItem( *rSet, SID_ATTR_NUMBERFORMAT_SOURCE );
+ if ( pBoolItem )
+ m_xCbSourceFormat->set_active(pBoolItem->GetValue());
+ else
+ m_xCbSourceFormat->set_active( false );
+ m_xCbSourceFormat->set_sensitive(true);
+ m_xCbSourceFormat->show();
+ }
+ else
+ {
+ bool bInit = false; // set to sal_True for debug test
+ m_xCbSourceFormat->set_active( bInit );
+ m_xCbSourceFormat->set_sensitive( bInit );
+ m_xCbSourceFormat->set_visible( bInit );
+ }
+
+ // pNumItem must have been set from outside!
+ DBG_ASSERT( pNumItem, "No NumberInfo, no NumberFormatter, goodbye. CRASH. :-(" );
+
+ eState = rSet->GetItemState( GetWhich( SID_ATTR_NUMBERFORMAT_VALUE ) );
+
+ if ( SfxItemState::DONTCARE != eState )
+ pValFmtAttr = GetItem( *rSet, SID_ATTR_NUMBERFORMAT_VALUE );
+
+ eValType = pNumItem->GetValueType();
+
+ switch ( eValType )
+ {
+ case SvxNumberValueType::String:
+ aValString = pNumItem->GetValueString();
+ break;
+ case SvxNumberValueType::Number:
+ // #50441# string may be set in addition to the value
+ aValString = pNumItem->GetValueString();
+ nValDouble = pNumItem->GetValueDouble();
+ break;
+ case SvxNumberValueType::Undefined:
+ default:
+ break;
+ }
+
+ pNumFmtShell.reset(); // delete old shell if applicable (== reset)
+
+ nInitFormat = pValFmtAttr // memorize init key
+ ? pValFmtAttr->GetValue() // (for FillItemSet())
+ : std::numeric_limits<sal_uInt32>::max(); // == DONT_KNOW
+
+
+ if ( eValType == SvxNumberValueType::String )
+ pNumFmtShell.reset( SvxNumberFormatShell::Create(
+ pNumItem->GetNumberFormatter(),
+ pValFmtAttr ? nInitFormat : 0,
+ eValType,
+ aValString ) );
+ else
+ pNumFmtShell.reset( SvxNumberFormatShell::Create(
+ pNumItem->GetNumberFormatter(),
+ pValFmtAttr ? nInitFormat : 0,
+ eValType,
+ nValDouble,
+ &aValString ) );
+
+
+ bool bUseStarFormat = false;
+ if (SfxObjectShell* pDocSh = SfxObjectShell::Current())
+ {
+ // is this a calc document
+ Reference< XServiceInfo > xSI( pDocSh->GetModel(), UNO_QUERY );
+ if ( xSI.is() )
+ bUseStarFormat = xSI->supportsService("com.sun.star.sheet.SpreadsheetDocument");
+ }
+ pNumFmtShell->SetUseStarFormat( bUseStarFormat );
+
+ FillCurrencyBox();
+
+ OUString aPrevString;
+ const Color* pDummy = nullptr;
+ pNumFmtShell->GetInitSettings( nCatLbSelPos, eLangType, nFmtLbSelPos,
+ aFmtEntryList, aPrevString, pDummy );
+
+ if (nCatLbSelPos==CAT_CURRENCY)
+ set_active_currency(pNumFmtShell->GetCurrencySymbol());
+
+ nFixedCategory=nCatLbSelPos;
+ if(bOneAreaFlag)
+ {
+ OUString sFixedCategory = m_xLbCategory->get_text(nFixedCategory);
+ m_xLbCategory->clear();
+ m_xLbCategory->append_text(sFixedCategory);
+ SetCategory(0);
+ }
+ else
+ {
+ SetCategory(nCatLbSelPos );
+ }
+ eState = rSet->GetItemState( SID_ATTR_NUMBERFORMAT_ADD_AUTO );
+ if(SfxItemState::SET == eState)
+ pAutoEntryAttr = GetItem( *rSet, SID_ATTR_NUMBERFORMAT_ADD_AUTO );
+ // no_NO is an alias for nb_NO and normally isn't listed, we need it for
+ // backwards compatibility, but only if the format passed is of
+ // LanguageType no_NO.
+ if ( eLangType == LANGUAGE_NORWEGIAN )
+ {
+ m_xLbLanguage->remove_id(eLangType); // in case we're already called
+ m_xLbLanguage->InsertLanguage( eLangType );
+ }
+ m_xLbLanguage->set_active_id(eLangType);
+ if(pAutoEntryAttr)
+ AddAutomaticLanguage_Impl(eLangType, pAutoEntryAttr->GetValue());
+ UpdateFormatListBox_Impl(false,true);
+
+//! This spoils everything because it rematches currency formats based on
+//! the selected m_xLbCurrency entry instead of the current format.
+//! Besides that everything seems to be initialized by now, so why call it?
+// SelFormatHdl_Impl(m_xLbCategory.get());
+
+ if ( pValFmtAttr )
+ {
+ EditHdl_Impl(m_xEdFormat.get()); // UpdateOptions_Impl() as a side effect
+ }
+ else // DONT_KNOW
+ {
+ // everything disabled except direct input or changing the category
+ Obstructing();
+ }
+
+ if ( m_xCbSourceFormat->get_active() )
+ {
+ // everything disabled except SourceFormat checkbox
+ EnableBySourceFormat_Impl();
+ }
+}
+
+/*************************************************************************
+#* Method: Obstructing
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: Disable the controls except from changing the category
+#* and direct input.
+#* Input: ---
+#* Output: ---
+#*
+#************************************************************************/
+void SvxNumberFormatTabPage::Obstructing()
+{
+ m_xLbFormat->select(-1);
+ m_xLbLanguage->set_active(-1);
+ m_xFtLanguage->set_sensitive(false);
+ m_xLbLanguage->set_sensitive(false);
+
+ m_xIbAdd->set_sensitive(false );
+ m_xIbRemove->set_sensitive(false );
+ m_xIbInfo->set_sensitive(false );
+
+ m_xBtnNegRed->set_sensitive(false);
+ m_xBtnThousand->set_sensitive(false);
+ m_xBtnEngineering->set_sensitive(false);
+ m_xFtLeadZeroes->set_sensitive(false);
+ m_xFtDecimals->set_sensitive(false);
+ m_xFtDenominator->set_sensitive(false);
+ m_xEdLeadZeroes->set_sensitive(false);
+ m_xEdDecimals->set_sensitive(false);
+ m_xEdDenominator->set_sensitive(false);
+ m_xFtOptions->set_sensitive(false);
+ m_xEdDecimals->set_text( OUString() );
+ m_xEdLeadZeroes->set_text( OUString() );
+ m_xBtnNegRed->set_active( false );
+ m_xBtnThousand->set_active( false );
+ m_xBtnEngineering->set_active( false );
+ m_aWndPreview.NotifyChange( OUString() );
+
+ m_xLbCategory->select(0);
+ m_xEdFormat->set_text( OUString() );
+ m_xFtComment->set_label( OUString() );
+ m_xEdComment->set_text(m_xLbCategory->get_text(1)); // string for user defined
+
+ m_xEdFormat->grab_focus();
+}
+
+
+/*************************************************************************
+#* Enable/Disable dialog parts depending on the value of the SourceFormat
+#* checkbox.
+#************************************************************************/
+void SvxNumberFormatTabPage::EnableBySourceFormat_Impl()
+{
+ bool bEnable = !m_xCbSourceFormat->get_active();
+ if ( !bEnable )
+ m_xCbSourceFormat->grab_focus();
+ m_xFtCategory->set_sensitive( bEnable );
+ m_xLbCategory->set_sensitive( bEnable );
+ m_xFtFormat->set_sensitive( bEnable );
+ m_xLbCurrency->set_sensitive( bEnable );
+ m_xLbFormat->set_sensitive( bEnable );
+ m_xFtLanguage->set_sensitive( bEnable );
+ m_xLbLanguage->set_sensitive( bEnable );
+ m_xFtDecimals->set_sensitive( bEnable );
+ m_xEdDecimals->set_sensitive( bEnable );
+ m_xFtDenominator->set_sensitive( bEnable );
+ m_xEdDenominator->set_sensitive( bEnable );
+ m_xFtLeadZeroes->set_sensitive( bEnable );
+ m_xEdLeadZeroes->set_sensitive( bEnable );
+ m_xBtnNegRed->set_sensitive( bEnable );
+ m_xBtnThousand->set_sensitive( bEnable );
+ m_xBtnEngineering->set_sensitive( bEnable );
+ m_xFtOptions->set_sensitive( bEnable );
+ m_xFormatCodeFrame->set_sensitive( bEnable );
+}
+
+
+/*************************************************************************
+#* Method: HideLanguage
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: Hides the Languages and Locales:
+#* Input: sal_Bool nFlag
+#* Output: ---
+#*
+#************************************************************************/
+
+void SvxNumberFormatTabPage::HideLanguage(bool bFlag)
+{
+ m_xFtLanguage->set_visible(!bFlag);
+ m_xLbLanguage->set_visible(!bFlag);
+}
+
+/*************************************************************************
+#* Method: FillItemSet
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: Adjusts the attributes in the ItemSet,
+#* and - if bNumItemFlag is not set - the
+#* numItem in the DocShell.
+#* Input: SfxItemSet
+#* Output: ---
+#*
+#************************************************************************/
+
+bool SvxNumberFormatTabPage::FillItemSet( SfxItemSet* rCoreAttrs )
+{
+ bool bDataChanged = m_xFtLanguage->get_sensitive() || m_xCbSourceFormat->get_sensitive();
+ if ( bDataChanged )
+ {
+ const SfxItemSet& rMyItemSet = GetItemSet();
+ TypedWhichId<SfxUInt32Item> nWhich = GetWhich( SID_ATTR_NUMBERFORMAT_VALUE );
+ SfxItemState eItemState = rMyItemSet.GetItemState( nWhich, false );
+
+ // OK chosen - Is format code input entered already taken over?
+ // If not, simulate Add. Upon syntax error ignore input and prevent Put.
+ OUString aFormat = m_xEdFormat->get_text();
+ sal_uInt32 nCurKey = pNumFmtShell->GetCurNumFmtKey();
+
+ if ( m_xIbAdd->get_sensitive() || pNumFmtShell->IsTmpCurrencyFormat(aFormat) )
+ { // #79599# It is not sufficient to just add the format code (or
+ // delete it in case of bOneAreaFlag and resulting category change).
+ // Upon switching tab pages we need all settings to be consistent
+ // in case this page will be redisplayed later.
+ bDataChanged = Click_Impl(*m_xIbAdd);
+ nCurKey = pNumFmtShell->GetCurNumFmtKey();
+ }
+ else if(nCurKey == NUMKEY_UNDEFINED)
+ { // something went wrong, e.g. in Writer #70281#
+ pNumFmtShell->FindEntry(aFormat, &nCurKey);
+ }
+
+
+ // Chosen format:
+
+ if ( bDataChanged )
+ {
+ bDataChanged = ( nInitFormat != nCurKey );
+
+ if (bDataChanged)
+ {
+ rCoreAttrs->Put( SfxUInt32Item( nWhich, nCurKey ) );
+ }
+ else if(SfxItemState::DEFAULT == eItemState)
+ {
+ rCoreAttrs->ClearItem( nWhich );
+ }
+ }
+
+
+ // List of changed user defined formats:
+
+ std::vector<sal_uInt32> const & aDelFormats = pNumFmtShell->GetUpdateData();
+
+ if ( !aDelFormats.empty() )
+ {
+
+ pNumItem->SetDelFormats( std::vector(aDelFormats) );
+
+ if(bNumItemFlag)
+ {
+ rCoreAttrs->Put( *pNumItem );
+ }
+ else
+ {
+ SfxObjectShell* pDocSh = SfxObjectShell::Current();
+ DBG_ASSERT( pDocSh, "DocShell not found!" );
+ if (pDocSh)
+ pDocSh->PutItem( *pNumItem );
+ }
+ }
+
+
+ // Whether source format is to be taken or not:
+
+ if ( m_xCbSourceFormat->get_sensitive() )
+ {
+ SfxItemState _eItemState = rMyItemSet.GetItemState( SID_ATTR_NUMBERFORMAT_SOURCE, false );
+ const SfxBoolItem* pBoolItem =
+ GetItem( rMyItemSet, SID_ATTR_NUMBERFORMAT_SOURCE );
+ bool bOld = pBoolItem && pBoolItem->GetValue();
+ rCoreAttrs->Put( SfxBoolItem( SID_ATTR_NUMBERFORMAT_SOURCE, m_xCbSourceFormat->get_active() ) );
+ if ( !bDataChanged )
+ bDataChanged = (bOld != m_xCbSourceFormat->get_active() ||
+ _eItemState != SfxItemState::SET);
+ }
+
+ // FillItemSet is only called on OK, here we can notify the
+ // NumberFormatShell that all new user defined formats are valid.
+ pNumFmtShell->ValidateNewEntries();
+ if(m_xLbLanguage->get_visible() &&
+ m_xLbLanguage->find_text(sAutomaticLangEntry) != -1)
+ rCoreAttrs->Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_ADD_AUTO,
+ m_xLbLanguage->get_active_text() == sAutomaticLangEntry));
+ }
+
+ return bDataChanged;
+}
+
+
+DeactivateRC SvxNumberFormatTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if ( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+void SvxNumberFormatTabPage::FillFormatListBox_Impl( std::vector<OUString>& rEntries )
+{
+ OUString aEntry;
+ OUString aTmpString;
+ size_t i = 0;
+ short nTmpCatPos;
+
+ m_xLbFormat->clear();
+ if (rEntries.empty())
+ return;
+
+ m_xLbFormat->freeze();
+
+ if(bOneAreaFlag)
+ {
+ nTmpCatPos=nFixedCategory;
+ }
+ else
+ {
+ nTmpCatPos=m_xLbCategory->get_selected_index();
+ }
+
+ switch (nTmpCatPos)
+ {
+ case CAT_ALL:
+ case CAT_TEXT:
+ case CAT_NUMBER: i=1;
+ aEntry=rEntries[0];
+ if (nTmpCatPos == CAT_TEXT)
+ aTmpString=aEntry;
+ else
+ aTmpString = pNumFmtShell->GetStandardName();
+ m_xLbFormat->append_text(aTmpString);
+ break;
+
+ default: break;
+ }
+
+ if(pNumFmtShell!=nullptr)
+ {
+ for ( ; i < rEntries.size(); ++i )
+ {
+ aEntry = rEntries[i];
+ short aPrivCat = pNumFmtShell->GetCategory4Entry( static_cast<short>(i) );
+ if(aPrivCat!=CAT_TEXT)
+ {
+ const Color* pPreviewColor = nullptr;
+ OUString aPreviewString( GetExpColorString( pPreviewColor, aEntry, aPrivCat ) );
+ m_xLbFormat->append_text(aPreviewString);
+ if (pPreviewColor)
+ m_xLbFormat->set_font_color(m_xLbFormat->n_children() - 1, *pPreviewColor);
+ }
+ else
+ {
+ m_xLbFormat->append_text(aEntry);
+ }
+ }
+ }
+ m_xLbFormat->thaw();
+ rEntries.clear();
+}
+
+/*************************************************************************
+#* Method: UpdateOptions_Impl
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: Adjusts the options attributes
+#* depending on the selected format.
+#* Input: Flag, whether the category has changed.
+#* Output: ---
+#*
+#************************************************************************/
+
+void SvxNumberFormatTabPage::UpdateOptions_Impl( bool bCheckCatChange /*= sal_False*/ )
+{
+ OUString theFormat = m_xEdFormat->get_text();
+ sal_Int32 nCurCategory = m_xLbCategory->get_selected_index();
+ sal_uInt16 nCategory = static_cast<sal_uInt16>(nCurCategory);
+ sal_uInt16 nDecimals = 0;
+ sal_uInt16 nZeroes = 0;
+ bool bNegRed = false;
+ bool bThousand = false;
+ sal_Int32 nCurrencyPos = get_active_currency();
+
+ if(bOneAreaFlag)
+ nCurCategory=nFixedCategory;
+
+
+ pNumFmtShell->GetOptions( theFormat,
+ bThousand, bNegRed,
+ nDecimals, nZeroes,
+ nCategory );
+ bool bDoIt=false;
+ if(nCategory==CAT_CURRENCY)
+ {
+ sal_uInt16 nTstPos=pNumFmtShell->FindCurrencyFormat(theFormat);
+ if(nCurrencyPos!=static_cast<sal_Int32>(nTstPos) && nTstPos!=sal_uInt16(-1))
+ {
+ set_active_currency(nTstPos);
+ pNumFmtShell->SetCurrencySymbol(nTstPos);
+ bDoIt=true;
+ }
+ }
+
+ if ( nCategory != nCurCategory || bDoIt)
+ {
+ if ( bCheckCatChange )
+ {
+ if(bOneAreaFlag)
+ SetCategory(0);
+ else
+ SetCategory(nCategory );
+
+ UpdateFormatListBox_Impl( true, false );
+ }
+ }
+ else if ( m_xLbFormat->n_children() > 0 )
+ {
+ sal_uInt32 nCurEntryKey=NUMKEY_UNDEFINED;
+ if(!pNumFmtShell->FindEntry( m_xEdFormat->get_text(),&nCurEntryKey))
+ {
+ m_xLbFormat->select(-1);
+ }
+ }
+ if(bOneAreaFlag)
+ {
+ nCategory=nFixedCategory;
+ }
+
+ UpdateThousandEngineeringCheckBox();
+ UpdateDecimalsDenominatorEditBox();
+ switch ( nCategory )
+ {
+ case CAT_SCIENTIFIC: // bThousand is for Engineering notation
+ {
+ sal_uInt16 nIntDigits = pNumFmtShell->GetFormatIntegerDigits(theFormat);
+ bThousand = (nIntDigits > 0) && (nIntDigits % 3 == 0);
+ m_xBtnEngineering->set_sensitive(true);
+ m_xBtnEngineering->set_active( bThousand );
+ }
+ [[fallthrough]];
+ case CAT_NUMBER:
+ case CAT_PERCENT:
+ case CAT_CURRENCY:
+ case CAT_FRACTION:
+ case CAT_TIME:
+ m_xFtOptions->set_sensitive(true);
+ if ( nCategory == CAT_FRACTION )
+ {
+ m_xFtDenominator->set_sensitive(true);
+ m_xEdDenominator->set_sensitive(true);
+ }
+ else
+ {
+ m_xFtDecimals->set_sensitive(true);
+ m_xEdDecimals->set_sensitive(true);
+ }
+ m_xFtLeadZeroes->set_sensitive( nCategory != CAT_TIME );
+ m_xEdLeadZeroes->set_sensitive( nCategory != CAT_TIME );
+ m_xBtnNegRed->set_sensitive(true);
+ if ( nCategory == CAT_NUMBER && m_xLbFormat->get_selected_index() == 0 )
+ m_xEdDecimals->set_text( "" ); //General format tdf#44399
+ else
+ if ( nCategory == CAT_FRACTION )
+ m_xEdDenominator->set_value( nDecimals );
+ else
+ m_xEdDecimals->set_value( nDecimals );
+ if ( nCategory != CAT_TIME )
+ m_xEdLeadZeroes->set_value( nZeroes );
+ m_xBtnNegRed->set_active( bNegRed );
+ if ( nCategory != CAT_SCIENTIFIC )
+ {
+ m_xBtnThousand->set_sensitive( nCategory != CAT_TIME
+ && !pNumFmtShell->IsNatNum12( theFormat ) );
+ m_xBtnThousand->set_active( bThousand && nCategory != CAT_TIME );
+ }
+ break;
+
+ case CAT_ALL:
+ case CAT_USERDEFINED:
+ case CAT_TEXT:
+ case CAT_DATE:
+ case CAT_BOOLEAN:
+ default:
+ m_xFtOptions->set_sensitive(false);
+ m_xFtDecimals->set_sensitive(false);
+ m_xEdDecimals->set_sensitive(false);
+ m_xFtDenominator->set_sensitive(false);
+ m_xEdDenominator->set_sensitive(false);
+ m_xFtLeadZeroes->set_sensitive(false);
+ m_xEdLeadZeroes->set_sensitive(false);
+ m_xBtnNegRed->set_sensitive(false);
+ m_xBtnThousand->set_sensitive(false);
+ m_xBtnEngineering->set_sensitive(false);
+ m_xEdDecimals->set_text( OUString() );
+ m_xEdLeadZeroes->set_text( OUString() );
+ m_xBtnNegRed->set_active( false );
+ m_xBtnThousand->set_active( false );
+ m_xBtnEngineering->set_active( false );
+ }
+}
+
+
+/*************************************************************************
+#* Method: UpdateFormatListBox_Impl
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: Updates the format listbox and additionally the
+#* string in the editbox is changed depending on
+#* the bUpdateEdit flag.
+#* Input: Flags for category and editbox.
+#* Output: ---
+#*
+#************************************************************************/
+
+void SvxNumberFormatTabPage::UpdateFormatListBox_Impl
+ (
+ bool bCat, // Category or country/language ListBox?
+ bool bUpdateEdit
+ )
+{
+ std::vector<OUString> aEntryList;
+ short nFmtLbSelPos = 0;
+ short nTmpCatPos;
+
+ if(bOneAreaFlag)
+ {
+ nTmpCatPos=nFixedCategory;
+ }
+ else
+ {
+ nTmpCatPos=m_xLbCategory->get_selected_index();
+ }
+
+
+ if ( bCat )
+ {
+ if(nTmpCatPos!=CAT_CURRENCY)
+ m_xLbCurrency->hide();
+ else
+ m_xLbCurrency->show();
+
+ pNumFmtShell->CategoryChanged(nTmpCatPos,nFmtLbSelPos, aEntryList);
+ }
+ else
+ pNumFmtShell->LanguageChanged(m_xLbLanguage->get_active_id(),
+ nFmtLbSelPos,aEntryList);
+
+ REMOVE_DONTKNOW() // possibly UI-Enable
+
+
+ if ( (!aEntryList.empty()) && (nFmtLbSelPos != SELPOS_NONE) )
+ {
+ if(bUpdateEdit)
+ {
+ OUString aFormat=aEntryList[nFmtLbSelPos];
+ m_xEdFormat->set_text(aFormat);
+ m_xFtComment->set_label(pNumFmtShell->GetComment4Entry(nFmtLbSelPos));
+ }
+
+ if(!bOneAreaFlag || !bCat)
+ {
+ FillFormatListBox_Impl( aEntryList );
+ m_xLbFormat->select(nFmtLbSelPos);
+
+ m_xFtComment->set_label(pNumFmtShell->GetComment4Entry(nFmtLbSelPos));
+ if(pNumFmtShell->GetUserDefined4Entry(nFmtLbSelPos))
+ {
+ if(pNumFmtShell->GetComment4Entry(nFmtLbSelPos).isEmpty())
+ {
+ m_xFtComment->set_label(m_xLbCategory->get_text(1));
+ }
+ }
+ ChangePreviewText( static_cast<sal_uInt16>(nFmtLbSelPos) );
+ }
+
+ }
+ else
+ {
+ FillFormatListBox_Impl( aEntryList );
+ if(nFmtLbSelPos != SELPOS_NONE)
+ {
+ m_xLbFormat->select(static_cast<sal_uInt16>(nFmtLbSelPos));
+
+ m_xFtComment->set_label(pNumFmtShell->GetComment4Entry(nFmtLbSelPos));
+ if(pNumFmtShell->GetUserDefined4Entry(nFmtLbSelPos))
+ {
+ if(pNumFmtShell->GetComment4Entry(nFmtLbSelPos).isEmpty())
+ {
+ m_xFtComment->set_label(m_xLbCategory->get_text(1));
+ }
+ }
+ }
+ else
+ {
+ m_xLbFormat->select(-1);
+ }
+
+ if ( bUpdateEdit )
+ {
+ m_xEdFormat->set_text( OUString() );
+ m_aWndPreview.NotifyChange( OUString() );
+ }
+ }
+
+ aEntryList.clear();
+}
+
+
+/**
+ * Change visible checkbox according to category format
+ * if scientific format "Engineering notation"
+ * else "Thousands separator"
+ */
+
+void SvxNumberFormatTabPage::UpdateThousandEngineeringCheckBox()
+{
+ bool bIsScientific = m_xLbCategory->get_selected_index() == CAT_SCIENTIFIC;
+ m_xBtnThousand->set_visible( !bIsScientific );
+ m_xBtnEngineering->set_visible( bIsScientific );
+}
+
+
+/**
+ * Change visible Edit box and Fixed text according to category format
+ * if fraction format "Denominator places"
+ * else "Decimal places"
+ */
+
+void SvxNumberFormatTabPage::UpdateDecimalsDenominatorEditBox()
+{
+ bool bIsFraction = m_xLbCategory->get_selected_index() == CAT_FRACTION;
+ m_xFtDecimals->set_visible( !bIsFraction );
+ m_xEdDecimals->set_visible( !bIsFraction );
+ m_xFtDenominator->set_visible( bIsFraction );
+ m_xEdDenominator->set_visible( bIsFraction );
+}
+
+
+/*************************************************************************
+#* Handle: DoubleClickHdl_Impl
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: On a double click in the format listbox the
+#* value is adopted and the OK button pushed.
+#* Input: Pointer on the Listbox
+#* Output: ---
+#*
+#************************************************************************/
+IMPL_LINK(SvxNumberFormatTabPage, DoubleClickHdl_Impl, weld::TreeView&, rLb, bool)
+{
+ SelFormatHdl_Impl(&rLb);
+
+ SfxOkDialogController* pController = GetDialogController();
+ assert(pController);
+ weld::Button& rOkButton = pController->GetOKButton();
+ rOkButton.clicked();
+
+ return true;
+}
+
+/*************************************************************************
+#* Method: SelFormatHdl_Impl
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: Is called when the language, the category or the format
+#* is changed. Accordingly the settings are adjusted.
+#* Input: Pointer on the Listbox
+#* Output: ---
+#*
+#************************************************************************/
+
+IMPL_LINK(SvxNumberFormatTabPage, SelFormatClickHdl_Impl, weld::Toggleable&, rLb, void)
+{
+ SelFormatHdl_Impl(&rLb);
+}
+
+IMPL_LINK(SvxNumberFormatTabPage, SelFormatTreeListBoxHdl_Impl, weld::TreeView&, rLb, void)
+{
+ SelFormatHdl_Impl(&rLb);
+}
+
+IMPL_LINK(SvxNumberFormatTabPage, SelFormatListBoxHdl_Impl, weld::ComboBox&, rLb, void)
+{
+ SelFormatHdl_Impl(&rLb);
+}
+
+void SvxNumberFormatTabPage::SelFormatHdl_Impl(weld::Widget* pLb)
+{
+ if (m_nLbFormatSelPosEdComment != SELPOS_NONE)
+ {
+ // Click handler is called before focus change handler, so finish
+ // comment editing of previous format, otherwise a new format will have
+ // the old comment displayed after LostFocusHdl_Impl() is called
+ // later. Also, clicking into another category invalidates the format
+ // list and SvxNumberFormatShell::SetComment4Entry() could either
+ // access a wrong format from aCurEntryList[nEntry] or crash there if
+ // the new vector has less elements.
+ LostFocusHdl_Impl(*pLb);
+ }
+
+ if (pLb == m_xCbSourceFormat.get())
+ {
+ EnableBySourceFormat_Impl(); // enable/disable everything else
+ if ( m_xCbSourceFormat->get_active() )
+ return; // just disabled everything else
+
+ // Reinit options enable/disable for current selection.
+
+ // Current category may be UserDefined with no format entries defined.
+ if (m_xLbFormat->get_selected_index() == -1)
+ pLb = m_xLbCategory.get(); // continue with the current category selected
+ else
+ pLb = m_xLbFormat.get(); // continue with the current format selected
+ }
+
+ sal_Int32 nTmpCatPos;
+
+ if(bOneAreaFlag)
+ {
+ nTmpCatPos=nFixedCategory;
+ }
+ else
+ {
+ nTmpCatPos=m_xLbCategory->get_selected_index();
+ }
+
+ if (nTmpCatPos==CAT_CURRENCY && pLb == m_xLbCurrency.get())
+ pNumFmtShell->SetCurrencySymbol(get_active_currency());
+
+ // Format-ListBox ----------------------------------------------------
+ if (pLb == m_xLbFormat.get())
+ {
+ int nSelPos = m_xLbFormat->get_selected_index();
+ short nFmtLbSelPos = static_cast<short>(nSelPos);
+
+ OUString aFormat = pNumFmtShell->GetFormat4Entry(nFmtLbSelPos);
+ OUString aComment = pNumFmtShell->GetComment4Entry(nFmtLbSelPos);
+
+ if(pNumFmtShell->GetUserDefined4Entry(nFmtLbSelPos))
+ {
+ if(aComment.isEmpty())
+ {
+ aComment = m_xLbCategory->get_text(1);
+ }
+ }
+
+ if ( !aFormat.isEmpty() )
+ {
+ if (!m_xEdFormat->has_focus())
+ m_xEdFormat->set_text( aFormat );
+ m_xFtComment->set_label(aComment);
+ ChangePreviewText( static_cast<sal_uInt16>(nSelPos) );
+ }
+
+ REMOVE_DONTKNOW() // possibly UI-Enable
+
+ if ( pNumFmtShell->FindEntry( aFormat) )
+ {
+ m_xIbAdd->set_sensitive(false );
+ bool bIsUserDef=pNumFmtShell->IsUserDefined( aFormat );
+ m_xIbRemove->set_sensitive(bIsUserDef);
+ m_xIbInfo->set_sensitive(bIsUserDef);
+
+ }
+ else
+ {
+ m_xIbAdd->set_sensitive(true);
+ m_xIbInfo->set_sensitive(true);
+ m_xIbRemove->set_sensitive(false );
+ m_xFtComment->set_label(m_xEdComment->get_text());
+
+ }
+ UpdateOptions_Impl( false );
+
+ return;
+ }
+
+
+ // category-ListBox -------------------------------------------------
+ if (pLb == m_xLbCategory.get() || pLb == m_xLbCurrency.get())
+ {
+ UpdateFormatListBox_Impl( true, true );
+ EditHdl_Impl( nullptr );
+ UpdateOptions_Impl( false );
+
+ return;
+ }
+
+
+ // language/country-ListBox ----------------------------------------------
+ if (pLb == m_xLbLanguage->get_widget())
+ {
+ UpdateFormatListBox_Impl( false, true );
+ EditHdl_Impl(m_xEdFormat.get());
+
+ return;
+ }
+}
+
+
+/*************************************************************************
+#* Method: ClickHdl_Impl, weld::Button& rIB
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: Called when the add or delete button is pushed,
+#* adjusts the number format list.
+#* Input: Toolbox- Button
+#* Output: ---
+#*
+#************************************************************************/
+
+IMPL_LINK( SvxNumberFormatTabPage, ClickHdl_Impl, weld::Button&, rIB, void)
+{
+ Click_Impl(rIB);
+}
+
+bool SvxNumberFormatTabPage::Click_Impl(const weld::Button& rIB)
+{
+ sal_uInt8 nReturn = 0;
+ constexpr sal_uInt8 nReturnChanged = 0x1; // THE boolean return value
+ constexpr sal_uInt8 nReturnAdded = 0x2; // temp: format added
+ constexpr sal_uInt8 nReturnOneArea = 0x4; // temp: one area but category changed => ignored
+
+ if (&rIB == m_xIbAdd.get())
+ { // Also called from FillItemSet() if a temporary currency format has
+ // to be added, not only if the Add button is enabled.
+ OUString aFormat = m_xEdFormat->get_text();
+ std::vector<OUString> aEntryList;
+ std::vector<OUString> a2EntryList;
+ sal_uInt16 nCatLbSelPos = 0;
+ short nFmtLbSelPos = SELPOS_NONE;
+ sal_Int32 nErrPos=0;
+
+ pNumFmtShell->SetCurCurrencyEntry(nullptr);
+ bool bAdded = pNumFmtShell->AddFormat( aFormat, nErrPos,
+ nCatLbSelPos, nFmtLbSelPos,
+ aEntryList);
+ if ( bAdded )
+ nReturn |= nReturnChanged | nReturnAdded;
+
+ if (m_xEdComment->get_visible())
+ {
+ m_xEdFormat->grab_focus();
+ m_xEdComment->hide();
+ m_xFtComment->show();
+ m_xFtComment->set_label(m_xEdComment->get_text());
+ }
+
+ if ( !nErrPos ) // Syntax ok?
+ {
+ // May be sorted under a different locale if LCID was parsed.
+ if (bAdded)
+ m_xLbLanguage->set_active_id(pNumFmtShell->GetCurLanguage());
+
+ if (nCatLbSelPos==CAT_CURRENCY)
+ set_active_currency(pNumFmtShell->GetCurrencySymbol());
+
+ if(bOneAreaFlag && (nFixedCategory!=nCatLbSelPos))
+ {
+ if(bAdded) aEntryList.clear();
+ pNumFmtShell->RemoveFormat( aFormat,
+ nCatLbSelPos,
+ nFmtLbSelPos,
+ a2EntryList);
+ a2EntryList.clear();
+ m_xEdFormat->grab_focus();
+ m_xEdFormat->select_region(0, -1);
+ nReturn |= nReturnOneArea;
+ }
+ else
+ {
+ if ( bAdded && (nFmtLbSelPos != SELPOS_NONE) )
+ {
+ // everything all right
+ if(bOneAreaFlag) //@@ ???
+ SetCategory(0);
+ else
+ SetCategory(nCatLbSelPos );
+
+ FillFormatListBox_Impl( aEntryList );
+ if (m_xEdComment->get_text()!=m_xLbCategory->get_text(1))
+ {
+ pNumFmtShell->SetComment4Entry(nFmtLbSelPos,
+ m_xEdComment->get_text());
+ }
+ else
+ {
+ pNumFmtShell->SetComment4Entry(nFmtLbSelPos,
+ OUString());
+ }
+ m_xLbFormat->select(static_cast<sal_uInt16>(nFmtLbSelPos));
+ m_xEdFormat->set_text( aFormat );
+
+ m_xEdComment->set_text(m_xLbCategory->get_text(1)); // String for user defined
+
+ ChangePreviewText( static_cast<sal_uInt16>(nFmtLbSelPos) );
+ }
+ }
+ }
+ else // syntax error
+ {
+ m_xEdFormat->grab_focus();
+ m_xEdFormat->select_region(nErrPos == -1 ? m_xEdFormat->get_text().getLength() : nErrPos, -1);
+ }
+ EditHdl_Impl(m_xEdFormat.get());
+ nReturn = ((nReturn & nReturnOneArea) ? 0 : (nReturn & nReturnChanged));
+
+ aEntryList.clear();
+ a2EntryList.clear();
+ }
+ else if (&rIB == m_xIbRemove.get())
+ {
+ OUString aFormat = m_xEdFormat->get_text();
+ std::vector<OUString> aEntryList;
+ sal_uInt16 nCatLbSelPos = 0;
+ short nFmtLbSelPos = SELPOS_NONE;
+
+ pNumFmtShell->RemoveFormat( aFormat,
+ nCatLbSelPos,
+ nFmtLbSelPos,
+ aEntryList );
+
+ m_xEdComment->set_text(m_xLbCategory->get_text(1));
+
+ if( nFmtLbSelPos>=0 && o3tl::make_unsigned(nFmtLbSelPos)<aEntryList.size() )
+ {
+ aFormat = aEntryList[nFmtLbSelPos];
+ }
+
+ FillFormatListBox_Impl( aEntryList );
+
+ if ( nFmtLbSelPos != SELPOS_NONE )
+ {
+ if(bOneAreaFlag) //@@ ???
+ SetCategory(0);
+ else
+ SetCategory(nCatLbSelPos );
+
+ m_xLbFormat->select(static_cast<sal_uInt16>(nFmtLbSelPos));
+ m_xEdFormat->set_text( aFormat );
+ ChangePreviewText( static_cast<sal_uInt16>(nFmtLbSelPos) );
+ }
+ else
+ {
+ // set to "all/standard"
+ SetCategory(0);
+ SelFormatHdl_Impl(m_xLbCategory.get());
+ }
+
+ EditHdl_Impl(m_xEdFormat.get());
+
+ aEntryList.clear();
+ }
+ else if (&rIB == m_xIbInfo.get())
+ {
+ if (!m_xEdComment->get_visible())
+ {
+ if (!m_xIbAdd->get_sensitive())
+ // Editing for existing format.
+ m_nLbFormatSelPosEdComment = m_xLbFormat->get_selected_index();
+
+ m_xEdComment->set_text(m_xFtComment->get_label());
+ m_xEdComment->show();
+ m_xFtComment->hide();
+ m_xEdComment->grab_focus();
+ }
+ else
+ {
+ m_xEdFormat->grab_focus();
+ m_xFtComment->set_label( m_xEdComment->get_text());
+ m_xEdComment->hide();
+ m_xFtComment->show();
+ }
+ }
+
+ return nReturn;
+}
+
+
+/*************************************************************************
+#* Method: EditHdl_Impl
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: When the entry in the edit field is changed
+#* the preview is updated and
+#* Input: Pointer on Editbox
+#* Output: ---
+#*
+#************************************************************************/
+
+IMPL_LINK(SvxNumberFormatTabPage, EditModifyHdl_Impl, weld::Entry&, rEdit, void)
+{
+ EditHdl_Impl(&rEdit);
+}
+
+void SvxNumberFormatTabPage::EditHdl_Impl(const weld::Entry* pEdFormat)
+{
+ sal_uInt32 nCurKey = NUMKEY_UNDEFINED;
+
+ if ( m_xEdFormat->get_text().isEmpty() )
+ {
+ m_xIbAdd->set_sensitive(false );
+ m_xIbRemove->set_sensitive(false );
+ m_xIbInfo->set_sensitive(false );
+ m_xFtComment->set_label(OUString());
+ }
+ else
+ {
+ OUString aFormat = m_xEdFormat->get_text();
+ MakePreviewText( aFormat );
+
+ if ( pNumFmtShell->FindEntry( aFormat, &nCurKey ) )
+ {
+ m_xIbAdd->set_sensitive(false );
+ bool bUserDef=pNumFmtShell->IsUserDefined( aFormat );
+
+ m_xIbRemove->set_sensitive(bUserDef);
+ m_xIbInfo->set_sensitive(bUserDef);
+
+ if(bUserDef)
+ {
+ sal_uInt16 nTmpCurPos=pNumFmtShell->FindCurrencyFormat(aFormat );
+ if (nTmpCurPos != sal_uInt16(-1))
+ set_active_currency(nTmpCurPos);
+ }
+ short nPosi=pNumFmtShell->GetListPos4Entry( nCurKey, aFormat);
+ if(nPosi>=0)
+ m_xLbFormat->select(static_cast<sal_uInt16>(nPosi));
+
+ }
+ else
+ {
+
+ m_xIbAdd->set_sensitive(true);
+ m_xIbInfo->set_sensitive(true);
+ m_xIbRemove->set_sensitive(false );
+
+ m_xFtComment->set_label(m_xEdComment->get_text());
+
+ }
+ }
+
+ if (pEdFormat)
+ {
+ pNumFmtShell->SetCurNumFmtKey( nCurKey );
+ UpdateOptions_Impl( true );
+ }
+}
+
+
+/*************************************************************************
+#* Method: NotifyChange
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: Does changes in the number attributes.
+#* Input: Options- Controls
+#* Output: ---
+#*
+#************************************************************************/
+
+IMPL_LINK(SvxNumberFormatTabPage, OptClickHdl_Impl, weld::Toggleable&, rOptCtrl, void)
+{
+ OptHdl_Impl(&rOptCtrl);
+}
+
+IMPL_LINK(SvxNumberFormatTabPage, OptEditHdl_Impl, weld::SpinButton&, rEdit, void)
+{
+ OptHdl_Impl(&rEdit);
+}
+
+void SvxNumberFormatTabPage::OptHdl_Impl(const weld::Widget* pOptCtrl)
+{
+ if ( !(pOptCtrl == m_xEdLeadZeroes.get()
+ || pOptCtrl == m_xEdDecimals.get()
+ || pOptCtrl == m_xEdDenominator.get()
+ || pOptCtrl == m_xBtnNegRed.get()
+ || pOptCtrl == m_xBtnThousand.get()
+ || pOptCtrl == m_xBtnEngineering.get()))
+ return;
+
+ OUString aFormat;
+ bool bThousand = ( m_xBtnThousand->get_visible() && m_xBtnThousand->get_sensitive() && m_xBtnThousand->get_active() )
+ || ( m_xBtnEngineering->get_visible() && m_xBtnEngineering->get_sensitive() && m_xBtnEngineering->get_active() );
+ bool bNegRed = m_xBtnNegRed->get_sensitive() && m_xBtnNegRed->get_active();
+ sal_uInt16 nPrecision = (m_xEdDecimals->get_sensitive() && m_xEdDecimals->get_visible())
+ ? static_cast<sal_uInt16>(m_xEdDecimals->get_value())
+ : ( (m_xEdDenominator->get_sensitive() && m_xEdDenominator->get_visible())
+ ? static_cast<sal_uInt16>(m_xEdDenominator->get_value())
+ : sal_uInt16(0) );
+ sal_uInt16 nLeadZeroes = (m_xEdLeadZeroes->get_sensitive())
+ ? static_cast<sal_uInt16>(m_xEdLeadZeroes->get_value())
+ : sal_uInt16(0);
+ if ( pNumFmtShell->GetStandardName() == m_xEdFormat->get_text() )
+ {
+ m_xEdDecimals->set_value(nPrecision);
+ }
+
+ pNumFmtShell->MakeFormat( aFormat,
+ bThousand, bNegRed,
+ nPrecision, nLeadZeroes,
+ static_cast<sal_uInt16>(m_xLbFormat->get_selected_index()) );
+
+ m_xEdFormat->set_text( aFormat );
+ MakePreviewText( aFormat );
+
+ if ( pNumFmtShell->FindEntry( aFormat ) )
+ {
+ m_xIbAdd->set_sensitive(false );
+ bool bUserDef=pNumFmtShell->IsUserDefined( aFormat );
+ m_xIbRemove->set_sensitive(bUserDef);
+ m_xIbInfo->set_sensitive(bUserDef);
+ EditHdl_Impl(m_xEdFormat.get());
+
+ }
+ else
+ {
+ EditHdl_Impl( nullptr );
+ m_xLbFormat->select(-1);
+ }
+}
+
+/*************************************************************************
+#* Method: LostFocusHdl_Impl
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: Does changes in the number attributes.
+#* Input: Options- Controls
+#* Output: ---
+#*
+#************************************************************************/
+
+IMPL_LINK_NOARG(SvxNumberFormatTabPage, LostFocusHdl_Impl, weld::Widget&, void)
+{
+ if (!pNumFmtShell)
+ return;
+
+ const bool bAddSensitive = m_xIbAdd->get_sensitive();
+ if (bAddSensitive || m_nLbFormatSelPosEdComment != SELPOS_NONE)
+ // Comment editing was possible.
+ m_xFtComment->set_label(m_xEdComment->get_text());
+
+ m_xEdComment->hide();
+ m_xFtComment->show();
+ if (m_nLbFormatSelPosEdComment != SELPOS_NONE)
+ {
+ // Save edited comment of existing format.
+ pNumFmtShell->SetComment4Entry( m_nLbFormatSelPosEdComment, m_xEdComment->get_text());
+ m_nLbFormatSelPosEdComment = SELPOS_NONE;
+ }
+ if (!bAddSensitive)
+ {
+ // String for user defined, if present
+ OUString sEntry = m_xLbCategory->n_children() > 1 ? m_xLbCategory->get_text(1) : OUString();
+ m_xEdComment->set_text(sEntry);
+ }
+}
+
+/*************************************************************************
+#* Method: NotifyChange
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: Does changes in the number attributes.
+#* Input: Options- Controls
+#* Output: ---
+#*
+#************************************************************************/
+
+OUString SvxNumberFormatTabPage::GetExpColorString(
+ const Color*& rpPreviewColor, const OUString& rFormatStr, short nTmpCatPos)
+{
+ SvxNumValCategory i;
+ switch (nTmpCatPos)
+ {
+ case CAT_ALL: i=SvxNumValCategory::Standard; break;
+
+ case CAT_NUMBER: i=SvxNumValCategory::Standard; break;
+
+ case CAT_PERCENT: i=SvxNumValCategory::Percent; break;
+
+ case CAT_CURRENCY: i=SvxNumValCategory::Currency; break;
+
+ case CAT_DATE: i=SvxNumValCategory::Date; break;
+
+ case CAT_TIME: i=SvxNumValCategory::Time; break;
+
+ case CAT_SCIENTIFIC: i=SvxNumValCategory::Scientific; break;
+
+ case CAT_FRACTION: i=SvxNumValCategory::Fraction; break;
+
+ case CAT_BOOLEAN: i=SvxNumValCategory::Boolean; break;
+
+ case CAT_USERDEFINED: i=SvxNumValCategory::Standard; break;
+
+ case CAT_TEXT:
+ default: i=SvxNumValCategory::NoValue;break;
+ }
+ double fVal = fSvxNumValConst[i];
+
+ // use lower number for long NatNum12 transliteration
+ if ( ( CAT_CURRENCY == nTmpCatPos || CAT_NUMBER == nTmpCatPos ) &&
+ rFormatStr.indexOf("NatNum12") >= 0 )
+ {
+ if ( CAT_CURRENCY == nTmpCatPos )
+ fVal = 1.2;
+ else
+ fVal = 100; // show also title case for English: One Hundred
+ }
+
+ OUString aPreviewString;
+ pNumFmtShell->MakePrevStringFromVal( rFormatStr, aPreviewString, rpPreviewColor, fVal );
+ return aPreviewString;
+}
+
+void SvxNumberFormatTabPage::MakePreviewText( const OUString& rFormat )
+{
+ OUString aPreviewString;
+ const Color* pPreviewColor = nullptr;
+ pNumFmtShell->MakePreviewString( rFormat, aPreviewString, pPreviewColor );
+ m_aWndPreview.NotifyChange( aPreviewString, pPreviewColor );
+}
+
+void SvxNumberFormatTabPage::ChangePreviewText( sal_uInt16 nPos )
+{
+ OUString aPreviewString;
+ const Color* pPreviewColor = nullptr;
+ pNumFmtShell->FormatChanged( nPos, aPreviewString, pPreviewColor );
+ m_aWndPreview.NotifyChange( aPreviewString, pPreviewColor );
+}
+
+void SvxNumberFormatTabPage::FillCurrencyBox()
+{
+ std::vector<OUString> aList;
+
+ sal_uInt16 nSelPos=0;
+ pNumFmtShell->GetCurrencySymbols(aList, &nSelPos);
+
+ m_xLbCurrency->freeze();
+ m_xLbCurrency->clear();
+ bLegacyAutomaticCurrency = false;
+ for (std::vector<OUString>::iterator i = aList.begin() + 1;i != aList.end(); ++i)
+ m_xLbCurrency->append_text(*i);
+ m_xLbCurrency->thaw();
+
+ set_active_currency(nSelPos);
+}
+
+void SvxNumberFormatTabPage::SetCategory(sal_uInt16 nPos)
+{
+ int nCurCategory = m_xLbCategory->get_selected_index();
+ sal_uInt16 nTmpCatPos;
+
+ if (bOneAreaFlag)
+ {
+ nTmpCatPos=nFixedCategory;
+ }
+ else
+ {
+ nTmpCatPos=nPos;
+ }
+
+ if(m_xLbCategory->n_children()==1 || nCurCategory!=nPos)
+ {
+ if(nTmpCatPos!=CAT_CURRENCY)
+ m_xLbCurrency->hide();
+ else
+ m_xLbCurrency->show();
+ }
+ m_xLbCategory->select(nPos);
+}
+
+/* to support Writer text field language handling an
+ additional entry needs to be inserted into the ListBox
+ which marks a certain language as automatically detected
+ Additionally the "Default" language is removed
+*/
+void SvxNumberFormatTabPage::AddAutomaticLanguage_Impl(LanguageType eAutoLang, bool bSelect)
+{
+ m_xLbLanguage->remove_id(LANGUAGE_SYSTEM);
+ m_xLbLanguage->append(eAutoLang, sAutomaticLangEntry);
+ if (bSelect)
+ m_xLbLanguage->set_active_id(eAutoLang);
+}
+
+void SvxNumberFormatTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SvxNumberInfoItem* pNumberInfoItem = aSet.GetItem<SvxNumberInfoItem>(SID_ATTR_NUMBERFORMAT_INFO, false);
+ if (pNumberInfoItem && !pNumItem)
+ pNumItem.reset(pNumberInfoItem->Clone());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/numpages.cxx b/cui/source/tabpages/numpages.cxx
new file mode 100644
index 0000000000..d1cb793412
--- /dev/null
+++ b/cui/source/tabpages/numpages.cxx
@@ -0,0 +1,3400 @@
+/* -*- 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/text/VertOrientation.hpp>
+
+#include <numpages.hxx>
+#include <dialmgr.hxx>
+#include <tools/mapunit.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <i18nlangtag/mslangid.hxx>
+#include <editeng/numitem.hxx>
+#include <svl/eitem.hxx>
+#include <vcl/svapp.hxx>
+#include <svx/colorbox.hxx>
+#include <svx/dlgutil.hxx>
+#include <svx/strarray.hxx>
+#include <svx/gallery.hxx>
+#include <editeng/brushitem.hxx>
+#include <svl/intitem.hxx>
+#include <sfx2/objsh.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/settings.hxx>
+#include <cui/cuicharmap.hxx>
+#include <editeng/flstitem.hxx>
+#include <svx/numvset.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <unotools/pathoptions.hxx>
+#include <svtools/ctrltool.hxx>
+#include <svtools/unitconv.hxx>
+#include <svtools/colorcfg.hxx>
+#include <com/sun/star/style/NumberingType.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/text/XDefaultNumberingProvider.hpp>
+#include <com/sun/star/text/XNumberingFormatter.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <comphelper/lok.hxx>
+#include <svx/svxids.hrc>
+#include <o3tl/string_view.hxx>
+
+#include <algorithm>
+#include <memory>
+#include <vector>
+#include <sfx2/opengrf.hxx>
+
+#include <strings.hrc>
+#include <svl/stritem.hxx>
+#include <svl/slstitm.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <com/sun/star/ucb/SimpleFileAccess.hpp>
+#include <sal/log.hxx>
+#include <vcl/cvtgrf.hxx>
+#include <vcl/graphicfilter.hxx>
+#include <svx/SvxNumOptionsTabPageHelper.hxx>
+#include <tools/urlobj.hxx>
+#include <o3tl/temporary.hxx>
+#include <osl/diagnose.h>
+
+using namespace css;
+using namespace css::uno;
+using namespace css::beans;
+using namespace css::lang;
+using namespace css::text;
+using namespace css::container;
+using namespace css::style;
+
+#define SHOW_NUMBERING 0
+#define SHOW_BULLET 1
+#define SHOW_BITMAP 2
+
+#define MAX_BMP_WIDTH 16
+#define MAX_BMP_HEIGHT 16
+#define SEARCHPATH_DELIMITER u';'
+#define SEARCHFILENAME_DELIMITER u'/'
+
+static bool bLastRelative = false;
+
+static SvxNumSettings_Impl* lcl_CreateNumSettingsPtr(const Sequence<PropertyValue>& rLevelProps)
+{
+ const PropertyValue* pValues = rLevelProps.getConstArray();
+ SvxNumSettings_Impl* pNew = new SvxNumSettings_Impl;
+ for(sal_Int32 j = 0; j < rLevelProps.getLength(); j++)
+ {
+ if ( pValues[j].Name == "NumberingType" )
+ {
+ sal_Int16 nTmp;
+ if (pValues[j].Value >>= nTmp)
+ pNew->nNumberType = static_cast<SvxNumType>(nTmp);
+ }
+ else if ( pValues[j].Name == "Prefix" )
+ pValues[j].Value >>= pNew->sPrefix;
+ else if ( pValues[j].Name == "Suffix" )
+ pValues[j].Value >>= pNew->sSuffix;
+ else if ( pValues[j].Name == "ParentNumbering" )
+ pValues[j].Value >>= pNew->nParentNumbering;
+ else if ( pValues[j].Name == "BulletChar" )
+ pValues[j].Value >>= pNew->sBulletChar;
+ else if ( pValues[j].Name == "BulletFontName" )
+ pValues[j].Value >>= pNew->sBulletFont;
+ }
+ return pNew;
+}
+
+// the selection of bullets from the OpenSymbol
+const sal_Unicode aBulletTypes[] =
+{
+ 0x2022,
+ 0x25cf,
+ 0xe00c,
+ 0xe00a,
+ 0x2794,
+ 0x27a2,
+ 0x2717,
+ 0x2714
+};
+
+// Is one of the masked formats set?
+static bool lcl_IsNumFmtSet(SvxNumRule const * pNum, sal_uInt16 nLevelMask)
+{
+ bool bRet = false;
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < SVX_MAX_NUM && !bRet; i++ )
+ {
+ if(nLevelMask & nMask)
+ bRet |= nullptr != pNum->Get( i );
+ nMask <<= 1 ;
+ }
+ return bRet;
+}
+
+static const vcl::Font& lcl_GetDefaultBulletFont()
+{
+ static vcl::Font aDefBulletFont = []()
+ {
+ vcl::Font tmp("OpenSymbol", "", Size(0, 14));
+ tmp.SetCharSet( RTL_TEXTENCODING_SYMBOL );
+ tmp.SetFamily( FAMILY_DONTKNOW );
+ tmp.SetPitch( PITCH_DONTKNOW );
+ tmp.SetWeight( WEIGHT_DONTKNOW );
+ tmp.SetTransparent( true );
+ return tmp;
+ }();
+ return aDefBulletFont;
+}
+
+SvxSingleNumPickTabPage::SvxSingleNumPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/picknumberingpage.ui", "PickNumberingPage", &rSet)
+ , nActNumLvl(SAL_MAX_UINT16)
+ , bModified(false)
+ , bPreset(false)
+ , nNumItemId(SID_ATTR_NUMBERING_RULE)
+ , m_xExamplesVS(new SvxNumValueSet(m_xBuilder->weld_scrolled_window("valuesetwin", true)))
+ , m_xExamplesVSWin(new weld::CustomWeld(*m_xBuilder, "valueset", *m_xExamplesVS))
+{
+ SetExchangeSupport();
+ m_xExamplesVS->init(NumberingPageType::SINGLENUM);
+ m_xExamplesVS->SetSelectHdl(LINK(this, SvxSingleNumPickTabPage, NumSelectHdl_Impl));
+ m_xExamplesVS->SetDoubleClickHdl(LINK(this, SvxSingleNumPickTabPage, DoubleClickHdl_Impl));
+
+ Reference<XDefaultNumberingProvider> xDefNum = SvxNumOptionsTabPageHelper::GetNumberingProvider();
+ if(!xDefNum.is())
+ return;
+
+ Sequence< Sequence< PropertyValue > > aNumberings;
+ const Locale& rLocale = Application::GetSettings().GetLanguageTag().getLocale();
+ try
+ {
+ aNumberings =
+ xDefNum->getDefaultContinuousNumberingLevels( rLocale );
+
+
+ sal_Int32 nLength = std::min<sal_Int32>(aNumberings.getLength(), NUM_VALUSET_COUNT);
+
+ const Sequence<PropertyValue>* pValuesArr = aNumberings.getConstArray();
+ for(sal_Int32 i = 0; i < nLength; i++)
+ {
+ SvxNumSettings_Impl* pNew = lcl_CreateNumSettingsPtr(pValuesArr[i]);
+ aNumSettingsArr.push_back(std::unique_ptr<SvxNumSettings_Impl>(pNew));
+ }
+ }
+ catch(const Exception&)
+ {
+ }
+ Reference<XNumberingFormatter> xFormat(xDefNum, UNO_QUERY);
+ m_xExamplesVS->SetNumberingSettings(aNumberings, xFormat, rLocale);
+}
+
+SvxSingleNumPickTabPage::~SvxSingleNumPickTabPage()
+{
+ m_xExamplesVSWin.reset();
+ m_xExamplesVS.reset();
+}
+
+std::unique_ptr<SfxTabPage> SvxSingleNumPickTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxSingleNumPickTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxSingleNumPickTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ if( (bPreset || bModified) && pSaveNum)
+ {
+ *pSaveNum = *pActNum;
+ rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ));
+ rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, bPreset));
+ }
+
+ return bModified;
+}
+
+void SvxSingleNumPickTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ bPreset = false;
+ bool bIsPreset = false;
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ if(pExampleSet)
+ {
+ if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false))
+ bIsPreset = pPresetItem->GetValue();
+ if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false))
+ nActNumLvl = pLevelItem->GetValue();
+ }
+ if(const SvxNumBulletItem* pNumItem = rSet.GetItemIfSet(nNumItemId, false))
+ {
+ pSaveNum.reset( new SvxNumRule(pNumItem->GetNumRule()) );
+ }
+ if(pActNum && *pSaveNum != *pActNum)
+ {
+ *pActNum = *pSaveNum;
+ m_xExamplesVS->SetNoSelection();
+ }
+
+ if(pActNum && (!lcl_IsNumFmtSet(pActNum.get(), nActNumLvl) || bIsPreset))
+ {
+ m_xExamplesVS->SelectItem(1);
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ bPreset = true;
+ }
+ bPreset |= bIsPreset;
+
+ bModified = false;
+}
+
+DeactivateRC SvxSingleNumPickTabPage::DeactivatePage(SfxItemSet *_pSet)
+{
+ if(_pSet)
+ FillItemSet(_pSet);
+ return DeactivateRC::LeavePage;
+}
+
+void SvxSingleNumPickTabPage::Reset( const SfxItemSet* rSet )
+{
+ const SfxPoolItem* pItem;
+
+ // in Draw the item exists as WhichId, in Writer only as SlotId
+ SfxItemState eState = rSet->GetItemState(SID_ATTR_NUMBERING_RULE, false, &pItem);
+ if(eState != SfxItemState::SET)
+ {
+ nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE);
+ eState = rSet->GetItemState(nNumItemId, false, &pItem);
+
+ if( eState != SfxItemState::SET )
+ {
+ pItem = & rSet->Get( nNumItemId );
+ eState = SfxItemState::SET;
+ }
+ }
+ DBG_ASSERT(eState == SfxItemState::SET, "no item found!");
+ pSaveNum.reset( new SvxNumRule(static_cast<const SvxNumBulletItem*>(pItem)->GetNumRule()) );
+
+ if(!pActNum)
+ pActNum.reset( new SvxNumRule(*pSaveNum) );
+ else if(*pSaveNum != *pActNum)
+ *pActNum = *pSaveNum;
+}
+
+IMPL_LINK_NOARG(SvxSingleNumPickTabPage, NumSelectHdl_Impl, ValueSet*, void)
+{
+ if(!pActNum)
+ return;
+
+ bPreset = false;
+ bModified = true;
+ sal_uInt16 nIdx = m_xExamplesVS->GetSelectedItemId() - 1;
+ DBG_ASSERT(aNumSettingsArr.size() > nIdx, "wrong index");
+ if(aNumSettingsArr.size() <= nIdx)
+ return;
+ SvxNumSettings_Impl* _pSet = aNumSettingsArr[nIdx].get();
+ SvxNumType eNewType = _pSet->nNumberType;
+ const sal_Unicode cLocalPrefix = !_pSet->sPrefix.isEmpty() ? _pSet->sPrefix[0] : 0;
+ const sal_Unicode cLocalSuffix = !_pSet->sSuffix.isEmpty() ? _pSet->sSuffix[0] : 0;
+
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aFmt(pActNum->GetLevel(i));
+ aFmt.SetNumberingType(eNewType);
+ aFmt.SetListFormat(cLocalPrefix == ' ' ? "" : _pSet->sPrefix,
+ cLocalSuffix == ' ' ? "" : _pSet->sSuffix, i);
+ aFmt.SetCharFormatName("");
+ aFmt.SetBulletRelSize(100);
+ pActNum->SetLevel(i, aFmt);
+ }
+ nMask <<= 1;
+ }
+}
+
+IMPL_LINK_NOARG(SvxSingleNumPickTabPage, DoubleClickHdl_Impl, ValueSet*, void)
+{
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ weld::Button& rOk = GetDialogController()->GetOKButton();
+ rOk.clicked();
+}
+
+SvxBulletPickTabPage::SvxBulletPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/pickbulletpage.ui", "PickBulletPage", &rSet)
+ , nActNumLvl(SAL_MAX_UINT16)
+ , bModified(false)
+ , bPreset(false)
+ , nNumItemId(SID_ATTR_NUMBERING_RULE)
+ , m_xExamplesVS(new SvxNumValueSet(m_xBuilder->weld_scrolled_window("valuesetwin", true)))
+ , m_xExamplesVSWin(new weld::CustomWeld(*m_xBuilder, "valueset", *m_xExamplesVS))
+{
+ SetExchangeSupport();
+ m_xExamplesVS->init(NumberingPageType::BULLET);
+ m_xExamplesVS->SetSelectHdl(LINK(this, SvxBulletPickTabPage, NumSelectHdl_Impl));
+ m_xExamplesVS->SetDoubleClickHdl(LINK(this, SvxBulletPickTabPage, DoubleClickHdl_Impl));
+}
+
+SvxBulletPickTabPage::~SvxBulletPickTabPage()
+{
+ m_xExamplesVSWin.reset();
+ m_xExamplesVS.reset();
+}
+
+std::unique_ptr<SfxTabPage> SvxBulletPickTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxBulletPickTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxBulletPickTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ if( (bPreset || bModified) && pActNum)
+ {
+ *pSaveNum = *pActNum;
+ rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ));
+ rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, bPreset));
+ }
+ return bModified;
+}
+
+void SvxBulletPickTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ bPreset = false;
+ bool bIsPreset = false;
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ if(pExampleSet)
+ {
+ if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false))
+ bIsPreset = pPresetItem->GetValue();
+ if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false))
+ nActNumLvl = pLevelItem->GetValue();
+ }
+ if(const SvxNumBulletItem* pBulletItem = rSet.GetItemIfSet(nNumItemId, false))
+ {
+ pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) );
+ }
+ if(pActNum && *pSaveNum != *pActNum)
+ {
+ *pActNum = *pSaveNum;
+ m_xExamplesVS->SetNoSelection();
+ }
+
+ if(pActNum && (!lcl_IsNumFmtSet(pActNum.get(), nActNumLvl) || bIsPreset))
+ {
+ m_xExamplesVS->SelectItem(1);
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ bPreset = true;
+ }
+ bPreset |= bIsPreset;
+ bModified = false;
+}
+
+DeactivateRC SvxBulletPickTabPage::DeactivatePage(SfxItemSet *_pSet)
+{
+ if(_pSet)
+ FillItemSet(_pSet);
+ return DeactivateRC::LeavePage;
+}
+
+void SvxBulletPickTabPage::Reset( const SfxItemSet* rSet )
+{
+ // in Draw the item exists as WhichId, in Writer only as SlotId
+ const SvxNumBulletItem* pItem = rSet->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false);
+ if(!pItem)
+ {
+ nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE);
+ pItem = rSet->GetItemIfSet(nNumItemId, false);
+
+ if( !pItem )
+ {
+ pItem = & rSet->Get( nNumItemId );
+ }
+
+ }
+ pSaveNum.reset( new SvxNumRule(pItem->GetNumRule()) );
+
+ if(!pActNum)
+ pActNum.reset( new SvxNumRule(*pSaveNum) );
+ else if(*pSaveNum != *pActNum)
+ *pActNum = *pSaveNum;
+}
+
+IMPL_LINK_NOARG(SvxBulletPickTabPage, NumSelectHdl_Impl, ValueSet*, void)
+{
+ if(!pActNum)
+ return;
+
+ bPreset = false;
+ bModified = true;
+ sal_Unicode cChar = aBulletTypes[m_xExamplesVS->GetSelectedItemId() - 1];
+ const vcl::Font& rActBulletFont = lcl_GetDefaultBulletFont();
+
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aFmt(pActNum->GetLevel(i));
+ aFmt.SetNumberingType( SVX_NUM_CHAR_SPECIAL );
+ // #i93908# clear suffix for bullet lists
+ aFmt.SetListFormat("", "", i);
+ aFmt.SetBulletFont(&rActBulletFont);
+ aFmt.SetBulletChar(cChar );
+ aFmt.SetCharFormatName(sBulletCharFormatName);
+ aFmt.SetBulletRelSize(45);
+ pActNum->SetLevel(i, aFmt);
+ }
+ nMask <<= 1;
+ }
+}
+
+IMPL_LINK_NOARG(SvxBulletPickTabPage, DoubleClickHdl_Impl, ValueSet*, void)
+{
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ weld::Button& rOk = GetDialogController()->GetOKButton();
+ rOk.clicked();
+}
+
+void SvxBulletPickTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxStringItem* pBulletCharFmt = aSet.GetItem<SfxStringItem>(SID_BULLET_CHAR_FMT, false);
+
+ if (pBulletCharFmt)
+ sBulletCharFormatName = pBulletCharFmt->GetValue();
+}
+
+SvxNumPickTabPage::SvxNumPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/pickoutlinepage.ui", "PickOutlinePage", &rSet)
+ , nActNumLvl(SAL_MAX_UINT16)
+ , nNumItemId(SID_ATTR_NUMBERING_RULE)
+ , bModified(false)
+ , bPreset(false)
+ , m_xExamplesVS(new SvxNumValueSet(m_xBuilder->weld_scrolled_window("valuesetwin", true)))
+ , m_xExamplesVSWin(new weld::CustomWeld(*m_xBuilder, "valueset", *m_xExamplesVS))
+{
+ SetExchangeSupport();
+
+ m_xExamplesVS->init(NumberingPageType::OUTLINE);
+ m_xExamplesVS->SetSelectHdl(LINK(this, SvxNumPickTabPage, NumSelectHdl_Impl));
+ m_xExamplesVS->SetDoubleClickHdl(LINK(this, SvxNumPickTabPage, DoubleClickHdl_Impl));
+
+ Reference<XDefaultNumberingProvider> xDefNum = SvxNumOptionsTabPageHelper::GetNumberingProvider();
+ if(!xDefNum.is())
+ return;
+
+ Sequence<Reference<XIndexAccess> > aOutlineAccess;
+ const Locale& rLocale = Application::GetSettings().GetLanguageTag().getLocale();
+ try
+ {
+ aOutlineAccess = xDefNum->getDefaultOutlineNumberings( rLocale );
+
+ for(sal_Int32 nItem = 0;
+ nItem < aOutlineAccess.getLength() && nItem < NUM_VALUSET_COUNT;
+ nItem++ )
+ {
+ SvxNumSettingsArr_Impl& rItemArr = aNumSettingsArrays[ nItem ];
+
+ Reference<XIndexAccess> xLevel = aOutlineAccess.getConstArray()[nItem];
+ for(sal_Int32 nLevel = 0; nLevel < SVX_MAX_NUM; nLevel++)
+ {
+ // use the last locale-defined level for all remaining levels.
+ sal_Int32 nLocaleLevel = std::min(nLevel, xLevel->getCount() - 1);
+ Sequence<PropertyValue> aLevelProps;
+ if (nLocaleLevel >= 0)
+ xLevel->getByIndex(nLocaleLevel) >>= aLevelProps;
+
+ SvxNumSettings_Impl* pNew = lcl_CreateNumSettingsPtr(aLevelProps);
+ rItemArr.push_back( std::unique_ptr<SvxNumSettings_Impl>(pNew) );
+ }
+ }
+ }
+ catch(const Exception&)
+ {
+ }
+ Reference<XNumberingFormatter> xFormat(xDefNum, UNO_QUERY);
+ m_xExamplesVS->SetOutlineNumberingSettings(aOutlineAccess, xFormat, rLocale);
+}
+
+SvxNumPickTabPage::~SvxNumPickTabPage()
+{
+ m_xExamplesVSWin.reset();
+ m_xExamplesVS.reset();
+}
+
+std::unique_ptr<SfxTabPage> SvxNumPickTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxNumPickTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxNumPickTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ if( (bPreset || bModified) && pActNum)
+ {
+ *pSaveNum = *pActNum;
+ rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ));
+ rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, bPreset));
+ }
+ return bModified;
+}
+
+void SvxNumPickTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ bPreset = false;
+ bool bIsPreset = false;
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ if(pExampleSet)
+ {
+ if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false))
+ bIsPreset = pPresetItem->GetValue();
+ if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false))
+ nActNumLvl = pLevelItem->GetValue();
+ }
+ if(const SvxNumBulletItem* pBulletItem = rSet.GetItemIfSet(nNumItemId, false))
+ {
+ pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) );
+ }
+ if(pActNum && *pSaveNum != *pActNum)
+ {
+ *pActNum = *pSaveNum;
+ m_xExamplesVS->SetNoSelection();
+ }
+
+ if(pActNum && (!lcl_IsNumFmtSet(pActNum.get(), nActNumLvl) || bIsPreset))
+ {
+ m_xExamplesVS->SelectItem(1);
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ bPreset = true;
+ }
+ bPreset |= bIsPreset;
+ bModified = false;
+}
+
+DeactivateRC SvxNumPickTabPage::DeactivatePage(SfxItemSet *_pSet)
+{
+ if(_pSet)
+ FillItemSet(_pSet);
+ return DeactivateRC::LeavePage;
+}
+
+void SvxNumPickTabPage::Reset( const SfxItemSet* rSet )
+{
+ // in Draw the item exists as WhichId, in Writer only as SlotId
+ const SvxNumBulletItem* pItem = rSet->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false);
+ if(!pItem)
+ {
+ nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE);
+ pItem = rSet->GetItemIfSet(nNumItemId, false);
+
+ if( !pItem )
+ {
+ pItem = & rSet->Get( nNumItemId );
+ }
+ }
+ pSaveNum.reset( new SvxNumRule(pItem->GetNumRule()) );
+
+ if(!pActNum)
+ pActNum.reset( new SvxNumRule(*pSaveNum) );
+ else if(*pSaveNum != *pActNum)
+ *pActNum = *pSaveNum;
+
+}
+
+// all levels are changed here
+IMPL_LINK_NOARG(SvxNumPickTabPage, NumSelectHdl_Impl, ValueSet*, void)
+{
+ if(!pActNum)
+ return;
+
+ bPreset = false;
+ bModified = true;
+
+ const FontList* pList = nullptr;
+
+ SvxNumSettingsArr_Impl& rItemArr = aNumSettingsArrays[m_xExamplesVS->GetSelectedItemId() - 1];
+
+ const vcl::Font& rActBulletFont = lcl_GetDefaultBulletFont();
+ SvxNumSettings_Impl* pLevelSettings = nullptr;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(rItemArr.size() > i)
+ pLevelSettings = rItemArr[i].get();
+ if(!pLevelSettings)
+ break;
+ SvxNumberFormat aFmt(pActNum->GetLevel(i));
+ aFmt.SetNumberingType( pLevelSettings->nNumberType );
+ sal_uInt16 nUpperLevelOrChar = static_cast<sal_uInt16>(pLevelSettings->nParentNumbering);
+ if(aFmt.GetNumberingType() == SVX_NUM_CHAR_SPECIAL)
+ {
+ // #i93908# clear suffix for bullet lists
+ aFmt.SetListFormat("", "", i);
+ if( !pLevelSettings->sBulletFont.isEmpty() &&
+ pLevelSettings->sBulletFont != rActBulletFont.GetFamilyName())
+ {
+ //search for the font
+ if(!pList)
+ {
+ if (SfxObjectShell* pCurDocShell = SfxObjectShell::Current())
+ {
+ const SvxFontListItem* pFontListItem =
+ static_cast<const SvxFontListItem*>( pCurDocShell
+ ->GetItem( SID_ATTR_CHAR_FONTLIST ));
+ pList = pFontListItem ? pFontListItem->GetFontList() : nullptr;
+ }
+ }
+ if(pList && pList->IsAvailable( pLevelSettings->sBulletFont ) )
+ {
+ FontMetric aFontMetric = pList->Get(
+ pLevelSettings->sBulletFont,WEIGHT_NORMAL, ITALIC_NONE);
+ vcl::Font aFont(aFontMetric);
+ aFmt.SetBulletFont(&aFont);
+ }
+ else
+ {
+ //if it cannot be found then create a new one
+ vcl::Font aCreateFont( pLevelSettings->sBulletFont,
+ OUString(), Size( 0, 14 ) );
+ aCreateFont.SetCharSet( RTL_TEXTENCODING_DONTKNOW );
+ aCreateFont.SetFamily( FAMILY_DONTKNOW );
+ aCreateFont.SetPitch( PITCH_DONTKNOW );
+ aCreateFont.SetWeight( WEIGHT_DONTKNOW );
+ aCreateFont.SetTransparent( true );
+ aFmt.SetBulletFont( &aCreateFont );
+ }
+ }
+ else
+ aFmt.SetBulletFont( &rActBulletFont );
+
+ aFmt.SetBulletChar( !pLevelSettings->sBulletChar.isEmpty()
+ ? pLevelSettings->sBulletChar.iterateCodePoints(
+ &o3tl::temporary(sal_Int32(0)))
+ : 0 );
+ aFmt.SetCharFormatName( sBulletCharFormatName );
+ aFmt.SetBulletRelSize(45);
+ }
+ else
+ {
+ aFmt.SetIncludeUpperLevels(sal::static_int_cast< sal_uInt8 >(0 != nUpperLevelOrChar ? pActNum->GetLevelCount() : 1));
+ aFmt.SetCharFormatName(sNumCharFmtName);
+ aFmt.SetBulletRelSize(100);
+
+ // Completely ignore the Left/Right value provided by the locale outline definition,
+ // because this function doesn't actually modify the indents at all,
+ // and right-adjusted numbering definitely needs a different FirstLineIndent.
+
+ // #i93908#
+ aFmt.SetListFormat(pLevelSettings->sPrefix, pLevelSettings->sSuffix, i);
+ }
+ pActNum->SetLevel(i, aFmt);
+ }
+}
+
+IMPL_LINK_NOARG(SvxNumPickTabPage, DoubleClickHdl_Impl, ValueSet*, void)
+{
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ weld::Button& rOk = GetDialogController()->GetOKButton();
+ rOk.clicked();
+}
+
+void SvxNumPickTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxStringItem* pNumCharFmt = aSet.GetItem<SfxStringItem>(SID_NUM_CHAR_FMT, false);
+ const SfxStringItem* pBulletCharFmt = aSet.GetItem<SfxStringItem>(SID_BULLET_CHAR_FMT, false);
+
+
+ if (pNumCharFmt &&pBulletCharFmt)
+ SetCharFormatNames( pNumCharFmt->GetValue(),pBulletCharFmt->GetValue());
+}
+
+SvxBitmapPickTabPage::SvxBitmapPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/pickgraphicpage.ui", "PickGraphicPage", &rSet)
+ , nActNumLvl(SAL_MAX_UINT16)
+ , nNumItemId(SID_ATTR_NUMBERING_RULE)
+ , bModified(false)
+ , bPreset(false)
+ , m_xErrorText(m_xBuilder->weld_label("errorft"))
+ , m_xBtBrowseFile(m_xBuilder->weld_button("browseBtn"))
+ , m_xExamplesVS(new SvxBmpNumValueSet(m_xBuilder->weld_scrolled_window("valuesetwin", true)))
+ , m_xExamplesVSWin(new weld::CustomWeld(*m_xBuilder, "valueset", *m_xExamplesVS))
+{
+ SetExchangeSupport();
+
+ m_xExamplesVS->init();
+ m_xExamplesVS->SetSelectHdl(LINK(this, SvxBitmapPickTabPage, NumSelectHdl_Impl));
+ m_xExamplesVS->SetDoubleClickHdl(LINK(this, SvxBitmapPickTabPage, DoubleClickHdl_Impl));
+ m_xBtBrowseFile->connect_clicked(LINK(this, SvxBitmapPickTabPage, ClickAddBrowseHdl_Impl));
+
+ eCoreUnit = rSet.GetPool()->GetMetric(rSet.GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE));
+
+ // determine graphic name
+ GalleryExplorer::FillObjList(GALLERY_THEME_BULLETS, aGrfNames);
+
+ size_t i = 0;
+ for (auto & grfName : aGrfNames)
+ {
+ m_xExamplesVS->InsertItem( i + 1, i);
+
+ INetURLObject aObj(grfName);
+ if (aObj.GetProtocol() == INetProtocol::File)
+ {
+ // tdf#114070 - only show the last name of the filename without its extension
+ aObj.removeExtension();
+ grfName = aObj.GetLastName(INetURLObject::DecodeMechanism::Unambiguous);
+ }
+
+ m_xExamplesVS->SetItemText( i + 1, grfName );
+ ++i;
+ }
+
+ if(aGrfNames.empty())
+ {
+ m_xErrorText->show();
+ }
+ else
+ {
+ m_xExamplesVS->Show();
+ m_xExamplesVS->SetFormat();
+ m_xExamplesVS->Invalidate();
+ }
+}
+
+SvxBitmapPickTabPage::~SvxBitmapPickTabPage()
+{
+ m_xExamplesVSWin.reset();
+ m_xExamplesVS.reset();
+}
+
+std::unique_ptr<SfxTabPage> SvxBitmapPickTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxBitmapPickTabPage>(pPage, pController, *rAttrSet);
+}
+
+void SvxBitmapPickTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ bPreset = false;
+ bool bIsPreset = false;
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ if(pExampleSet)
+ {
+ if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false))
+ bIsPreset = pPresetItem->GetValue();
+ if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false))
+ nActNumLvl = pLevelItem->GetValue();
+ }
+ if(const SvxNumBulletItem* pBulletItem = rSet.GetItemIfSet(nNumItemId, false))
+ {
+ pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) );
+ }
+ if(pActNum && *pSaveNum != *pActNum)
+ {
+ *pActNum = *pSaveNum;
+ m_xExamplesVS->SetNoSelection();
+ }
+
+ if(!aGrfNames.empty() &&
+ (pActNum && (!lcl_IsNumFmtSet(pActNum.get(), nActNumLvl) || bIsPreset)))
+ {
+ m_xExamplesVS->SelectItem(1);
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ bPreset = true;
+ }
+ bPreset |= bIsPreset;
+ bModified = false;
+}
+
+DeactivateRC SvxBitmapPickTabPage::DeactivatePage(SfxItemSet *_pSet)
+{
+ if(_pSet)
+ FillItemSet(_pSet);
+ return DeactivateRC::LeavePage;
+}
+
+bool SvxBitmapPickTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ if ( aGrfNames.empty() )
+ {
+ return false;
+ }
+ if( (bPreset || bModified) && pActNum)
+ {
+ *pSaveNum = *pActNum;
+ rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ) );
+ rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, bPreset));
+ }
+
+ return bModified;
+}
+
+void SvxBitmapPickTabPage::Reset( const SfxItemSet* rSet )
+{
+ // in Draw the item exists as WhichId, in Writer only as SlotId
+ const SvxNumBulletItem* pItem = rSet->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false);
+ if(!pItem)
+ {
+ nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE);
+ pItem = rSet->GetItemIfSet(nNumItemId, false);
+
+ if( !pItem )
+ {
+ pItem = & rSet->Get( nNumItemId );
+ }
+
+ }
+ DBG_ASSERT(pItem, "no item found!");
+ pSaveNum.reset( new SvxNumRule(pItem->GetNumRule()) );
+
+ if(!pActNum)
+ pActNum.reset( new SvxNumRule(*pSaveNum) );
+ else if(*pSaveNum != *pActNum)
+ *pActNum = *pSaveNum;
+}
+
+IMPL_LINK_NOARG(SvxBitmapPickTabPage, NumSelectHdl_Impl, ValueSet*, void)
+{
+ if(!pActNum)
+ return;
+
+ bPreset = false;
+ bModified = true;
+ sal_uInt16 nIdx = m_xExamplesVS->GetSelectedItemId() - 1;
+
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aFmt(pActNum->GetLevel(i));
+ aFmt.SetNumberingType(SVX_NUM_BITMAP);
+ aFmt.SetListFormat("", "", i);
+ aFmt.SetCharFormatName( "" );
+
+ Graphic aGraphic;
+ if(GalleryExplorer::GetGraphicObj( GALLERY_THEME_BULLETS, nIdx, &aGraphic))
+ {
+ Size aSize = SvxNumberFormat::GetGraphicSizeMM100(&aGraphic);
+ sal_Int16 eOrient = text::VertOrientation::LINE_CENTER;
+ aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(eCoreUnit));
+ SvxBrushItem aBrush(aGraphic, GPOS_AREA, SID_ATTR_BRUSH );
+ aFmt.SetGraphicBrush( &aBrush, &aSize, &eOrient );
+ }
+ else if(aGrfNames.size() > nIdx)
+ aFmt.SetGraphic( aGrfNames[nIdx] );
+ pActNum->SetLevel(i, aFmt);
+ }
+ nMask <<= 1;
+ }
+}
+
+IMPL_LINK_NOARG(SvxBitmapPickTabPage, DoubleClickHdl_Impl, ValueSet*, void)
+{
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ weld::Button& rOk = GetDialogController()->GetOKButton();
+ rOk.clicked();
+}
+
+IMPL_LINK_NOARG(SvxBitmapPickTabPage, ClickAddBrowseHdl_Impl, weld::Button&, void)
+{
+ sfx2::FileDialogHelper aFileDialog(0, FileDialogFlags::NONE, GetFrameWeld());
+ aFileDialog.SetContext(sfx2::FileDialogHelper::BulletsAddImage);
+ aFileDialog.SetTitle(CuiResId(RID_CUISTR_ADD_IMAGE));
+ if ( aFileDialog.Execute() != ERRCODE_NONE )
+ return;
+
+ OUString aPath = SvtPathOptions().GetGalleryPath();
+ std::u16string_view aPathToken = o3tl::getToken(aPath, 1 , SEARCHPATH_DELIMITER );
+
+ OUString aUserImageURL = aFileDialog.GetPath();
+
+ OUString aFileName;
+ const sal_Int32 nPos {aUserImageURL.lastIndexOf(SEARCHFILENAME_DELIMITER)+1};
+ if (nPos<=0)
+ aFileName = aUserImageURL;
+ else if (nPos<aUserImageURL.getLength())
+ aFileName = aUserImageURL.copy(nPos);
+
+ OUString aUserGalleryURL = OUString::Concat(aPathToken) + "/" + aFileName;
+ INetURLObject aURL( aUserImageURL );
+ DBG_ASSERT( aURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
+
+ GraphicDescriptor aDescriptor(aURL);
+ if (!aDescriptor.Detect())
+ return;
+
+ uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ uno::Reference<ucb::XSimpleFileAccess3> xSimpleFileAccess(
+ ucb::SimpleFileAccess::create( ::comphelper::getComponentContext(xFactory) ) );
+ if ( !xSimpleFileAccess->exists( aUserImageURL ))
+ return;
+
+ xSimpleFileAccess->copy( aUserImageURL, aUserGalleryURL );
+ INetURLObject gURL( aUserGalleryURL );
+ std::unique_ptr<SvStream> pIn(::utl::UcbStreamHelper::CreateStream(
+ gURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ ));
+ if ( !pIn )
+ return;
+
+ Graphic aGraphic;
+ GraphicConverter::Import( *pIn, aGraphic );
+
+ BitmapEx aBitmap = aGraphic.GetBitmapEx();
+ tools::Long nPixelX = aBitmap.GetSizePixel().Width();
+ tools::Long nPixelY = aBitmap.GetSizePixel().Height();
+ double ratio = nPixelY/static_cast<double>(nPixelX);
+ if(nPixelX > 30)
+ {
+ nPixelX = 30;
+ nPixelY = static_cast<tools::Long>(nPixelX*ratio);
+ }
+ if(nPixelY > 30)
+ {
+ nPixelY = 30;
+ nPixelX = static_cast<tools::Long>(nPixelY/ratio);
+ }
+
+ aBitmap.Scale( Size( nPixelX, nPixelY ), BmpScaleFlag::Fast );
+ Graphic aScaledGraphic( aBitmap );
+ GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
+
+ Sequence< PropertyValue > aFilterData{
+ comphelper::makePropertyValue("Compression", sal_Int32(-1)),
+ comphelper::makePropertyValue("Quality", sal_Int32(1))
+ };
+
+ sal_uInt16 nFilterFormat = rFilter.GetExportFormatNumberForShortName( gURL.GetFileExtension() );
+ rFilter.ExportGraphic( aScaledGraphic, gURL , nFilterFormat, &aFilterData );
+ GalleryExplorer::InsertURL( GALLERY_THEME_BULLETS, aUserGalleryURL );
+
+ aGrfNames.push_back(aUserGalleryURL);
+ size_t i = 0;
+ for (auto & grfName : aGrfNames)
+ {
+ m_xExamplesVS->InsertItem( i + 1, i);
+ INetURLObject aObj(grfName);
+ if (aObj.GetProtocol() == INetProtocol::File)
+ {
+ // tdf#114070 - only show the last name of the filename without its extension
+ aObj.removeExtension();
+ grfName = aObj.GetLastName(INetURLObject::DecodeMechanism::Unambiguous);
+ }
+ m_xExamplesVS->SetItemText( i + 1, grfName );
+ ++i;
+ }
+
+ if(aGrfNames.empty())
+ {
+ m_xErrorText->show();
+ }
+ else
+ {
+ m_xExamplesVS->Show();
+ m_xExamplesVS->SetFormat();
+ }
+}
+
+// tabpage numbering options
+SvxNumOptionsTabPage::SvxNumOptionsTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/numberingoptionspage.ui", "NumberingOptionsPage", &rSet)
+ , aInvalidateTimer("cui SvxNumOptionsTabPage aInvalidateTimer")
+ , m_pLevelHdlEvent(nullptr)
+ , bLastWidthModified(false)
+ , bModified(false)
+ , bPreset(false)
+ , bAutomaticCharStyles(true)
+ , bHTMLMode(false)
+ , nBullet(0xff)
+ , nActNumLvl(1)
+ , nNumItemId(SID_ATTR_NUMBERING_RULE)
+ , m_xGrid(m_xBuilder->weld_widget("grid2"))
+ , m_xLevelLB(m_xBuilder->weld_tree_view("levellb"))
+ , m_xFmtLB(m_xBuilder->weld_combo_box("numfmtlb"))
+ , m_xSeparatorFT(m_xBuilder->weld_label("separator"))
+ , m_xPrefixFT(m_xBuilder->weld_label("prefixft"))
+ , m_xPrefixED(m_xBuilder->weld_entry("prefix"))
+ , m_xSuffixFT(m_xBuilder->weld_label("suffixft"))
+ , m_xSuffixED(m_xBuilder->weld_entry("suffix"))
+ , m_xCharFmtFT(m_xBuilder->weld_label("charstyleft"))
+ , m_xCharFmtLB(m_xBuilder->weld_combo_box("charstyle"))
+ , m_xBulColorFT(m_xBuilder->weld_label("colorft"))
+ , m_xBulColLB(new ColorListBox(m_xBuilder->weld_menu_button("color"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xBulRelSizeFT(m_xBuilder->weld_label("relsizeft"))
+ , m_xBulRelSizeMF(m_xBuilder->weld_metric_spin_button("relsize", FieldUnit::PERCENT))
+ , m_xAllLevelFT(m_xBuilder->weld_label("sublevelsft"))
+ , m_xAllLevelNF(m_xBuilder->weld_spin_button("sublevels"))
+ , m_xIsLegalCB(m_xBuilder->weld_check_button("islegal"))
+ , m_xStartFT(m_xBuilder->weld_label("startatft"))
+ , m_xStartED(m_xBuilder->weld_spin_button("startat"))
+ , m_xBulletFT(m_xBuilder->weld_label("bulletft"))
+ , m_xBulletPB(m_xBuilder->weld_button("bullet"))
+ , m_xBitmapFT(m_xBuilder->weld_label("bitmapft"))
+ , m_xBitmapMB(m_xBuilder->weld_menu_button("bitmap"))
+ , m_xWidthFT(m_xBuilder->weld_label("widthft"))
+ , m_xWidthMF(m_xBuilder->weld_metric_spin_button("widthmf", FieldUnit::CM))
+ , m_xHeightFT(m_xBuilder->weld_label("heightft"))
+ , m_xHeightMF(m_xBuilder->weld_metric_spin_button("heightmf", FieldUnit::CM))
+ , m_xRatioCB(m_xBuilder->weld_check_button("keepratio"))
+ , m_xOrientFT(m_xBuilder->weld_label("orientft"))
+ , m_xOrientLB(m_xBuilder->weld_combo_box("orientlb"))
+ , m_xAllLevelsFrame(m_xBuilder->weld_widget("levelsframe"))
+ , m_xSameLevelCB(m_xBuilder->weld_check_button("allsame"))
+ , m_xPreviewWIN(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWIN))
+{
+ m_xBulColLB->SetSlotId(SID_ATTR_CHAR_COLOR);
+ m_xBulRelSizeMF->set_min(SVX_NUM_REL_SIZE_MIN, FieldUnit::PERCENT);
+ m_xBulRelSizeMF->set_increments(5, 50, FieldUnit::PERCENT);
+ SetExchangeSupport();
+ aActBulletFont = lcl_GetDefaultBulletFont();
+
+ m_xBulletPB->connect_clicked(LINK(this, SvxNumOptionsTabPage, BulletHdl_Impl));
+ m_xFmtLB->connect_changed(LINK(this, SvxNumOptionsTabPage, NumberTypeSelectHdl_Impl));
+ m_xBitmapMB->connect_selected(LINK(this, SvxNumOptionsTabPage, GraphicHdl_Impl));
+ m_xBitmapMB->connect_toggled(LINK(this, SvxNumOptionsTabPage, PopupActivateHdl_Impl));
+ m_xLevelLB->set_selection_mode(SelectionMode::Multiple);
+ m_xLevelLB->connect_changed(LINK(this, SvxNumOptionsTabPage, LevelHdl_Impl));
+ m_xCharFmtLB->connect_changed(LINK(this, SvxNumOptionsTabPage, CharFmtHdl_Impl));
+ m_xWidthMF->connect_value_changed(LINK(this, SvxNumOptionsTabPage, SizeHdl_Impl));
+ m_xHeightMF->connect_value_changed(LINK(this, SvxNumOptionsTabPage, SizeHdl_Impl));
+ m_xRatioCB->connect_toggled(LINK(this, SvxNumOptionsTabPage, RatioHdl_Impl));
+ m_xStartED->connect_value_changed(LINK(this, SvxNumOptionsTabPage, SpinModifyHdl_Impl));
+ m_xPrefixED->connect_changed(LINK(this, SvxNumOptionsTabPage, EditModifyHdl_Impl));
+ m_xSuffixED->connect_changed(LINK(this, SvxNumOptionsTabPage, EditModifyHdl_Impl));
+ m_xAllLevelNF->connect_value_changed(LINK(this,SvxNumOptionsTabPage, AllLevelHdl_Impl));
+ m_xIsLegalCB->connect_toggled(LINK(this, SvxNumOptionsTabPage, IsLegalHdl_Impl));
+ m_xOrientLB->connect_changed(LINK(this, SvxNumOptionsTabPage, OrientHdl_Impl));
+ m_xSameLevelCB->connect_toggled(LINK(this, SvxNumOptionsTabPage, SameLevelHdl_Impl));
+ m_xBulRelSizeMF->connect_value_changed(LINK(this,SvxNumOptionsTabPage, BulRelSizeHdl_Impl));
+ m_xBulColLB->SetSelectHdl(LINK(this, SvxNumOptionsTabPage, BulColorHdl_Impl));
+ aInvalidateTimer.SetInvokeHandler(LINK(this, SvxNumOptionsTabPage, PreviewInvalidateHdl_Impl));
+ aInvalidateTimer.SetTimeout(50);
+
+ eCoreUnit = rSet.GetPool()->GetMetric(rSet.GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE));
+
+ // Fill ListBox with predefined / translated numbering types.
+ sal_uInt32 nCount = SvxNumberingTypeTable::Count();
+ for (sal_uInt32 i = 0; i < nCount; ++i)
+ {
+ int nValue = SvxNumberingTypeTable::GetValue(i);
+ if (comphelper::LibreOfficeKit::isActive() && (nValue & SVX_NUM_BITMAP)) continue;
+ m_xFmtLB->append(OUString::number(nValue), SvxNumberingTypeTable::GetString(i));
+ }
+
+ // Get advanced numbering types from the component.
+ // Watch out for the ugly
+ // 136 == 0x88 == SVX_NUM_BITMAP|0x80 == SVX_NUM_BITMAP|LINK_TOKEN
+ // to not remove that.
+ SvxNumOptionsTabPageHelper::GetI18nNumbering( *m_xFmtLB, (SVX_NUM_BITMAP | LINK_TOKEN));
+
+ m_xFmtLB->set_active(0);
+
+ m_xCharFmtLB->set_size_request(m_xCharFmtLB->get_approximate_digit_width() * 10, -1);
+ Size aSize(m_xGrid->get_preferred_size());
+ m_xGrid->set_size_request(aSize.Width(), -1);
+}
+
+SvxNumOptionsTabPage::~SvxNumOptionsTabPage()
+{
+ m_xPreviewWIN.reset();
+ m_xBulColLB.reset();
+ pActNum.reset();
+ pSaveNum.reset();
+ if (m_pLevelHdlEvent)
+ {
+ Application::RemoveUserEvent(m_pLevelHdlEvent);
+ m_pLevelHdlEvent = nullptr;
+ }
+}
+
+void SvxNumOptionsTabPage::SetMetric(FieldUnit eMetric)
+{
+ if(eMetric == FieldUnit::MM)
+ {
+ m_xWidthMF->set_digits(1);
+ m_xHeightMF->set_digits(1);
+ }
+ m_xWidthMF->set_unit(eMetric);
+ m_xHeightMF->set_unit(eMetric);
+}
+
+std::unique_ptr<SfxTabPage> SvxNumOptionsTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxNumOptionsTabPage>(pPage, pController, *rAttrSet);
+};
+
+void SvxNumOptionsTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ sal_uInt16 nTmpNumLvl = 1;
+ if(pExampleSet)
+ {
+ if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false))
+ bPreset = pPresetItem->GetValue();
+ if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false))
+ nTmpNumLvl = pLevelItem->GetValue();
+ }
+ if(const SvxNumBulletItem* pBulletItem = rSet.GetItemIfSet(nNumItemId, false))
+ {
+ pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) );
+ }
+
+ bModified = (!pActNum->Get( 0 ) || bPreset);
+ if(*pActNum == *pSaveNum && nActNumLvl == nTmpNumLvl)
+ return;
+
+ nActNumLvl = nTmpNumLvl;
+ sal_uInt16 nMask = 1;
+ m_xLevelLB->unselect_all();
+ if (nActNumLvl == SAL_MAX_UINT16)
+ m_xLevelLB->select(pActNum->GetLevelCount());
+ if(nActNumLvl != SAL_MAX_UINT16)
+ {
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ m_xLevelLB->select(i);
+ nMask <<= 1 ;
+ }
+ }
+ *pActNum = *pSaveNum;
+
+ InitControls();
+}
+
+DeactivateRC SvxNumOptionsTabPage::DeactivatePage(SfxItemSet * _pSet)
+{
+ if(_pSet)
+ FillItemSet(_pSet);
+ return DeactivateRC::LeavePage;
+}
+
+bool SvxNumOptionsTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ rSet->Put(SfxUInt16Item(SID_PARAM_CUR_NUM_LEVEL, nActNumLvl));
+ if(bModified && pActNum)
+ {
+ *pSaveNum = *pActNum;
+ rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ));
+ rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, false));
+ }
+ return bModified;
+};
+
+void SvxNumOptionsTabPage::Reset( const SfxItemSet* rSet )
+{
+ // in Draw the item exists as WhichId, in Writer only as SlotId
+ const SvxNumBulletItem* pBulletItem =
+ rSet->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false);
+ if(!pBulletItem)
+ {
+ nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE);
+ pBulletItem = rSet->GetItemIfSet(nNumItemId, false);
+
+ if( !pBulletItem )
+ {
+ pBulletItem = & rSet->Get( nNumItemId );
+ }
+ }
+ DBG_ASSERT(pBulletItem, "no item found!");
+ pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) );
+
+ // insert levels
+ if (!m_xLevelLB->n_children())
+ {
+ for(sal_uInt16 i = 1; i <= pSaveNum->GetLevelCount(); i++)
+ m_xLevelLB->append_text(OUString::number(i));
+ if(pSaveNum->GetLevelCount() > 1)
+ {
+ OUString sEntry = "1 - " + OUString::number( pSaveNum->GetLevelCount() );
+ m_xLevelLB->append_text(sEntry);
+ m_xLevelLB->select_text(sEntry);
+ }
+ else
+ m_xLevelLB->select(0);
+ }
+ else
+ m_xLevelLB->select(m_xLevelLB->n_children() - 1);
+
+ sal_uInt16 nMask = 1;
+ m_xLevelLB->unselect_all();
+ if (nActNumLvl == SAL_MAX_UINT16)
+ {
+ m_xLevelLB->select( pSaveNum->GetLevelCount() );
+ }
+ else
+ {
+ for(sal_uInt16 i = 0; i < pSaveNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ m_xLevelLB->select( i );
+ nMask <<= 1 ;
+ }
+ }
+
+ if(!pActNum)
+ pActNum.reset( new SvxNumRule(*pSaveNum) );
+ else if(*pSaveNum != *pActNum)
+ *pActNum = *pSaveNum;
+ m_aPreviewWIN.SetNumRule(pActNum.get());
+ m_xSameLevelCB->set_active(pActNum->IsContinuousNumbering());
+
+ const SfxUInt16Item* pHtmlModeItem =
+ rSet->GetItemIfSet( SID_HTML_MODE, false );
+ if (!pHtmlModeItem)
+ {
+ if (SfxObjectShell* pShell = SfxObjectShell::Current())
+ pHtmlModeItem = pShell->GetItem( SID_HTML_MODE );
+ }
+ if ( pHtmlModeItem )
+ {
+ sal_uInt16 nHtmlMode = pHtmlModeItem->GetValue();
+ bHTMLMode = 0 != (nHtmlMode&HTMLMODE_ON);
+ }
+
+ bool bCharFmt = pActNum->IsFeatureSupported(SvxNumRuleFlags::CHAR_STYLE);
+ m_xCharFmtFT->set_visible(bCharFmt);
+ m_xCharFmtLB->set_visible(bCharFmt);
+
+ bool bContinuous = pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS);
+
+ bool bAllLevel = bContinuous && !bHTMLMode;
+ m_xAllLevelFT->set_visible(bAllLevel);
+ m_xAllLevelNF->set_visible(bAllLevel);
+ m_xIsLegalCB->set_visible(bAllLevel);
+
+ m_xAllLevelsFrame->set_visible(bContinuous);
+
+ // again misusage: in Draw there is numeration only until the bitmap
+ // without SVX_NUM_NUMBER_NONE
+ //remove types that are unsupported by Draw/Impress
+ if(!bContinuous)
+ {
+ sal_Int32 nFmtCount = m_xFmtLB->get_count();
+ for(sal_Int32 i = nFmtCount; i; i--)
+ {
+ sal_uInt16 nEntryData = m_xFmtLB->get_id(i - 1).toUInt32();
+ if(/*SVX_NUM_NUMBER_NONE == nEntryData ||*/
+ (SVX_NUM_BITMAP|LINK_TOKEN) == nEntryData)
+ m_xFmtLB->remove(i - 1);
+ }
+ }
+ //one must be enabled
+ if(!pActNum->IsFeatureSupported(SvxNumRuleFlags::ENABLE_LINKED_BMP))
+ {
+ auto nPos = m_xFmtLB->find_id(OUString::number(SVX_NUM_BITMAP|LINK_TOKEN));
+ if (nPos != -1)
+ m_xFmtLB->remove(nPos);
+ }
+ else if(!pActNum->IsFeatureSupported(SvxNumRuleFlags::ENABLE_EMBEDDED_BMP))
+ {
+ auto nPos = m_xFmtLB->find_id(OUString::number(SVX_NUM_BITMAP));
+ if (nPos != -1)
+ m_xFmtLB->remove(nPos);
+ }
+
+ // MegaHack: because of a not-fixable 'design mistake/error' in Impress
+ // delete all kinds of numeric enumerations
+ if(pActNum->IsFeatureSupported(SvxNumRuleFlags::NO_NUMBERS))
+ {
+ sal_Int32 nFmtCount = m_xFmtLB->get_count();
+ for(sal_Int32 i = nFmtCount; i; i--)
+ {
+ sal_uInt16 nEntryData = m_xFmtLB->get_id(i - 1).toUInt32();
+ if( /*nEntryData >= SVX_NUM_CHARS_UPPER_LETTER &&*/ nEntryData <= SVX_NUM_NUMBER_NONE)
+ m_xFmtLB->remove(i - 1);
+ }
+ }
+
+ InitControls();
+ bModified = false;
+}
+
+void SvxNumOptionsTabPage::InitControls()
+{
+ bool bShowBullet = true;
+ bool bShowBitmap = true;
+ bool bSameType = true;
+ bool bSameStart = true;
+ bool bSamePrefix = true;
+ bool bSameSuffix = true;
+ bool bAllLevel = true;
+ bool bSameCharFmt = true;
+ bool bSameVOrient = true;
+ bool bSameSize = true;
+ bool bSameBulColor = true;
+ bool bSameBulRelSize= true;
+
+ TriState isLegal = TRISTATE_INDET;
+
+ const SvxNumberFormat* aNumFmtArr[SVX_MAX_NUM];
+ OUString sFirstCharFmt;
+ sal_Int16 eFirstOrient = text::VertOrientation::NONE;
+ Size aFirstSize(0,0);
+ sal_uInt16 nMask = 1;
+ sal_uInt16 nLvl = SAL_MAX_UINT16;
+ sal_uInt16 nHighestLevel = 0;
+
+ bool bBullColor = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_COLOR);
+ bool bBullRelSize = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_REL_SIZE);
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ aNumFmtArr[i] = &pActNum->GetLevel(i);
+ bShowBullet &= aNumFmtArr[i]->GetNumberingType() == SVX_NUM_CHAR_SPECIAL;
+ bShowBitmap &= (aNumFmtArr[i]->GetNumberingType()&(~LINK_TOKEN)) == SVX_NUM_BITMAP;
+ if(SAL_MAX_UINT16 == nLvl)
+ {
+ nLvl = i;
+ sFirstCharFmt = aNumFmtArr[i]->GetCharFormatName();
+ eFirstOrient = aNumFmtArr[i]->GetVertOrient();
+ if(bShowBitmap)
+ aFirstSize = aNumFmtArr[i]->GetGraphicSize();
+ isLegal = aNumFmtArr[i]->GetIsLegal() ? TRISTATE_TRUE : TRISTATE_FALSE;
+ }
+ if( i > nLvl)
+ {
+ bSameType &= aNumFmtArr[i]->GetNumberingType() == aNumFmtArr[nLvl]->GetNumberingType();
+ bSameStart = aNumFmtArr[i]->GetStart() == aNumFmtArr[nLvl]->GetStart();
+
+ bSamePrefix = aNumFmtArr[i]->GetPrefix() == aNumFmtArr[nLvl]->GetPrefix();
+ bSameSuffix = aNumFmtArr[i]->GetSuffix() == aNumFmtArr[nLvl]->GetSuffix();
+ bAllLevel &= aNumFmtArr[i]->GetIncludeUpperLevels() == aNumFmtArr[nLvl]->GetIncludeUpperLevels();
+ if (aNumFmtArr[i]->GetIsLegal() != aNumFmtArr[nLvl]->GetIsLegal())
+ isLegal = TRISTATE_INDET;
+ bSameCharFmt &= sFirstCharFmt == aNumFmtArr[i]->GetCharFormatName();
+ bSameVOrient &= eFirstOrient == aNumFmtArr[i]->GetVertOrient();
+ if(bShowBitmap && bSameSize)
+ bSameSize &= aNumFmtArr[i]->GetGraphicSize() == aFirstSize;
+ bSameBulColor &= aNumFmtArr[i]->GetBulletColor() == aNumFmtArr[nLvl]->GetBulletColor();
+ bSameBulRelSize &= aNumFmtArr[i]->GetBulletRelSize() == aNumFmtArr[nLvl]->GetBulletRelSize();
+ }
+ nHighestLevel = i;
+ }
+ else
+ aNumFmtArr[i] = nullptr;
+
+ nMask <<= 1 ;
+ }
+ SwitchNumberType(bShowBullet ? 1 : bShowBitmap ? 2 : 0);
+
+ sal_uInt16 nNumberingType;
+ if (nLvl != SAL_MAX_UINT16)
+ nNumberingType = aNumFmtArr[nLvl]->GetNumberingType();
+ else
+ {
+ nNumberingType = SVX_NUM_NUMBER_NONE;
+ bAllLevel = false;
+ bSameBulRelSize = false;
+ bSameBulColor = false;
+ bSameStart = false;
+ bSamePrefix = false;
+ bSameSuffix = false;
+ }
+
+ CheckForStartValue_Impl(nNumberingType);
+
+ if(bShowBitmap)
+ {
+ if(!bSameVOrient || eFirstOrient == text::VertOrientation::NONE)
+ m_xOrientLB->set_active(-1);
+ else
+ m_xOrientLB->set_active(
+ sal::static_int_cast< sal_Int32 >(eFirstOrient - 1));
+ // no text::VertOrientation::NONE
+
+ if(bSameSize)
+ {
+ SetMetricValue(*m_xHeightMF, aFirstSize.Height(), eCoreUnit);
+ SetMetricValue(*m_xWidthMF, aFirstSize.Width(), eCoreUnit);
+ }
+ else
+ {
+ m_xHeightMF->set_text("");
+ m_xWidthMF->set_text("");
+ }
+ }
+
+ if(bSameType)
+ {
+ sal_uInt16 nLBData = nNumberingType;
+ m_xFmtLB->set_active_id(OUString::number(nLBData));
+ }
+ else
+ m_xFmtLB->set_active(-1);
+
+ m_xAllLevelNF->set_sensitive(nHighestLevel > 0 && !m_xSameLevelCB->get_active());
+ m_xAllLevelNF->set_max(nHighestLevel + 1);
+ if(bAllLevel)
+ {
+ m_xAllLevelNF->set_value(aNumFmtArr[nLvl]->GetIncludeUpperLevels());
+ }
+ else
+ {
+ m_xAllLevelNF->set_text("");
+ }
+
+ m_xIsLegalCB->set_state(isLegal);
+ m_xIsLegalCB->set_sensitive(!m_xSameLevelCB->get_active());
+
+ if(bBullRelSize)
+ {
+ if(bSameBulRelSize)
+ m_xBulRelSizeMF->set_value(aNumFmtArr[nLvl]->GetBulletRelSize(), FieldUnit::PERCENT);
+ else
+ m_xBulRelSizeMF->set_text("");
+ }
+ if(bBullColor)
+ {
+ if(bSameBulColor)
+ m_xBulColLB->SelectEntry(aNumFmtArr[nLvl]->GetBulletColor());
+ else
+ m_xBulColLB->SetNoSelection();
+ }
+ m_xStartED->set_value(1); // If this isn't set then changing the bullet type to a numbered type doesn't reset the start level
+ switch(nBullet)
+ {
+ case SHOW_NUMBERING:
+ if(bSameStart)
+ {
+ m_xStartED->set_value(aNumFmtArr[nLvl]->GetStart());
+ }
+ else
+ m_xStartED->set_text("");
+ break;
+ case SHOW_BULLET:
+ break;
+ case SHOW_BITMAP:
+ break;
+ }
+
+ if(bSamePrefix)
+ m_xPrefixED->set_text(aNumFmtArr[nLvl]->GetPrefix());
+ else
+ m_xPrefixED->set_text("");
+ if(bSameSuffix)
+ m_xSuffixED->set_text(aNumFmtArr[nLvl]->GetSuffix());
+ else
+ m_xSuffixED->set_text("");
+
+ if(bSameCharFmt)
+ {
+ if (!sFirstCharFmt.isEmpty())
+ m_xCharFmtLB->set_active_text(sFirstCharFmt);
+ else if (m_xCharFmtLB->get_count())
+ m_xCharFmtLB->set_active(0);
+ }
+ else
+ m_xCharFmtLB->set_active(-1);
+
+ m_aPreviewWIN.SetLevel(nActNumLvl);
+ m_aPreviewWIN.Invalidate();
+}
+
+// 0 - Number; 1 - Bullet; 2 - Bitmap
+void SvxNumOptionsTabPage::SwitchNumberType( sal_uInt8 nType )
+{
+ if(nBullet == nType)
+ return;
+ nBullet = nType;
+ bool bBullet = (nType == SHOW_BULLET);
+ bool bBitmap = (nType == SHOW_BITMAP);
+ bool bEnableBitmap = (nType == SHOW_BITMAP);
+ bool bNumeric = !(bBitmap||bBullet);
+ m_xSeparatorFT->set_visible(bNumeric);
+ m_xPrefixFT->set_visible(bNumeric);
+ m_xPrefixED->set_visible(bNumeric);
+ m_xSuffixFT->set_visible(bNumeric);
+ m_xSuffixED->set_visible(bNumeric);
+
+ bool bCharFmt = pActNum->IsFeatureSupported(SvxNumRuleFlags::CHAR_STYLE);
+ m_xCharFmtFT->set_visible(!bBitmap && bCharFmt);
+ m_xCharFmtLB->set_visible(!bBitmap && bCharFmt);
+
+ // this is rather misusage, as there is no own flag
+ // for complete numeration
+ bool bAllLevelFeature = pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS);
+ bool bAllLevel = bNumeric && bAllLevelFeature && !bHTMLMode;
+ m_xAllLevelFT->set_visible(bAllLevel);
+ m_xAllLevelNF->set_visible(bAllLevel);
+ m_xIsLegalCB->set_visible(bAllLevel);
+
+ m_xStartFT->set_visible(!(bBullet||bBitmap));
+ m_xStartED->set_visible(!(bBullet||bBitmap));
+
+ m_xBulletFT->set_visible(bBullet);
+ m_xBulletPB->set_visible(bBullet);
+ bool bBullColor = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_COLOR);
+ m_xBulColorFT->set_visible(!bBitmap && bBullColor);
+ m_xBulColLB->set_visible(!bBitmap && bBullColor);
+ bool bBullResSize = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_REL_SIZE);
+ m_xBulRelSizeFT->set_visible(!bBitmap && bBullResSize);
+ m_xBulRelSizeMF->set_visible(!bBitmap && bBullResSize);
+
+ m_xBitmapFT->set_visible(bBitmap);
+ m_xBitmapMB->set_visible(bBitmap);
+
+ m_xWidthFT->set_visible(bBitmap);
+ m_xWidthMF->set_visible(bBitmap);
+ m_xHeightFT->set_visible(bBitmap);
+ m_xHeightMF->set_visible(bBitmap);
+ m_xRatioCB->set_visible(bBitmap);
+
+ m_xOrientFT->set_visible(bBitmap && bAllLevelFeature);
+ m_xOrientLB->set_visible(bBitmap && bAllLevelFeature);
+
+ m_xWidthFT->set_sensitive(bEnableBitmap);
+ m_xWidthMF->set_sensitive(bEnableBitmap);
+ m_xHeightFT->set_sensitive(bEnableBitmap);
+ m_xHeightMF->set_sensitive(bEnableBitmap);
+ m_xRatioCB->set_sensitive(bEnableBitmap);
+ m_xOrientFT->set_sensitive(bEnableBitmap);
+ m_xOrientLB->set_sensitive(bEnableBitmap);
+}
+
+IMPL_LINK_NOARG(SvxNumOptionsTabPage, LevelHdl_Impl, weld::TreeView&, void)
+{
+ if (m_pLevelHdlEvent)
+ return;
+ // tdf#127112 (borrowing tdf#127120 solution) multiselection may be implemented by deselect follow by select so
+ // fire off the handler to happen on next event loop and only process the
+ // final state
+ m_pLevelHdlEvent = Application::PostUserEvent(LINK(this, SvxNumOptionsTabPage, LevelHdl));
+}
+
+IMPL_LINK_NOARG(SvxNumOptionsTabPage, LevelHdl, void*, void)
+{
+ m_pLevelHdlEvent = nullptr;
+
+ sal_uInt16 nSaveNumLvl = nActNumLvl;
+ nActNumLvl = 0;
+ std::vector<int> aSelectedRows = m_xLevelLB->get_selected_rows();
+ if (std::find(aSelectedRows.begin(), aSelectedRows.end(), pActNum->GetLevelCount()) != aSelectedRows.end() &&
+ (aSelectedRows.size() == 1 || nSaveNumLvl != 0xffff))
+ {
+ nActNumLvl = 0xFFFF;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
+ m_xLevelLB->unselect(i);
+ }
+ else if (!aSelectedRows.empty())
+ {
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
+ {
+ if (std::find(aSelectedRows.begin(), aSelectedRows.end(), i) != aSelectedRows.end())
+ nActNumLvl |= nMask;
+ nMask <<= 1;
+ }
+ m_xLevelLB->unselect(pActNum->GetLevelCount());
+ }
+ else
+ {
+ nActNumLvl = nSaveNumLvl;
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
+ {
+ if(nActNumLvl & nMask)
+ {
+ m_xLevelLB->select(i);
+ break;
+ }
+ nMask <<=1;
+ }
+ }
+ InitControls();
+}
+
+IMPL_LINK_NOARG(SvxNumOptionsTabPage, PreviewInvalidateHdl_Impl, Timer *, void)
+{
+ m_aPreviewWIN.Invalidate();
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, AllLevelHdl_Impl, weld::SpinButton&, rBox, void)
+{
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 e = 0; e < pActNum->GetLevelCount(); e++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(e));
+ aNumFmt.SetIncludeUpperLevels(static_cast<sal_uInt8>(std::min(rBox.get_value(), sal_Int64(e + 1))) );
+ // Set the same prefix/suffix to generate list format with changed IncludedUpperLevels
+ aNumFmt.SetListFormat(aNumFmt.GetPrefix(), aNumFmt.GetSuffix(), e);
+ pActNum->SetLevel(e, aNumFmt);
+ }
+ nMask <<= 1;
+ }
+ SetModified();
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, IsLegalHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ bool bSet = rBox.get_active();
+ for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if (nActNumLvl & (sal_uInt16(1) << i))
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ aNumFmt.SetIsLegal(bSet);
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ }
+ SetModified();
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, NumberTypeSelectHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ OUString sSelectStyle;
+ bool bShowOrient = false;
+ bool bBmp = false;
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ // PAGEDESC does not exist
+ SvxNumType nNumType = static_cast<SvxNumType>(rBox.get_active_id().toUInt32());
+ aNumFmt.SetNumberingType(nNumType);
+ sal_uInt16 nNumberingType = aNumFmt.GetNumberingType();
+ if(SVX_NUM_BITMAP == (nNumberingType&(~LINK_TOKEN)))
+ {
+ bBmp |= nullptr != aNumFmt.GetBrush();
+ aNumFmt.SetIncludeUpperLevels( 1 );
+ aNumFmt.SetListFormat("", "", i);
+ if(!bBmp)
+ aNumFmt.SetGraphic("");
+ pActNum->SetLevel(i, aNumFmt);
+ SwitchNumberType(SHOW_BITMAP);
+ bShowOrient = true;
+ }
+ else if( SVX_NUM_CHAR_SPECIAL == nNumberingType )
+ {
+ aNumFmt.SetIncludeUpperLevels( 1 );
+ aNumFmt.SetListFormat("", "", i);
+ if( !aNumFmt.GetBulletFont() )
+ aNumFmt.SetBulletFont(&aActBulletFont);
+ if( !aNumFmt.GetBulletChar() )
+ aNumFmt.SetBulletChar( SVX_DEF_BULLET );
+ pActNum->SetLevel(i, aNumFmt);
+ SwitchNumberType(SHOW_BULLET);
+ // allocation of the drawing pattern is automatic
+ if(bAutomaticCharStyles)
+ {
+ sSelectStyle = m_sBulletCharFormatName;
+ }
+ }
+ else
+ {
+ aNumFmt.SetListFormat(m_xPrefixED->get_text(), m_xSuffixED->get_text(), i);
+
+ SwitchNumberType(SHOW_NUMBERING);
+ pActNum->SetLevel(i, aNumFmt);
+ CheckForStartValue_Impl(nNumberingType);
+
+ // allocation of the drawing pattern is automatic
+ if(bAutomaticCharStyles)
+ {
+ sSelectStyle = m_sNumCharFmtName;
+ }
+ }
+ }
+ nMask <<= 1;
+ }
+ bool bAllLevelFeature = pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS);
+ if(bShowOrient && bAllLevelFeature)
+ {
+ m_xOrientFT->show();
+ m_xOrientLB->show();
+ }
+ else
+ {
+ m_xOrientFT->hide();
+ m_xOrientLB->hide();
+ }
+ SetModified();
+ if(!sSelectStyle.isEmpty())
+ {
+ m_xCharFmtLB->set_active_text(sSelectStyle);
+ CharFmtHdl_Impl(*m_xCharFmtLB);
+ bAutomaticCharStyles = true;
+ }
+}
+
+void SvxNumOptionsTabPage::CheckForStartValue_Impl(sal_uInt16 nNumberingType)
+{
+ bool bIsNull = m_xStartED->get_value() == 0;
+ bool bNoZeroAllowed = nNumberingType < SVX_NUM_ARABIC ||
+ SVX_NUM_CHARS_UPPER_LETTER_N == nNumberingType ||
+ SVX_NUM_CHARS_LOWER_LETTER_N == nNumberingType;
+ m_xStartED->set_min(bNoZeroAllowed ? 1 : 0);
+ if (bIsNull && bNoZeroAllowed)
+ EditModifyHdl_Impl(*m_xStartED);
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, OrientHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ sal_Int32 nPos = rBox.get_active();
+ nPos ++; // no VERT_NONE
+
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ if(SVX_NUM_BITMAP == (aNumFmt.GetNumberingType()&(~LINK_TOKEN)))
+ {
+ const SvxBrushItem* pBrushItem = aNumFmt.GetBrush();
+ const Size& rSize = aNumFmt.GetGraphicSize();
+ sal_Int16 eOrient = static_cast<sal_Int16>(nPos);
+ aNumFmt.SetGraphicBrush( pBrushItem, &rSize, &eOrient );
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ }
+ nMask <<= 1;
+ }
+ SetModified(false);
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, SameLevelHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ bool bSet = rBox.get_active();
+ pActNum->SetContinuousNumbering(bSet);
+ bool bRepaint = false;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ if(aNumFmt.GetNumberingType() != SVX_NUM_NUMBER_NONE)
+ {
+ bRepaint = true;
+ break;
+ }
+ }
+ SetModified(bRepaint);
+ InitControls();
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, BulColorHdl_Impl, ColorListBox&, rColorBox, void)
+{
+ Color nSetColor = rColorBox.GetSelectEntryColor();
+
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ aNumFmt.SetBulletColor(nSetColor);
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ nMask <<= 1;
+ }
+ SetModified();
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, BulRelSizeHdl_Impl, weld::MetricSpinButton&, rField, void)
+{
+ sal_uInt16 nRelSize = rField.get_value(FieldUnit::PERCENT);
+
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ aNumFmt.SetBulletRelSize(nRelSize);
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ nMask <<= 1;
+ }
+ SetModified();
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, GraphicHdl_Impl, const OUString&, rIdent, void)
+{
+ OUString aGrfName;
+ Size aSize;
+ bool bSucc(false);
+ SvxOpenGraphicDialog aGrfDlg(CuiResId(RID_CUISTR_EDIT_GRAPHIC), GetFrameWeld());
+
+ OUString sNumber;
+ if (rIdent.startsWith("gallery", &sNumber))
+ {
+ auto idx = sNumber.toUInt32();
+ if (idx < aGrfNames.size())
+ {
+ aGrfName = aGrfNames[idx];
+ Graphic aGraphic;
+ if(GalleryExplorer::GetGraphicObj( GALLERY_THEME_BULLETS, idx, &aGraphic))
+ {
+ aSize = SvxNumberFormat::GetGraphicSizeMM100(&aGraphic);
+ bSucc = true;
+ }
+ }
+ }
+ else if (rIdent == "fromfile")
+ {
+ aGrfDlg.EnableLink( false );
+ aGrfDlg.AsLink( false );
+ if ( !aGrfDlg.Execute() )
+ {
+ // memorize selected filter
+ aGrfName = aGrfDlg.GetPath();
+
+ Graphic aGraphic;
+ if( !aGrfDlg.GetGraphic(aGraphic) )
+ {
+ aSize = SvxNumberFormat::GetGraphicSizeMM100(&aGraphic);
+ bSucc = true;
+ }
+ }
+ }
+ if(!bSucc)
+ return;
+
+ aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(eCoreUnit));
+
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ aNumFmt.SetCharFormatName(m_sNumCharFmtName);
+ aNumFmt.SetGraphic(aGrfName);
+
+ // set size for a later comparison
+ const SvxBrushItem* pBrushItem = aNumFmt.GetBrush();
+ // initiate asynchronous loading
+ sal_Int16 eOrient = aNumFmt.GetVertOrient();
+ aNumFmt.SetGraphicBrush( pBrushItem, &aSize, &eOrient );
+ aInitSize[i] = aNumFmt.GetGraphicSize();
+
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ nMask <<= 1;
+ }
+ m_xRatioCB->set_sensitive(true);
+ m_xWidthFT->set_sensitive(true);
+ m_xHeightFT->set_sensitive(true);
+ m_xWidthMF->set_sensitive(true);
+ m_xHeightMF->set_sensitive(true);
+ SetMetricValue(*m_xWidthMF, aSize.Width(), eCoreUnit);
+ SetMetricValue(*m_xHeightMF, aSize.Height(), eCoreUnit);
+ m_xOrientFT->set_sensitive(true);
+ m_xOrientLB->set_sensitive(true);
+ SetModified();
+ //needed due to asynchronous loading of graphics in the SvxBrushItem
+ aInvalidateTimer.Start();
+}
+
+IMPL_LINK_NOARG(SvxNumOptionsTabPage, PopupActivateHdl_Impl, weld::Toggleable&, void)
+{
+ if (m_xGalleryMenu)
+ return;
+
+ m_xGalleryMenu = m_xBuilder->weld_menu("gallerysubmenu");
+ weld::WaitObject aWait(GetFrameWeld());
+
+ if (!GalleryExplorer::FillObjList(GALLERY_THEME_BULLETS, aGrfNames))
+ return;
+
+ GalleryExplorer::BeginLocking(GALLERY_THEME_BULLETS);
+
+ Graphic aGraphic;
+ OUString sGrfName;
+ ScopedVclPtrInstance< VirtualDevice > pVD;
+ size_t i = 0;
+ for (const auto & grfName : aGrfNames)
+ {
+ sGrfName = grfName;
+ OUString sItemId = "gallery" + OUString::number(i);
+ INetURLObject aObj(sGrfName);
+ if (aObj.GetProtocol() == INetProtocol::File)
+ {
+ // tdf#141334 - only show the last name of the filename without its extension
+ aObj.removeExtension();
+ sGrfName = aObj.GetLastName(INetURLObject::DecodeMechanism::Unambiguous);
+ }
+ if(GalleryExplorer::GetGraphicObj( GALLERY_THEME_BULLETS, i, &aGraphic))
+ {
+ BitmapEx aBitmap(aGraphic.GetBitmapEx());
+ Size aSize(aBitmap.GetSizePixel());
+ if(aSize.Width() > MAX_BMP_WIDTH ||
+ aSize.Height() > MAX_BMP_HEIGHT)
+ {
+ bool bWidth = aSize.Width() > aSize.Height();
+ double nScale = bWidth ?
+ double(MAX_BMP_WIDTH) / static_cast<double>(aSize.Width()):
+ double(MAX_BMP_HEIGHT) / static_cast<double>(aSize.Height());
+ aBitmap.Scale(nScale, nScale);
+ }
+ pVD->SetOutputSizePixel(aBitmap.GetSizePixel(), false);
+ pVD->DrawBitmapEx(Point(), aBitmap);
+ m_xGalleryMenu->append(sItemId, sGrfName, *pVD);
+ }
+ else
+ {
+ m_xGalleryMenu->append(sItemId, sGrfName);
+ }
+ ++i;
+ }
+ GalleryExplorer::EndLocking(GALLERY_THEME_BULLETS);
+}
+
+IMPL_LINK_NOARG(SvxNumOptionsTabPage, BulletHdl_Impl, weld::Button&, void)
+{
+ SvxCharacterMap aMap(GetFrameWeld(), nullptr, nullptr);
+
+ sal_uInt16 nMask = 1;
+ std::optional<vcl::Font> pFmtFont;
+ bool bSameBullet = true;
+ sal_UCS4 cBullet = 0;
+ bool bFirst = true;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ const SvxNumberFormat& rCurFmt = pActNum->GetLevel(i);
+ if(bFirst)
+ {
+ cBullet = rCurFmt.GetBulletChar();
+ }
+ else if(rCurFmt.GetBulletChar() != cBullet )
+ {
+ bSameBullet = false;
+ break;
+ }
+ if(!pFmtFont)
+ pFmtFont = rCurFmt.GetBulletFont();
+ bFirst = false;
+ }
+ nMask <<= 1;
+
+ }
+
+ if (pFmtFont)
+ aMap.SetCharFont(*pFmtFont);
+ else
+ aMap.SetCharFont(aActBulletFont);
+ if (bSameBullet)
+ aMap.SetChar(cBullet);
+ if (aMap.run() != RET_OK)
+ return;
+
+ // change Font Numrules
+ aActBulletFont = aMap.GetCharFont();
+
+ sal_uInt16 _nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & _nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ aNumFmt.SetBulletFont(&aActBulletFont);
+ aNumFmt.SetBulletChar(aMap.GetChar());
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ _nMask <<= 1;
+ }
+
+ SetModified();
+}
+
+IMPL_LINK( SvxNumOptionsTabPage, SizeHdl_Impl, weld::MetricSpinButton&, rField, void)
+{
+ bool bWidth = &rField == m_xWidthMF.get();
+ bLastWidthModified = bWidth;
+ bool bRatio = m_xRatioCB->get_active();
+ tools::Long nWidthVal = static_cast<tools::Long>(m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::MM_100TH)));
+ tools::Long nHeightVal = static_cast<tools::Long>(m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::MM_100TH)));
+ nWidthVal = OutputDevice::LogicToLogic( nWidthVal ,
+ MapUnit::Map100thMM, eCoreUnit );
+ nHeightVal = OutputDevice::LogicToLogic( nHeightVal,
+ MapUnit::Map100thMM, eCoreUnit);
+ double fSizeRatio;
+
+ bool bRepaint = false;
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ if(SVX_NUM_BITMAP == (aNumFmt.GetNumberingType()&(~LINK_TOKEN)))
+ {
+ Size aSize(aNumFmt.GetGraphicSize() );
+ Size aSaveSize(aSize);
+
+ if (aInitSize[i].Height())
+ fSizeRatio = static_cast<double>(aInitSize[i].Width()) / static_cast<double>(aInitSize[i].Height());
+ else
+ fSizeRatio = double(1);
+
+ if(bWidth)
+ {
+ tools::Long nDelta = nWidthVal - aInitSize[i].Width();
+ aSize.setWidth( nWidthVal );
+ if (bRatio)
+ {
+ aSize.setHeight( aInitSize[i].Height() + static_cast<tools::Long>(static_cast<double>(nDelta) / fSizeRatio) );
+ m_xHeightMF->set_value(m_xHeightMF->normalize(
+ OutputDevice::LogicToLogic( aSize.Height(), eCoreUnit, MapUnit::Map100thMM )),
+ FieldUnit::MM_100TH);
+ }
+ }
+ else
+ {
+ tools::Long nDelta = nHeightVal - aInitSize[i].Height();
+ aSize.setHeight( nHeightVal );
+ if (bRatio)
+ {
+ aSize.setWidth( aInitSize[i].Width() + static_cast<tools::Long>(static_cast<double>(nDelta) * fSizeRatio) );
+ m_xWidthMF->set_value(m_xWidthMF->normalize(
+ OutputDevice::LogicToLogic( aSize.Width(), eCoreUnit, MapUnit::Map100thMM )),
+ FieldUnit::MM_100TH);
+ }
+ }
+ const SvxBrushItem* pBrushItem = aNumFmt.GetBrush();
+ sal_Int16 eOrient = aNumFmt.GetVertOrient();
+ if(aSize != aSaveSize)
+ bRepaint = true;
+ aNumFmt.SetGraphicBrush( pBrushItem, &aSize, &eOrient );
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ }
+ nMask <<= 1;
+ }
+ SetModified(bRepaint);
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, RatioHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ if (rBox.get_active())
+ {
+ if (bLastWidthModified)
+ SizeHdl_Impl(*m_xWidthMF);
+ else
+ SizeHdl_Impl(*m_xHeightMF);
+ }
+}
+
+IMPL_LINK_NOARG(SvxNumOptionsTabPage, CharFmtHdl_Impl, weld::ComboBox&, void)
+{
+ bAutomaticCharStyles = false;
+ sal_Int32 nEntryPos = m_xCharFmtLB->get_active();
+ OUString sEntry = m_xCharFmtLB->get_active_text();
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ if( 0 == nEntryPos )
+ aNumFmt.SetCharFormatName("");
+ else
+ {
+ if(SVX_NUM_BITMAP != (aNumFmt.GetNumberingType()&(~LINK_TOKEN)))
+ aNumFmt.SetCharFormatName(sEntry);
+ }
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ nMask <<= 1;
+ }
+ SetModified(false);
+};
+
+IMPL_LINK(SvxNumOptionsTabPage, EditModifyHdl_Impl, weld::Entry&, rEdit, void)
+{
+ EditModifyHdl_Impl(&rEdit);
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, SpinModifyHdl_Impl, weld::SpinButton&, rSpinButton, void)
+{
+ EditModifyHdl_Impl(&rSpinButton);
+}
+
+void SvxNumOptionsTabPage::EditModifyHdl_Impl(const weld::Entry* pEdit)
+{
+ bool bPrefixSuffix = (pEdit == m_xPrefixED.get())|| (pEdit == m_xSuffixED.get());
+ bool bStart = pEdit == m_xStartED.get();
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ if (bPrefixSuffix)
+ aNumFmt.SetListFormat(m_xPrefixED->get_text(), m_xSuffixED->get_text(), i);
+ else if(bStart)
+ aNumFmt.SetStart(m_xStartED->get_value());
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ nMask <<= 1;
+ }
+ SetModified();
+}
+
+static tools::Long lcl_DrawGraphic(VirtualDevice& rVDev, const SvxNumberFormat &rFmt, tools::Long nXStart,
+ tools::Long nYMiddle, tools::Long nDivision)
+{
+ const SvxBrushItem* pBrushItem = rFmt.GetBrush();
+ tools::Long nRet = 0;
+ if(pBrushItem)
+ {
+ const Graphic* pGrf = pBrushItem->GetGraphic();
+ if(pGrf)
+ {
+ Size aGSize( rFmt.GetGraphicSize() );
+ aGSize.setWidth( aGSize.Width() / nDivision );
+ nRet = aGSize.Width();
+ aGSize.setHeight( aGSize.Height() / nDivision );
+ pGrf->Draw(rVDev, Point(nXStart,nYMiddle - ( aGSize.Height() / 2) ),
+ rVDev.PixelToLogic( aGSize ) );
+ }
+ }
+ return nRet;
+
+}
+
+static tools::Long lcl_DrawBullet(VirtualDevice* pVDev,
+ const SvxNumberFormat& rFmt, tools::Long nXStart,
+ tools::Long nYStart, const Size& rSize)
+{
+ vcl::Font aTmpFont(pVDev->GetFont());
+
+ // via Uno it's possible that no font has been set!
+ vcl::Font aFont(rFmt.GetBulletFont() ? *rFmt.GetBulletFont() : aTmpFont);
+ Size aTmpSize(rSize);
+ aTmpSize.setWidth( aTmpSize.Width() * ( rFmt.GetBulletRelSize()) );
+ aTmpSize.setWidth( aTmpSize.Width() / 100 ) ;
+ aTmpSize.setHeight( aTmpSize.Height() * ( rFmt.GetBulletRelSize()) );
+ aTmpSize.setHeight( aTmpSize.Height() / 100 ) ;
+ // in case of a height of zero it is drawn in original height
+ if(!aTmpSize.Height())
+ aTmpSize.setHeight( 1 );
+ aFont.SetFontSize(aTmpSize);
+ aFont.SetTransparent(true);
+ Color aBulletColor = rFmt.GetBulletColor();
+ if (aBulletColor == COL_AUTO)
+ aBulletColor = pVDev->GetBackgroundColor().IsDark() ? COL_WHITE : COL_BLACK;
+ else if (pVDev->GetBackgroundColor().IsDark() == aBulletColor.IsDark())
+ aBulletColor = pVDev->GetBackgroundColor().IsDark() ? COL_WHITE : COL_BLACK;
+ aFont.SetColor(aBulletColor);
+ pVDev->SetFont( aFont );
+ sal_UCS4 cChar = rFmt.GetBulletChar();
+ OUString aText(&cChar, 1);
+ tools::Long nY = nYStart;
+ nY -= ((aTmpSize.Height() - rSize.Height())/ 2);
+ pVDev->DrawText( Point(nXStart, nY), aText );
+ tools::Long nRet = pVDev->GetTextWidth(aText);
+
+ pVDev->SetFont(aTmpFont);
+ return nRet;
+}
+
+SvxNumberingPreview::SvxNumberingPreview()
+ : pActNum(nullptr)
+ , bPosition(false)
+ , nActLevel(SAL_MAX_UINT16)
+{
+}
+
+// paint preview of numeration
+void SvxNumberingPreview::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& /*rRect*/)
+{
+ Size aSize(rRenderContext.PixelToLogic(GetOutputSizePixel()));
+
+ // Use default document and font colors to create preview
+ const Color aBackColor = svtools::ColorConfig().GetColorValue(svtools::DOCCOLOR).nColor;
+ const Color aTextColor = svtools::ColorConfig().GetColorValue(svtools::FONTCOLOR).nColor;
+
+ ScopedVclPtrInstance<VirtualDevice> pVDev(rRenderContext);
+ pVDev->EnableRTL(rRenderContext.IsRTLEnabled());
+ pVDev->SetMapMode(rRenderContext.GetMapMode());
+ pVDev->SetOutputSize(aSize);
+
+ Color aLineColor(COL_LIGHTGRAY);
+ if (aLineColor == aBackColor)
+ aLineColor.Invert();
+ pVDev->SetLineColor(aLineColor);
+ pVDev->SetFillColor(aBackColor);
+ pVDev->SetBackground(Wallpaper(aBackColor));
+ pVDev->DrawWallpaper(pVDev->GetOutputRectPixel(), pVDev->GetBackground());
+
+ if (pActNum)
+ {
+ tools::Long nWidthRelation = 30; // chapter dialog
+
+ // height per level
+ tools::Long nXStep = aSize.Width() / (pActNum->GetLevelCount() > 1 ? 3 * pActNum->GetLevelCount() : 3);
+ if (pActNum->GetLevelCount() < 10)
+ nXStep /= 2;
+ tools::Long nYStart = 4;
+ // the whole height mustn't be used for a single level
+ tools::Long nYStep = (aSize.Height() - 6)/ (pActNum->GetLevelCount() > 1 ? pActNum->GetLevelCount() : 5);
+
+ aStdFont = OutputDevice::GetDefaultFont(DefaultFontType::UI_SANS, MsLangId::getConfiguredSystemLanguage(), GetDefaultFontFlags::OnlyOne);
+ aStdFont.SetColor(aTextColor);
+ aStdFont.SetFillColor(aBackColor);
+
+ tools::Long nFontHeight = nYStep * 6 / 10;
+ if (bPosition)
+ nFontHeight = nYStep * 15 / 10;
+ aStdFont.SetFontSize(Size( 0, nFontHeight ));
+
+ SvxNodeNum aNum;
+ sal_uInt16 nPreNum = pActNum->GetLevel(0).GetStart();
+
+ if (bPosition)
+ {
+ // When bPosition == true, draw the preview used in the Writer's "Position" tab
+ // This is not used in Impress/Draw
+
+ tools::Long nLineHeight = nFontHeight * 8 / 7;
+ sal_uInt8 nStart = 0;
+ while (!(nActLevel & (1<<nStart)))
+ {
+ nStart++;
+ }
+ if (nStart)
+ nStart--;
+ sal_uInt8 nEnd = std::min(sal_uInt8(nStart + 3), sal_uInt8(pActNum->GetLevelCount()));
+ for (sal_uInt8 nLevel = nStart; nLevel < nEnd; ++nLevel)
+ {
+ const SvxNumberFormat &rFmt = pActNum->GetLevel(nLevel);
+ aNum.GetLevelVal()[nLevel] = rFmt.GetStart();
+
+ tools::Long nXStart( 0 );
+ short nTextOffset( 0 );
+ tools::Long nNumberXPos( 0 );
+ if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION)
+ {
+ nXStart = rFmt.GetAbsLSpace() / nWidthRelation;
+ nTextOffset = rFmt.GetCharTextDistance() / nWidthRelation;
+ nNumberXPos = nXStart;
+ tools::Long nFirstLineOffset = (-rFmt.GetFirstLineOffset()) / nWidthRelation;
+
+ if (nFirstLineOffset <= nNumberXPos)
+ nNumberXPos = nNumberXPos - nFirstLineOffset;
+ else
+ nNumberXPos = 0;
+ // in draw this is valid
+ if (nTextOffset < 0)
+ nNumberXPos = nNumberXPos + nTextOffset;
+ }
+ else if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT)
+ {
+ const tools::Long nTmpNumberXPos((rFmt.GetIndentAt() + rFmt.GetFirstLineIndent() ) / nWidthRelation);
+ if (nTmpNumberXPos < 0)
+ {
+ nNumberXPos = 0;
+ }
+ else
+ {
+ nNumberXPos = nTmpNumberXPos;
+ }
+ }
+
+ tools::Long nBulletWidth = 0;
+ if (SVX_NUM_BITMAP == (rFmt.GetNumberingType() &(~LINK_TOKEN)))
+ {
+ tools::Long nYMiddle = nYStart + ( nFontHeight / 2 );
+ nBulletWidth = rFmt.IsShowSymbol() ? lcl_DrawGraphic(*pVDev, rFmt, nNumberXPos, nYMiddle, nWidthRelation) : 0;
+ }
+ else if (SVX_NUM_CHAR_SPECIAL == rFmt.GetNumberingType())
+ {
+ nBulletWidth = rFmt.IsShowSymbol() ? lcl_DrawBullet(pVDev.get(), rFmt, nNumberXPos, nYStart, aStdFont.GetFontSize()) : 0;
+ }
+ else
+ {
+ pVDev->SetFont(aStdFont);
+ aNum.SetLevel(nLevel);
+ if (pActNum->IsContinuousNumbering())
+ aNum.GetLevelVal()[nLevel] = nPreNum;
+ OUString aText(pActNum->MakeNumString( aNum ));
+ vcl::Font aSaveFont = pVDev->GetFont();
+ vcl::Font aColorFont(aSaveFont);
+ Color aTmpBulletColor = rFmt.GetBulletColor();
+ if (aTmpBulletColor == COL_AUTO)
+ aTmpBulletColor = pVDev->GetBackgroundColor().IsDark() ? COL_WHITE : COL_BLACK;
+ else if (pVDev->GetBackgroundColor().IsDark() == aTmpBulletColor.IsDark())
+ aTmpBulletColor = pVDev->GetBackgroundColor().IsDark() ? COL_WHITE : COL_BLACK;
+ aColorFont.SetColor(aTmpBulletColor);
+ pVDev->SetFont(aColorFont);
+ pVDev->DrawText(Point(nNumberXPos, nYStart), aText);
+ pVDev->SetFont(aSaveFont);
+ nBulletWidth = pVDev->GetTextWidth(aText);
+ nPreNum++;
+ }
+ if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT &&
+ rFmt.GetLabelFollowedBy() == SvxNumberFormat::SPACE )
+ {
+ pVDev->SetFont(aStdFont);
+ OUString aText(' ');
+ pVDev->DrawText( Point(nNumberXPos, nYStart), aText );
+ nBulletWidth = nBulletWidth + pVDev->GetTextWidth(aText);
+ }
+
+ tools::Long nTextXPos( 0 );
+ if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION)
+ {
+ nTextXPos = nXStart;
+ if (nTextOffset < 0)
+ nTextXPos = nTextXPos + nTextOffset;
+ if (nNumberXPos + nBulletWidth + nTextOffset > nTextXPos)
+ nTextXPos = nNumberXPos + nBulletWidth + nTextOffset;
+ }
+ else if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT)
+ {
+ switch (rFmt.GetLabelFollowedBy())
+ {
+ case SvxNumberFormat::LISTTAB:
+ {
+ nTextXPos = rFmt.GetListtabPos() / nWidthRelation;
+ if (nTextXPos < nNumberXPos + nBulletWidth)
+ {
+ nTextXPos = nNumberXPos + nBulletWidth;
+ }
+ }
+ break;
+ case SvxNumberFormat::SPACE:
+ case SvxNumberFormat::NOTHING:
+ case SvxNumberFormat::NEWLINE:
+ {
+ nTextXPos = nNumberXPos + nBulletWidth;
+ }
+ break;
+ }
+
+ nXStart = rFmt.GetIndentAt() / nWidthRelation;
+ }
+
+ ::tools::Rectangle aRect1(Point(nTextXPos, nYStart + nFontHeight / 2), Size(aSize.Width() / 2, 2));
+ pVDev->SetFillColor(aBackColor);
+ pVDev->DrawRect(aRect1);
+
+ ::tools::Rectangle aRect2(Point(nXStart, nYStart + nLineHeight + nFontHeight / 2 ), Size(aSize.Width() / 2, 2));
+ pVDev->DrawRect(aRect2);
+ nYStart += 2 * nLineHeight;
+ }
+ }
+ else
+ {
+ // When bPosition == false, draw the preview used in Writer's "Customize" tab
+ // and in Impress' "Bullets and Numbering" dialog
+
+ //#i5153# painting gray or black rectangles as 'normal' numbering text
+ tools::Long nWidth = pVDev->GetTextWidth("Preview");
+ tools::Long nTextHeight = pVDev->GetTextHeight();
+ tools::Long nRectHeight = nTextHeight * 2 / 3;
+ tools::Long nTopOffset = nTextHeight - nRectHeight;
+ Color aSelRectColor = pVDev->GetBackgroundColor().IsDark() ? COL_WHITE : COL_BLACK;
+
+ for (sal_uInt16 nLevel = 0; nLevel < pActNum->GetLevelCount(); ++nLevel, nYStart = nYStart + nYStep)
+ {
+ const SvxNumberFormat &rFmt = pActNum->GetLevel(nLevel);
+ aNum.GetLevelVal()[ nLevel ] = rFmt.GetStart();
+ tools::Long nXStart( 0 );
+ pVDev->SetFillColor( aBackColor );
+
+ if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION)
+ {
+ nXStart = rFmt.GetAbsLSpace() / nWidthRelation;
+ }
+ else if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT)
+ {
+ const tools::Long nTmpXStart((rFmt.GetIndentAt() + rFmt.GetFirstLineIndent() ) / nWidthRelation);
+ if (nTmpXStart < 0)
+ {
+ nXStart = 0;
+ }
+ else
+ {
+ nXStart = nTmpXStart;
+ }
+ }
+ nXStart /= 2;
+ nXStart += 2;
+ tools::Long nTextOffset = 2 * nXStep;
+ if (SVX_NUM_BITMAP == (rFmt.GetNumberingType()&(~LINK_TOKEN)))
+ {
+ if (rFmt.IsShowSymbol())
+ {
+ tools::Long nYMiddle = nYStart + ( nFontHeight / 2 );
+ nTextOffset = lcl_DrawGraphic(*pVDev, rFmt, nXStart, nYMiddle, nWidthRelation);
+ nTextOffset = nTextOffset + nXStep;
+ }
+ }
+ else if (SVX_NUM_CHAR_SPECIAL == rFmt.GetNumberingType())
+ {
+ if (rFmt.IsShowSymbol())
+ {
+ nTextOffset = lcl_DrawBullet(pVDev.get(), rFmt, nXStart, nYStart, aStdFont.GetFontSize());
+ nTextOffset = nTextOffset + nXStep;
+ }
+ }
+ else
+ {
+ vcl::Font aFont(aStdFont);
+ Size aTmpSize(aStdFont.GetFontSize());
+ if(pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_REL_SIZE))
+ {
+ aTmpSize.setWidth( aTmpSize.Width() * ( rFmt.GetBulletRelSize()) );
+ aTmpSize.setWidth( aTmpSize.Width() / 100 ) ;
+ aTmpSize.setHeight( aTmpSize.Height() * ( rFmt.GetBulletRelSize()) );
+ aTmpSize.setHeight( aTmpSize.Height() / 100 ) ;
+ }
+ if(!aTmpSize.Height())
+ aTmpSize.setHeight( 1 );
+ aFont.SetFontSize(aTmpSize);
+ Color aTmpBulletColor = rFmt.GetBulletColor();
+ if (aTmpBulletColor == COL_AUTO)
+ aTmpBulletColor = pVDev->GetBackgroundColor().IsDark() ? COL_WHITE : COL_BLACK;
+ else if (pVDev->GetBackgroundColor().IsDark() == aTmpBulletColor.IsDark())
+ aTmpBulletColor = pVDev->GetBackgroundColor().IsDark() ? COL_WHITE : COL_BLACK;
+ aFont.SetColor(aTmpBulletColor);
+ pVDev->SetFont(aFont);
+ aNum.SetLevel( nLevel );
+ if (pActNum->IsContinuousNumbering())
+ aNum.GetLevelVal()[nLevel] = nPreNum;
+ OUString aText(pActNum->MakeNumString(aNum));
+ tools::Long nY = nYStart;
+ nY -= (pVDev->GetTextHeight() - nTextHeight - pVDev->GetFontMetric().GetDescent());
+ pVDev->DrawText(Point(nXStart, nY), aText);
+ nTextOffset = pVDev->GetTextWidth(aText);
+ nTextOffset = nTextOffset + nXStep;
+ nPreNum++;
+ pVDev->SetFont(aStdFont);
+ }
+ //#i5153# the selected rectangle(s) should be black
+ if (0 != (nActLevel & (1<<nLevel)))
+ {
+ pVDev->SetFillColor( aSelRectColor );
+ pVDev->SetLineColor( aSelRectColor );
+ }
+ else
+ {
+ //#i5153# unselected levels are gray
+ pVDev->SetFillColor( aLineColor );
+ pVDev->SetLineColor( aLineColor );
+ }
+ ::tools::Rectangle aRect1(Point(nXStart + nTextOffset, nYStart + nTopOffset), Size(nWidth, nRectHeight));
+ pVDev->DrawRect(aRect1);
+ }
+ }
+ }
+ rRenderContext.DrawOutDev(Point(), aSize, Point(), aSize, *pVDev);
+}
+
+
+//See uiconfig/swriter/ui/outlinepositionpage.ui for effectively a duplicate
+//dialog to this one, except with a different preview window impl.
+//TODO, determine if SwNumPositionTabPage and SvxNumPositionTabPage can be
+//merged
+SvxNumPositionTabPage::SvxNumPositionTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/numberingpositionpage.ui", "NumberingPositionPage", &rSet)
+ , m_pLevelHdlEvent(nullptr)
+ , nActNumLvl(1)
+ , nNumItemId(SID_ATTR_NUMBERING_RULE)
+ , bModified(false)
+ , bPreset(false)
+ , bInInintControl(false)
+ , bLabelAlignmentPosAndSpaceModeActive(false)
+ , m_xLevelLB(m_xBuilder->weld_tree_view("levellb"))
+ , m_xDistBorderFT(m_xBuilder->weld_label("indent"))
+ , m_xDistBorderMF(m_xBuilder->weld_metric_spin_button("indentmf", FieldUnit::CM))
+ , m_xRelativeCB(m_xBuilder->weld_check_button("relative"))
+ , m_xIndentFT(m_xBuilder->weld_label("numberingwidth"))
+ , m_xIndentMF(m_xBuilder->weld_metric_spin_button("numberingwidthmf", FieldUnit::CM))
+ , m_xDistNumFT(m_xBuilder->weld_label("numdist"))
+ , m_xDistNumMF(m_xBuilder->weld_metric_spin_button("numdistmf", FieldUnit::CM))
+ , m_xAlignFT(m_xBuilder->weld_label("numalign"))
+ , m_xAlignLB(m_xBuilder->weld_combo_box("numalignlb"))
+ , m_xLabelFollowedByFT(m_xBuilder->weld_label("numfollowedby"))
+ , m_xLabelFollowedByLB(m_xBuilder->weld_combo_box("numfollowedbylb"))
+ , m_xListtabFT(m_xBuilder->weld_label("at"))
+ , m_xListtabMF(m_xBuilder->weld_metric_spin_button("atmf", FieldUnit::CM))
+ , m_xAlign2FT(m_xBuilder->weld_label("num2align"))
+ , m_xAlign2LB(m_xBuilder->weld_combo_box("num2alignlb"))
+ , m_xAlignedAtFT(m_xBuilder->weld_label("alignedat"))
+ , m_xAlignedAtMF(m_xBuilder->weld_metric_spin_button("alignedatmf", FieldUnit::CM))
+ , m_xIndentAtFT(m_xBuilder->weld_label("indentat"))
+ , m_xIndentAtMF(m_xBuilder->weld_metric_spin_button("indentatmf", FieldUnit::CM))
+ , m_xStandardPB(m_xBuilder->weld_button("standard"))
+ , m_xPreviewWIN(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWIN))
+{
+ SetExchangeSupport();
+
+ // set metric
+ FieldUnit eFUnit = GetModuleFieldUnit(rSet);
+
+ SetFieldUnit( *m_xDistBorderMF, eFUnit );
+ SetFieldUnit( *m_xIndentMF, eFUnit );
+ SetFieldUnit( *m_xDistNumMF, eFUnit );
+
+ m_xAlignedAtMF->set_range(0, SAL_MAX_INT32, FieldUnit::NONE);
+ m_xListtabMF->set_range(0, SAL_MAX_INT32, FieldUnit::NONE);
+ m_xIndentAtMF->set_range(0, SAL_MAX_INT32, FieldUnit::NONE);
+
+ m_xRelativeCB->set_active(true);
+ m_xAlignLB->connect_changed(LINK(this, SvxNumPositionTabPage, EditModifyHdl_Impl));
+ m_xAlign2LB->connect_changed(LINK(this, SvxNumPositionTabPage, EditModifyHdl_Impl));
+ for ( sal_Int32 i = 0; i < m_xAlignLB->get_count(); ++i )
+ {
+ m_xAlign2LB->append_text(m_xAlignLB->get_text(i));
+ }
+
+ Link<weld::MetricSpinButton&,void> aLk3 = LINK(this, SvxNumPositionTabPage, DistanceHdl_Impl);
+ m_xDistBorderMF->connect_value_changed(aLk3);
+ m_xDistNumMF->connect_value_changed(aLk3);
+ m_xIndentMF->connect_value_changed(aLk3);
+
+ m_xLabelFollowedByLB->connect_changed(LINK(this, SvxNumPositionTabPage, LabelFollowedByHdl_Impl));
+
+ m_xListtabMF->connect_value_changed(LINK(this, SvxNumPositionTabPage, ListtabPosHdl_Impl));
+ m_xAlignedAtMF->connect_value_changed(LINK(this, SvxNumPositionTabPage, AlignAtHdl_Impl));
+ m_xIndentAtMF->connect_value_changed(LINK(this, SvxNumPositionTabPage, IndentAtHdl_Impl));
+
+ m_xLevelLB->set_selection_mode(SelectionMode::Multiple);
+ m_xLevelLB->connect_changed(LINK(this, SvxNumPositionTabPage, LevelHdl_Impl));
+ m_xRelativeCB->connect_toggled(LINK(this, SvxNumPositionTabPage, RelativeHdl_Impl));
+ m_xStandardPB->connect_clicked(LINK(this, SvxNumPositionTabPage, StandardHdl_Impl));
+
+ m_xRelativeCB->set_active(bLastRelative);
+ m_aPreviewWIN.SetPositionMode();
+ eCoreUnit = rSet.GetPool()->GetMetric(rSet.GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE));
+}
+
+SvxNumPositionTabPage::~SvxNumPositionTabPage()
+{
+ if (m_pLevelHdlEvent)
+ {
+ Application::RemoveUserEvent(m_pLevelHdlEvent);
+ m_pLevelHdlEvent = nullptr;
+ }
+ m_xPreviewWIN.reset();
+}
+
+/*-------------------------------------------------------*/
+
+void SvxNumPositionTabPage::InitControls()
+{
+ bInInintControl = true;
+ const bool bRelative = !bLabelAlignmentPosAndSpaceModeActive &&
+ m_xRelativeCB->get_sensitive() && m_xRelativeCB->get_active();
+ const bool bSingleSelection = m_xLevelLB->count_selected_rows() == 1 &&
+ SAL_MAX_UINT16 != nActNumLvl;
+
+ m_xDistBorderMF->set_sensitive( !bLabelAlignmentPosAndSpaceModeActive &&
+ ( bSingleSelection || bRelative ) );
+ m_xDistBorderFT->set_sensitive( !bLabelAlignmentPosAndSpaceModeActive &&
+ ( bSingleSelection || bRelative ) );
+
+ bool bSetDistEmpty = false;
+ bool bSameDistBorderNum = !bLabelAlignmentPosAndSpaceModeActive;
+ bool bSameDist = !bLabelAlignmentPosAndSpaceModeActive;
+ bool bSameIndent = !bLabelAlignmentPosAndSpaceModeActive;
+ bool bSameAdjust = true;
+
+ bool bSameLabelFollowedBy = bLabelAlignmentPosAndSpaceModeActive;
+ bool bSameListtab = bLabelAlignmentPosAndSpaceModeActive;
+ bool bSameAlignAt = bLabelAlignmentPosAndSpaceModeActive;
+ bool bSameIndentAt = bLabelAlignmentPosAndSpaceModeActive;
+
+ const SvxNumberFormat* aNumFmtArr[SVX_MAX_NUM];
+ sal_uInt16 nMask = 1;
+ sal_uInt16 nLvl = SAL_MAX_UINT16;
+ tools::Long nFirstBorderTextRelative = -1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ aNumFmtArr[i] = &pActNum->GetLevel(i);
+ if(nActNumLvl & nMask)
+ {
+ if(SAL_MAX_UINT16 == nLvl)
+ nLvl = i;
+
+ if( i > nLvl)
+ {
+ bSameAdjust &= aNumFmtArr[i]->GetNumAdjust() == aNumFmtArr[nLvl]->GetNumAdjust();
+ if ( !bLabelAlignmentPosAndSpaceModeActive )
+ {
+ if(bRelative)
+ {
+ if(nFirstBorderTextRelative == -1)
+ nFirstBorderTextRelative =
+ (aNumFmtArr[i]->GetAbsLSpace() + aNumFmtArr[i]->GetFirstLineOffset() -
+ aNumFmtArr[i - 1]->GetAbsLSpace() + aNumFmtArr[i - 1]->GetFirstLineOffset());
+ else
+ bSameDistBorderNum &= nFirstBorderTextRelative ==
+ (aNumFmtArr[i]->GetAbsLSpace() + aNumFmtArr[i]->GetFirstLineOffset() -
+ aNumFmtArr[i - 1]->GetAbsLSpace() + aNumFmtArr[i - 1]->GetFirstLineOffset());
+ }
+ else
+ bSameDistBorderNum &=
+ aNumFmtArr[i]->GetAbsLSpace() - aNumFmtArr[i]->GetFirstLineOffset() ==
+ aNumFmtArr[i - 1]->GetAbsLSpace() - aNumFmtArr[i - 1]->GetFirstLineOffset();
+
+ bSameDist &= aNumFmtArr[i]->GetCharTextDistance() == aNumFmtArr[nLvl]->GetCharTextDistance();
+ bSameIndent &= aNumFmtArr[i]->GetFirstLineOffset() == aNumFmtArr[nLvl]->GetFirstLineOffset();
+ }
+ else
+ {
+ bSameLabelFollowedBy &=
+ aNumFmtArr[i]->GetLabelFollowedBy() == aNumFmtArr[nLvl]->GetLabelFollowedBy();
+ bSameListtab &=
+ aNumFmtArr[i]->GetListtabPos() == aNumFmtArr[nLvl]->GetListtabPos();
+ bSameAlignAt &=
+ ( ( aNumFmtArr[i]->GetIndentAt() + aNumFmtArr[i]->GetFirstLineIndent() )
+ == ( aNumFmtArr[nLvl]->GetIndentAt() + aNumFmtArr[nLvl]->GetFirstLineIndent() ) );
+ bSameIndentAt &=
+ aNumFmtArr[i]->GetIndentAt() == aNumFmtArr[nLvl]->GetIndentAt();
+ }
+ }
+ }
+ nMask <<= 1;
+
+ }
+ if (SVX_MAX_NUM <= nLvl)
+ {
+ OSL_ENSURE(false, "cannot happen.");
+ return;
+ }
+
+ if(bSameDistBorderNum)
+ {
+ tools::Long nDistBorderNum;
+ if(bRelative)
+ {
+ nDistBorderNum = static_cast<tools::Long>(aNumFmtArr[nLvl]->GetAbsLSpace())+ aNumFmtArr[nLvl]->GetFirstLineOffset();
+ if(nLvl)
+ nDistBorderNum -= static_cast<tools::Long>(aNumFmtArr[nLvl - 1]->GetAbsLSpace())+ aNumFmtArr[nLvl - 1]->GetFirstLineOffset();
+ }
+ else
+ {
+ nDistBorderNum = static_cast<tools::Long>(aNumFmtArr[nLvl]->GetAbsLSpace())+ aNumFmtArr[nLvl]->GetFirstLineOffset();
+ }
+ SetMetricValue(*m_xDistBorderMF, nDistBorderNum, eCoreUnit);
+ }
+ else
+ bSetDistEmpty = true;
+
+ if(bSameDist)
+ SetMetricValue(*m_xDistNumMF, aNumFmtArr[nLvl]->GetCharTextDistance(), eCoreUnit);
+ else
+ m_xDistNumMF->set_text("");
+ if(bSameIndent)
+ SetMetricValue(*m_xIndentMF, - aNumFmtArr[nLvl]->GetFirstLineOffset(), eCoreUnit);
+ else
+ m_xIndentMF->set_text("");
+
+ if(bSameAdjust)
+ {
+ sal_Int32 nPos = 1; // centered
+ if(aNumFmtArr[nLvl]->GetNumAdjust() == SvxAdjust::Left)
+ nPos = 0;
+ else if(aNumFmtArr[nLvl]->GetNumAdjust() == SvxAdjust::Right)
+ nPos = 2;
+ m_xAlignLB->set_active(nPos);
+ m_xAlign2LB->set_active(nPos);
+ }
+ else
+ {
+ m_xAlignLB->set_active(-1);
+ m_xAlign2LB->set_active(-1);
+ }
+
+ if ( bSameLabelFollowedBy )
+ {
+ sal_Int32 nPos = 0; // LISTTAB
+ if ( aNumFmtArr[nLvl]->GetLabelFollowedBy() == SvxNumberFormat::SPACE )
+ {
+ nPos = 1;
+ }
+ else if ( aNumFmtArr[nLvl]->GetLabelFollowedBy() == SvxNumberFormat::NOTHING )
+ {
+ nPos = 2;
+ }
+ else if ( aNumFmtArr[nLvl]->GetLabelFollowedBy() == SvxNumberFormat::NEWLINE )
+ {
+ nPos = 3;
+ }
+ m_xLabelFollowedByLB->set_active(nPos);
+ }
+ else
+ {
+ m_xLabelFollowedByLB->set_active(-1);
+ }
+
+ if ( aNumFmtArr[nLvl]->GetLabelFollowedBy() == SvxNumberFormat::LISTTAB )
+ {
+ m_xListtabFT->set_sensitive(true);
+ m_xListtabMF->set_sensitive(true);
+ if ( bSameListtab )
+ {
+ SetMetricValue(*m_xListtabMF, aNumFmtArr[nLvl]->GetListtabPos(), eCoreUnit);
+ }
+ else
+ {
+ m_xListtabMF->set_text("");
+ }
+ }
+ else
+ {
+ m_xListtabFT->set_sensitive(false);
+ m_xListtabMF->set_sensitive(false);
+ m_xListtabMF->set_text("");
+ }
+
+ if ( bSameAlignAt )
+ {
+ SetMetricValue(*m_xAlignedAtMF,
+ aNumFmtArr[nLvl]->GetIndentAt() + aNumFmtArr[nLvl]->GetFirstLineIndent(),
+ eCoreUnit);
+ }
+ else
+ {
+ m_xAlignedAtMF->set_text("");
+ }
+
+ if ( bSameIndentAt )
+ {
+ SetMetricValue(*m_xIndentAtMF, aNumFmtArr[nLvl]->GetIndentAt(), eCoreUnit);
+ }
+ else
+ {
+ m_xIndentAtMF->set_text("");
+ }
+
+ if ( bSetDistEmpty )
+ m_xDistBorderMF->set_text("");
+
+ bInInintControl = false;
+}
+
+void SvxNumPositionTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ sal_uInt16 nTmpNumLvl = 1;
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ if(pExampleSet)
+ {
+ if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false))
+ bPreset = pPresetItem->GetValue();
+ if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false))
+ nTmpNumLvl = pLevelItem->GetValue();
+ }
+ if(const SvxNumBulletItem* pBulletItem = rSet.GetItemIfSet(nNumItemId, false))
+ {
+ pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) );
+ }
+ bModified = (!pActNum->Get( 0 ) || bPreset);
+ if(*pSaveNum != *pActNum ||
+ nActNumLvl != nTmpNumLvl )
+ {
+ *pActNum = *pSaveNum;
+ nActNumLvl = nTmpNumLvl;
+ sal_uInt16 nMask = 1;
+ m_xLevelLB->unselect_all();
+ if (nActNumLvl == SAL_MAX_UINT16)
+ m_xLevelLB->select(pActNum->GetLevelCount());
+ if (nActNumLvl != SAL_MAX_UINT16)
+ for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if (nActNumLvl & nMask)
+ m_xLevelLB->select(i);
+ nMask <<= 1 ;
+ }
+ m_xRelativeCB->set_sensitive(nActNumLvl != 1);
+
+ InitPosAndSpaceMode();
+ ShowControlsDependingOnPosAndSpaceMode();
+
+ InitControls();
+ }
+ m_aPreviewWIN.SetLevel(nActNumLvl);
+ m_aPreviewWIN.Invalidate();
+}
+
+DeactivateRC SvxNumPositionTabPage::DeactivatePage(SfxItemSet *_pSet)
+{
+ if(_pSet)
+ {
+ if (m_xDistBorderMF->get_sensitive())
+ DistanceHdl_Impl(*m_xDistBorderMF);
+ DistanceHdl_Impl(*m_xIndentMF);
+ FillItemSet(_pSet);
+ }
+ return DeactivateRC::LeavePage;
+}
+
+bool SvxNumPositionTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ rSet->Put(SfxUInt16Item(SID_PARAM_CUR_NUM_LEVEL, nActNumLvl));
+
+ if(bModified && pActNum)
+ {
+ *pSaveNum = *pActNum;
+ rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ));
+ rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, false));
+ }
+ return bModified;
+}
+
+void SvxNumPositionTabPage::Reset( const SfxItemSet* rSet )
+{
+ // in Draw the item exists as WhichId, in Writer only as SlotId
+ const SvxNumBulletItem* pItem =
+ rSet->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false);
+ if(!pItem)
+ {
+ nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE);
+ pItem = rSet->GetItemIfSet(nNumItemId, false);
+
+ if( !pItem )
+ {
+ pItem = & rSet->Get( nNumItemId );
+ }
+ }
+ DBG_ASSERT(pItem, "no item found!");
+ pSaveNum.reset( new SvxNumRule(pItem->GetNumRule()) );
+
+ // insert levels
+ if (!m_xLevelLB->count_selected_rows())
+ {
+ for(sal_uInt16 i = 1; i <= pSaveNum->GetLevelCount(); i++)
+ m_xLevelLB->append_text(OUString::number(i));
+ if(pSaveNum->GetLevelCount() > 1)
+ {
+ OUString sEntry = "1 - " + OUString::number( pSaveNum->GetLevelCount() );
+ m_xLevelLB->append_text(sEntry);
+ m_xLevelLB->select_text(sEntry);
+ }
+ else
+ m_xLevelLB->select(0);
+ }
+ else
+ m_xLevelLB->select(m_xLevelLB->count_selected_rows() - 1);
+ sal_uInt16 nMask = 1;
+ m_xLevelLB->unselect_all();
+ if (nActNumLvl == SAL_MAX_UINT16)
+ {
+ m_xLevelLB->select(pSaveNum->GetLevelCount());
+ }
+ else
+ {
+ for(sal_uInt16 i = 0; i < pSaveNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ m_xLevelLB->select(i);
+ nMask <<= 1;
+ }
+ }
+
+ if(!pActNum)
+ pActNum.reset( new SvxNumRule(*pSaveNum) );
+ else if(*pSaveNum != *pActNum)
+ *pActNum = *pSaveNum;
+ m_aPreviewWIN.SetNumRule(pActNum.get());
+
+ InitPosAndSpaceMode();
+ ShowControlsDependingOnPosAndSpaceMode();
+
+ InitControls();
+ bModified = false;
+}
+
+void SvxNumPositionTabPage::InitPosAndSpaceMode()
+{
+ if ( pActNum == nullptr )
+ {
+ SAL_WARN( "cui.tabpages",
+ "<SvxNumPositionTabPage::InitPosAndSpaceMode()> - misusage of method -> <pAktNum> has to be already set!" );
+ return;
+ }
+
+ SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode =
+ SvxNumberFormat::LABEL_ALIGNMENT;
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i )
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt( pActNum->GetLevel(i) );
+ ePosAndSpaceMode = aNumFmt.GetPositionAndSpaceMode();
+ if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
+ {
+ break;
+ }
+ }
+ nMask <<= 1;
+ }
+
+ bLabelAlignmentPosAndSpaceModeActive =
+ ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT;
+}
+
+void SvxNumPositionTabPage::ShowControlsDependingOnPosAndSpaceMode()
+{
+ m_xDistBorderFT->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
+ m_xDistBorderMF->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
+ m_xRelativeCB->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
+ m_xIndentFT->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
+ m_xIndentMF->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
+ m_xDistNumFT->set_visible( !bLabelAlignmentPosAndSpaceModeActive &&
+ pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS) );
+ m_xDistNumMF->set_visible( !bLabelAlignmentPosAndSpaceModeActive &&
+ pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS));
+ m_xAlignFT->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
+ m_xAlignLB->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
+
+ m_xLabelFollowedByFT->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xLabelFollowedByLB->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xListtabFT->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xListtabMF->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xAlign2FT->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xAlign2LB->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xAlignedAtFT->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xAlignedAtMF->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xIndentAtFT->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xIndentAtMF->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+}
+
+std::unique_ptr<SfxTabPage> SvxNumPositionTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxNumPositionTabPage>(pPage, pController, *rAttrSet);
+}
+
+void SvxNumPositionTabPage::SetMetric(FieldUnit eMetric)
+{
+ if (eMetric == FieldUnit::MM)
+ {
+ m_xDistBorderMF->set_digits(1);
+ m_xDistNumMF->set_digits(1);
+ m_xIndentMF->set_digits(1);
+ m_xListtabMF->set_digits(1);
+ m_xAlignedAtMF->set_digits(1);
+ m_xIndentAtMF->set_digits(1);
+ }
+ m_xDistBorderMF->set_unit(eMetric);
+ m_xDistNumMF->set_unit(eMetric);
+ m_xIndentMF->set_unit(eMetric);
+ m_xListtabMF->set_unit(eMetric);
+ m_xAlignedAtMF->set_unit(eMetric);
+ m_xIndentAtMF->set_unit(eMetric);
+}
+
+IMPL_LINK_NOARG(SvxNumPositionTabPage, EditModifyHdl_Impl, weld::ComboBox&, void)
+{
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+
+ const sal_Int32 nPos = m_xAlignLB->get_visible()
+ ? m_xAlignLB->get_active()
+ : m_xAlign2LB->get_active();
+ SvxAdjust eAdjust = SvxAdjust::Center;
+ if(nPos == 0)
+ eAdjust = SvxAdjust::Left;
+ else if(nPos == 2)
+ eAdjust = SvxAdjust::Right;
+ aNumFmt.SetNumAdjust( eAdjust );
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ nMask <<= 1;
+ }
+ SetModified();
+}
+
+IMPL_LINK_NOARG(SvxNumPositionTabPage, LevelHdl_Impl, weld::TreeView&, void)
+{
+ if (m_pLevelHdlEvent)
+ return;
+ // tdf#127120 multiselection may be implemented by deselect follow by select so
+ // fire off the handler to happen on next event loop and only process the
+ // final state
+ m_pLevelHdlEvent = Application::PostUserEvent(LINK(this, SvxNumPositionTabPage, LevelHdl));
+}
+
+IMPL_LINK_NOARG(SvxNumPositionTabPage, LevelHdl, void*, void)
+{
+ m_pLevelHdlEvent = nullptr;
+
+ sal_uInt16 nSaveNumLvl = nActNumLvl;
+ nActNumLvl = 0;
+ std::vector<int> aSelectedRows = m_xLevelLB->get_selected_rows();
+ if (std::find(aSelectedRows.begin(), aSelectedRows.end(), pActNum->GetLevelCount()) != aSelectedRows.end() &&
+ (aSelectedRows.size() == 1 || nSaveNumLvl != 0xffff))
+ {
+ nActNumLvl = 0xFFFF;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
+ m_xLevelLB->unselect(i);
+ }
+ else if (!aSelectedRows.empty())
+ {
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
+ {
+ if (std::find(aSelectedRows.begin(), aSelectedRows.end(), i) != aSelectedRows.end())
+ nActNumLvl |= nMask;
+ nMask <<= 1;
+ }
+ m_xLevelLB->unselect(pActNum->GetLevelCount());
+ }
+ else
+ {
+ nActNumLvl = nSaveNumLvl;
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
+ {
+ if(nActNumLvl & nMask)
+ {
+ m_xLevelLB->select(i);
+ break;
+ }
+ nMask <<=1;
+ }
+ }
+ m_xRelativeCB->set_sensitive(nActNumLvl != 1);
+ SetModified();
+ InitPosAndSpaceMode();
+ ShowControlsDependingOnPosAndSpaceMode();
+ InitControls();
+}
+
+IMPL_LINK(SvxNumPositionTabPage, DistanceHdl_Impl, weld::MetricSpinButton&, rFld, void)
+{
+ if(bInInintControl)
+ return;
+ tools::Long nValue = GetCoreValue(rFld, eCoreUnit);
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt( pActNum->GetLevel( i ) );
+ if (&rFld == m_xDistBorderMF.get())
+ {
+
+ if (m_xRelativeCB->get_active())
+ {
+ if(0 == i)
+ {
+ auto const nTmp = aNumFmt.GetFirstLineOffset();
+ aNumFmt.SetAbsLSpace( nValue - nTmp);
+ }
+ else
+ {
+ tools::Long nTmp = pActNum->GetLevel( i - 1 ).GetAbsLSpace() +
+ pActNum->GetLevel( i - 1 ).GetFirstLineOffset() -
+ pActNum->GetLevel( i ).GetFirstLineOffset();
+
+ aNumFmt.SetAbsLSpace( nValue + nTmp);
+ }
+ }
+ else
+ {
+ aNumFmt.SetAbsLSpace( nValue - aNumFmt.GetFirstLineOffset());
+ }
+ }
+ else if (&rFld == m_xDistNumMF.get())
+ {
+ aNumFmt.SetCharTextDistance( static_cast<short>(nValue) );
+ }
+ else if (&rFld == m_xIndentMF.get())
+ {
+ // together with the FirstLineOffset the AbsLSpace must be changed, too
+ tools::Long nDiff = nValue + aNumFmt.GetFirstLineOffset();
+ auto const nAbsLSpace = aNumFmt.GetAbsLSpace();
+ aNumFmt.SetAbsLSpace(nAbsLSpace + nDiff);
+ aNumFmt.SetFirstLineOffset( -nValue );
+ }
+
+ pActNum->SetLevel( i, aNumFmt );
+ }
+ nMask <<= 1;
+ }
+
+ SetModified();
+ if (!m_xDistBorderMF->get_sensitive())
+ {
+ m_xDistBorderMF->set_text("");
+ }
+}
+
+IMPL_LINK(SvxNumPositionTabPage, RelativeHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ bool bOn = rBox.get_active();
+ bool bSingleSelection = m_xLevelLB->count_selected_rows() == 1 && SAL_MAX_UINT16 != nActNumLvl;
+ bool bSetValue = false;
+ tools::Long nValue = 0;
+ if(bOn || bSingleSelection)
+ {
+ sal_uInt16 nMask = 1;
+ bool bFirst = true;
+ bSetValue = true;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ const SvxNumberFormat &rNumFmt = pActNum->GetLevel(i);
+ if(bFirst)
+ {
+ nValue = rNumFmt.GetAbsLSpace() + rNumFmt.GetFirstLineOffset();
+ if(bOn && i)
+ nValue -= (pActNum->GetLevel(i - 1).GetAbsLSpace() + pActNum->GetLevel(i - 1).GetFirstLineOffset());
+ }
+ else
+ bSetValue = nValue ==
+ (rNumFmt.GetAbsLSpace() + rNumFmt.GetFirstLineOffset()) -
+ (pActNum->GetLevel(i - 1).GetAbsLSpace() + pActNum->GetLevel(i - 1).GetFirstLineOffset());
+ bFirst = false;
+ }
+ nMask <<= 1;
+ }
+
+ }
+ if(bSetValue)
+ SetMetricValue(*m_xDistBorderMF, nValue, eCoreUnit);
+ else
+ m_xDistBorderMF->set_text("");
+ m_xDistBorderMF->set_sensitive(bOn || bSingleSelection);
+ m_xDistBorderFT->set_sensitive(bOn || bSingleSelection);
+ bLastRelative = bOn;
+}
+
+IMPL_LINK_NOARG(SvxNumPositionTabPage, LabelFollowedByHdl_Impl, weld::ComboBox&, void)
+{
+ // determine value to be set at the chosen list levels
+ SvxNumberFormat::LabelFollowedBy eLabelFollowedBy = SvxNumberFormat::LISTTAB;
+ {
+ const auto nPos = m_xLabelFollowedByLB->get_active();
+ if ( nPos == 1 )
+ {
+ eLabelFollowedBy = SvxNumberFormat::SPACE;
+ }
+ else if ( nPos == 2 )
+ {
+ eLabelFollowedBy = SvxNumberFormat::NOTHING;
+ }
+ else if ( nPos == 3 )
+ {
+ eLabelFollowedBy = SvxNumberFormat::NEWLINE;
+ }
+ }
+
+ // set value at the chosen list levels
+ bool bSameListtabPos = true;
+ sal_uInt16 nFirstLvl = SAL_MAX_UINT16;
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i )
+ {
+ if ( nActNumLvl & nMask )
+ {
+ SvxNumberFormat aNumFmt( pActNum->GetLevel(i) );
+ aNumFmt.SetLabelFollowedBy( eLabelFollowedBy );
+ pActNum->SetLevel( i, aNumFmt );
+
+ if ( nFirstLvl == SAL_MAX_UINT16 )
+ {
+ nFirstLvl = i;
+ }
+ else
+ {
+ bSameListtabPos &= aNumFmt.GetListtabPos() ==
+ pActNum->GetLevel( nFirstLvl ).GetListtabPos();
+ }
+ }
+ nMask <<= 1;
+ }
+
+ // enable/disable metric field for list tab stop position depending on
+ // selected item following the list label.
+ m_xListtabFT->set_sensitive( eLabelFollowedBy == SvxNumberFormat::LISTTAB );
+ m_xListtabMF->set_sensitive( eLabelFollowedBy == SvxNumberFormat::LISTTAB );
+ if ( bSameListtabPos && eLabelFollowedBy == SvxNumberFormat::LISTTAB )
+ {
+ SetMetricValue(*m_xListtabMF, pActNum->GetLevel( nFirstLvl ).GetListtabPos(), eCoreUnit);
+ }
+ else
+ {
+ m_xListtabMF->set_text(OUString());
+ }
+
+ SetModified();
+}
+
+IMPL_LINK(SvxNumPositionTabPage, ListtabPosHdl_Impl, weld::MetricSpinButton&, rFld, void)
+{
+ // determine value to be set at the chosen list levels
+ const tools::Long nValue = GetCoreValue(rFld, eCoreUnit);
+
+ // set value at the chosen list levels
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i )
+ {
+ if ( nActNumLvl & nMask )
+ {
+ SvxNumberFormat aNumFmt( pActNum->GetLevel(i) );
+ aNumFmt.SetListtabPos( nValue );
+ pActNum->SetLevel( i, aNumFmt );
+ }
+ nMask <<= 1;
+ }
+
+ SetModified();
+}
+
+IMPL_LINK(SvxNumPositionTabPage, AlignAtHdl_Impl, weld::MetricSpinButton&, rFld, void)
+{
+ // determine value to be set at the chosen list levels
+ const tools::Long nValue = GetCoreValue(rFld, eCoreUnit);
+
+ // set value at the chosen list levels
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i )
+ {
+ if ( nActNumLvl & nMask )
+ {
+ SvxNumberFormat aNumFmt( pActNum->GetLevel(i) );
+ const tools::Long nFirstLineIndent = nValue - aNumFmt.GetIndentAt();
+ aNumFmt.SetFirstLineIndent( nFirstLineIndent );
+ pActNum->SetLevel( i, aNumFmt );
+ }
+ nMask <<= 1;
+ }
+
+ SetModified();
+}
+
+IMPL_LINK(SvxNumPositionTabPage, IndentAtHdl_Impl, weld::MetricSpinButton&, rFld, void)
+{
+ // determine value to be set at the chosen list levels
+ const tools::Long nValue = GetCoreValue(rFld, eCoreUnit);
+
+ // set value at the chosen list levels
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i )
+ {
+ if ( nActNumLvl & nMask )
+ {
+ SvxNumberFormat aNumFmt( pActNum->GetLevel(i) );
+ const tools::Long nAlignedAt = aNumFmt.GetIndentAt() +
+ aNumFmt.GetFirstLineIndent();
+ aNumFmt.SetIndentAt( nValue );
+ const tools::Long nNewFirstLineIndent = nAlignedAt - nValue;
+ aNumFmt.SetFirstLineIndent( nNewFirstLineIndent );
+ pActNum->SetLevel( i, aNumFmt );
+ }
+ nMask <<= 1;
+ }
+
+ SetModified();
+}
+
+IMPL_LINK_NOARG(SvxNumPositionTabPage, StandardHdl_Impl, weld::Button&, void)
+{
+ sal_uInt16 nMask = 1;
+ SvxNumRule aTmpNumRule( pActNum->GetFeatureFlags(),
+ pActNum->GetLevelCount(),
+ pActNum->IsContinuousNumbering(),
+ SvxNumRuleType::NUMBERING,
+ pActNum->GetLevel( 0 ).GetPositionAndSpaceMode() );
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt( pActNum->GetLevel( i ) );
+ const SvxNumberFormat& aTempFmt(aTmpNumRule.GetLevel( i ));
+ aNumFmt.SetPositionAndSpaceMode( aTempFmt.GetPositionAndSpaceMode() );
+ if ( aTempFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
+ {
+ aNumFmt.SetAbsLSpace( aTempFmt.GetAbsLSpace() );
+ aNumFmt.SetCharTextDistance( aTempFmt.GetCharTextDistance() );
+ aNumFmt.SetFirstLineOffset( aTempFmt.GetFirstLineOffset() );
+ }
+ else if ( aTempFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
+ {
+ aNumFmt.SetNumAdjust( aTempFmt.GetNumAdjust() );
+ aNumFmt.SetLabelFollowedBy( aTempFmt.GetLabelFollowedBy() );
+ aNumFmt.SetListtabPos( aTempFmt.GetListtabPos() );
+ aNumFmt.SetFirstLineIndent( aTempFmt.GetFirstLineIndent() );
+ aNumFmt.SetIndentAt( aTempFmt.GetIndentAt() );
+ }
+
+ pActNum->SetLevel( i, aNumFmt );
+ }
+ nMask <<= 1;
+ }
+
+ InitControls();
+ SetModified();
+}
+
+void SvxNumPositionTabPage::SetModified()
+{
+ bModified = true;
+ m_aPreviewWIN.SetLevel(nActNumLvl);
+ m_aPreviewWIN.Invalidate();
+}
+
+void SvxNumOptionsTabPage::SetModified(bool bRepaint)
+{
+ bModified = true;
+ if (bRepaint)
+ {
+ m_aPreviewWIN.SetLevel(nActNumLvl);
+ m_aPreviewWIN.Invalidate();
+ }
+}
+
+void SvxNumOptionsTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxStringListItem* pListItem = aSet.GetItem<SfxStringListItem>(SID_CHAR_FMT_LIST_BOX, false);
+ const SfxStringItem* pNumCharFmt = aSet.GetItem<SfxStringItem>(SID_NUM_CHAR_FMT, false);
+ const SfxStringItem* pBulletCharFmt = aSet.GetItem<SfxStringItem>(SID_BULLET_CHAR_FMT, false);
+ const SfxUInt16Item* pMetricItem = aSet.GetItem<SfxUInt16Item>(SID_METRIC_ITEM, false);
+
+ if (pNumCharFmt &&pBulletCharFmt)
+ SetCharFmts( pNumCharFmt->GetValue(),pBulletCharFmt->GetValue());
+
+ if (pListItem)
+ {
+ const std::vector<OUString> &aList = pListItem->GetList();
+ sal_uInt32 nCount = aList.size();
+ for(sal_uInt32 i = 0; i < nCount; i++)
+ m_xCharFmtLB->append_text(aList[i]);
+ }
+ if (pMetricItem)
+ SetMetric(static_cast<FieldUnit>(pMetricItem->GetValue()));
+}
+
+void SvxNumPositionTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxUInt16Item* pMetricItem = aSet.GetItem<SfxUInt16Item>(SID_METRIC_ITEM, false);
+
+ if (pMetricItem)
+ SetMetric(static_cast<FieldUnit>(pMetricItem->GetValue()));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/page.cxx b/cui/source/tabpages/page.cxx
new file mode 100644
index 0000000000..d810a9471d
--- /dev/null
+++ b/cui/source/tabpages/page.cxx
@@ -0,0 +1,1665 @@
+/* -*- 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 <memory>
+#include <o3tl/unit_conversion.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/viewsh.hxx>
+#include <svl/cjkoptions.hxx>
+#include <svl/ctloptions.hxx>
+#include <svtools/unitconv.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <sal/macros.h>
+#include <osl/diagnose.h>
+
+#include <svx/strings.hrc>
+#include <svx/dialmgr.hxx>
+#include <page.hxx>
+#include <svx/pageitem.hxx>
+#include <editeng/brushitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/shaditem.hxx>
+#include <editeng/pbinitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/sizeitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <svx/dlgutil.hxx>
+#include <editeng/paperinf.hxx>
+#include <svl/stritem.hxx>
+#include <editeng/eerdll.hxx>
+#include <editeng/editrids.hrc>
+#include <svx/svxids.hrc>
+#include <svtools/optionsdrawinglayer.hxx>
+#include <svl/slstitm.hxx>
+#include <svx/xdef.hxx>
+#include <svx/unobrushitemhelper.hxx>
+#include <svx/SvxNumOptionsTabPageHelper.hxx>
+#include <sal/log.hxx>
+#include <svl/grabbagitem.hxx>
+
+// static ----------------------------------------------------------------
+
+// #i19922# - tdf#126051 see svx/source/dialog/hdft.cxx and sw/source/uibase/sidebar/PageMarginControl.hxx
+constexpr tools::Long MINBODY = o3tl::toTwips(1, o3tl::Length::mm); // 1mm in twips rounded
+
+const WhichRangesContainer SvxPageDescPage::pRanges(
+ svl::Items<
+ SID_ATTR_BORDER_OUTER, SID_ATTR_BORDER_SHADOW,
+ SID_ATTR_LRSPACE, SID_ATTR_PAGE_SHARED,
+ SID_SWREGISTER_COLLECTION, SID_SWREGISTER_MODE>);
+// ------- Mapping page layout ------------------------------------------
+
+const SvxPageUsage aArr[] =
+{
+ SvxPageUsage::All,
+ SvxPageUsage::Mirror,
+ SvxPageUsage::Right,
+ SvxPageUsage::Left
+};
+
+
+static sal_uInt16 PageUsageToPos_Impl( SvxPageUsage nUsage )
+{
+ for ( size_t i = 0; i < std::size(aArr); ++i )
+ if ( aArr[i] == nUsage )
+ return i;
+ return 3;
+}
+
+
+static SvxPageUsage PosToPageUsage_Impl( sal_uInt16 nPos )
+{
+ if ( nPos >= std::size(aArr) )
+ return SvxPageUsage::NONE;
+ return aArr[nPos];
+}
+
+
+static Size GetMinBorderSpace_Impl( const SvxShadowItem& rShadow, const SvxBoxItem& rBox )
+{
+ Size aSz;
+ aSz.setHeight( rShadow.CalcShadowSpace( SvxShadowItemSide::BOTTOM ) + rBox.CalcLineSpace( SvxBoxItemLine::BOTTOM ) );
+ aSz.AdjustHeight(rShadow.CalcShadowSpace( SvxShadowItemSide::TOP ) + rBox.CalcLineSpace( SvxBoxItemLine::TOP ) );
+ aSz.setWidth( rShadow.CalcShadowSpace( SvxShadowItemSide::LEFT ) + rBox.CalcLineSpace( SvxBoxItemLine::LEFT ) );
+ aSz.AdjustWidth(rShadow.CalcShadowSpace( SvxShadowItemSide::RIGHT ) + rBox.CalcLineSpace( SvxBoxItemLine::RIGHT ) );
+ return aSz;
+}
+
+
+static tools::Long ConvertLong_Impl( const tools::Long nIn, MapUnit eUnit )
+{
+ return OutputDevice::LogicToLogic( nIn, eUnit, MapUnit::MapTwip );
+}
+
+static bool IsEqualSize_Impl( const SvxSizeItem* pSize, const Size& rSize )
+{
+ if ( pSize )
+ {
+ Size aSize = pSize->GetSize();
+ tools::Long nDiffW = std::abs( rSize.Width () - aSize.Width () );
+ tools::Long nDiffH = std::abs( rSize.Height() - aSize.Height() );
+ return ( nDiffW < 10 && nDiffH < 10 );
+ }
+ else
+ return false;
+}
+
+
+#define MARGIN_LEFT ( MarginPosition(0x0001) )
+#define MARGIN_RIGHT ( MarginPosition(0x0002) )
+#define MARGIN_TOP ( MarginPosition(0x0004) )
+#define MARGIN_BOTTOM ( MarginPosition(0x0008) )
+
+// class SvxPageDescPage --------------------------------------------------
+
+std::unique_ptr<SfxTabPage> SvxPageDescPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet )
+{
+ return std::make_unique<SvxPageDescPage>(pPage, pController, *rSet);
+}
+
+SvxPageDescPage::SvxPageDescPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttr)
+ : SfxTabPage(pPage, pController, "cui/ui/pageformatpage.ui", "PageFormatPage", &rAttr)
+ , bLandscape(false)
+ , eMode(SVX_PAGE_MODE_STANDARD)
+ , ePaperStart(PAPER_A3)
+ , m_nPos(0)
+ , mpDefPrinter(nullptr)
+ , mbDelPrinter(false)
+ , mbEnableDrawingLayerFillStyles(false)
+ , m_xPaperSizeBox(new SvxPaperSizeListBox(m_xBuilder->weld_combo_box("comboPageFormat")))
+ , m_xPaperWidthEdit(m_xBuilder->weld_metric_spin_button("spinWidth", FieldUnit::CM))
+ , m_xPaperHeightEdit(m_xBuilder->weld_metric_spin_button("spinHeight", FieldUnit::CM))
+ , m_xPortraitBtn(m_xBuilder->weld_radio_button("radiobuttonPortrait"))
+ , m_xLandscapeBtn(m_xBuilder->weld_radio_button("radiobuttonLandscape"))
+ , m_xTextFlowLbl(m_xBuilder->weld_label("labelTextFlow"))
+ , m_xTextFlowBox(new svx::FrameDirectionListBox(m_xBuilder->weld_combo_box("comboTextFlowBox")))
+ , m_xPaperTrayBox(m_xBuilder->weld_combo_box("comboPaperTray"))
+ , m_xLeftMarginLbl(m_xBuilder->weld_label("labelLeftMargin"))
+ , m_xLeftMarginEdit(m_xBuilder->weld_metric_spin_button("spinMargLeft", FieldUnit::CM))
+ , m_xRightMarginLbl(m_xBuilder->weld_label("labelRightMargin"))
+ , m_xRightMarginEdit(m_xBuilder->weld_metric_spin_button("spinMargRight", FieldUnit::CM))
+ , m_xTopMarginEdit(m_xBuilder->weld_metric_spin_button("spinMargTop", FieldUnit::CM))
+ , m_xBottomMarginEdit(m_xBuilder->weld_metric_spin_button("spinMargBot", FieldUnit::CM))
+ , m_xGutterMarginLbl(m_xBuilder->weld_label("labelGutterMargin"))
+ , m_xGutterMarginEdit(m_xBuilder->weld_metric_spin_button("spinMargGut", FieldUnit::CM))
+ , m_xPageText(m_xBuilder->weld_label("labelPageLayout"))
+ , m_xLayoutBox(m_xBuilder->weld_combo_box("comboPageLayout"))
+ , m_xNumberFormatText(m_xBuilder->weld_label("labelPageNumbers"))
+ , m_xNumberFormatBox(new SvxPageNumberListBox(m_xBuilder->weld_combo_box("comboLayoutFormat")))
+ , m_xTblAlignFT(m_xBuilder->weld_label("labelTblAlign"))
+ , m_xHorzBox(m_xBuilder->weld_check_button("checkbuttonHorz"))
+ , m_xVertBox(m_xBuilder->weld_check_button("checkbuttonVert"))
+ , m_xAdaptBox(m_xBuilder->weld_check_button("checkAdaptBox"))
+ , m_xRegisterCB(m_xBuilder->weld_check_button("checkRegisterTrue"))
+ , m_xRegisterFT(m_xBuilder->weld_label("labelRegisterStyle"))
+ , m_xRegisterLB(m_xBuilder->weld_combo_box("comboRegisterStyle"))
+ , m_xGutterPositionFT(m_xBuilder->weld_label("labelGutterPosition"))
+ , m_xGutterPositionLB(m_xBuilder->weld_combo_box("comboGutterPosition"))
+ , m_xRtlGutterCB(m_xBuilder->weld_check_button("checkRtlGutter"))
+ , m_xBackgroundFullSizeCB(m_xBuilder->weld_check_button("checkBackgroundFullSize"))
+ // Strings stored in UI
+ , m_xInsideLbl(m_xBuilder->weld_label("labelInner"))
+ , m_xOutsideLbl(m_xBuilder->weld_label("labelOuter"))
+ , m_xPrintRangeQueryText(m_xBuilder->weld_label("labelMsg"))
+ , m_xBspWin(new weld::CustomWeld(*m_xBuilder, "drawingareaPageDirection", m_aBspWin))
+{
+ m_xRegisterLB->set_size_request(m_xRegisterLB->get_approximate_digit_width() * 20, -1);
+
+ bBorderModified = false;
+ m_aBspWin.EnableRTL(false);
+
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ bool bCJK = SvtCJKOptions::IsAsianTypographyEnabled();
+ bool bCTL = SvtCTLOptions::IsCTLFontEnabled();
+ bool bWeb = false;
+
+ const SfxUInt16Item* pHtmlModeItem = rAttr.GetItemIfSet(SID_HTML_MODE, false);
+ if (!pHtmlModeItem)
+ {
+ if (SfxObjectShell* pShell = SfxObjectShell::Current())
+ pHtmlModeItem = pShell->GetItem(SID_HTML_MODE);
+ }
+ if (pHtmlModeItem)
+ bWeb = 0 != (pHtmlModeItem->GetValue() & HTMLMODE_ON);
+
+ // fill text flow listbox with valid entries
+
+ m_xTextFlowBox->append(SvxFrameDirection::Horizontal_LR_TB, SvxResId(RID_SVXSTR_PAGEDIR_LTR_HORI));
+
+ if (bCTL)
+ m_xTextFlowBox->append(SvxFrameDirection::Horizontal_RL_TB, SvxResId(RID_SVXSTR_PAGEDIR_RTL_HORI));
+
+
+ // #109989# do not show vertical directions in Writer/Web
+ if( !bWeb && bCJK )
+ {
+ m_xTextFlowBox->append(SvxFrameDirection::Vertical_RL_TB, SvxResId(RID_SVXSTR_PAGEDIR_RTL_VERT));
+ m_xTextFlowBox->append(SvxFrameDirection::Vertical_LR_TB, SvxResId(RID_SVXSTR_PAGEDIR_LTR_VERT));
+ }
+
+ // #109989# show the text direction box in Writer/Web too
+ if( (bCJK || bCTL) &&
+ SfxItemState::UNKNOWN < rAttr.GetItemState(GetWhich( SID_ATTR_FRAMEDIRECTION )))
+ {
+ m_xTextFlowLbl->show();
+ m_xTextFlowBox->show();
+ m_xTextFlowBox->connect_changed(LINK(this, SvxPageDescPage, FrameDirectionModify_Impl));
+
+ m_aBspWin.EnableFrameDirection(true);
+ }
+ Init_Impl();
+
+ FieldUnit eFUnit = GetModuleFieldUnit( rAttr );
+ SetFieldUnit( *m_xLeftMarginEdit, eFUnit );
+ SetFieldUnit( *m_xRightMarginEdit, eFUnit );
+ SetFieldUnit( *m_xTopMarginEdit, eFUnit );
+ SetFieldUnit( *m_xBottomMarginEdit, eFUnit );
+ SetFieldUnit(*m_xGutterMarginEdit, eFUnit);
+ SetFieldUnit( *m_xPaperWidthEdit, eFUnit );
+ SetFieldUnit( *m_xPaperHeightEdit, eFUnit );
+
+ if ( SfxViewShell::Current() && SfxViewShell::Current()->GetPrinter() )
+ {
+ mpDefPrinter = SfxViewShell::Current()->GetPrinter();
+ }
+ else
+ {
+ mpDefPrinter = VclPtr<Printer>::Create();
+ mbDelPrinter = true;
+ }
+
+ MapMode aOldMode = mpDefPrinter->GetMapMode();
+ mpDefPrinter->SetMapMode(MapMode(MapUnit::MapTwip));
+
+ // set first- and last-values for the margins
+ Size aPaperSize = mpDefPrinter->GetPaperSize();
+ Size aPrintSize = mpDefPrinter->GetOutputSize();
+
+ /*
+ * To convert a point ( 0,0 ) into logic coordinates
+ * looks like nonsense; but it makes sense when the
+ * coordinate system's origin has been moved.
+ */
+ Point aPrintOffset = mpDefPrinter->GetPageOffset() - mpDefPrinter->PixelToLogic( Point() );
+ mpDefPrinter->SetMapMode( aOldMode );
+
+ nFirstLeftMargin = m_xLeftMarginEdit->convert_value_from(m_xLeftMarginEdit->normalize(aPrintOffset.X()), FieldUnit::TWIP);
+ nFirstRightMargin = m_xRightMarginEdit->convert_value_from(m_xRightMarginEdit->normalize(aPaperSize.Width() - aPrintSize.Width() - aPrintOffset.X()), FieldUnit::TWIP);
+ nFirstTopMargin = m_xTopMarginEdit->convert_value_from(m_xTopMarginEdit->normalize(aPrintOffset.Y() ), FieldUnit::TWIP);
+ nFirstBottomMargin = m_xBottomMarginEdit->convert_value_from(m_xBottomMarginEdit->normalize(aPaperSize.Height() - aPrintSize.Height() - aPrintOffset.Y()), FieldUnit::TWIP );
+ nLastLeftMargin = m_xLeftMarginEdit->convert_value_from(m_xLeftMarginEdit->normalize(aPrintOffset.X() + aPrintSize.Width()), FieldUnit::TWIP);
+ nLastRightMargin = m_xRightMarginEdit->convert_value_from(m_xRightMarginEdit->normalize(aPrintOffset.X() + aPrintSize.Width()), FieldUnit::TWIP);
+ nLastTopMargin = m_xTopMarginEdit->convert_value_from(m_xTopMarginEdit->normalize(aPrintOffset.Y() + aPrintSize.Height()), FieldUnit::TWIP);
+ nLastBottomMargin = m_xBottomMarginEdit->convert_value_from(m_xBottomMarginEdit->normalize(aPrintOffset.Y() + aPrintSize.Height()), FieldUnit::TWIP);
+
+ // #i4219# take Maximum now from configuration (1/100th cm)
+ // was: 11900 -> 119 cm ;new value 3 meters -> 300 cm -> 30000
+ m_xPaperWidthEdit->set_max(m_xPaperWidthEdit->normalize(SvtOptionsDrawinglayer::GetMaximumPaperWidth()), FieldUnit::CM);
+ m_xPaperHeightEdit->set_max(m_xPaperHeightEdit->normalize(SvtOptionsDrawinglayer::GetMaximumPaperHeight()), FieldUnit::CM);
+
+ // #i4219# also for margins (1/100th cm). Was: 9999, keeping.
+ m_xLeftMarginEdit->set_max(m_xLeftMarginEdit->normalize(SvtOptionsDrawinglayer::GetMaximumPaperLeftMargin()), FieldUnit::MM);
+ m_xRightMarginEdit->set_max(m_xRightMarginEdit->normalize(SvtOptionsDrawinglayer::GetMaximumPaperRightMargin()), FieldUnit::MM);
+ m_xTopMarginEdit->set_max(m_xTopMarginEdit->normalize(SvtOptionsDrawinglayer::GetMaximumPaperTopMargin()), FieldUnit::MM);
+ m_xBottomMarginEdit->set_max(m_xBottomMarginEdit->normalize(SvtOptionsDrawinglayer::GetMaximumPaperBottomMargin()), FieldUnit::MM);
+ m_xGutterMarginEdit->set_max(
+ m_xGutterMarginEdit->normalize(SvtOptionsDrawinglayer::GetMaximumPaperLeftMargin()),
+ FieldUnit::MM);
+
+ // Get the i18n framework numberings and add them to the listbox.
+ SvxNumOptionsTabPageHelper::GetI18nNumbering(m_xNumberFormatBox->get_widget(), std::numeric_limits<sal_uInt16>::max());
+}
+
+SvxPageDescPage::~SvxPageDescPage()
+{
+ if(mbDelPrinter)
+ {
+ mpDefPrinter.disposeAndClear();
+ mbDelPrinter = false;
+ }
+}
+
+void SvxPageDescPage::Init_Impl()
+{
+ // adjust the handler
+ m_xLayoutBox->connect_changed(LINK(this, SvxPageDescPage, LayoutHdl_Impl));
+ m_xGutterPositionLB->connect_changed(LINK(this, SvxPageDescPage, GutterPositionHdl_Impl));
+
+ m_xPaperSizeBox->connect_changed(LINK(this, SvxPageDescPage, PaperSizeSelect_Impl));
+ m_xPaperWidthEdit->connect_value_changed( LINK(this, SvxPageDescPage, PaperSizeModify_Impl));
+ m_xPaperHeightEdit->connect_value_changed(LINK(this, SvxPageDescPage, PaperSizeModify_Impl));
+ m_xLandscapeBtn->connect_toggled(LINK(this, SvxPageDescPage, SwapOrientation_Impl));
+ m_xPortraitBtn->connect_toggled(LINK(this, SvxPageDescPage, SwapOrientation_Impl));
+
+ Link<weld::MetricSpinButton&, void> aLink = LINK(this, SvxPageDescPage, BorderModify_Impl);
+ m_xLeftMarginEdit->connect_value_changed(aLink);
+ m_xRightMarginEdit->connect_value_changed(aLink);
+ m_xTopMarginEdit->connect_value_changed(aLink);
+ m_xBottomMarginEdit->connect_value_changed(aLink);
+ m_xGutterMarginEdit->connect_value_changed(aLink);
+
+ m_xHorzBox->connect_toggled(LINK(this, SvxPageDescPage, CenterHdl_Impl));
+ m_xVertBox->connect_toggled(LINK(this, SvxPageDescPage, CenterHdl_Impl));
+}
+
+void SvxPageDescPage::Reset( const SfxItemSet* rSet )
+{
+ SfxItemPool* pPool = rSet->GetPool();
+ SAL_WARN_IF(!pPool, "cui.tabpages", "Where is the pool?");
+ MapUnit eUnit = pPool->GetMetric( GetWhich( SID_ATTR_LRSPACE ) );
+
+ // adjust margins (right/left)
+ const SfxPoolItem* pItem = GetItem( *rSet, SID_ATTR_LRSPACE );
+
+ if ( pItem )
+ {
+ const SvxLRSpaceItem& rLRSpace = static_cast<const SvxLRSpaceItem&>(*pItem);
+ SetMetricValue( *m_xLeftMarginEdit, rLRSpace.GetLeft(), eUnit );
+ SetMetricValue(*m_xGutterMarginEdit, rLRSpace.GetGutterMargin(), eUnit);
+ m_aBspWin.SetLeft(
+ static_cast<sal_uInt16>(ConvertLong_Impl( rLRSpace.GetLeft(), eUnit )) );
+ SetMetricValue( *m_xRightMarginEdit, rLRSpace.GetRight(), eUnit );
+ m_aBspWin.SetRight(
+ static_cast<sal_uInt16>(ConvertLong_Impl( rLRSpace.GetRight(), eUnit )) );
+ }
+
+ // adjust margins (top/bottom)
+ pItem = GetItem( *rSet, SID_ATTR_ULSPACE );
+
+ if ( pItem )
+ {
+ const SvxULSpaceItem& rULSpace = static_cast<const SvxULSpaceItem&>(*pItem);
+ SetMetricValue( *m_xTopMarginEdit, rULSpace.GetUpper(), eUnit );
+ m_aBspWin.SetTop(
+ static_cast<sal_uInt16>(ConvertLong_Impl( static_cast<tools::Long>(rULSpace.GetUpper()), eUnit )) );
+ SetMetricValue( *m_xBottomMarginEdit, rULSpace.GetLower(), eUnit );
+ m_aBspWin.SetBottom(
+ static_cast<sal_uInt16>(ConvertLong_Impl( static_cast<tools::Long>(rULSpace.GetLower()), eUnit )) );
+ }
+
+ if (const SfxGrabBagItem* pGragbagItem = rSet->GetItemIfSet(SID_ATTR_CHAR_GRABBAG))
+ {
+ bool bGutterAtTop{};
+ auto it = pGragbagItem->GetGrabBag().find("GutterAtTop");
+ if (it != pGragbagItem->GetGrabBag().end())
+ {
+ it->second >>= bGutterAtTop;
+ }
+
+ if (bGutterAtTop)
+ {
+ m_xGutterPositionLB->set_active(1);
+ }
+ else
+ {
+ // Left.
+ m_xGutterPositionLB->set_active(0);
+ }
+ it = pGragbagItem->GetGrabBag().find("RtlGutter");
+ bool bRtlGutter{};
+ if (it != pGragbagItem->GetGrabBag().end())
+ {
+ it->second >>= bRtlGutter;
+ m_xRtlGutterCB->set_active(bRtlGutter);
+ m_xRtlGutterCB->show();
+ }
+ it = pGragbagItem->GetGrabBag().find("BackgroundFullSize");
+ bool isBackgroundFullSize{};
+ if (it != pGragbagItem->GetGrabBag().end())
+ {
+ it->second >>= isBackgroundFullSize;
+ m_xBackgroundFullSizeCB->set_active(isBackgroundFullSize);
+ m_xBackgroundFullSizeCB->show();
+ }
+ }
+
+ // general page data
+ SvxNumType eNumType = SVX_NUM_ARABIC;
+ bLandscape = ( mpDefPrinter->GetOrientation() == Orientation::Landscape );
+ SvxPageUsage nUse = SvxPageUsage::All;
+ pItem = GetItem( *rSet, SID_ATTR_PAGE );
+
+ if ( pItem )
+ {
+ const SvxPageItem& rItem = static_cast<const SvxPageItem&>(*pItem);
+ eNumType = rItem.GetNumType();
+ nUse = rItem.GetPageUsage();
+ bLandscape = rItem.IsLandscape();
+ }
+
+ // alignment
+ m_xLayoutBox->set_active(::PageUsageToPos_Impl(nUse));
+ m_aBspWin.SetUsage( nUse );
+ LayoutHdl_Impl( *m_xLayoutBox );
+
+ //adjust numeration type of the page style
+ m_xNumberFormatBox->set_active_id(eNumType);
+
+ m_xPaperTrayBox->clear();
+ sal_uInt8 nPaperBin = PAPERBIN_PRINTER_SETTINGS;
+ pItem = GetItem( *rSet, SID_ATTR_PAGE_PAPERBIN );
+
+ if ( pItem )
+ {
+ nPaperBin = static_cast<const SvxPaperBinItem*>(pItem)->GetValue();
+
+ if ( nPaperBin >= mpDefPrinter->GetPaperBinCount() )
+ nPaperBin = PAPERBIN_PRINTER_SETTINGS;
+ }
+
+ OUString aBinName;
+
+ if ( PAPERBIN_PRINTER_SETTINGS == nPaperBin )
+ aBinName = EditResId(RID_SVXSTR_PAPERBIN_SETTINGS);
+ else
+ aBinName = mpDefPrinter->GetPaperBinName( static_cast<sal_uInt16>(nPaperBin) );
+
+ m_xPaperTrayBox->append(OUString::number(nPaperBin), aBinName);
+ m_xPaperTrayBox->set_active_text(aBinName);
+ // reset focus handler to default first so know none already connected
+ m_xPaperTrayBox->connect_focus_in(Link<weld::Widget&, void>());
+ // update the list when widget gets focus
+ m_xPaperTrayBox->connect_focus_in(LINK(this, SvxPageDescPage, PaperBinHdl_Impl));
+
+ Size aPaperSize = SvxPaperInfo::GetPaperSize( mpDefPrinter );
+ pItem = GetItem( *rSet, SID_ATTR_PAGE_SIZE );
+
+ if ( pItem )
+ aPaperSize = static_cast<const SvxSizeItem*>(pItem)->GetSize();
+
+ bool bOrientationSupport =
+ mpDefPrinter->HasSupport( PrinterSupport::SetOrientation );
+
+ if ( !bOrientationSupport &&
+ aPaperSize.Width() > aPaperSize.Height() )
+ bLandscape = true;
+
+ // tdf#130548 disable callbacks on the other of a pair of the radiogroup
+ // when toggling its partner
+ m_xLandscapeBtn->connect_toggled(Link<weld::Toggleable&, void>());
+ m_xPortraitBtn->connect_toggled(Link<weld::Toggleable&, void>());
+
+ m_xLandscapeBtn->set_active(bLandscape);
+ m_xPortraitBtn->set_active(!bLandscape);
+
+ m_xLandscapeBtn->connect_toggled(LINK(this, SvxPageDescPage, SwapOrientation_Impl));
+ m_xPortraitBtn->connect_toggled(LINK(this, SvxPageDescPage, SwapOrientation_Impl));
+
+ m_aBspWin.SetSize( Size( ConvertLong_Impl( aPaperSize.Width(), eUnit ),
+ ConvertLong_Impl( aPaperSize.Height(), eUnit ) ) );
+
+ aPaperSize = OutputDevice::LogicToLogic(aPaperSize, MapMode(eUnit), MapMode(MapUnit::Map100thMM));
+ if ( bLandscape )
+ Swap( aPaperSize );
+
+ // Actual Paper Format
+ Paper ePaper = SvxPaperInfo::GetSvxPaper( aPaperSize, MapUnit::Map100thMM );
+
+ if ( PAPER_USER != ePaper )
+ aPaperSize = SvxPaperInfo::GetPaperSize( ePaper, MapUnit::Map100thMM );
+
+ if ( bLandscape )
+ Swap( aPaperSize );
+
+ // write values into the edits
+ SetMetricValue( *m_xPaperHeightEdit, aPaperSize.Height(), MapUnit::Map100thMM );
+ SetMetricValue( *m_xPaperWidthEdit, aPaperSize.Width(), MapUnit::Map100thMM );
+ m_xPaperSizeBox->clear();
+
+ m_xPaperSizeBox->FillPaperSizeEntries( ( ePaperStart == PAPER_A3 ) ? PaperSizeApp::Std : PaperSizeApp::Draw );
+ m_xPaperSizeBox->set_active_id( ePaper );
+
+ // application specific
+
+ switch ( eMode )
+ {
+ case SVX_PAGE_MODE_CENTER:
+ {
+ m_xTblAlignFT->show();
+ m_xHorzBox->show();
+ m_xVertBox->show();
+ DisableVerticalPageDir();
+
+ // horizontal alignment
+ pItem = GetItem( *rSet, SID_ATTR_PAGE_EXT1 );
+ m_xHorzBox->set_active(pItem && static_cast<const SfxBoolItem*>(pItem)->GetValue());
+
+ // vertical alignment
+ pItem = GetItem( *rSet, SID_ATTR_PAGE_EXT2 );
+ m_xVertBox->set_active(pItem && static_cast<const SfxBoolItem*>(pItem)->GetValue());
+
+ // set example window on the table
+ m_aBspWin.SetTable( true );
+ m_aBspWin.SetHorz(m_xHorzBox->get_active());
+ m_aBspWin.SetVert(m_xVertBox->get_active());
+
+ m_xGutterMarginLbl->hide();
+ m_xGutterMarginEdit->hide();
+ m_xGutterPositionFT->hide();
+ m_xGutterPositionLB->hide();
+
+ break;
+ }
+
+ case SVX_PAGE_MODE_PRESENTATION:
+ {
+ DisableVerticalPageDir();
+ m_xAdaptBox->show();
+ pItem = GetItem( *rSet, SID_ATTR_PAGE_EXT1 );
+ m_xAdaptBox->set_active( pItem &&
+ static_cast<const SfxBoolItem*>(pItem)->GetValue() );
+
+ //!!! hidden, because not implemented by StarDraw
+ m_xLayoutBox->hide();
+ m_xPageText->hide();
+
+ m_xGutterMarginLbl->hide();
+ m_xGutterMarginEdit->hide();
+ m_xGutterPositionFT->hide();
+ m_xGutterPositionLB->hide();
+
+ break;
+ }
+ default: ;//prevent warning
+ }
+
+
+ // display background and border in the example
+ ResetBackground_Impl( *rSet );
+//! UpdateExample_Impl();
+ RangeHdl_Impl();
+
+ InitHeadFoot_Impl( *rSet );
+
+ bBorderModified = false;
+ SwapFirstValues_Impl( false );
+ UpdateExample_Impl();
+
+ m_xLeftMarginEdit->save_value();
+ m_xRightMarginEdit->save_value();
+ m_xTopMarginEdit->save_value();
+ m_xBottomMarginEdit->save_value();
+ m_xGutterMarginEdit->save_value();
+ m_xLayoutBox->save_value();
+ m_xNumberFormatBox->save_value();
+ m_xPaperSizeBox->save_value();
+ m_xPaperWidthEdit->save_value();
+ m_xPaperHeightEdit->save_value();
+ m_xPortraitBtn->save_state();
+ m_xLandscapeBtn->save_state();
+ m_xPaperTrayBox->save_value();
+ m_xVertBox->save_state();
+ m_xHorzBox->save_state();
+ m_xAdaptBox->save_state();
+ m_xGutterPositionLB->save_value();
+ m_xRtlGutterCB->save_state();
+ m_xBackgroundFullSizeCB->save_state();
+
+ CheckMarginEdits( true );
+
+
+ if(SfxItemState::SET == rSet->GetItemState(SID_SWREGISTER_MODE))
+ {
+ m_xRegisterCB->set_active(rSet->Get(SID_SWREGISTER_MODE).GetValue());
+ m_xRegisterCB->save_state();
+ RegisterModify(*m_xRegisterCB);
+ }
+ if(SfxItemState::SET == rSet->GetItemState(SID_SWREGISTER_COLLECTION))
+ {
+ m_xRegisterLB->set_active_text(
+ rSet->Get(SID_SWREGISTER_COLLECTION).GetValue());
+ m_xRegisterLB->save_value();
+ }
+
+ SfxItemState eState = rSet->GetItemState( GetWhich( SID_ATTR_FRAMEDIRECTION ),
+ true, &pItem );
+ if( SfxItemState::UNKNOWN != eState )
+ {
+ SvxFrameDirection nVal = SfxItemState::SET == eState
+ ? static_cast<const SvxFrameDirectionItem*>(pItem)->GetValue()
+ : SvxFrameDirection::Horizontal_LR_TB;
+ m_xTextFlowBox->set_active_id(nVal);
+
+ m_xTextFlowBox->save_value();
+ m_aBspWin.SetFrameDirection(nVal);
+ }
+}
+
+void SvxPageDescPage::FillUserData()
+{
+ if (SVX_PAGE_MODE_PRESENTATION == eMode)
+ SetUserData(m_xAdaptBox->get_active() ? OUString("1") : OUString("0")) ;
+
+}
+
+bool SvxPageDescPage::FillItemSet( SfxItemSet* rSet )
+{
+ bool bModified = false;
+ const SfxItemSet& rOldSet = GetItemSet();
+ SfxItemPool* pPool = rOldSet.GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_LRSPACE );
+ MapUnit eUnit = pPool->GetMetric( nWhich );
+ const SfxPoolItem* pOld = nullptr;
+
+ // copy old left and right margins
+ SvxLRSpaceItem aMargin( static_cast<const SvxLRSpaceItem&>(rOldSet.Get( nWhich )) );
+
+ // copy old top and bottom margins
+ nWhich = GetWhich( SID_ATTR_ULSPACE );
+ SvxULSpaceItem aTopMargin( static_cast<const SvxULSpaceItem&>(rOldSet.Get( nWhich )) );
+
+ if (m_xLeftMarginEdit->get_value_changed_from_saved())
+ {
+ aMargin.SetLeft( static_cast<sal_uInt16>(GetCoreValue( *m_xLeftMarginEdit, eUnit )) );
+ bModified = true;
+ }
+
+ if (m_xRightMarginEdit->get_value_changed_from_saved())
+ {
+ aMargin.SetRight( static_cast<sal_uInt16>(GetCoreValue( *m_xRightMarginEdit, eUnit )) );
+ bModified = true;
+ }
+
+ if (m_xGutterMarginEdit->get_value_changed_from_saved())
+ {
+ aMargin.SetGutterMargin(static_cast<sal_uInt16>(GetCoreValue(*m_xGutterMarginEdit, eUnit)));
+ bModified = true;
+ }
+
+ // set left and right margins
+ if (bModified)
+ {
+ pOld = GetOldItem( *rSet, SID_ATTR_LRSPACE );
+
+ if ( !pOld || *static_cast<const SvxLRSpaceItem*>(pOld) != aMargin )
+ rSet->Put( aMargin );
+ else
+ bModified = false;
+ }
+
+ if (rOldSet.HasItem(SID_ATTR_CHAR_GRABBAG))
+ {
+ // Set gutter position.
+ SfxGrabBagItem aGrabBagItem(rOldSet.Get(SID_ATTR_CHAR_GRABBAG));
+ if (m_xGutterPositionLB->get_value_changed_from_saved())
+ {
+ bool bGutterAtTop = m_xGutterPositionLB->get_active() == 1;
+ aGrabBagItem.GetGrabBag()["GutterAtTop"] <<= bGutterAtTop;
+ bModified = true;
+ }
+ if (m_xRtlGutterCB->get_state_changed_from_saved())
+ {
+ bool const bRtlGutter(m_xRtlGutterCB->get_active());
+ aGrabBagItem.GetGrabBag()["RtlGutter"] <<= bRtlGutter;
+ bModified = true;
+ }
+ if (m_xBackgroundFullSizeCB->get_state_changed_from_saved())
+ {
+ bool const isBackgroundFullSize(m_xBackgroundFullSizeCB->get_active());
+ aGrabBagItem.GetGrabBag()["BackgroundFullSize"] <<= isBackgroundFullSize;
+ bModified = true;
+ }
+
+ if (bModified)
+ {
+ pOld = rOldSet.GetItem(SID_ATTR_CHAR_GRABBAG);
+
+ if (!pOld || static_cast<const SfxGrabBagItem&>(*pOld) != aGrabBagItem)
+ rSet->Put(aGrabBagItem);
+ else
+ bModified = false;
+ }
+ }
+
+ bool bMod = false;
+
+ if (m_xTopMarginEdit->get_value_changed_from_saved())
+ {
+ aTopMargin.SetUpper( static_cast<sal_uInt16>(GetCoreValue( *m_xTopMarginEdit, eUnit )) );
+ bMod = true;
+ }
+
+ if (m_xBottomMarginEdit->get_value_changed_from_saved())
+ {
+ aTopMargin.SetLower( static_cast<sal_uInt16>(GetCoreValue( *m_xBottomMarginEdit, eUnit )) );
+ bMod = true;
+ }
+
+ // set top and bottom margins
+
+ if ( bMod )
+ {
+ pOld = GetOldItem( *rSet, SID_ATTR_ULSPACE );
+
+ if ( !pOld || *static_cast<const SvxULSpaceItem*>(pOld) != aTopMargin )
+ {
+ bModified = true;
+ rSet->Put( aTopMargin );
+ }
+ }
+
+ // paper tray
+ TypedWhichId<SvxPaperBinItem> nPaperWhich = GetWhich( SID_ATTR_PAGE_PAPERBIN );
+ sal_Int32 nPos = m_xPaperTrayBox->get_active();
+ sal_uInt16 nBin = m_xPaperTrayBox->get_id(nPos).toInt32();
+ pOld = GetOldItem( *rSet, SID_ATTR_PAGE_PAPERBIN );
+
+ if ( !pOld || static_cast<const SvxPaperBinItem*>(pOld)->GetValue() != nBin )
+ {
+ rSet->Put( SvxPaperBinItem( nPaperWhich, static_cast<sal_uInt8>(nBin) ) );
+ bModified = true;
+ }
+
+ Paper ePaper = m_xPaperSizeBox->get_active_id();
+ bool bChecked = m_xLandscapeBtn->get_active();
+
+ if ( PAPER_USER == ePaper )
+ {
+ if ( m_xPaperSizeBox->get_value_changed_from_saved() ||
+ m_xPaperWidthEdit->get_value_changed_from_saved() ||
+ m_xPaperHeightEdit->get_value_changed_from_saved() ||
+ m_xLandscapeBtn->get_state_changed_from_saved() )
+ {
+ Size aSize( GetCoreValue( *m_xPaperWidthEdit, eUnit ),
+ GetCoreValue( *m_xPaperHeightEdit, eUnit ) );
+ pOld = GetOldItem( *rSet, SID_ATTR_PAGE_SIZE );
+
+ if ( !pOld || static_cast<const SvxSizeItem*>(pOld)->GetSize() != aSize )
+ {
+ rSet->Put( SvxSizeItem( GetWhich(SID_ATTR_PAGE_SIZE), aSize ) );
+ bModified = true;
+ }
+ }
+ }
+ else
+ {
+ if (m_xPaperSizeBox->get_value_changed_from_saved() || m_xLandscapeBtn->get_state_changed_from_saved())
+ {
+ Size aSize( SvxPaperInfo::GetPaperSize( ePaper, eUnit ) );
+
+ if ( bChecked )
+ Swap( aSize );
+
+ pOld = GetOldItem( *rSet, SID_ATTR_PAGE_SIZE );
+
+ if ( !pOld || static_cast<const SvxSizeItem*>(pOld)->GetSize() != aSize )
+ {
+ rSet->Put( SvxSizeItem( GetWhich(SID_ATTR_PAGE_SIZE), aSize ) );
+ bModified = true;
+ }
+ }
+ }
+
+ nWhich = GetWhich( SID_ATTR_PAGE );
+ SvxPageItem aPage( static_cast<const SvxPageItem&>(rOldSet.Get( nWhich )) );
+ bMod = m_xLayoutBox->get_value_changed_from_saved();
+
+ if ( bMod )
+ aPage.SetPageUsage(::PosToPageUsage_Impl(m_xLayoutBox->get_active()));
+
+ if (m_xLandscapeBtn->get_state_changed_from_saved())
+ {
+ aPage.SetLandscape(bChecked);
+ bMod = true;
+ }
+
+ //Get the NumType value
+ if (m_xNumberFormatBox->get_value_changed_from_saved())
+ {
+ SvxNumType nEntryData = m_xNumberFormatBox->get_active_id();
+ aPage.SetNumType( nEntryData );
+ bMod = true;
+ }
+
+ if ( bMod )
+ {
+ pOld = GetOldItem( *rSet, SID_ATTR_PAGE );
+
+ if ( !pOld || *static_cast<const SvxPageItem*>(pOld) != aPage )
+ {
+ rSet->Put( aPage );
+ bModified = true;
+ }
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich ) )
+ rSet->ClearItem( nWhich );
+ else
+ rSet->Put( rOldSet.Get( nWhich ) );
+
+ // evaluate mode specific controls
+
+ switch ( eMode )
+ {
+ case SVX_PAGE_MODE_CENTER:
+ {
+ if (m_xHorzBox->get_state_changed_from_saved())
+ {
+ SfxBoolItem aHorz( GetWhich( SID_ATTR_PAGE_EXT1 ),
+ m_xHorzBox->get_active() );
+ rSet->Put( aHorz );
+ bModified = true;
+ }
+
+ if (m_xVertBox->get_state_changed_from_saved())
+ {
+ SfxBoolItem aVert( GetWhich( SID_ATTR_PAGE_EXT2 ),
+ m_xVertBox->get_active() );
+ rSet->Put( aVert );
+ bModified = true;
+ }
+ break;
+ }
+
+ case SVX_PAGE_MODE_PRESENTATION:
+ {
+ // always put so that draw can evaluate this
+ rSet->Put( SfxBoolItem( GetWhich( SID_ATTR_PAGE_EXT1 ),
+ m_xAdaptBox->get_active() ) );
+ bModified = true;
+ break;
+ }
+ default: ;//prevent warning
+
+ }
+
+ if (m_xRegisterCB->get_visible() &&
+ (m_xRegisterCB->get_active() || m_xRegisterCB->get_state_changed_from_saved()))
+ {
+ const SfxBoolItem& rRegItem = rOldSet.Get(SID_SWREGISTER_MODE);
+ std::unique_ptr<SfxBoolItem> pRegItem(rRegItem.Clone());
+ bool bCheck = m_xRegisterCB->get_active();
+ pRegItem->SetValue(bCheck);
+ rSet->Put(std::move(pRegItem));
+ bModified = true;
+ if(bCheck)
+ {
+ bModified = true;
+ rSet->Put(SfxStringItem(SID_SWREGISTER_COLLECTION,
+ m_xRegisterLB->get_active_text()));
+ }
+ }
+
+ if (m_xTextFlowBox->get_visible() && m_xTextFlowBox->get_value_changed_from_saved())
+ {
+ SvxFrameDirection eDirection = m_xTextFlowBox->get_active_id();
+ rSet->Put( SvxFrameDirectionItem( eDirection, GetWhich( SID_ATTR_FRAMEDIRECTION ) ) );
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+IMPL_LINK_NOARG(SvxPageDescPage, LayoutHdl_Impl, weld::ComboBox&, void)
+{
+ // switch inside outside
+ const SvxPageUsage nUsage = PosToPageUsage_Impl(m_xLayoutBox->get_active());
+
+ if (nUsage == SvxPageUsage::Mirror)
+ {
+ m_xLeftMarginLbl->hide();
+ m_xRightMarginLbl->hide();
+ m_xInsideLbl->show();
+ m_xOutsideLbl->show();
+ }
+ else
+ {
+ m_xLeftMarginLbl->show();
+ m_xRightMarginLbl->show();
+ m_xInsideLbl->hide();
+ m_xOutsideLbl->hide();
+ }
+ UpdateExample_Impl( true );
+}
+
+IMPL_LINK_NOARG(SvxPageDescPage, GutterPositionHdl_Impl, weld::ComboBox&, void)
+{
+ UpdateExample_Impl(true);
+}
+
+IMPL_LINK_NOARG(SvxPageDescPage, PaperBinHdl_Impl, weld::Widget&, void)
+{
+ // tdf#124226 disconnect so not called again, unless Reset occurs
+ m_xPaperTrayBox->connect_focus_in(Link<weld::Widget&, void>());
+
+ OUString aOldName = m_xPaperTrayBox->get_active_text();
+ m_xPaperTrayBox->freeze();
+ m_xPaperTrayBox->clear();
+ m_xPaperTrayBox->append(OUString::number(PAPERBIN_PRINTER_SETTINGS), EditResId(RID_SVXSTR_PAPERBIN_SETTINGS));
+ OUString aPaperBin(EditResId(RID_SVXSTR_PAPERBIN));
+ const sal_uInt16 nBinCount = mpDefPrinter->GetPaperBinCount();
+
+ for (sal_uInt16 i = 0; i < nBinCount; ++i)
+ {
+ OUString aName = mpDefPrinter->GetPaperBinName(i);
+ if (aName.isEmpty())
+ {
+ aName = aPaperBin + " " + OUString::number( i+1 );
+ }
+ m_xPaperTrayBox->append(OUString::number(i), aName);
+ }
+ m_xPaperTrayBox->thaw();
+ m_xPaperTrayBox->set_active_text(aOldName);
+
+ // tdf#123650 explicitly grab-focus after the modification otherwise gtk loses track
+ // of there the focus should be
+ m_xPaperTrayBox->grab_focus();
+}
+
+IMPL_LINK_NOARG(SvxPageDescPage, PaperSizeSelect_Impl, weld::ComboBox&, void)
+{
+ Paper ePaper = m_xPaperSizeBox->get_active_id();
+
+ if ( ePaper == PAPER_USER )
+ return;
+
+ Size aSize( SvxPaperInfo::GetPaperSize( ePaper, MapUnit::Map100thMM ) );
+
+ if (m_xLandscapeBtn->get_active())
+ Swap( aSize );
+
+ if ( aSize.Height() < m_xPaperHeightEdit->get_min( FieldUnit::MM_100TH ) )
+ m_xPaperHeightEdit->set_min(
+ m_xPaperHeightEdit->normalize( aSize.Height() ), FieldUnit::MM_100TH );
+ if ( aSize.Width() < m_xPaperWidthEdit->get_min( FieldUnit::MM_100TH ) )
+ m_xPaperWidthEdit->set_min(
+ m_xPaperWidthEdit->normalize( aSize.Width() ), FieldUnit::MM_100TH );
+ SetMetricValue( *m_xPaperHeightEdit, aSize.Height(), MapUnit::Map100thMM );
+ SetMetricValue( *m_xPaperWidthEdit, aSize.Width(), MapUnit::Map100thMM );
+
+ CalcMargin_Impl();
+
+ RangeHdl_Impl();
+ UpdateExample_Impl( true );
+
+ if ( eMode != SVX_PAGE_MODE_PRESENTATION )
+ return;
+
+ // Draw: if paper format the margin shall be 1 cm
+ tools::Long nTmp = 0;
+ bool bScreen = (( PAPER_SCREEN_4_3 == ePaper )||( PAPER_SCREEN_16_9 == ePaper)||( PAPER_SCREEN_16_10 == ePaper)||( PAPER_WIDESCREEN == ePaper)||( PAPER_ONSCREENSHOW_4_3 == ePaper)||( PAPER_ONSCREENSHOW_16_9 == ePaper)||( PAPER_ONSCREENSHOW_16_10 == ePaper));
+
+ if ( !bScreen )
+ // no margin if screen
+ nTmp = 1; // accordingly 1 cm
+
+ if ( bScreen || m_xRightMarginEdit->get_value(FieldUnit::NONE) == 0 )
+ SetMetricValue( *m_xRightMarginEdit, nTmp, MapUnit::MapCM );
+ if ( bScreen || m_xLeftMarginEdit->get_value(FieldUnit::NONE) == 0 )
+ SetMetricValue( *m_xLeftMarginEdit, nTmp, MapUnit::MapCM );
+ if ( bScreen || m_xBottomMarginEdit->get_value(FieldUnit::NONE) == 0 )
+ SetMetricValue( *m_xBottomMarginEdit, nTmp, MapUnit::MapCM );
+ if ( bScreen || m_xTopMarginEdit->get_value(FieldUnit::NONE) == 0 )
+ SetMetricValue( *m_xTopMarginEdit, nTmp, MapUnit::MapCM );
+ UpdateExample_Impl( true );
+}
+
+IMPL_LINK_NOARG(SvxPageDescPage, PaperSizeModify_Impl, weld::MetricSpinButton&, void)
+{
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_LRSPACE );
+ MapUnit eUnit = GetItemSet().GetPool()->GetMetric( nWhich );
+ Size aSize( GetCoreValue( *m_xPaperWidthEdit, eUnit ),
+ GetCoreValue( *m_xPaperHeightEdit, eUnit ) );
+
+ if ( aSize.Width() > aSize.Height() )
+ {
+ m_xLandscapeBtn->set_active(true);
+ bLandscape = true;
+ }
+ else
+ {
+ m_xPortraitBtn->set_active(true);
+ bLandscape = false;
+ }
+
+ Paper ePaper = SvxPaperInfo::GetSvxPaper( aSize, eUnit );
+ m_xPaperSizeBox->set_active_id( ePaper );
+ UpdateExample_Impl( true );
+
+ RangeHdl_Impl();
+}
+
+IMPL_LINK(SvxPageDescPage, SwapOrientation_Impl, weld::Toggleable&, rBtn, void)
+{
+ if (!rBtn.get_active())
+ return;
+
+ bLandscape = m_xLandscapeBtn->get_active();
+
+ const tools::Long lWidth = GetCoreValue( *m_xPaperWidthEdit, MapUnit::Map100thMM );
+ const tools::Long lHeight = GetCoreValue( *m_xPaperHeightEdit, MapUnit::Map100thMM );
+
+ // swap width and height
+ SetMetricValue(*m_xPaperWidthEdit, lHeight, MapUnit::Map100thMM);
+ SetMetricValue(*m_xPaperHeightEdit, lWidth, MapUnit::Map100thMM);
+
+ // recalculate margins if necessary
+ CalcMargin_Impl();
+
+ PaperSizeSelect_Impl(m_xPaperSizeBox->get_widget());
+ RangeHdl_Impl();
+ SwapFirstValues_Impl(bBorderModified);
+ UpdateExample_Impl(true);
+}
+
+void SvxPageDescPage::SwapFirstValues_Impl( bool bSet )
+{
+ MapMode aOldMode = mpDefPrinter->GetMapMode();
+ Orientation eOri = Orientation::Portrait;
+
+ if ( bLandscape )
+ eOri = Orientation::Landscape;
+ Orientation eOldOri = mpDefPrinter->GetOrientation();
+ mpDefPrinter->SetOrientation( eOri );
+ mpDefPrinter->SetMapMode(MapMode(MapUnit::MapTwip));
+
+ // set first- and last-values for margins
+ Size aPaperSize = mpDefPrinter->GetPaperSize();
+ Size aPrintSize = mpDefPrinter->GetOutputSize();
+ /*
+ * To convert a point ( 0,0 ) into logic coordinates
+ * looks like nonsense; but it makes sense if the
+ * coordinate system's origin has been moved.
+ */
+ Point aPrintOffset = mpDefPrinter->GetPageOffset() - mpDefPrinter->PixelToLogic( Point() );
+ mpDefPrinter->SetMapMode( aOldMode );
+ mpDefPrinter->SetOrientation( eOldOri );
+
+ sal_Int64 nSetL = m_xLeftMarginEdit->denormalize(
+ m_xLeftMarginEdit->get_value( FieldUnit::TWIP ) );
+ sal_Int64 nSetR = m_xRightMarginEdit->denormalize(
+ m_xRightMarginEdit->get_value( FieldUnit::TWIP ) );
+ sal_Int64 nSetT = m_xTopMarginEdit->denormalize(
+ m_xTopMarginEdit->get_value( FieldUnit::TWIP ) );
+ sal_Int64 nSetB = m_xBottomMarginEdit->denormalize(
+ m_xBottomMarginEdit->get_value( FieldUnit::TWIP ) );
+
+ tools::Long nNewL = aPrintOffset.X();
+ tools::Long nNewR = aPaperSize.Width() - aPrintSize.Width() - aPrintOffset.X();
+ tools::Long nNewT = aPrintOffset.Y();
+ tools::Long nNewB = aPaperSize.Height() - aPrintSize.Height() - aPrintOffset.Y();
+
+ nFirstLeftMargin = m_xLeftMarginEdit->convert_value_from(m_xLeftMarginEdit->normalize(nNewL), FieldUnit::TWIP);
+ nFirstRightMargin = m_xRightMarginEdit->convert_value_from(m_xRightMarginEdit->normalize(nNewR), FieldUnit::TWIP);
+ nFirstTopMargin = m_xTopMarginEdit->convert_value_from(m_xTopMarginEdit->normalize(nNewT), FieldUnit::TWIP);
+ nFirstBottomMargin = m_xBottomMarginEdit->convert_value_from(m_xBottomMarginEdit->normalize(nNewB), FieldUnit::TWIP);
+
+ if ( !bSet )
+ return;
+
+ if ( nSetL < nNewL )
+ m_xLeftMarginEdit->set_value( m_xLeftMarginEdit->normalize( nNewL ),
+ FieldUnit::TWIP );
+ if ( nSetR < nNewR )
+ m_xRightMarginEdit->set_value( m_xRightMarginEdit->normalize( nNewR ),
+ FieldUnit::TWIP );
+ if ( nSetT < nNewT )
+ m_xTopMarginEdit->set_value( m_xTopMarginEdit->normalize( nNewT ),
+ FieldUnit::TWIP );
+ if ( nSetB < nNewB )
+ m_xBottomMarginEdit->set_value( m_xBottomMarginEdit->normalize( nNewB ),
+ FieldUnit::TWIP );
+}
+
+IMPL_LINK_NOARG(SvxPageDescPage, BorderModify_Impl, weld::MetricSpinButton&, void)
+{
+ if ( !bBorderModified )
+ bBorderModified = true;
+ UpdateExample_Impl();
+
+ RangeHdl_Impl();
+}
+
+void SvxPageDescPage::UpdateExample_Impl( bool bResetbackground )
+{
+ // Size
+ Size aSize( GetCoreValue( *m_xPaperWidthEdit, MapUnit::MapTwip ),
+ GetCoreValue( *m_xPaperHeightEdit, MapUnit::MapTwip ) );
+
+ m_aBspWin.SetSize( aSize );
+
+ // Margins
+ bool bGutterAtTop = m_xGutterPositionLB->get_active() == 1;
+ tools::Long nTop = GetCoreValue(*m_xTopMarginEdit, MapUnit::MapTwip);
+ if (bGutterAtTop)
+ {
+ nTop += GetCoreValue(*m_xGutterMarginEdit, MapUnit::MapTwip);
+ }
+ m_aBspWin.SetTop(nTop);
+ m_aBspWin.SetBottom( GetCoreValue( *m_xBottomMarginEdit, MapUnit::MapTwip ) );
+ tools::Long nLeft = GetCoreValue(*m_xLeftMarginEdit, MapUnit::MapTwip);
+ if (!bGutterAtTop)
+ {
+ nLeft += GetCoreValue(*m_xGutterMarginEdit, MapUnit::MapTwip);
+ }
+ m_aBspWin.SetLeft(nLeft);
+ m_aBspWin.SetRight( GetCoreValue( *m_xRightMarginEdit, MapUnit::MapTwip ) );
+
+ // Layout
+ m_aBspWin.SetUsage(PosToPageUsage_Impl(m_xLayoutBox->get_active()));
+ if ( bResetbackground )
+ m_aBspWin.ResetBackground();
+ m_aBspWin.Invalidate();
+}
+
+
+void SvxPageDescPage::ResetBackground_Impl(const SfxItemSet& rSet)
+{
+ sal_uInt16 nWhich(GetWhich(SID_ATTR_PAGE_HEADERSET));
+
+ if (SfxItemState::SET == rSet.GetItemState(nWhich, false))
+ {
+ const SvxSetItem& rSetItem = static_cast< const SvxSetItem& >(rSet.Get(nWhich, false));
+ const SfxItemSet& rTmpSet = rSetItem.GetItemSet();
+ const SfxBoolItem& rOn = rTmpSet.Get(GetWhich(SID_ATTR_PAGE_ON));
+
+ if(rOn.GetValue())
+ {
+ drawinglayer::attribute::SdrAllFillAttributesHelperPtr aHeaderFillAttributes;
+
+ if(mbEnableDrawingLayerFillStyles)
+ {
+ // create FillAttributes directly from DrawingLayer FillStyle entries
+ aHeaderFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(rTmpSet);
+ }
+ else
+ {
+ nWhich = GetWhich(SID_ATTR_BRUSH);
+
+ if(SfxItemState::SET == rTmpSet.GetItemState(nWhich))
+ {
+ // create FillAttributes from SvxBrushItem
+ const SvxBrushItem& rItem = static_cast< const SvxBrushItem& >(rTmpSet.Get(nWhich));
+ SfxItemSetFixed<XATTR_FILL_FIRST, XATTR_FILL_LAST> aTempSet(*rTmpSet.GetPool());
+
+ setSvxBrushItemAsFillAttributesToTargetSet(rItem, aTempSet);
+ aHeaderFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(aTempSet);
+ }
+ }
+
+ m_aBspWin.setHeaderFillAttributes(aHeaderFillAttributes);
+ }
+ }
+
+ nWhich = GetWhich(SID_ATTR_PAGE_FOOTERSET);
+
+ if (SfxItemState::SET == rSet.GetItemState(nWhich, false))
+ {
+ const SvxSetItem& rSetItem = static_cast< const SvxSetItem& >(rSet.Get(nWhich,false));
+ const SfxItemSet& rTmpSet = rSetItem.GetItemSet();
+ const SfxBoolItem& rOn = rTmpSet.Get(GetWhich(SID_ATTR_PAGE_ON));
+
+ if(rOn.GetValue())
+ {
+ drawinglayer::attribute::SdrAllFillAttributesHelperPtr aFooterFillAttributes;
+
+ if(mbEnableDrawingLayerFillStyles)
+ {
+ // create FillAttributes directly from DrawingLayer FillStyle entries
+ aFooterFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(rTmpSet);
+ }
+ else
+ {
+ nWhich = GetWhich(SID_ATTR_BRUSH);
+
+ if(SfxItemState::SET == rTmpSet.GetItemState(nWhich))
+ {
+ // create FillAttributes from SvxBrushItem
+ const SvxBrushItem& rItem = static_cast< const SvxBrushItem& >(rTmpSet.Get(nWhich));
+ SfxItemSetFixed<XATTR_FILL_FIRST, XATTR_FILL_LAST> aTempSet(*rTmpSet.GetPool());
+
+ setSvxBrushItemAsFillAttributesToTargetSet(rItem, aTempSet);
+ aFooterFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(aTempSet);
+ }
+ }
+
+ m_aBspWin.setFooterFillAttributes(aFooterFillAttributes);
+ }
+ }
+
+ drawinglayer::attribute::SdrAllFillAttributesHelperPtr aPageFillAttributes;
+
+ if(mbEnableDrawingLayerFillStyles)
+ {
+ // create FillAttributes directly from DrawingLayer FillStyle entries
+ aPageFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(rSet);
+ }
+ else
+ {
+ const SfxPoolItem* pItem = GetItem(rSet, SID_ATTR_BRUSH);
+
+ if(pItem)
+ {
+ // create FillAttributes from SvxBrushItem
+ const SvxBrushItem& rItem = static_cast< const SvxBrushItem& >(*pItem);
+ SfxItemSetFixed<XATTR_FILL_FIRST, XATTR_FILL_LAST> aTempSet(*rSet.GetPool());
+
+ setSvxBrushItemAsFillAttributesToTargetSet(rItem, aTempSet);
+ aPageFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(aTempSet);
+ }
+ }
+
+ m_aBspWin.setPageFillAttributes(aPageFillAttributes);
+}
+
+void SvxPageDescPage::InitHeadFoot_Impl( const SfxItemSet& rSet )
+{
+ bLandscape = m_xLandscapeBtn->get_active();
+ const SfxPoolItem* pItem = GetItem( rSet, SID_ATTR_PAGE_SIZE );
+
+ if ( pItem )
+ m_aBspWin.SetSize( static_cast<const SvxSizeItem*>(pItem)->GetSize() );
+
+ const SvxSetItem* pSetItem = nullptr;
+
+ // evaluate header attributes
+
+ if ( SfxItemState::SET ==
+ rSet.GetItemState( GetWhich( SID_ATTR_PAGE_HEADERSET ),
+ false, reinterpret_cast<const SfxPoolItem**>(&pSetItem) ) )
+ {
+ const SfxItemSet& rHeaderSet = pSetItem->GetItemSet();
+ const SfxBoolItem& rHeaderOn =
+ rHeaderSet.Get( GetWhich( SID_ATTR_PAGE_ON ) );
+
+ if ( rHeaderOn.GetValue() )
+ {
+ const SvxSizeItem& rSize =
+ rHeaderSet.Get( GetWhich( SID_ATTR_PAGE_SIZE ) );
+ const SvxULSpaceItem& rUL =
+ rHeaderSet.Get( GetWhich( SID_ATTR_ULSPACE ) );
+ tools::Long nDist = rUL.GetLower();
+ m_aBspWin.SetHdHeight( rSize.GetSize().Height() - nDist );
+ m_aBspWin.SetHdDist( nDist );
+ const SvxLRSpaceItem& rLR =
+ rHeaderSet.Get( GetWhich( SID_ATTR_LRSPACE ) );
+ m_aBspWin.SetHdLeft( rLR.GetLeft() );
+ m_aBspWin.SetHdRight( rLR.GetRight() );
+ m_aBspWin.SetHeader( true );
+ }
+ else
+ m_aBspWin.SetHeader( false );
+
+ // show background and border in the example
+ drawinglayer::attribute::SdrAllFillAttributesHelperPtr aHeaderFillAttributes;
+
+ if(mbEnableDrawingLayerFillStyles)
+ {
+ // create FillAttributes directly from DrawingLayer FillStyle entries
+ aHeaderFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(rHeaderSet);
+ }
+ else
+ {
+ const sal_uInt16 nWhich(GetWhich(SID_ATTR_BRUSH));
+
+ if(rHeaderSet.GetItemState(nWhich) >= SfxItemState::DEFAULT)
+ {
+ // aBspWin.SetHdColor(rItem.GetColor());
+ const SvxBrushItem& rItem = static_cast< const SvxBrushItem& >(rHeaderSet.Get(nWhich));
+ SfxItemSetFixed<XATTR_FILL_FIRST, XATTR_FILL_LAST> aTempSet(*rHeaderSet.GetPool());
+
+ setSvxBrushItemAsFillAttributesToTargetSet(rItem, aTempSet);
+ aHeaderFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(aTempSet);
+ }
+ }
+
+ m_aBspWin.setHeaderFillAttributes(aHeaderFillAttributes);
+ }
+
+ // evaluate footer attributes
+
+ if ( SfxItemState::SET !=
+ rSet.GetItemState( GetWhich( SID_ATTR_PAGE_FOOTERSET ),
+ false, reinterpret_cast<const SfxPoolItem**>(&pSetItem) ) )
+ return;
+
+ const SfxItemSet& rFooterSet = pSetItem->GetItemSet();
+ const SfxBoolItem& rFooterOn =
+ rFooterSet.Get( GetWhich( SID_ATTR_PAGE_ON ) );
+
+ if ( rFooterOn.GetValue() )
+ {
+ const SvxSizeItem& rSize =
+ rFooterSet.Get( GetWhich( SID_ATTR_PAGE_SIZE ) );
+ const SvxULSpaceItem& rUL =
+ rFooterSet.Get( GetWhich( SID_ATTR_ULSPACE ) );
+ tools::Long nDist = rUL.GetUpper();
+ m_aBspWin.SetFtHeight( rSize.GetSize().Height() - nDist );
+ m_aBspWin.SetFtDist( nDist );
+ const SvxLRSpaceItem& rLR =
+ rFooterSet.Get( GetWhich( SID_ATTR_LRSPACE ) );
+ m_aBspWin.SetFtLeft( rLR.GetLeft() );
+ m_aBspWin.SetFtRight( rLR.GetRight() );
+ m_aBspWin.SetFooter( true );
+ }
+ else
+ m_aBspWin.SetFooter( false );
+
+ // show background and border in the example
+ drawinglayer::attribute::SdrAllFillAttributesHelperPtr aFooterFillAttributes;
+
+ if(mbEnableDrawingLayerFillStyles)
+ {
+ // create FillAttributes directly from DrawingLayer FillStyle entries
+ aFooterFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(rFooterSet);
+ }
+ else
+ {
+ const sal_uInt16 nWhich(GetWhich(SID_ATTR_BRUSH));
+
+ if(rFooterSet.GetItemState(nWhich) >= SfxItemState::DEFAULT)
+ {
+ // aBspWin.SetFtColor(rItem.GetColor());
+ const SvxBrushItem& rItem = static_cast<const SvxBrushItem&>(rFooterSet.Get(nWhich));
+ SfxItemSetFixed<XATTR_FILL_FIRST, XATTR_FILL_LAST> aTempSet(*rFooterSet.GetPool());
+
+ setSvxBrushItemAsFillAttributesToTargetSet(rItem, aTempSet);
+ aFooterFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(aTempSet);
+ }
+ }
+
+ m_aBspWin.setFooterFillAttributes(aFooterFillAttributes);
+}
+
+void SvxPageDescPage::ActivatePage( const SfxItemSet& rSet )
+{
+ InitHeadFoot_Impl( rSet );
+ UpdateExample_Impl();
+ ResetBackground_Impl( rSet );
+ RangeHdl_Impl();
+}
+
+DeactivateRC SvxPageDescPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ // Inquiry whether the page margins are beyond the printing area.
+ // If not, ask user whether they shall be taken.
+ // If not, stay on the TabPage.
+ Paper ePaper = m_xPaperSizeBox->get_active_id();
+
+ if ( ePaper != PAPER_SCREEN_4_3 && ePaper != PAPER_SCREEN_16_9 && ePaper != PAPER_SCREEN_16_10 && ePaper != PAPER_WIDESCREEN && ePaper != PAPER_ONSCREENSHOW_4_3 && ePaper != PAPER_ONSCREENSHOW_16_9 && ePaper != PAPER_ONSCREENSHOW_16_10 && IsMarginOutOfRange() )
+ {
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ m_xPrintRangeQueryText->get_label()));
+ xQueryBox->set_default_response(RET_NO);
+ if (xQueryBox->run() == RET_NO)
+ {
+ weld::MetricSpinButton* pField = nullptr;
+ if ( IsPrinterRangeOverflow( *m_xLeftMarginEdit, nFirstLeftMargin, nLastLeftMargin, MARGIN_LEFT ) )
+ pField = m_xLeftMarginEdit.get();
+ if ( IsPrinterRangeOverflow( *m_xRightMarginEdit, nFirstRightMargin, nLastRightMargin, MARGIN_RIGHT )
+ && !pField )
+ pField = m_xRightMarginEdit.get();
+ if ( IsPrinterRangeOverflow( *m_xTopMarginEdit, nFirstTopMargin, nLastTopMargin, MARGIN_TOP )
+ && !pField )
+ pField = m_xTopMarginEdit.get();
+ if ( IsPrinterRangeOverflow( *m_xBottomMarginEdit, nFirstBottomMargin, nLastBottomMargin, MARGIN_BOTTOM )
+ && !pField )
+ pField = m_xBottomMarginEdit.get();
+ if ( pField )
+ pField->grab_focus();
+ UpdateExample_Impl();
+ return DeactivateRC::KeepPage;
+ }
+ else
+ CheckMarginEdits( false );
+ }
+
+ if ( _pSet )
+ {
+ FillItemSet( _pSet );
+
+ // put portray/landscape if applicable
+ sal_uInt16 nWh = GetWhich( SID_ATTR_PAGE_SIZE );
+ MapUnit eUnit = GetItemSet().GetPool()->GetMetric( nWh );
+ Size aSize( GetCoreValue( *m_xPaperWidthEdit, eUnit ),
+ GetCoreValue( *m_xPaperHeightEdit, eUnit ) );
+
+ // put, if current size is different to the value in _pSet
+ const SvxSizeItem* pSize = GetItem( *_pSet, SID_ATTR_PAGE_SIZE );
+ if ( aSize.Width() && ( !pSize || !IsEqualSize_Impl( pSize, aSize ) ) )
+ _pSet->Put( SvxSizeItem( nWh, aSize ) );
+ }
+
+ return DeactivateRC::LeavePage;
+}
+
+void SvxPageDescPage::RangeHdl_Impl()
+{
+ // example window
+ tools::Long nHHeight = m_aBspWin.GetHdHeight();
+ tools::Long nHDist = m_aBspWin.GetHdDist();
+
+ tools::Long nFHeight = m_aBspWin.GetFtHeight();
+ tools::Long nFDist = m_aBspWin.GetFtDist();
+
+ tools::Long nHFLeft = std::max(m_aBspWin.GetHdLeft(), m_aBspWin.GetFtLeft());
+ tools::Long nHFRight = std::max(m_aBspWin.GetHdRight(), m_aBspWin.GetFtRight());
+
+ // current values for page margins
+ tools::Long nBT = static_cast<tools::Long>(m_xTopMarginEdit->denormalize(m_xTopMarginEdit->get_value(FieldUnit::TWIP)));
+ tools::Long nBB = static_cast<tools::Long>(m_xBottomMarginEdit->denormalize(m_xBottomMarginEdit->get_value(FieldUnit::TWIP)));
+ tools::Long nBL = static_cast<tools::Long>(m_xLeftMarginEdit->denormalize(m_xLeftMarginEdit->get_value(FieldUnit::TWIP)));
+ tools::Long nBR = static_cast<tools::Long>(m_xRightMarginEdit->denormalize(m_xRightMarginEdit->get_value(FieldUnit::TWIP)));
+
+ // calculate width of page border
+ const SfxItemSet* _pSet = &GetItemSet();
+ Size aBorder;
+
+ if ( _pSet->GetItemState( GetWhich(SID_ATTR_BORDER_SHADOW) ) >=
+ SfxItemState::DEFAULT &&
+ _pSet->GetItemState( GetWhich(SID_ATTR_BORDER_OUTER) ) >=
+ SfxItemState::DEFAULT )
+ {
+ aBorder = GetMinBorderSpace_Impl(
+ _pSet->Get(GetWhich(SID_ATTR_BORDER_SHADOW)),
+ _pSet->Get(GetWhich(SID_ATTR_BORDER_OUTER)));
+ }
+
+ // limits paper
+ // maximum is 54 cm
+
+ tools::Long nMin = nHHeight + nHDist + nFDist + nFHeight + nBT + nBB +
+ MINBODY + aBorder.Height();
+ m_xPaperHeightEdit->set_min(m_xPaperHeightEdit->normalize(nMin), FieldUnit::TWIP);
+
+ nMin = MINBODY + nBL + nBR + aBorder.Width();
+ m_xPaperWidthEdit->set_min(m_xPaperWidthEdit->normalize(nMin), FieldUnit::TWIP);
+
+ tools::Long nH = static_cast<tools::Long>(m_xPaperHeightEdit->denormalize(m_xPaperHeightEdit->get_value(FieldUnit::TWIP)));
+ tools::Long nW = static_cast<tools::Long>(m_xPaperWidthEdit->denormalize(m_xPaperWidthEdit->get_value(FieldUnit::TWIP)));
+
+ // Top
+ tools::Long nMax = nH - nBB - aBorder.Height() - MINBODY -
+ nFDist - nFHeight - nHDist - nHHeight;
+
+ m_xTopMarginEdit->set_max(m_xTopMarginEdit->normalize(nMax), FieldUnit::TWIP);
+
+ // Bottom
+ nMax = nH - nBT - aBorder.Height() - MINBODY -
+ nFDist - nFHeight - nHDist - nHHeight;
+
+ m_xBottomMarginEdit->set_max(m_xTopMarginEdit->normalize(nMax), FieldUnit::TWIP);
+
+ // Left
+ nMax = nW - nBR - MINBODY - aBorder.Width() - nHFLeft - nHFRight;
+ m_xLeftMarginEdit->set_max(m_xLeftMarginEdit->normalize(nMax), FieldUnit::TWIP);
+
+ // Right
+ nMax = nW - nBL - MINBODY - aBorder.Width() - nHFLeft - nHFRight;
+ m_xRightMarginEdit->set_max(m_xRightMarginEdit->normalize(nMax), FieldUnit::TWIP);
+}
+
+void SvxPageDescPage::CalcMargin_Impl()
+{
+ // current values for page margins
+ tools::Long nBT = GetCoreValue( *m_xTopMarginEdit, MapUnit::MapTwip );
+ tools::Long nBB = GetCoreValue( *m_xBottomMarginEdit, MapUnit::MapTwip );
+
+ tools::Long nBL = GetCoreValue( *m_xLeftMarginEdit, MapUnit::MapTwip );
+ tools::Long nBR = GetCoreValue( *m_xRightMarginEdit, MapUnit::MapTwip );
+
+ tools::Long nH = GetCoreValue( *m_xPaperHeightEdit, MapUnit::MapTwip );
+ tools::Long nW = GetCoreValue( *m_xPaperWidthEdit, MapUnit::MapTwip );
+
+ tools::Long nWidth = nBL + nBR + MINBODY;
+ tools::Long nHeight = nBT + nBB + MINBODY;
+
+ if ( nWidth <= nW && nHeight <= nH )
+ return;
+
+ if ( nWidth > nW )
+ {
+ tools::Long nTmp = nBL <= nBR ? nBR : nBL;
+ nTmp -= nWidth - nW;
+
+ if ( nBL <= nBR )
+ SetMetricValue( *m_xRightMarginEdit, nTmp, MapUnit::MapTwip );
+ else
+ SetMetricValue( *m_xLeftMarginEdit, nTmp, MapUnit::MapTwip );
+ }
+
+ if ( nHeight > nH )
+ {
+ tools::Long nTmp = nBT <= nBB ? nBB : nBT;
+ nTmp -= nHeight - nH;
+
+ if ( nBT <= nBB )
+ SetMetricValue( *m_xBottomMarginEdit, nTmp, MapUnit::MapTwip );
+ else
+ SetMetricValue( *m_xTopMarginEdit, nTmp, MapUnit::MapTwip );
+ }
+}
+
+IMPL_LINK_NOARG(SvxPageDescPage, CenterHdl_Impl, weld::Toggleable&, void)
+{
+ m_aBspWin.SetHorz(m_xHorzBox->get_active());
+ m_aBspWin.SetVert(m_xVertBox->get_active());
+ UpdateExample_Impl();
+}
+
+void SvxPageDescPage::SetCollectionList(const std::vector<OUString> &aList)
+{
+ OSL_ENSURE(!aList.empty(), "Empty string list");
+
+ sStandardRegister = aList[0];
+ m_xRegisterLB->freeze();
+ for (size_t i = 1; i < aList.size(); ++i)
+ m_xRegisterLB->append_text(aList[i]);
+ m_xRegisterLB->thaw();
+
+ m_xRegisterCB->show();
+ m_xRegisterFT->show();
+ m_xRegisterLB->show();
+ m_xRegisterCB->connect_toggled(LINK(this, SvxPageDescPage, RegisterModify));
+}
+
+IMPL_LINK(SvxPageDescPage, RegisterModify, weld::Toggleable&, rBox, void)
+{
+ bool bEnable = false;
+ if (rBox.get_active())
+ {
+ bEnable = true;
+ if (m_xRegisterLB->get_active() == -1)
+ m_xRegisterLB->set_active_text(sStandardRegister);
+ }
+ m_xRegisterFT->set_sensitive(bEnable);
+ m_xRegisterLB->set_sensitive(bEnable);
+}
+
+void SvxPageDescPage::DisableVerticalPageDir()
+{
+ m_xTextFlowBox->remove_id(SvxFrameDirection::Vertical_RL_TB);
+ m_xTextFlowBox->remove_id(SvxFrameDirection::Vertical_LR_TB);
+ if (m_xTextFlowBox->get_count() < 2)
+ {
+ m_xTextFlowLbl->hide();
+ m_xTextFlowBox->hide();
+ m_aBspWin.EnableFrameDirection( false );
+ }
+}
+
+IMPL_LINK_NOARG(SvxPageDescPage, FrameDirectionModify_Impl, weld::ComboBox&, void)
+{
+ m_aBspWin.SetFrameDirection(m_xTextFlowBox->get_active_id());
+ m_aBspWin.Invalidate();
+}
+
+bool SvxPageDescPage::IsPrinterRangeOverflow(
+ weld::MetricSpinButton& rField, tools::Long nFirstMargin, tools::Long nLastMargin, MarginPosition nPos )
+{
+ bool bRet = false;
+ bool bCheck = ( ( m_nPos & nPos ) == 0 );
+ tools::Long nValue = rField.get_value(FieldUnit::NONE);
+ if ( bCheck &&
+ ( nValue < nFirstMargin || nValue > nLastMargin ) &&
+ rField.get_value_changed_from_saved() )
+ {
+ rField.set_value(nValue < nFirstMargin ? nFirstMargin : nLastMargin, FieldUnit::NONE);
+ bRet = true;
+ }
+
+ return bRet;
+}
+
+/** Check if a value of a margin edit is outside the printer paper margins
+ and save this information.
+*/
+void SvxPageDescPage::CheckMarginEdits( bool _bClear )
+{
+ if ( _bClear )
+ m_nPos = 0;
+
+ sal_Int64 nValue = m_xLeftMarginEdit->get_value(FieldUnit::NONE);
+ if ( nValue < nFirstLeftMargin || nValue > nLastLeftMargin )
+ m_nPos |= MARGIN_LEFT;
+ nValue = m_xRightMarginEdit->get_value(FieldUnit::NONE);
+ if ( nValue < nFirstRightMargin || nValue > nLastRightMargin )
+ m_nPos |= MARGIN_RIGHT;
+ nValue = m_xTopMarginEdit->get_value(FieldUnit::NONE);
+ if ( nValue < nFirstTopMargin || nValue > nLastTopMargin )
+ m_nPos |= MARGIN_TOP;
+ nValue = m_xBottomMarginEdit->get_value(FieldUnit::NONE);
+ if ( nValue < nFirstBottomMargin || nValue > nLastBottomMargin )
+ m_nPos |= MARGIN_BOTTOM;
+}
+
+bool SvxPageDescPage::IsMarginOutOfRange() const
+{
+ bool bRet = ( ( ( !( m_nPos & MARGIN_LEFT ) &&
+ m_xLeftMarginEdit->get_value_changed_from_saved() ) &&
+ ( m_xLeftMarginEdit->get_value(FieldUnit::NONE) < nFirstLeftMargin ||
+ m_xLeftMarginEdit->get_value(FieldUnit::NONE) > nLastLeftMargin ) ) ||
+ ( ( !( m_nPos & MARGIN_RIGHT ) &&
+ m_xRightMarginEdit->get_value_changed_from_saved() ) &&
+ ( m_xRightMarginEdit->get_value(FieldUnit::NONE) < nFirstRightMargin ||
+ m_xRightMarginEdit->get_value(FieldUnit::NONE) > nLastRightMargin ) ) ||
+ ( ( !( m_nPos & MARGIN_TOP ) &&
+ m_xTopMarginEdit->get_value_changed_from_saved() ) &&
+ ( m_xTopMarginEdit->get_value(FieldUnit::NONE) < nFirstTopMargin ||
+ m_xTopMarginEdit->get_value(FieldUnit::NONE) > nLastTopMargin ) ) ||
+ ( ( !( m_nPos & MARGIN_BOTTOM ) &&
+ m_xBottomMarginEdit->get_value_changed_from_saved() ) &&
+ ( m_xBottomMarginEdit->get_value(FieldUnit::NONE) < nFirstBottomMargin ||
+ m_xBottomMarginEdit->get_value(FieldUnit::NONE) > nLastBottomMargin ) ) );
+ return bRet;
+}
+
+void SvxPageDescPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxUInt16Item* pModeItem = aSet.GetItem(SID_ENUM_PAGE_MODE, false);
+ const SfxUInt16Item* pPaperStartItem = aSet.GetItem(SID_PAPER_START, false);
+ const SfxUInt16Item* pPaperEndItem = aSet.GetItem(SID_PAPER_END, false);
+ const SfxStringListItem* pCollectListItem = aSet.GetItem<SfxStringListItem>(SID_COLLECT_LIST, false);
+ const SfxBoolItem* pSupportDrawingLayerFillStyleItem = aSet.GetItem<SfxBoolItem>(SID_DRAWINGLAYER_FILLSTYLES, false);
+ const SfxBoolItem* pIsImpressDoc = aSet.GetItem<SfxBoolItem>(SID_IMPRESS_DOC, false);
+
+ if (pModeItem)
+ {
+ eMode = static_cast<SvxModeType>(pModeItem->GetValue());
+ }
+
+ if(pPaperStartItem && pPaperEndItem)
+ {
+ SetPaperFormatRanges(static_cast<Paper>(pPaperStartItem->GetValue()));
+ }
+
+ if(pCollectListItem)
+ {
+ SetCollectionList(pCollectListItem->GetList());
+ }
+
+ if(pSupportDrawingLayerFillStyleItem)
+ {
+ const bool bNew(pSupportDrawingLayerFillStyleItem->GetValue());
+
+ mbEnableDrawingLayerFillStyles = bNew;
+ }
+
+ if (pIsImpressDoc)
+ m_xNumberFormatText->set_label(SvxResId(STR_SLIDE_NUMBERS));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/paragrph.cxx b/cui/source/tabpages/paragrph.cxx
new file mode 100644
index 0000000000..132b125f02
--- /dev/null
+++ b/cui/source/tabpages/paragrph.cxx
@@ -0,0 +1,2595 @@
+/* -*- 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 <memory>
+#include <osl/diagnose.h>
+#include <svl/style.hxx>
+#include <sfx2/objsh.hxx>
+#include <vcl/mnemonic.hxx>
+#include <vcl/settings.hxx>
+#include <svx/flagsdef.hxx>
+#include <svx/svxids.hrc>
+#include <svx/sdtaitm.hxx>
+
+#include <svl/cjkoptions.hxx>
+#include <editeng/pgrditem.hxx>
+#include <svx/strings.hrc>
+#include <svx/dialmgr.hxx>
+#include <paragrph.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/lspcitem.hxx>
+#include <editeng/adjustitem.hxx>
+#include <editeng/orphitem.hxx>
+#include <editeng/widwitem.hxx>
+#include <editeng/tstpitem.hxx>
+#include <editeng/pmdlitem.hxx>
+#include <editeng/spltitem.hxx>
+#include <editeng/hyphenzoneitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/formatbreakitem.hxx>
+#include <editeng/keepitem.hxx>
+#include <editeng/scriptspaceitem.hxx>
+#include <editeng/hngpnctitem.hxx>
+#include <editeng/forbiddenruleitem.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <i18nlangtag/mslangid.hxx>
+#include <svx/dlgutil.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <editeng/paravertalignitem.hxx>
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include <unotools/syslocaleoptions.hxx>
+
+const WhichRangesContainer SvxStdParagraphTabPage::pStdRanges(
+ svl::Items<
+ SID_ATTR_PARA_LINESPACE, SID_ATTR_PARA_LINESPACE, // 10033
+ SID_ATTR_PARA_LEFTSPACE, SID_ATTR_PARA_FIRSTLINESPACE,
+ SID_ATTR_LRSPACE, SID_ATTR_ULSPACE, // 10048 - 10049
+ SID_ATTR_PARA_REGISTER, SID_ATTR_PARA_REGISTER // 10413
+ >);
+
+const WhichRangesContainer SvxParaAlignTabPage::pAlignRanges(
+ svl::Items<
+ SID_ATTR_PARA_ADJUST, SID_ATTR_PARA_ADJUST, // 10027
+ // tdf#154543 - reset snap to grid to parent
+ SID_ATTR_PARA_SNAPTOGRID, SID_ATTR_PARA_SNAPTOGRID // 10945
+ >);
+
+const WhichRangesContainer SvxParaAlignTabPage::pSdrAlignRanges(
+ svl::Items<
+ SDRATTR_TEXT_VERTADJUST, SDRATTR_TEXT_VERTADJUST, // 1076
+ SID_ATTR_PARA_ADJUST, SID_ATTR_PARA_ADJUST , // 10027
+ SID_ATTR_FRAMEDIRECTION, SID_ATTR_FRAMEDIRECTION // 10944
+ >);
+
+const WhichRangesContainer SvxExtParagraphTabPage::pExtRanges(svl::Items<
+ SID_ATTR_PARA_PAGEBREAK, SID_ATTR_PARA_WIDOWS, // 10037 - 10041
+ SID_ATTR_PARA_MODEL, SID_ATTR_PARA_KEEP // 10065 - 10066
+>);
+
+#define MAX_DURCH 31680 // tdf#68335: 1584 pt for UX interoperability with Word
+#define FIX_DIST_DEF 283 // standard fix distance 0,5 cm
+
+namespace {
+
+enum LineSpaceList
+{
+ LLINESPACE_1 = 0,
+ LLINESPACE_115 = 1,
+ LLINESPACE_15 = 2,
+ LLINESPACE_2 = 3,
+ LLINESPACE_PROP = 4,
+ LLINESPACE_MIN = 5,
+ LLINESPACE_DURCH= 6,
+ LLINESPACE_FIX = 7
+};
+
+}
+
+static void SetLineSpace_Impl( SvxLineSpacingItem&, int, tools::Long lValue = 0 );
+
+void SetLineSpace_Impl( SvxLineSpacingItem& rLineSpace,
+ int 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( 115 );
+ break;
+
+ case LLINESPACE_15:
+ rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
+ rLineSpace.SetPropLineSpace( 150 );
+ break;
+
+ case LLINESPACE_2:
+ rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
+ rLineSpace.SetPropLineSpace( 200 );
+ 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;
+ }
+}
+
+static sal_uInt16 GetHtmlMode_Impl(const SfxItemSet& rSet)
+{
+ sal_uInt16 nHtmlMode = 0;
+ const SfxUInt16Item* pItem = rSet.GetItemIfSet(SID_HTML_MODE, false);
+ if (!pItem)
+ {
+ if (SfxObjectShell* pShell = SfxObjectShell::Current())
+ pItem = pShell->GetItem(SID_HTML_MODE);
+ }
+ if(pItem)
+ {
+ nHtmlMode = pItem->GetValue();
+ }
+ return nHtmlMode;
+
+}
+
+void SvxStdParagraphTabPage::ELRLoseFocus()
+{
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ FieldUnit eUnit =
+ MapToFieldUnit( pPool->GetMetric( GetWhich( SID_ATTR_LRSPACE ) ) );
+
+ sal_Int64 nL = m_aLeftIndent.denormalize(m_aLeftIndent.get_value(eUnit));
+ sal_Int64 nR = m_aRightIndent.denormalize(m_aRightIndent.get_value(eUnit));
+ OUString aTmp = m_aFLineIndent.get_text();
+
+ if (m_aLeftIndent.get_min(FieldUnit::NONE) < 0)
+ m_aFLineIndent.set_min(-99999, FieldUnit::MM);
+ else
+ m_aFLineIndent.set_min(m_aFLineIndent.normalize(-nL), eUnit);
+
+ // Check only for concrete width (Shell)
+ sal_Int64 nTmp = nWidth - nL - nR - MM50;
+ m_aFLineIndent.set_max(m_aFLineIndent.normalize(nTmp), eUnit);
+
+ if (aTmp.isEmpty())
+ m_aFLineIndent.set_text(OUString());
+ // maximum left right
+ aTmp = m_aLeftIndent.get_text();
+ nTmp = nWidth - nR - MM50;
+ m_aLeftIndent.set_max(m_aLeftIndent.normalize(nTmp), eUnit);
+
+ if ( aTmp.isEmpty() )
+ m_aLeftIndent.set_text(OUString());
+ aTmp = m_aRightIndent.get_text();
+ nTmp = nWidth - nL - MM50;
+ m_aRightIndent.set_max(m_aRightIndent.normalize(nTmp), eUnit);
+
+ if ( aTmp.isEmpty() )
+ m_aRightIndent.set_text(OUString());
+
+ UpdateExample_Impl();
+}
+
+IMPL_LINK_NOARG(SvxStdParagraphTabPage, ELRLoseFocusHdl, weld::MetricSpinButton&, void)
+{
+ ELRLoseFocus();
+}
+
+std::unique_ptr<SfxTabPage> SvxStdParagraphTabPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxStdParagraphTabPage>(pPage, pController, *rSet);
+}
+
+bool SvxStdParagraphTabPage::FillItemSet( SfxItemSet* rOutSet )
+{
+ const SfxPoolItem* pOld = nullptr;
+ SfxItemPool* pPool = rOutSet->GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+
+ bool bModified = false;
+ sal_uInt16 nWhich;
+ int nPos = m_xLineDist->get_active();
+
+ if ( nPos != -1 &&
+ ( m_bLineDistToggled ||
+ m_xLineDist->get_value_changed_from_saved() ||
+ m_xLineDistAtPercentBox->get_value_changed_from_saved() ||
+ m_xLineDistAtMetricBox->get_value_changed_from_saved() ) )
+ {
+ nWhich = GetWhich( SID_ATTR_PARA_LINESPACE );
+ MapUnit eUnit = pPool->GetMetric( nWhich );
+ SvxLineSpacingItem aSpacing(
+ static_cast<const SvxLineSpacingItem&>(GetItemSet().Get( nWhich )) );
+
+ switch ( nPos )
+ {
+ case LLINESPACE_1:
+ case LLINESPACE_115:
+ case LLINESPACE_15:
+ case LLINESPACE_2:
+ SetLineSpace_Impl( aSpacing, nPos );
+ break;
+
+ case LLINESPACE_PROP:
+ SetLineSpace_Impl( aSpacing, nPos,
+ static_cast<tools::Long>(m_xLineDistAtPercentBox->denormalize(
+ m_xLineDistAtPercentBox->get_value(FieldUnit::NONE) )) );
+ break;
+
+ case LLINESPACE_MIN:
+ case LLINESPACE_DURCH:
+ case LLINESPACE_FIX:
+ SetLineSpace_Impl( aSpacing, nPos,
+ GetCoreValue( *m_xLineDistAtMetricBox, eUnit ) );
+ break;
+
+ default:
+ OSL_FAIL( "unknown LineDist entry" );
+ break;
+ }
+ pOld = GetOldItem( *rOutSet, SID_ATTR_PARA_LINESPACE );
+
+ if ( m_bLineDistToggled ||
+ !pOld || !( *static_cast<const SvxLineSpacingItem*>(pOld) == aSpacing ) ||
+ SfxItemState::DONTCARE == GetItemSet().GetItemState( nWhich ) )
+ {
+ rOutSet->Put( aSpacing );
+ bModified = true;
+ }
+ }
+
+ if ( m_aTopDist.get_value_changed_from_saved() || m_aBottomDist.get_value_changed_from_saved()
+ || m_xContextualCB->get_state_changed_from_saved())
+ {
+ nWhich = GetWhich( SID_ATTR_ULSPACE );
+ MapUnit eUnit = pPool->GetMetric( nWhich );
+ pOld = GetOldItem( *rOutSet, SID_ATTR_ULSPACE );
+ SvxULSpaceItem aMargin( nWhich );
+
+ if ( bRelativeMode )
+ {
+ DBG_ASSERT( GetItemSet().GetParent(), "No ParentSet" );
+
+ const SvxULSpaceItem& rOldItem =
+ static_cast<const SvxULSpaceItem&>(GetItemSet().GetParent()->Get( nWhich ));
+
+ if ( m_aTopDist.IsRelative() )
+ aMargin.SetUpper( rOldItem.GetUpper(),
+ static_cast<sal_uInt16>(m_aTopDist.get_value(FieldUnit::NONE)) );
+ else
+ aMargin.SetUpper( static_cast<sal_uInt16>(m_aTopDist.GetCoreValue(eUnit)) );
+
+ if ( m_aBottomDist.IsRelative() )
+ aMargin.SetLower( rOldItem.GetLower(),
+ static_cast<sal_uInt16>(m_aBottomDist.get_value(FieldUnit::NONE)) );
+ else
+ aMargin.SetLower( static_cast<sal_uInt16>(m_aBottomDist.GetCoreValue(eUnit)) );
+
+ }
+ else
+ {
+ aMargin.SetUpper(static_cast<sal_uInt16>(m_aTopDist.GetCoreValue(eUnit)));
+ aMargin.SetLower(static_cast<sal_uInt16>(m_aBottomDist.GetCoreValue(eUnit)));
+ }
+ aMargin.SetContextValue(m_xContextualCB->get_active());
+
+ if ( !pOld || *static_cast<const SvxULSpaceItem*>(pOld) != aMargin ||
+ SfxItemState::DONTCARE == GetItemSet().GetItemState( nWhich ) )
+ {
+ rOutSet->Put( aMargin );
+ bModified = true;
+ }
+ }
+ bool bNullTab = false;
+
+ if (m_bSplitLRSpace && m_aLeftIndent.get_value_changed_from_saved())
+ {
+ nWhich = GetWhich(SID_ATTR_PARA_LEFTSPACE);
+ MapUnit const eUnit = pPool->GetMetric(nWhich);
+ SvxTextLeftMarginItem item(nWhich);
+ pOld = GetOldItem(*rOutSet, SID_ATTR_PARA_LEFTSPACE);
+
+ if (bRelativeMode)
+ {
+ assert(GetItemSet().GetParent());
+
+ const SvxTextLeftMarginItem & rOldItem(
+ static_cast<const SvxTextLeftMarginItem&>(GetItemSet().GetParent()->Get(nWhich)));
+
+ if (m_aLeftIndent.IsRelative())
+ {
+ item.SetTextLeft(rOldItem.GetTextLeft(),
+ static_cast<sal_uInt16>(m_aLeftIndent.get_value(FieldUnit::NONE)));
+ }
+ else
+ {
+ item.SetTextLeft(m_aLeftIndent.GetCoreValue(eUnit));
+ }
+ }
+ else
+ {
+ item.SetTextLeft(m_aLeftIndent.GetCoreValue(eUnit));
+ }
+ if (!pOld || *static_cast<const SvxTextLeftMarginItem*>(pOld) != item
+ || SfxItemState::DONTCARE == GetItemSet().GetItemState(nWhich))
+ {
+ rOutSet->Put(item);
+ bModified = true;
+ }
+ }
+
+ if (m_bSplitLRSpace && m_aRightIndent.get_value_changed_from_saved())
+ {
+ nWhich = GetWhich(SID_ATTR_PARA_RIGHTSPACE);
+ MapUnit const eUnit = pPool->GetMetric(nWhich);
+ SvxRightMarginItem item(nWhich);
+ pOld = GetOldItem(*rOutSet, SID_ATTR_PARA_RIGHTSPACE);
+
+ if (bRelativeMode)
+ {
+ assert(GetItemSet().GetParent());
+
+ const SvxRightMarginItem & rOldItem(
+ static_cast<const SvxRightMarginItem&>(GetItemSet().GetParent()->Get(nWhich)));
+
+ if (m_aRightIndent.IsRelative())
+ {
+ item.SetRight(rOldItem.GetRight(),
+ static_cast<sal_uInt16>(m_aRightIndent.get_value(FieldUnit::NONE)));
+ }
+ else
+ {
+ item.SetRight(m_aRightIndent.GetCoreValue(eUnit));
+ }
+ }
+ else
+ {
+ item.SetRight(m_aRightIndent.GetCoreValue(eUnit));
+ }
+ if (!pOld || *static_cast<const SvxRightMarginItem*>(pOld) != item
+ || SfxItemState::DONTCARE == GetItemSet().GetItemState(nWhich))
+ {
+ rOutSet->Put(item);
+ bModified = true;
+ }
+ }
+
+ if (m_bSplitLRSpace && (m_aFLineIndent.get_value_changed_from_saved()
+ || m_xAutoCB->get_state_changed_from_saved()))
+ {
+ nWhich = GetWhich(SID_ATTR_PARA_FIRSTLINESPACE);
+ MapUnit const eUnit = pPool->GetMetric(nWhich);
+ SvxFirstLineIndentItem item(nWhich);
+ pOld = GetOldItem(*rOutSet, SID_ATTR_PARA_FIRSTLINESPACE);
+
+ if (bRelativeMode)
+ {
+ assert(GetItemSet().GetParent());
+
+ const SvxFirstLineIndentItem & rOldItem(
+ static_cast<const SvxFirstLineIndentItem&>(GetItemSet().GetParent()->Get(nWhich)));
+
+ if (m_aFLineIndent.IsRelative())
+ {
+ item.SetTextFirstLineOffset(rOldItem.GetTextFirstLineOffset(),
+ static_cast<sal_uInt16>(m_aFLineIndent.get_value(FieldUnit::NONE)));
+ }
+ else
+ {
+ item.SetTextFirstLineOffset(static_cast<sal_uInt16>(m_aFLineIndent.GetCoreValue(eUnit)));
+ }
+ }
+ else
+ {
+ item.SetTextFirstLineOffset(static_cast<sal_uInt16>(m_aFLineIndent.GetCoreValue(eUnit)));
+ }
+ item.SetAutoFirst(m_xAutoCB->get_active());
+ if (item.GetTextFirstLineOffset() < 0)
+ {
+ bNullTab = true;
+ }
+
+ if (!pOld || *static_cast<const SvxFirstLineIndentItem*>(pOld) != item
+ || SfxItemState::DONTCARE == GetItemSet().GetItemState(nWhich))
+ {
+ rOutSet->Put(item);
+ bModified = true;
+ }
+ }
+
+ if (!m_bSplitLRSpace &&
+ (m_aLeftIndent.get_value_changed_from_saved() ||
+ m_aFLineIndent.get_value_changed_from_saved() ||
+ m_aRightIndent.get_value_changed_from_saved() ||
+ m_xAutoCB->get_state_changed_from_saved()))
+ {
+ nWhich = GetWhich( SID_ATTR_LRSPACE );
+ MapUnit eUnit = pPool->GetMetric( nWhich );
+ SvxLRSpaceItem aMargin( nWhich );
+ pOld = GetOldItem( *rOutSet, SID_ATTR_LRSPACE );
+
+ if ( bRelativeMode )
+ {
+ DBG_ASSERT( GetItemSet().GetParent(), "No ParentSet" );
+
+ const SvxLRSpaceItem& rOldItem =
+ static_cast<const SvxLRSpaceItem&>(GetItemSet().GetParent()->Get( nWhich ));
+
+ if (m_aLeftIndent.IsRelative())
+ aMargin.SetTextLeft( rOldItem.GetTextLeft(),
+ static_cast<sal_uInt16>(m_aLeftIndent.get_value(FieldUnit::NONE)) );
+ else
+ aMargin.SetTextLeft(m_aLeftIndent.GetCoreValue(eUnit));
+
+ if ( m_aRightIndent.IsRelative() )
+ aMargin.SetRight( rOldItem.GetRight(),
+ static_cast<sal_uInt16>(m_aRightIndent.get_value(FieldUnit::NONE)) );
+ else
+ aMargin.SetRight(m_aRightIndent.GetCoreValue(eUnit));
+
+ if ( m_aFLineIndent.IsRelative() )
+ aMargin.SetTextFirstLineOffset( rOldItem.GetTextFirstLineOffset(),
+ static_cast<sal_uInt16>(m_aFLineIndent.get_value(FieldUnit::NONE)) );
+ else
+ aMargin.SetTextFirstLineOffset(static_cast<sal_uInt16>(m_aFLineIndent.GetCoreValue(eUnit)));
+ }
+ else
+ {
+ aMargin.SetTextLeft(m_aLeftIndent.GetCoreValue(eUnit));
+ aMargin.SetRight(m_aRightIndent.GetCoreValue(eUnit));
+ aMargin.SetTextFirstLineOffset(static_cast<sal_uInt16>(m_aFLineIndent.GetCoreValue(eUnit)));
+ }
+ aMargin.SetAutoFirst(m_xAutoCB->get_active());
+ if ( aMargin.GetTextFirstLineOffset() < 0 )
+ bNullTab = true;
+
+ if ( !pOld || *static_cast<const SvxLRSpaceItem*>(pOld) != aMargin ||
+ SfxItemState::DONTCARE == GetItemSet().GetItemState( nWhich ) )
+ {
+ rOutSet->Put( aMargin );
+ bModified = true;
+ }
+ }
+
+ if ( bNullTab )
+ {
+ MapUnit eUnit = pPool->GetMetric( GetWhich( SID_ATTR_TABSTOP ) );
+ if ( MapUnit::Map100thMM != eUnit )
+ {
+
+ // negative first line indent -> set null default tabstob if applicable
+ sal_uInt16 _nWhich = GetWhich( SID_ATTR_TABSTOP );
+ const SfxItemSet& rInSet = GetItemSet();
+
+ if ( rInSet.GetItemState( _nWhich ) >= SfxItemState::DEFAULT )
+ {
+ const SvxTabStopItem& rTabItem =
+ static_cast<const SvxTabStopItem&>(rInSet.Get( _nWhich ));
+ SvxTabStopItem aNullTab( rTabItem );
+ SvxTabStop aNull( 0, SvxTabAdjust::Default );
+ aNullTab.Insert( aNull );
+ rOutSet->Put( aNullTab );
+ }
+ }
+ }
+ if (m_xRegisterCB->get_visible())
+ {
+ const SfxBoolItem* pBoolItem = static_cast<const SfxBoolItem*>(GetOldItem(
+ *rOutSet, SID_ATTR_PARA_REGISTER));
+ if (!pBoolItem)
+ return bModified;
+ sal_uInt16 _nWhich = GetWhich( SID_ATTR_PARA_REGISTER );
+ bool bSet = pBoolItem->GetValue();
+
+ if (m_xRegisterCB->get_active() != bSet)
+ {
+ std::unique_ptr<SfxBoolItem> pRegItem(pBoolItem->Clone());
+ pRegItem->SetValue(!bSet);
+ rOutSet->Put(std::move(pRegItem));
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == GetItemSet().GetItemState( _nWhich, false ) )
+ rOutSet->ClearItem(_nWhich);
+ }
+
+ return bModified;
+}
+
+static bool UseCharUnitInUI(const SfxItemSet& rSet)
+{
+ const bool bApplyCharUnit = GetApplyCharUnit(rSet);
+ if (!bApplyCharUnit)
+ return false;
+ if (!SvtCJKOptions::IsAsianTypographyEnabled())
+ return false;
+ // tdf#101895 Given that we choose to show cm vs inch based on this Locale
+ // setting, also choose to use ch[ar] and line based on that locale when
+ // bApplyCharUnit is enabled.
+ return MsLangId::isCJK(SvtSysLocaleOptions().GetRealLanguageTag().getLanguageType());
+}
+
+void SvxStdParagraphTabPage::Reset( const SfxItemSet* rSet )
+{
+ SfxItemPool* pPool = rSet->GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+
+ // adjust metric
+ FieldUnit eFUnit = GetModuleFieldUnit( *rSet );
+ if (UseCharUnitInUI(*rSet))
+ eFUnit = FieldUnit::CHAR;
+
+ m_aLeftIndent.SetFieldUnit(eFUnit);
+ m_aRightIndent.SetFieldUnit(eFUnit);
+ m_aFLineIndent.SetFieldUnit(eFUnit);
+ if ( eFUnit == FieldUnit::CHAR )
+ {
+ m_aTopDist.SetFieldUnit(FieldUnit::LINE);
+ m_aBottomDist.SetFieldUnit(FieldUnit::LINE);
+ SetFieldUnit(*m_xLineDistAtMetricBox, FieldUnit::POINT);
+ }
+ else
+ {
+ m_aTopDist.SetFieldUnit(eFUnit);
+ m_aBottomDist.SetFieldUnit(eFUnit);
+ SetFieldUnit(*m_xLineDistAtMetricBox, eFUnit);
+ }
+
+ sal_uInt16 const nWhichFL(GetWhich(SID_ATTR_PARA_FIRSTLINESPACE));
+ m_bSplitLRSpace = (nWhichFL != SID_ATTR_PARA_FIRSTLINESPACE);
+ SfxItemState const eItemStateFL(rSet->GetItemState(nWhichFL));
+ sal_uInt16 const nWhichLM(GetWhich(SID_ATTR_PARA_LEFTSPACE));
+ SfxItemState const eItemStateLM(rSet->GetItemState(nWhichLM));
+ sal_uInt16 const nWhichRM(GetWhich(SID_ATTR_PARA_RIGHTSPACE));
+ SfxItemState const eItemStateRM(rSet->GetItemState(nWhichRM));
+
+ if (m_bSplitLRSpace && SfxItemState::DEFAULT <= eItemStateLM)
+ {
+ const SvxTextLeftMarginItem & rOldLeftMargin(
+ static_cast<const SvxTextLeftMarginItem &>(rSet->Get(nWhichLM)));
+
+ MapUnit const eUnit = pPool->GetMetric(nWhichLM);
+
+ if (bRelativeMode)
+ {
+ if (rOldLeftMargin.GetPropLeft() != 100)
+ {
+ m_aLeftIndent.SetRelative( true );
+ m_aLeftIndent.set_value(rOldLeftMargin.GetPropLeft(), FieldUnit::NONE);
+ }
+ else
+ {
+ m_aLeftIndent.SetRelative(false);
+ m_aLeftIndent.SetFieldUnit(eFUnit);
+ m_aLeftIndent.SetMetricValue(rOldLeftMargin.GetTextLeft(), eUnit);
+ }
+ }
+ else
+ {
+ m_aLeftIndent.SetMetricValue(rOldLeftMargin.GetTextLeft(), eUnit);
+ }
+ }
+ else if (m_bSplitLRSpace)
+ {
+ m_aLeftIndent.set_text(OUString());
+ }
+
+ if (m_bSplitLRSpace && SfxItemState::DEFAULT <= eItemStateRM)
+ {
+ const SvxRightMarginItem & rOldRightMargin(
+ static_cast<const SvxRightMarginItem &>(rSet->Get(nWhichRM)));
+
+ MapUnit const eUnit = pPool->GetMetric(nWhichRM);
+
+ if (bRelativeMode)
+ {
+ if (rOldRightMargin.GetPropRight() != 100)
+ {
+ m_aRightIndent.SetRelative( true );
+ m_aRightIndent.set_value(rOldRightMargin.GetPropRight(), FieldUnit::NONE);
+ }
+ else
+ {
+ m_aRightIndent.SetRelative(false);
+ m_aRightIndent.SetFieldUnit(eFUnit);
+ m_aRightIndent.SetMetricValue(rOldRightMargin.GetRight(), eUnit);
+ }
+ }
+ else
+ {
+ m_aRightIndent.SetMetricValue(rOldRightMargin.GetRight(), eUnit);
+ }
+ }
+ else if (m_bSplitLRSpace)
+ {
+ m_aRightIndent.set_text(OUString());
+ }
+
+ if (m_bSplitLRSpace && SfxItemState::DEFAULT <= eItemStateFL)
+ {
+ const SvxFirstLineIndentItem & rOldFirstLine(
+ static_cast<const SvxFirstLineIndentItem &>(rSet->Get(nWhichFL)));
+
+ MapUnit const eUnit = pPool->GetMetric(nWhichFL);
+
+ if (bRelativeMode)
+ {
+ if (rOldFirstLine.GetPropTextFirstLineOffset() != 100)
+ {
+ m_aFLineIndent.SetRelative(true);
+ m_aFLineIndent.set_value(rOldFirstLine.GetPropTextFirstLineOffset(), FieldUnit::NONE);
+ }
+ else
+ {
+ m_aFLineIndent.SetRelative(false);
+ m_aFLineIndent.set_min(-9999, FieldUnit::NONE);
+ m_aFLineIndent.SetFieldUnit(eFUnit);
+ m_aFLineIndent.SetMetricValue(rOldFirstLine.GetTextFirstLineOffset(), eUnit);
+ }
+ m_xAutoCB->set_active(rOldFirstLine.IsAutoFirst());
+ }
+ else
+ {
+ m_aFLineIndent.SetMetricValue(rOldFirstLine.GetTextFirstLineOffset(), eUnit);
+ m_xAutoCB->set_active(rOldFirstLine.IsAutoFirst());
+ }
+ AutoHdl_Impl(*m_xAutoCB);
+ }
+ else if (m_bSplitLRSpace)
+ {
+ m_aFLineIndent.set_text(OUString());
+ }
+
+ sal_uInt16 _nWhich = GetWhich( SID_ATTR_LRSPACE );
+ SfxItemState eItemState = rSet->GetItemState( _nWhich );
+
+ if (!m_bSplitLRSpace && SfxItemState::DEFAULT <= eItemState)
+ {
+ MapUnit eUnit = pPool->GetMetric( _nWhich );
+
+ if ( bRelativeMode )
+ {
+ const SvxLRSpaceItem& rOldItem =
+ static_cast<const SvxLRSpaceItem&>(rSet->Get( _nWhich ));
+
+ if ( rOldItem.GetPropLeft() != 100 )
+ {
+ m_aLeftIndent.SetRelative( true );
+ m_aLeftIndent.set_value(rOldItem.GetPropLeft(), FieldUnit::NONE);
+ }
+ else
+ {
+ m_aLeftIndent.SetRelative(false);
+ m_aLeftIndent.SetFieldUnit(eFUnit);
+ m_aLeftIndent.SetMetricValue(rOldItem.GetTextLeft(), eUnit);
+ }
+
+ if ( rOldItem.GetPropRight() != 100 )
+ {
+ m_aRightIndent.SetRelative( true );
+ m_aRightIndent.set_value(rOldItem.GetPropRight(), FieldUnit::NONE);
+ }
+ else
+ {
+ m_aRightIndent.SetRelative(false);
+ m_aRightIndent.SetFieldUnit(eFUnit);
+ m_aRightIndent.SetMetricValue(rOldItem.GetRight(), eUnit);
+ }
+
+ if ( rOldItem.GetPropTextFirstLineOffset() != 100 )
+ {
+ m_aFLineIndent.SetRelative(true);
+ m_aFLineIndent.set_value(rOldItem.GetPropTextFirstLineOffset(), FieldUnit::NONE);
+ }
+ else
+ {
+ m_aFLineIndent.SetRelative(false);
+ m_aFLineIndent.set_min(-9999, FieldUnit::NONE);
+ m_aFLineIndent.SetFieldUnit(eFUnit);
+ m_aFLineIndent.SetMetricValue(rOldItem.GetTextFirstLineOffset(), eUnit);
+ }
+ m_xAutoCB->set_active(rOldItem.IsAutoFirst());
+ }
+ else
+ {
+ const SvxLRSpaceItem& rSpace =
+ static_cast<const SvxLRSpaceItem&>(rSet->Get( _nWhich ));
+
+ m_aLeftIndent.SetMetricValue(rSpace.GetTextLeft(), eUnit);
+ m_aRightIndent.SetMetricValue(rSpace.GetRight(), eUnit);
+ m_aFLineIndent.SetMetricValue(rSpace.GetTextFirstLineOffset(), eUnit);
+ m_xAutoCB->set_active(rSpace.IsAutoFirst());
+ }
+ AutoHdl_Impl(*m_xAutoCB);
+ }
+ else if (!m_bSplitLRSpace)
+ {
+ m_aLeftIndent.set_text(OUString());
+ m_aRightIndent.set_text(OUString());
+ m_aFLineIndent.set_text(OUString());
+ }
+
+ _nWhich = GetWhich( SID_ATTR_ULSPACE );
+ eItemState = rSet->GetItemState( _nWhich );
+
+ if ( eItemState >= SfxItemState::DEFAULT )
+ {
+ MapUnit eUnit = pPool->GetMetric( _nWhich );
+
+ const SvxULSpaceItem& rOldItem =
+ static_cast<const SvxULSpaceItem&>(rSet->Get( _nWhich ));
+ if ( bRelativeMode )
+ {
+
+ if ( rOldItem.GetPropUpper() != 100 )
+ {
+ m_aTopDist.SetRelative( true );
+ m_aTopDist.set_value(rOldItem.GetPropUpper(), FieldUnit::NONE);
+ }
+ else
+ {
+ m_aTopDist.SetRelative(false);
+ if (eFUnit == FieldUnit::CHAR)
+ m_aTopDist.SetFieldUnit(FieldUnit::LINE);
+ else
+ m_aTopDist.SetFieldUnit(eFUnit);
+ m_aTopDist.SetMetricValue(rOldItem.GetUpper(), eUnit);
+ }
+
+ if ( rOldItem.GetPropLower() != 100 )
+ {
+ m_aBottomDist.SetRelative( true );
+ m_aBottomDist.set_value(rOldItem.GetPropLower(), FieldUnit::NONE);
+ }
+ else
+ {
+ m_aBottomDist.SetRelative(false);
+ if (eFUnit == FieldUnit::CHAR)
+ m_aBottomDist.SetFieldUnit(FieldUnit::LINE);
+ else
+ m_aBottomDist.SetFieldUnit(eFUnit);
+ m_aBottomDist.SetMetricValue(rOldItem.GetLower(), eUnit);
+ }
+ }
+ else
+ {
+ m_aTopDist.SetMetricValue(rOldItem.GetUpper(), eUnit);
+ m_aBottomDist.SetMetricValue(rOldItem.GetLower(), eUnit);
+ }
+ m_xContextualCB->set_active(rOldItem.GetContext());
+ }
+ else
+ {
+ m_aTopDist.set_text(OUString());
+ m_aBottomDist.set_text(OUString());
+ }
+
+ _nWhich = GetWhich( SID_ATTR_PARA_LINESPACE );
+ eItemState = rSet->GetItemState( _nWhich );
+
+ if ( eItemState >= SfxItemState::DEFAULT )
+ SetLineSpacing_Impl( static_cast<const SvxLineSpacingItem &>(rSet->Get( _nWhich )) );
+ else
+ m_xLineDist->set_active(-1);
+
+ _nWhich = GetWhich( SID_ATTR_PARA_REGISTER );
+ eItemState = rSet->GetItemState( _nWhich );
+
+ if ( eItemState >= SfxItemState::DEFAULT )
+ m_xRegisterCB->set_active( static_cast<const SfxBoolItem &>(rSet->Get( _nWhich )).GetValue());
+ m_xRegisterCB->save_state();
+ sal_uInt16 nHtmlMode = GetHtmlMode_Impl(*rSet);
+ if(nHtmlMode & HTMLMODE_ON)
+ {
+ m_xRegisterCB->hide();
+ m_xAutoCB->hide();
+ }
+
+ // this sets the min/max limits; do this _after_ setting the values,
+ // because for Impress the min of first-line indent depends on value of
+ // left-indent!
+ ELRLoseFocus();
+ ChangesApplied();
+}
+
+void SvxStdParagraphTabPage::ChangesApplied()
+{
+ m_aLeftIndent.save_value();
+ m_aRightIndent.save_value();
+ m_aFLineIndent.save_value();
+ m_xLineDist->save_value();
+ m_xLineDistAtPercentBox->save_value();
+ m_xLineDistAtMetricBox->save_value();
+ m_xRegisterCB->save_state();
+ m_aTopDist.save_value();
+ m_aBottomDist.save_value();
+ m_xContextualCB->save_state();
+ m_xAutoCB->save_state();
+}
+
+void SvxStdParagraphTabPage::EnableRelativeMode()
+{
+ DBG_ASSERT( GetItemSet().GetParent(), "RelativeMode, but no parent-set!" );
+
+ m_aLeftIndent.EnableRelativeMode( 0, 999 );
+ m_aFLineIndent.EnableRelativeMode( 0, 999 );
+ m_aRightIndent.EnableRelativeMode( 0, 999 );
+ m_aTopDist.EnableRelativeMode( 0, 999 );
+ m_aBottomDist.EnableRelativeMode( 0, 999 );
+ bRelativeMode = true;
+}
+
+void SvxStdParagraphTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ sal_uInt16 _nWhich = GetWhich( SID_ATTR_PARA_ADJUST );
+ SfxItemState eItemState = rSet.GetItemState( _nWhich );
+
+ if ( eItemState < SfxItemState::DEFAULT )
+ return;
+
+ const SvxAdjustItem& rAdj = static_cast<const SvxAdjustItem&>( rSet.Get( _nWhich ) );
+ SvxAdjust eAdjust = rAdj.GetAdjust();
+ if ( eAdjust == SvxAdjust::Center || eAdjust == SvxAdjust::Block )
+ {
+ _nWhich = GetWhich( SID_ATTR_FRAMEDIRECTION );
+ eItemState = rSet.GetItemState( _nWhich );
+
+ if ( eItemState >= SfxItemState::DEFAULT )
+ {
+ const SvxFrameDirectionItem& rFrameDirItem = static_cast<const SvxFrameDirectionItem&>( rSet.Get( _nWhich ) );
+ SvxFrameDirection eFrameDirection = rFrameDirItem.GetValue();
+
+ m_aExampleWin.EnableRTL( SvxFrameDirection::Horizontal_RL_TB == eFrameDirection );
+
+ if ( eAdjust == SvxAdjust::Block )
+ m_aExampleWin.SetLastLine( rAdj.GetLastBlock() );
+ }
+ }
+ else
+ {
+ m_aExampleWin.EnableRTL( eAdjust == SvxAdjust::Right );
+ eAdjust = SvxAdjust::Left; //required for correct preview display
+ m_aExampleWin.SetLastLine( eAdjust );
+ }
+ m_aExampleWin.SetAdjust( eAdjust );
+
+ UpdateExample_Impl();
+}
+
+DeactivateRC SvxStdParagraphTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ ELRLoseFocus();
+
+ if ( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+SvxStdParagraphTabPage::SvxStdParagraphTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttr)
+ : SfxTabPage(pPage, pController, "cui/ui/paraindentspacing.ui", "ParaIndentSpacing", &rAttr)
+ , nWidth(11905 /*567 * 50*/)
+ , nMinFixDist(0)
+ , bRelativeMode(false)
+ , m_aLeftIndent(m_xBuilder->weld_metric_spin_button("spinED_LEFTINDENT", FieldUnit::CM))
+ , m_aRightIndent(m_xBuilder->weld_metric_spin_button("spinED_RIGHTINDENT", FieldUnit::CM))
+ , m_xFLineLabel(m_xBuilder->weld_label("labelFT_FLINEINDENT"))
+ , m_aFLineIndent(m_xBuilder->weld_metric_spin_button("spinED_FLINEINDENT", FieldUnit::CM))
+ , m_xAutoCB(m_xBuilder->weld_check_button("checkCB_AUTO"))
+ , m_aTopDist(m_xBuilder->weld_metric_spin_button("spinED_TOPDIST", FieldUnit::CM))
+ , m_aBottomDist(m_xBuilder->weld_metric_spin_button("spinED_BOTTOMDIST", FieldUnit::CM))
+ , m_xContextualCB(m_xBuilder->weld_check_button("checkCB_CONTEXTUALSPACING"))
+ , m_xLineDist(m_xBuilder->weld_combo_box("comboLB_LINEDIST"))
+ , m_xLineDistAtPercentBox(m_xBuilder->weld_metric_spin_button("spinED_LINEDISTPERCENT", FieldUnit::PERCENT))
+ , m_xLineDistAtMetricBox(m_xBuilder->weld_metric_spin_button("spinED_LINEDISTMETRIC", FieldUnit::CM))
+ , m_xLineDistAtPlaceHolderBox(m_xBuilder->weld_metric_spin_button("spinED_BLANK", FieldUnit::CM))
+ , m_xLineDistAtLabel(m_xBuilder->weld_label("labelFT_LINEDIST"))
+ , m_xAbsDist(m_xBuilder->weld_label("labelST_LINEDIST_ABS"))
+ , m_xRegisterCB(m_xBuilder->weld_check_button("checkCB_REGISTER"))
+ , m_xExampleWin(new weld::CustomWeld(*m_xBuilder, "drawingareaWN_EXAMPLE", m_aExampleWin))
+{
+ sAbsDist = m_xAbsDist->get_label();
+
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ m_xLineDistAtMetricBox->hide();
+ m_xLineDistAtPlaceHolderBox->hide();
+ m_xLineDistAtPlaceHolderBox->set_text(OUString());
+
+ Init_Impl();
+ m_aFLineIndent.set_min(-9999, FieldUnit::NONE); // is set to 0 on default
+}
+
+SvxStdParagraphTabPage::~SvxStdParagraphTabPage()
+{
+}
+
+void SvxStdParagraphTabPage::EnableNegativeMode()
+{
+ m_aLeftIndent.set_min(-9999, FieldUnit::NONE);
+ m_aRightIndent.set_min(-9999, FieldUnit::NONE);
+ m_aRightIndent.EnableNegativeMode();
+ m_aLeftIndent.EnableNegativeMode();
+}
+
+void SvxStdParagraphTabPage::SetLineSpacing_Impl
+(
+ const SvxLineSpacingItem &rAttr
+)
+{
+ MapUnit eUnit = GetItemSet().GetPool()->GetMetric( rAttr.Which() );
+
+ switch( rAttr.GetLineSpaceRule() )
+ {
+ case SvxLineSpaceRule::Auto:
+ {
+ SvxInterLineSpaceRule eInter = rAttr.GetInterLineSpaceRule();
+
+ switch( eInter )
+ {
+ // Default single line spacing
+ case SvxInterLineSpaceRule::Off:
+ m_xLineDist->set_active( LLINESPACE_1 );
+ break;
+
+ // Default single line spacing
+ case SvxInterLineSpaceRule::Prop:
+ if ( 100 == rAttr.GetPropLineSpace() )
+ {
+ m_xLineDist->set_active( LLINESPACE_1 );
+ break;
+ }
+ // 1.15 line spacing
+ if ( 115 == rAttr.GetPropLineSpace() )
+ {
+ m_xLineDist->set_active( LLINESPACE_115 );
+ break;
+ }
+ // 1.5 line spacing
+ if ( 150 == rAttr.GetPropLineSpace() )
+ {
+ m_xLineDist->set_active( LLINESPACE_15 );
+ break;
+ }
+ // double line spacing
+ if ( 200 == rAttr.GetPropLineSpace() )
+ {
+ m_xLineDist->set_active( LLINESPACE_2 );
+ break;
+ }
+ // the set per cent value
+ m_xLineDistAtPercentBox->set_value(m_xLineDistAtPercentBox->normalize(rAttr.GetPropLineSpace()), FieldUnit::NONE);
+ m_xLineDist->set_active( LLINESPACE_PROP );
+ break;
+
+ case SvxInterLineSpaceRule::Fix:
+ SetMetricValue( *m_xLineDistAtMetricBox, rAttr.GetInterLineSpace(), eUnit );
+ m_xLineDist->set_active( LLINESPACE_DURCH );
+ break;
+ default: ;//prevent warning
+ }
+ }
+ break;
+ case SvxLineSpaceRule::Fix:
+ SetMetricValue(*m_xLineDistAtMetricBox, rAttr.GetLineHeight(), eUnit);
+ m_xLineDist->set_active( LLINESPACE_FIX );
+ break;
+
+ case SvxLineSpaceRule::Min:
+ SetMetricValue(*m_xLineDistAtMetricBox, rAttr.GetLineHeight(), eUnit);
+ m_xLineDist->set_active( LLINESPACE_MIN );
+ break;
+ default: ;//prevent warning
+ }
+ LineDistHdl_Impl( *m_xLineDist );
+}
+
+IMPL_LINK_NOARG(SvxStdParagraphTabPage, LineDistPopupHdl_Impl, weld::ComboBox&, void)
+{
+ m_bLineDistToggled = true;
+}
+
+IMPL_LINK(SvxStdParagraphTabPage, LineDistHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ switch (rBox.get_active())
+ {
+ case LLINESPACE_1:
+ case LLINESPACE_115:
+ case LLINESPACE_15:
+ case LLINESPACE_2:
+ m_xLineDistAtLabel->set_sensitive(false);
+ m_xLineDistAtPercentBox->hide();
+ m_xLineDistAtMetricBox->hide();
+ m_xLineDistAtPlaceHolderBox->show();
+ break;
+
+ case LLINESPACE_DURCH:
+ // setting a sensible default?
+ // limit MS min(10, aPageSize)
+ m_xLineDistAtMetricBox->set_min(0, FieldUnit::NONE);
+
+ if (m_xLineDistAtPlaceHolderBox->get_visible())
+ m_xLineDistAtMetricBox->set_value(m_xLineDistAtMetricBox->normalize(1), FieldUnit::NONE);
+ m_xLineDistAtPlaceHolderBox->hide();
+ m_xLineDistAtPercentBox->hide();
+ m_xLineDistAtMetricBox->show();
+ m_xLineDistAtLabel->set_sensitive(true);
+ break;
+
+ case LLINESPACE_MIN:
+ m_xLineDistAtMetricBox->set_min(0, FieldUnit::NONE);
+
+ if (m_xLineDistAtPlaceHolderBox->get_visible())
+ m_xLineDistAtMetricBox->set_value(m_xLineDistAtMetricBox->normalize(10), FieldUnit::TWIP);
+ m_xLineDistAtPlaceHolderBox->hide();
+ m_xLineDistAtPercentBox->hide();
+ m_xLineDistAtMetricBox->show();
+ m_xLineDistAtLabel->set_sensitive(true);
+ break;
+
+ case LLINESPACE_PROP:
+
+ if (m_xLineDistAtPlaceHolderBox->get_visible())
+ m_xLineDistAtPercentBox->set_value(m_xLineDistAtPercentBox->normalize(100), FieldUnit::TWIP);
+ m_xLineDistAtPlaceHolderBox->hide();
+ m_xLineDistAtMetricBox->hide();
+ m_xLineDistAtPercentBox->show();
+ m_xLineDistAtLabel->set_sensitive(true);
+ break;
+ case LLINESPACE_FIX:
+ {
+ auto nTemp = m_xLineDistAtMetricBox->get_value(FieldUnit::NONE);
+ m_xLineDistAtMetricBox->set_min(m_xLineDistAtMetricBox->normalize(nMinFixDist), FieldUnit::TWIP);
+
+ // if the value has been changed at SetMin,
+ // it is time for the default
+ if (m_xLineDistAtMetricBox->get_value(FieldUnit::NONE) != nTemp)
+ SetMetricValue( *m_xLineDistAtMetricBox, FIX_DIST_DEF, MapUnit::MapTwip ); // fix is only in Writer
+ m_xLineDistAtPlaceHolderBox->hide();
+ m_xLineDistAtPercentBox->hide();
+ m_xLineDistAtMetricBox->show();
+ m_xLineDistAtLabel->set_sensitive(true);
+ }
+ break;
+ }
+ UpdateExample_Impl();
+}
+
+IMPL_LINK_NOARG(SvxStdParagraphTabPage, ModifyHdl_Impl, weld::MetricSpinButton&, void)
+{
+ UpdateExample_Impl();
+}
+
+void SvxStdParagraphTabPage::Init_Impl()
+{
+ m_xLineDist->connect_popup_toggled(LINK(this, SvxStdParagraphTabPage, LineDistPopupHdl_Impl));
+ m_xLineDist->connect_changed(LINK(this, SvxStdParagraphTabPage, LineDistHdl_Impl));
+
+ Link<weld::MetricSpinButton&,void> aLink2 = LINK(this, SvxStdParagraphTabPage, ELRLoseFocusHdl);
+ m_aFLineIndent.connect_value_changed(aLink2);
+ m_aLeftIndent.connect_value_changed(aLink2);
+ m_aRightIndent.connect_value_changed(aLink2);
+
+ Link<weld::MetricSpinButton&,void> aLink = LINK(this, SvxStdParagraphTabPage, ModifyHdl_Impl);
+ m_aTopDist.connect_value_changed(aLink);
+ m_aBottomDist.connect_value_changed(aLink);
+
+ m_xAutoCB->connect_toggled(LINK(this, SvxStdParagraphTabPage, AutoHdl_Impl));
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( GetWhich( SID_ATTR_LRSPACE ) ) );
+
+ m_aTopDist.set_max( m_aTopDist.normalize( MAX_DURCH ), eUnit );
+ m_aBottomDist.set_max( m_aBottomDist.normalize( MAX_DURCH ), eUnit );
+ m_xLineDistAtMetricBox->set_max( m_xLineDistAtMetricBox->normalize( MAX_DURCH ), eUnit );
+}
+
+void SvxStdParagraphTabPage::UpdateExample_Impl()
+{
+ m_aExampleWin.SetFirstLineOffset( static_cast<short>(m_aFLineIndent.denormalize( m_aFLineIndent.get_value( FieldUnit::TWIP ) )) );
+ m_aExampleWin.SetLeftMargin( static_cast<tools::Long>(m_aLeftIndent.denormalize( m_aLeftIndent.get_value( FieldUnit::TWIP ) ) ) );
+ m_aExampleWin.SetRightMargin( static_cast<tools::Long>(m_aRightIndent.denormalize( m_aRightIndent.get_value( FieldUnit::TWIP ) ) ) );
+ m_aExampleWin.SetUpper( static_cast<sal_uInt16>(m_aTopDist.denormalize( m_aTopDist.get_value( FieldUnit::TWIP ) )) );
+ m_aExampleWin.SetLower( static_cast<sal_uInt16>(m_aBottomDist.denormalize( m_aBottomDist.get_value( FieldUnit::TWIP ) )) );
+
+ int nPos = m_xLineDist->get_active();
+
+ switch ( nPos )
+ {
+ case LLINESPACE_1:
+ case LLINESPACE_115:
+ case LLINESPACE_15:
+ case LLINESPACE_2:
+ case LLINESPACE_PROP:
+ case LLINESPACE_MIN:
+ case LLINESPACE_DURCH:
+ case LLINESPACE_FIX:
+ m_aExampleWin.SetLineSpace( static_cast<SvxPrevLineSpace>(nPos) );
+ break;
+ }
+ m_aExampleWin.Invalidate();
+}
+
+void SvxStdParagraphTabPage::EnableRegisterMode()
+{
+ m_xRegisterCB->show();
+}
+
+void SvxStdParagraphTabPage::EnableContextualMode()
+{
+ m_xContextualCB->show();
+}
+
+IMPL_LINK(SvxStdParagraphTabPage, AutoHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ bool bEnable = !rBox.get_active();
+ m_xFLineLabel->set_sensitive(bEnable);
+ m_aFLineIndent.set_sensitive(bEnable);
+}
+
+void SvxStdParagraphTabPage::EnableAutoFirstLine()
+{
+ m_xAutoCB->show();
+}
+
+void SvxStdParagraphTabPage::EnableAbsLineDist(tools::Long nMinTwip)
+{
+ m_xLineDist->append_text(sAbsDist);
+ nMinFixDist = nMinTwip;
+}
+
+void SvxStdParagraphTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+
+/* different bit represent call to different method of SvxStdParagraphTabPage
+ 0x0001 --->EnableRelativeMode()
+ 0x0002 --->EnableRegisterMode()
+ 0x0004 --->EnableAutoFirstLine()
+ 0x0008 --->EnableNegativeMode()
+ 0x0010 --->EnableContextualMode()
+ */
+ const SfxUInt16Item* pPageWidthItem = aSet.GetItem<SfxUInt16Item>(SID_SVXSTDPARAGRAPHTABPAGE_PAGEWIDTH, false);
+ const SfxUInt32Item* pFlagSetItem = aSet.GetItem<SfxUInt32Item>(SID_SVXSTDPARAGRAPHTABPAGE_FLAGSET, false);
+ const SfxUInt32Item* pLineDistItem = aSet.GetItem<SfxUInt32Item>(SID_SVXSTDPARAGRAPHTABPAGE_ABSLINEDIST, false);
+
+ if (pPageWidthItem)
+ nWidth = pPageWidthItem->GetValue();
+
+ if (pFlagSetItem )
+ {
+ if (( 0x0001 & pFlagSetItem->GetValue())== 0x0001 )
+ EnableRelativeMode();
+
+ if (( 0x0002 & pFlagSetItem->GetValue())== 0x0002 )
+ EnableRegisterMode();
+
+ if ( ( 0x0004 & pFlagSetItem->GetValue())== 0x0004 )
+ EnableAutoFirstLine();
+ }
+
+ if(pLineDistItem)
+ EnableAbsLineDist(pLineDistItem->GetValue());
+
+ if (pFlagSetItem)
+ {
+ if (( 0x0008 & pFlagSetItem->GetValue()) == 0x0008 )
+ EnableNegativeMode();
+
+ if (( 0x0010 & pFlagSetItem->GetValue()) == 0x0010 )
+ EnableContextualMode();
+ }
+}
+
+#define LASTLINEPOS_DEFAULT 0
+#define LASTLINEPOS_LEFT 1
+
+#define LASTLINECOUNT_OLD 3
+#define LASTLINECOUNT_NEW 4
+
+SvxParaAlignTabPage::SvxParaAlignTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/paragalignpage.ui", "ParaAlignPage", &rSet)
+ , m_bSdrVertAlign(false)
+ , m_xLeft(m_xBuilder->weld_radio_button("radioBTN_LEFTALIGN"))
+ , m_xRight(m_xBuilder->weld_radio_button("radioBTN_RIGHTALIGN"))
+ , m_xCenter(m_xBuilder->weld_radio_button("radioBTN_CENTERALIGN"))
+ , m_xJustify(m_xBuilder->weld_radio_button("radioBTN_JUSTIFYALIGN"))
+ , m_xLeftBottom(m_xBuilder->weld_label("labelST_LEFTALIGN_ASIAN"))
+ , m_xRightTop(m_xBuilder->weld_label("labelST_RIGHTALIGN_ASIAN"))
+ , m_xLastLineFT(m_xBuilder->weld_label("labelLB_LASTLINE"))
+ , m_xLastLineLB(m_xBuilder->weld_combo_box("comboLB_LASTLINE"))
+ , m_xExpandCB(m_xBuilder->weld_check_button("checkCB_EXPAND"))
+ , m_xSnapToGridCB(m_xBuilder->weld_check_button("checkCB_SNAP"))
+ , m_xExampleWin(new weld::CustomWeld(*m_xBuilder, "drawingareaWN_EXAMPLE", m_aExampleWin))
+ , m_xVertAlignFL(m_xBuilder->weld_widget("frameFL_VERTALIGN"))
+ , m_xVertAlignLB(m_xBuilder->weld_combo_box("comboLB_VERTALIGN"))
+ , m_xVertAlign(m_xBuilder->weld_label("labelFL_VERTALIGN"))
+ , m_xVertAlignSdr(m_xBuilder->weld_label("labelST_VERTALIGN_SDR"))
+ , m_xTextDirectionLB(new svx::FrameDirectionListBox(m_xBuilder->weld_combo_box("comboLB_TEXTDIRECTION")))
+{
+ SetExchangeSupport();
+
+ sal_uInt16 nLastLinePos = LASTLINEPOS_DEFAULT;
+
+ if ( SvtCJKOptions::IsAsianTypographyEnabled() )
+ {
+ m_xLeft->set_label(m_xLeftBottom->get_label());
+ m_xRight->set_label(m_xRightTop->get_label());
+
+ OUString sLeft(m_xLeft->get_label());
+ sLeft = MnemonicGenerator::EraseAllMnemonicChars( sLeft );
+
+ if (m_xLastLineLB->get_count() == LASTLINECOUNT_OLD)
+ {
+ m_xLastLineLB->remove(0);
+ m_xLastLineLB->insert_text(0, sLeft);
+ }
+ else
+ nLastLinePos = LASTLINEPOS_LEFT;
+ }
+
+ // remove "Default" or "Left" entry, depends on CJKOptions
+ if (m_xLastLineLB->get_count() == LASTLINECOUNT_NEW)
+ m_xLastLineLB->remove(nLastLinePos);
+
+ Link<weld::Toggleable&, void> aLink = LINK( this, SvxParaAlignTabPage, AlignHdl_Impl );
+ m_xLeft->connect_toggled(aLink);
+ m_xRight->connect_toggled(aLink);
+ m_xCenter->connect_toggled(aLink);
+ m_xJustify->connect_toggled(aLink);
+ m_xLastLineLB->connect_changed(LINK(this, SvxParaAlignTabPage, LastLineHdl_Impl));
+ m_xTextDirectionLB->connect_changed(LINK(this, SvxParaAlignTabPage, TextDirectionHdl_Impl));
+
+ m_xTextDirectionLB->append(SvxFrameDirection::Environment, SvxResId(RID_SVXSTR_FRAMEDIR_SUPER));
+ m_xTextDirectionLB->append(SvxFrameDirection::Horizontal_LR_TB, SvxResId(RID_SVXSTR_FRAMEDIR_LTR));
+ m_xTextDirectionLB->append(SvxFrameDirection::Horizontal_RL_TB, SvxResId(RID_SVXSTR_FRAMEDIR_RTL));
+}
+
+SvxParaAlignTabPage::~SvxParaAlignTabPage()
+{
+}
+
+DeactivateRC SvxParaAlignTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if ( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+std::unique_ptr<SfxTabPage> SvxParaAlignTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxParaAlignTabPage>(pPage, pController, *rSet);
+}
+
+bool SvxParaAlignTabPage::FillItemSet( SfxItemSet* rOutSet )
+{
+ bool bModified = false;
+
+ bool bAdj = false;
+ SvxAdjust eAdjust = SvxAdjust::Left;
+
+ if (m_xLeft->get_active())
+ {
+ eAdjust = SvxAdjust::Left;
+ bAdj = m_xLeft->get_saved_state() == TRISTATE_FALSE;
+ }
+ else if (m_xRight->get_active())
+ {
+ eAdjust = SvxAdjust::Right;
+ bAdj = m_xRight->get_saved_state() == TRISTATE_FALSE;
+ }
+ else if (m_xCenter->get_active())
+ {
+ eAdjust = SvxAdjust::Center;
+ bAdj = m_xCenter->get_saved_state() == TRISTATE_FALSE;
+ }
+ else if (m_xJustify->get_active())
+ {
+ eAdjust = SvxAdjust::Block;
+ bAdj = m_xJustify->get_saved_state() == TRISTATE_FALSE ||
+ m_xExpandCB->get_state_changed_from_saved() ||
+ m_xLastLineLB->get_value_changed_from_saved();
+ }
+
+ sal_uInt16 _nWhich = GetWhich( SID_ATTR_PARA_ADJUST );
+
+ if (bAdj)
+ {
+ SvxAdjust eOneWord = m_xExpandCB->get_active() ? SvxAdjust::Block : SvxAdjust::Left;
+
+ int nLBPos = m_xLastLineLB->get_active();
+ SvxAdjust eLastBlock = SvxAdjust::Left;
+ if ( 1 == nLBPos )
+ eLastBlock = SvxAdjust::Center;
+ else if ( 2 == nLBPos )
+ eLastBlock = SvxAdjust::Block;
+
+ SvxAdjustItem aAdj( static_cast<const SvxAdjustItem&>(GetItemSet().Get( _nWhich )) );
+ aAdj.SetAdjust( eAdjust );
+ aAdj.SetOneWord( eOneWord );
+ aAdj.SetLastBlock( eLastBlock );
+ rOutSet->Put( aAdj );
+ bModified = true;
+ }
+
+ if (m_xSnapToGridCB->get_state_changed_from_saved())
+ {
+ rOutSet->Put(SvxParaGridItem(m_xSnapToGridCB->get_active(), GetWhich( SID_ATTR_PARA_SNAPTOGRID )));
+ bModified = true;
+ }
+
+ if (m_xVertAlignLB->get_value_changed_from_saved())
+ {
+ if (m_bSdrVertAlign)
+ rOutSet->Put(SdrTextVertAdjustItem(static_cast<SdrTextVertAdjust>(m_xVertAlignLB->get_active())));
+ else
+ rOutSet->Put(SvxParaVertAlignItem(static_cast<SvxParaVertAlignItem::Align>(m_xVertAlignLB->get_active()), GetWhich( SID_PARA_VERTALIGN )));
+ bModified = true;
+ }
+
+ if (m_xTextDirectionLB->get_visible())
+ {
+ if (m_xTextDirectionLB->get_value_changed_from_saved())
+ {
+ SvxFrameDirection eDir = m_xTextDirectionLB->get_active_id();
+ rOutSet->Put( SvxFrameDirectionItem( eDir, GetWhich( SID_ATTR_FRAMEDIRECTION ) ) );
+ bModified = true;
+ }
+ }
+
+ return bModified;
+}
+
+void SvxParaAlignTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ Reset( &rSet );
+}
+
+void SvxParaAlignTabPage::Reset( const SfxItemSet* rSet )
+{
+ sal_uInt16 _nWhich = GetWhich( SID_ATTR_PARA_ADJUST );
+ SfxItemState eItemState = rSet->GetItemState( _nWhich );
+
+ sal_Int32 nLBSelect = 0;
+ if ( eItemState >= SfxItemState::DEFAULT )
+ {
+ const SvxAdjustItem& rAdj = static_cast<const SvxAdjustItem&>(rSet->Get( _nWhich ));
+
+ switch ( rAdj.GetAdjust() /*!!! ask VB rAdj.GetLastBlock()*/ )
+ {
+ case SvxAdjust::Left: m_xLeft->set_active(true); break;
+
+ case SvxAdjust::Right: m_xRight->set_active(true); break;
+
+ case SvxAdjust::Center: m_xCenter->set_active(true); break;
+
+ case SvxAdjust::Block: m_xJustify->set_active(true); break;
+ default: ; //prevent warning
+ }
+ bool bEnable = m_xJustify->get_active();
+ m_xLastLineFT->set_sensitive(bEnable);
+ m_xLastLineLB->set_sensitive(bEnable);
+
+ switch(rAdj.GetLastBlock())
+ {
+ case SvxAdjust::Left: nLBSelect = 0; break;
+
+ case SvxAdjust::Center: nLBSelect = 1; break;
+
+ case SvxAdjust::Block: nLBSelect = 2; break;
+ default: ; //prevent warning
+ }
+ m_xExpandCB->set_sensitive(bEnable && nLBSelect == 2);
+ m_xExpandCB->set_active(SvxAdjust::Block == rAdj.GetOneWord());
+ }
+ else
+ {
+ m_xLeft->set_active(false);
+ m_xRight->set_active(false);
+ m_xCenter->set_active(false);
+ m_xJustify->set_active(false);
+ }
+ m_xLastLineLB->set_active(nLBSelect);
+
+ sal_uInt16 nHtmlMode = GetHtmlMode_Impl(*rSet);
+ if(nHtmlMode & HTMLMODE_ON)
+ {
+ m_xLastLineLB->hide();
+ m_xLastLineFT->hide();
+ m_xExpandCB->hide();
+ if(!(nHtmlMode & HTMLMODE_FULL_STYLES) )
+ m_xJustify->set_sensitive(false);
+ m_xSnapToGridCB->hide();
+ }
+ _nWhich = GetWhich(SID_ATTR_PARA_SNAPTOGRID);
+ eItemState = rSet->GetItemState( _nWhich );
+ if ( eItemState >= SfxItemState::DEFAULT )
+ {
+ const SvxParaGridItem& rSnap = static_cast<const SvxParaGridItem&>(rSet->Get( _nWhich ));
+ m_xSnapToGridCB->set_active(rSnap.GetValue());
+ }
+
+ _nWhich = m_bSdrVertAlign ? SDRATTR_TEXT_VERTADJUST : GetWhich( SID_PARA_VERTALIGN );
+ eItemState = rSet->GetItemState( _nWhich );
+
+ if ( eItemState >= SfxItemState::DEFAULT )
+ {
+ m_xVertAlignFL->show();
+
+ if (m_bSdrVertAlign)
+ {
+ const SdrTextVertAdjustItem& rAlign = static_cast<const SdrTextVertAdjustItem&>(rSet->Get( _nWhich ));
+ m_xVertAlignLB->set_active(rAlign.GetValue());
+ }
+ else
+ {
+ const SvxParaVertAlignItem& rAlign = static_cast<const SvxParaVertAlignItem&>(rSet->Get( _nWhich ));
+ m_xVertAlignLB->set_active(static_cast<sal_Int32>(rAlign.GetValue()));
+ }
+ }
+
+ _nWhich = GetWhich( SID_ATTR_FRAMEDIRECTION );
+ //text direction
+ if( SfxItemState::DEFAULT <= rSet->GetItemState( _nWhich ) )
+ {
+ const SvxFrameDirectionItem& rFrameDirItem = static_cast<const SvxFrameDirectionItem&>( rSet->Get( _nWhich ) );
+ m_xTextDirectionLB->set_active_id(rFrameDirItem.GetValue());
+ m_xTextDirectionLB->save_value();
+ }
+
+ m_xSnapToGridCB->save_state();
+ m_xVertAlignLB->save_value();
+ m_xLeft->save_state();
+ m_xRight->save_state();
+ m_xCenter->save_state();
+ m_xJustify->save_state();
+ m_xLastLineLB->save_value();
+ m_xExpandCB->save_state();
+
+ UpdateExample_Impl();
+}
+
+void SvxParaAlignTabPage::ChangesApplied()
+{
+ m_xTextDirectionLB->save_value();
+ m_xSnapToGridCB->save_state();
+ m_xVertAlignLB->save_value();
+ m_xLeft->save_state();
+ m_xRight->save_state();
+ m_xCenter->save_state();
+ m_xJustify->save_state();
+ m_xLastLineLB->save_value();
+ m_xExpandCB->save_state();
+}
+
+IMPL_LINK_NOARG(SvxParaAlignTabPage, AlignHdl_Impl, weld::Toggleable&, void)
+{
+ bool bJustify = m_xJustify->get_active();
+ m_xLastLineFT->set_sensitive(bJustify);
+ m_xLastLineLB->set_sensitive(bJustify);
+ bool bLastLineIsBlock = m_xLastLineLB->get_active() == 2;
+ m_xExpandCB->set_sensitive(bJustify && bLastLineIsBlock);
+ //set last line listbox to entry position 0 if not enabled
+ if (!m_xLastLineLB->get_sensitive())
+ m_xLastLineLB->set_active(0);
+ //uncheck 'Expand ... word' when check box is not enabled
+ if (!m_xExpandCB->get_sensitive())
+ m_xExpandCB->set_active(false);
+ UpdateExample_Impl();
+}
+
+IMPL_LINK_NOARG(SvxParaAlignTabPage, LastLineHdl_Impl, weld::ComboBox&, void)
+{
+ //fdo#41350 only enable 'Expand last word' if last line is also justified
+ bool bLastLineIsBlock = m_xLastLineLB->get_active() == 2;
+ m_xExpandCB->set_sensitive(bLastLineIsBlock);
+ //uncheck 'Expand ... word' when check box is not enabled
+ if (!m_xExpandCB->get_sensitive())
+ m_xExpandCB->set_active(false);
+ UpdateExample_Impl();
+}
+
+IMPL_LINK_NOARG(SvxParaAlignTabPage, TextDirectionHdl_Impl, weld::ComboBox&, void)
+{
+ UpdateExample_Impl();
+}
+
+void SvxParaAlignTabPage::UpdateExample_Impl()
+{
+ if (m_xLeft->get_active())
+ {
+ m_aExampleWin.EnableRTL(false);
+ m_aExampleWin.SetAdjust(SvxAdjust::Left);
+ m_aExampleWin.SetLastLine(SvxAdjust::Left);
+ }
+ else if (m_xRight->get_active())
+ {
+ m_aExampleWin.EnableRTL(true);
+ m_aExampleWin.SetAdjust(SvxAdjust::Left);
+ m_aExampleWin.SetLastLine(SvxAdjust::Left);
+ }
+ else
+ {
+ SvxFrameDirection eDir = m_xTextDirectionLB->get_active_id();
+ switch ( eDir )
+ {
+ case SvxFrameDirection::Environment :
+ if ( !m_xRight->get_active() )
+ m_aExampleWin.EnableRTL( AllSettings::GetLayoutRTL() );
+ break;
+ case SvxFrameDirection::Horizontal_RL_TB :
+ if ( !m_xLeft->get_active() )
+ m_aExampleWin.EnableRTL( true );
+ break;
+ case SvxFrameDirection::Horizontal_LR_TB :
+ if ( !m_xRight->get_active() )
+ m_aExampleWin.EnableRTL( false );
+ break;
+ default: ; //prevent warning
+ }
+ if (m_xCenter->get_active())
+ m_aExampleWin.SetAdjust( SvxAdjust::Center );
+ else if (m_xJustify->get_active())
+ {
+ m_aExampleWin.SetAdjust( SvxAdjust::Block );
+ int nLBPos = m_xLastLineLB->get_active();
+ if (nLBPos == 0)
+ m_aExampleWin.SetLastLine(SvxAdjust::Left);
+ else if (nLBPos == 1)
+ m_aExampleWin.SetLastLine(SvxAdjust::Center);
+ else if (nLBPos == 2)
+ m_aExampleWin.SetLastLine(SvxAdjust::Block);
+ }
+ }
+
+ m_aExampleWin.Invalidate();
+}
+
+void SvxParaAlignTabPage::EnableJustifyExt()
+{
+ m_xLastLineFT->show();
+ m_xLastLineLB->show();
+ m_xExpandCB->show();
+ if (SvtCJKOptions::IsAsianTypographyEnabled())
+ m_xSnapToGridCB->show();
+
+}
+
+void SvxParaAlignTabPage::EnableSdrVertAlign()
+{
+ m_bSdrVertAlign = true;
+
+ m_xVertAlignLB->remove_id("0");
+ m_xVertAlignLB->remove_id("1");
+ m_xVertAlign->set_label(m_xVertAlignSdr->get_label());
+}
+
+void SvxParaAlignTabPage::PageCreated (const SfxAllItemSet& aSet)
+{
+ const SfxBoolItem* pBoolItem = aSet.GetItem<SfxBoolItem>(SID_SVXPARAALIGNTABPAGE_ENABLEJUSTIFYEXT, false);
+ if (pBoolItem && pBoolItem->GetValue())
+ EnableJustifyExt();
+}
+
+std::unique_ptr<SfxTabPage> SvxExtParagraphTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxExtParagraphTabPage>(pPage, pController, *rSet);
+}
+
+bool SvxExtParagraphTabPage::FillItemSet( SfxItemSet* rOutSet )
+{
+ bool bModified = false;
+ sal_uInt16 _nWhich = GetWhich( SID_ATTR_PARA_HYPHENZONE );
+ const TriState eHyphenState = m_xHyphenBox->get_state();
+ const SfxPoolItem* pOld = GetOldItem( *rOutSet, SID_ATTR_PARA_HYPHENZONE );
+
+ if ( m_xHyphenBox->get_state_changed_from_saved() ||
+ m_xHyphenNoCapsBox->get_state_changed_from_saved() ||
+ m_xHyphenNoLastWordBox->get_state_changed_from_saved() ||
+ m_xExtHyphenBeforeBox->get_value_changed_from_saved() ||
+ m_xExtHyphenAfterBox->get_value_changed_from_saved() ||
+ m_xMaxHyphenEdit->get_value_changed_from_saved() ||
+ m_xMinWordLength->get_value_changed_from_saved() ||
+ m_aHyphenZone.get_value_changed_from_saved() )
+ {
+ SvxHyphenZoneItem aHyphen(
+ static_cast<const SvxHyphenZoneItem&>(GetItemSet().Get( _nWhich )) );
+ aHyphen.SetHyphen( eHyphenState == TRISTATE_TRUE );
+ aHyphen.SetNoCapsHyphenation(m_xHyphenNoCapsBox->get_state() == TRISTATE_TRUE);
+ aHyphen.SetNoLastWordHyphenation(m_xHyphenNoLastWordBox->get_state() == TRISTATE_TRUE);
+
+ if ( eHyphenState == TRISTATE_TRUE )
+ {
+ aHyphen.GetMinLead() = static_cast<sal_uInt8>(m_xExtHyphenBeforeBox->get_value());
+ aHyphen.GetMinTrail() = static_cast<sal_uInt8>(m_xExtHyphenAfterBox->get_value());
+ aHyphen.GetMinWordLength() = static_cast<sal_uInt8>(m_xMinWordLength->get_value());
+ }
+ aHyphen.GetMaxHyphens() = static_cast<sal_uInt8>(m_xMaxHyphenEdit->get_value());
+
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ MapUnit eUnit = pPool->GetMetric( _nWhich );
+ aHyphen.GetTextHyphenZone() = static_cast<sal_uInt16>(m_aHyphenZone.GetCoreValue(eUnit));
+
+ if ( !pOld ||
+ *static_cast<const SvxHyphenZoneItem*>(pOld) != aHyphen ||
+ m_xHyphenBox->get_state_changed_from_saved())
+ {
+ rOutSet->Put( aHyphen );
+ bModified = true;
+ }
+ }
+
+ if (m_xPageNumBox->get_sensitive()
+ && (m_xPageNumBox->get_state_changed_from_saved() || m_xPagenumEdit->get_value_changed_from_saved()))
+ {
+ pOld = GetOldItem( *rOutSet, SID_ATTR_PARA_PAGENUM );
+
+ if (TRISTATE_TRUE == m_xPageNumBox->get_state()
+ && (!pOld || IsInvalidItem(pOld)
+ || static_cast<const SfxUInt16Item*>(pOld)->GetValue() != m_xPagenumEdit->get_value()))
+ {
+ SfxUInt16Item aPageNum(SID_ATTR_PARA_PAGENUM,
+ static_cast<sal_uInt16>(m_xPagenumEdit->get_value()));
+ rOutSet->Put( aPageNum );
+ bModified = true;
+ }
+ else if (TRISTATE_FALSE == m_xPageNumBox->get_state()
+ && (pOld || IsInvalidItem(pOld)))
+ {
+ // need to tell sw to remove the item
+ rOutSet->DisableItem(SID_ATTR_PARA_PAGENUM);
+ bModified = true;
+ }
+ }
+
+ // pagebreak
+
+ TriState eState = m_xApplyCollBtn->get_state();
+ bool bIsPageModel = false;
+
+ OUString sPage;
+ if ( m_xApplyCollBtn->get_state_changed_from_saved() ||
+ ( TRISTATE_TRUE == eState &&
+ m_xApplyCollBox->get_value_changed_from_saved() ) )
+ {
+ if ( eState == TRISTATE_TRUE )
+ {
+ sPage = m_xApplyCollBox->get_active_text();
+ bIsPageModel = !sPage.isEmpty();
+ }
+ pOld = GetOldItem( *rOutSet, SID_ATTR_PARA_MODEL );
+
+ if ( !pOld || static_cast<const SvxPageModelItem*>(pOld)->GetValue() != sPage )
+ {
+ rOutSet->Put( SvxPageModelItem( sPage, false, SID_ATTR_PARA_MODEL ) );
+ bModified = true;
+ }
+ else
+ bIsPageModel = false;
+ }
+ else if(TRISTATE_TRUE == eState && m_xApplyCollBtn->get_sensitive())
+ bIsPageModel = true;
+ else
+ rOutSet->Put( SvxPageModelItem( sPage, false, SID_ATTR_PARA_MODEL ) );
+
+ _nWhich = GetWhich( SID_ATTR_PARA_PAGEBREAK );
+
+ if ( bIsPageModel )
+ // if PageModel is turned on, always turn off PageBreak
+ rOutSet->Put( SvxFormatBreakItem( SvxBreak::NONE, _nWhich ) );
+ else
+ {
+ eState = m_xPageBreakBox->get_state();
+ SfxItemState eModelState = GetItemSet().GetItemState(SID_ATTR_PARA_MODEL, false);
+
+ if ( (eModelState == SfxItemState::SET && TRISTATE_TRUE == m_xPageBreakBox->get_state()) ||
+ m_xPageBreakBox->get_state_changed_from_saved() ||
+ m_xBreakTypeLB->get_value_changed_from_saved() ||
+ m_xBreakPositionLB->get_value_changed_from_saved() )
+ {
+ const SvxFormatBreakItem rOldBreak(
+ static_cast<const SvxFormatBreakItem&>(GetItemSet().Get( _nWhich )));
+ SvxFormatBreakItem aBreak(rOldBreak.GetBreak(), rOldBreak.Which());
+
+ switch ( eState )
+ {
+ case TRISTATE_TRUE:
+ {
+ bool bBefore = m_xBreakPositionLB->get_active() == 0;
+
+ if (m_xBreakTypeLB->get_active() == 0)
+ {
+ if ( bBefore )
+ aBreak.SetValue( SvxBreak::PageBefore );
+ else
+ aBreak.SetValue( SvxBreak::PageAfter );
+ }
+ else
+ {
+ if ( bBefore )
+ aBreak.SetValue( SvxBreak::ColumnBefore );
+ else
+ aBreak.SetValue( SvxBreak::ColumnAfter );
+ }
+ break;
+ }
+
+ case TRISTATE_FALSE:
+ aBreak.SetValue( SvxBreak::NONE );
+ break;
+ default: ; //prevent warning
+ }
+ pOld = GetOldItem( *rOutSet, SID_ATTR_PARA_PAGEBREAK );
+
+ if ( eState != m_xPageBreakBox->get_saved_state() ||
+ !pOld || !( *static_cast<const SvxFormatBreakItem*>(pOld) == aBreak ) )
+ {
+ bModified = true;
+ rOutSet->Put( aBreak );
+ }
+ }
+ }
+
+ // paragraph split
+ _nWhich = GetWhich( SID_ATTR_PARA_SPLIT );
+ eState = m_xAllowSplitBox->get_state();
+
+ if (m_xAllowSplitBox->get_state_changed_from_saved())
+ {
+ pOld = GetOldItem( *rOutSet, SID_ATTR_PARA_SPLIT );
+
+ if ( !pOld || static_cast<const SvxFormatSplitItem*>(pOld)->GetValue() !=
+ ( eState == TRISTATE_FALSE ) )
+ {
+ rOutSet->Put( SvxFormatSplitItem( eState == TRISTATE_FALSE, _nWhich ) );
+ bModified = true;
+ }
+ }
+
+ // keep paragraphs
+ _nWhich = GetWhich( SID_ATTR_PARA_KEEP );
+ eState = m_xKeepParaBox->get_state();
+
+ if (m_xKeepParaBox->get_state_changed_from_saved())
+ {
+ // if the status has changed, putting is necessary
+ rOutSet->Put( SvxFormatKeepItem( eState == TRISTATE_TRUE, _nWhich ) );
+ bModified = true;
+ }
+
+ // widows and orphans
+ TypedWhichId<SvxWidowsItem> nWidowsWhich = GetWhich( SID_ATTR_PARA_WIDOWS );
+ eState = m_xWidowBox->get_state();
+
+ if ( m_xWidowBox->get_state_changed_from_saved() ||
+ m_xWidowRowNo->get_value_changed_from_saved() )
+ {
+ SvxWidowsItem rItem( eState == TRISTATE_TRUE ?
+ static_cast<sal_uInt8>(m_xWidowRowNo->get_value()) : 0, nWidowsWhich );
+ pOld = GetOldItem( *rOutSet, SID_ATTR_PARA_WIDOWS );
+
+ if ( m_xWidowBox->get_state_changed_from_saved() || !pOld || !( *static_cast<const SvxWidowsItem*>(pOld) == rItem ) )
+ {
+ rOutSet->Put( rItem );
+ bModified = true;
+ }
+ }
+
+ TypedWhichId<SvxOrphansItem> nOrphansWhich = GetWhich( SID_ATTR_PARA_ORPHANS );
+ eState = m_xOrphanBox->get_state();
+
+ if ( m_xOrphanBox->get_state_changed_from_saved() ||
+ m_xOrphanRowNo->get_value_changed_from_saved() )
+ {
+ SvxOrphansItem rItem( eState == TRISTATE_TRUE ?
+ static_cast<sal_uInt8>(m_xOrphanRowNo->get_value()) : 0, nOrphansWhich );
+ pOld = GetOldItem( *rOutSet, SID_ATTR_PARA_ORPHANS );
+
+ if ( m_xOrphanBox->get_state_changed_from_saved() ||
+ !pOld ||
+ !( *static_cast<const SvxOrphansItem*>(pOld) == rItem ) )
+ {
+ rOutSet->Put( rItem );
+ bModified = true;
+ }
+ }
+
+ return bModified;
+}
+void SvxExtParagraphTabPage::Reset( const SfxItemSet* rSet )
+{
+ SfxItemPool* pPool = rSet->GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+
+ // adjust metric
+ FieldUnit eFUnit = GetModuleFieldUnit( *rSet );
+ if (UseCharUnitInUI(*rSet))
+ eFUnit = FieldUnit::CHAR;
+
+ sal_uInt16 _nWhich = GetWhich( SID_ATTR_PARA_HYPHENZONE );
+ SfxItemState eItemState = rSet->GetItemState( _nWhich );
+
+ bool bItemAvailable = eItemState >= SfxItemState::DEFAULT;
+ bool bIsHyphen = false;
+ if( !bHtmlMode && bItemAvailable )
+ {
+ const SvxHyphenZoneItem& rHyphen =
+ static_cast<const SvxHyphenZoneItem&>(rSet->Get( _nWhich ));
+ aHyphenState.bTriStateEnabled = false;
+
+ bIsHyphen = rHyphen.IsHyphen();
+ m_xHyphenBox->set_state(bIsHyphen ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xHyphenNoCapsBox->set_state(rHyphen.IsNoCapsHyphenation() ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xHyphenNoLastWordBox->set_state(rHyphen.IsNoLastWordHyphenation() ? TRISTATE_TRUE : TRISTATE_FALSE);
+
+ m_xExtHyphenBeforeBox->set_value(rHyphen.GetMinLead());
+ m_xExtHyphenAfterBox->set_value(rHyphen.GetMinTrail());
+ m_xMaxHyphenEdit->set_value(rHyphen.GetMaxHyphens());
+ m_xMinWordLength->set_value(rHyphen.GetMinWordLength());
+ m_aHyphenZone.SetFieldUnit(eFUnit);
+ m_aHyphenZone.SetMetricValue(rHyphen.GetTextHyphenZone(), MapUnit::MapTwip);
+ }
+ else
+ {
+ m_xHyphenBox->set_state(TRISTATE_INDET);
+ m_xHyphenNoCapsBox->set_state(TRISTATE_INDET);
+ m_xHyphenNoLastWordBox->set_state(TRISTATE_INDET);
+ }
+ bool bEnable = bItemAvailable && bIsHyphen;
+ m_xHyphenNoCapsBox->set_sensitive(bEnable);
+ m_xHyphenNoLastWordBox->set_sensitive(bEnable);
+ m_xExtHyphenBeforeBox->set_sensitive(bEnable);
+ m_xExtHyphenAfterBox->set_sensitive(bEnable);
+ m_xBeforeText->set_sensitive(bEnable);
+ m_xAfterText->set_sensitive(bEnable);
+ m_xMaxHyphenLabel->set_sensitive(bEnable);
+ m_xMaxHyphenEdit->set_sensitive(bEnable);
+ m_xMinWordLabel->set_sensitive(bEnable);
+ m_xMinWordLength->set_sensitive(bEnable);
+ m_xHyphenZoneLabel->set_sensitive(bEnable);
+ m_aHyphenZone.set_sensitive(bEnable);
+
+ switch (rSet->GetItemState(SID_ATTR_PARA_PAGENUM))
+ {
+ case SfxItemState::SET:
+ {
+ aPageNumState.bTriStateEnabled = false;
+ m_xPageNumBox->set_state(TRISTATE_TRUE);
+ SfxUInt16Item const*const pItem(rSet->GetItem<SfxUInt16Item>(SID_ATTR_PARA_PAGENUM));
+ const sal_uInt16 nPageNum(pItem->GetValue());
+ m_xPagenumEdit->set_value(nPageNum);
+ break;
+ }
+ case SfxItemState::DONTCARE:
+ {
+ aPageNumState.bTriStateEnabled = true;
+ m_xPageNumBox->set_state(TRISTATE_INDET);
+ break;
+ }
+ case SfxItemState::UNKNOWN:
+ case SfxItemState::DEFAULT:
+ case SfxItemState::DISABLED:
+ {
+ aPageNumState.bTriStateEnabled = false;
+ m_xPageNumBox->set_state(TRISTATE_FALSE);
+ break;
+ }
+ default:
+ assert(false); // unexpected
+ break;
+ }
+
+ if ( bPageBreak )
+ {
+ // first handle PageModel
+ bool bIsPageModel = false;
+ eItemState = rSet->GetItemState( SID_ATTR_PARA_MODEL );
+
+ if ( eItemState >= SfxItemState::SET )
+ {
+ aApplyCollState.bTriStateEnabled = false;
+
+ const SvxPageModelItem& rModel = rSet->Get( SID_ATTR_PARA_MODEL );
+ const OUString& aStr( rModel.GetValue() );
+
+ if (!aStr.isEmpty() && m_xApplyCollBox->find_text(aStr) != -1)
+ {
+ m_xApplyCollBox->set_active_text(aStr);
+ m_xApplyCollBtn->set_state(TRISTATE_TRUE);
+ bIsPageModel = true;
+
+ m_xPageBreakBox->set_sensitive(true);
+ aPageBreakState.bTriStateEnabled = false;
+ m_xBreakTypeFT->set_sensitive(true);
+ m_xBreakTypeLB->set_sensitive(true);
+ m_xBreakPositionFT->set_sensitive(true);
+ m_xBreakPositionLB->set_sensitive(true);
+ m_xApplyCollBtn->set_sensitive(false);
+ m_xPageBreakBox->set_state(TRISTATE_TRUE);
+
+ //select page break
+ m_xBreakTypeLB->set_active(0);
+ //select break before
+ m_xBreakPositionLB->set_active(0);
+ }
+ else
+ {
+ m_xApplyCollBox->set_active(-1);
+ m_xApplyCollBtn->set_state(TRISTATE_FALSE);
+ }
+ }
+ else if ( SfxItemState::DONTCARE == eItemState )
+ {
+ aApplyCollState.bTriStateEnabled = true;
+ m_xApplyCollBtn->set_state(TRISTATE_INDET);
+ m_xApplyCollBox->set_active(-1);
+ }
+ else
+ {
+ m_xApplyCollBtn->set_sensitive(false);
+ m_xApplyCollBox->set_sensitive(false);
+ m_xPagenumEdit->set_sensitive(false);
+ m_xPageNumBox->set_sensitive(false);
+ }
+
+ if ( !bIsPageModel )
+ {
+ _nWhich = GetWhich( SID_ATTR_PARA_PAGEBREAK );
+ eItemState = rSet->GetItemState( _nWhich );
+
+ if ( eItemState >= SfxItemState::DEFAULT )
+ {
+ const SvxFormatBreakItem& rPageBreak =
+ static_cast<const SvxFormatBreakItem&>(rSet->Get( _nWhich ));
+
+ SvxBreak eBreak = rPageBreak.GetBreak();
+
+ // PageBreak not via CTRL-RETURN,
+ // then CheckBox can be freed
+ m_xPageBreakBox->set_sensitive(true);
+ aPageBreakState.bTriStateEnabled = false;
+ m_xBreakTypeFT->set_sensitive(true);
+ m_xBreakTypeLB->set_sensitive(true);
+ m_xBreakPositionFT->set_sensitive(true);
+ m_xBreakPositionLB->set_sensitive(true);
+
+ m_xPageBreakBox->set_state(TRISTATE_TRUE);
+
+ bool _bEnable = eBreak != SvxBreak::NONE &&
+ eBreak != SvxBreak::ColumnBefore &&
+ eBreak != SvxBreak::ColumnAfter;
+ m_xApplyCollBtn->set_sensitive(_bEnable);
+ if (!_bEnable)
+ {
+ m_xApplyCollBox->set_sensitive(_bEnable);
+ m_xPageNumBox->set_sensitive(false);
+ m_xPagenumEdit->set_sensitive(_bEnable);
+ }
+
+ if ( eBreak == SvxBreak::NONE )
+ m_xPageBreakBox->set_state(TRISTATE_FALSE);
+
+ sal_Int32 nType = 0; // selection position in break type ListBox : Page
+ sal_Int32 nPosition = 0; // selection position in break position ListBox : Before
+ switch ( eBreak )
+ {
+ case SvxBreak::PageBefore:
+ break;
+ case SvxBreak::PageAfter:
+ nPosition = 1;
+ break;
+ case SvxBreak::ColumnBefore:
+ nType = 1;
+ break;
+ case SvxBreak::ColumnAfter:
+ nType = 1;
+ nPosition = 1;
+ break;
+ default: ;//prevent warning
+ }
+ m_xBreakTypeLB->set_active(nType);
+ m_xBreakPositionLB->set_active(nPosition);
+ }
+ else if ( SfxItemState::DONTCARE == eItemState )
+ m_xPageBreakBox->set_state(TRISTATE_INDET);
+ else
+ {
+ m_xPageBreakBox->set_sensitive(false);
+ m_xBreakTypeFT->set_sensitive(false);
+ m_xBreakTypeLB->set_sensitive(false);
+ m_xBreakPositionFT->set_sensitive(false);
+ m_xBreakPositionLB->set_sensitive(false);
+ }
+ }
+
+ PageBreakPosHdl_Impl(*m_xBreakPositionLB);
+ PageBreakHdl();
+ }
+
+ _nWhich = GetWhich( SID_ATTR_PARA_KEEP );
+ eItemState = rSet->GetItemState( _nWhich );
+
+ if ( eItemState >= SfxItemState::DEFAULT )
+ {
+ aKeepParaState.bTriStateEnabled = false;
+ const SvxFormatKeepItem& rKeep =
+ static_cast<const SvxFormatKeepItem&>(rSet->Get( _nWhich ));
+
+ if ( rKeep.GetValue() )
+ m_xKeepParaBox->set_state(TRISTATE_TRUE);
+ else
+ m_xKeepParaBox->set_state(TRISTATE_FALSE);
+ }
+ else if ( SfxItemState::DONTCARE == eItemState )
+ m_xKeepParaBox->set_state(TRISTATE_INDET);
+ else
+ m_xKeepParaBox->set_sensitive(false);
+
+ _nWhich = GetWhich( SID_ATTR_PARA_SPLIT );
+ eItemState = rSet->GetItemState( _nWhich );
+
+ if ( eItemState >= SfxItemState::DEFAULT )
+ {
+ const SvxFormatSplitItem& rSplit =
+ static_cast<const SvxFormatSplitItem&>(rSet->Get( _nWhich ));
+ aAllowSplitState.bTriStateEnabled = false;
+
+ if ( !rSplit.GetValue() )
+ m_xAllowSplitBox->set_state(TRISTATE_FALSE);
+ else
+ {
+ m_xAllowSplitBox->set_state(TRISTATE_TRUE);
+ // default widows and orphans to enabled
+ m_xWidowBox->set_sensitive(true);
+ m_xOrphanBox->set_sensitive(true);
+ }
+
+ // widows and orphans
+ _nWhich = GetWhich( SID_ATTR_PARA_WIDOWS );
+ SfxItemState eTmpState = rSet->GetItemState( _nWhich );
+
+ if ( eTmpState >= SfxItemState::DEFAULT )
+ {
+ const SvxWidowsItem& rWidow =
+ static_cast<const SvxWidowsItem&>(rSet->Get( _nWhich ));
+ aWidowState.bTriStateEnabled = false;
+ const sal_uInt16 nLines = rWidow.GetValue();
+
+ bool _bEnable = nLines > 0;
+ m_xWidowRowNo->set_value(m_xWidowRowNo->normalize(nLines));
+ m_xWidowBox->set_state(_bEnable ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xWidowRowNo->set_sensitive(_bEnable);
+ }
+ else if ( SfxItemState::DONTCARE == eTmpState )
+ m_xWidowBox->set_state( TRISTATE_INDET );
+ else
+ m_xWidowBox->set_sensitive(false);
+
+ _nWhich = GetWhich( SID_ATTR_PARA_ORPHANS );
+ eTmpState = rSet->GetItemState( _nWhich );
+
+ if ( eTmpState >= SfxItemState::DEFAULT )
+ {
+ const SvxOrphansItem& rOrphan =
+ static_cast<const SvxOrphansItem&>(rSet->Get( _nWhich ));
+ const sal_uInt16 nLines = rOrphan.GetValue();
+ aOrphanState.bTriStateEnabled = false;
+
+ bool _bEnable = nLines > 0;
+ m_xOrphanBox->set_state(_bEnable ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xOrphanRowNo->set_value(m_xOrphanRowNo->normalize(nLines));
+ m_xOrphanRowNo->set_sensitive(_bEnable);
+ m_xOrphanRowLabel->set_sensitive(_bEnable);
+
+ }
+ else if ( SfxItemState::DONTCARE == eTmpState )
+ m_xOrphanBox->set_state(TRISTATE_INDET);
+ else
+ m_xOrphanBox->set_sensitive(false);
+ aOrphanState.eState = m_xOrphanBox->get_state();
+ }
+ else if ( SfxItemState::DONTCARE == eItemState )
+ m_xAllowSplitBox->set_state(TRISTATE_INDET);
+ else
+ m_xAllowSplitBox->set_sensitive(false);
+
+ // so that everything is enabled correctly
+ AllowSplitHdl();
+ WidowHdl();
+ OrphanHdl();
+ ChangesApplied();
+}
+void SvxExtParagraphTabPage::ChangesApplied()
+{
+ m_xHyphenBox->save_state();
+ m_xHyphenNoCapsBox->save_state();
+ m_xHyphenNoLastWordBox->save_state();
+ m_xExtHyphenBeforeBox->save_value();
+ m_xExtHyphenAfterBox->save_value();
+ m_xMaxHyphenEdit->save_value();
+ m_xMinWordLength->save_value();
+ m_aHyphenZone.save_value();
+ m_xPageBreakBox->save_state();
+ m_xBreakPositionLB->save_value();
+ m_xBreakTypeLB->save_value();
+ m_xApplyCollBtn->save_state();
+ m_xApplyCollBox->save_value();
+ m_xPageNumBox->save_state();
+ m_xPagenumEdit->save_value();
+ m_xAllowSplitBox->save_state();
+ m_xKeepParaBox->save_state();
+ m_xWidowBox->save_state();
+ m_xOrphanBox->save_state();
+ m_xOrphanRowNo->save_value();
+ m_xWidowRowNo->save_value();
+}
+
+DeactivateRC SvxExtParagraphTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if ( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+void SvxExtParagraphTabPage::DisablePageBreak()
+{
+ bPageBreak = false;
+ m_xPageBreakBox->set_sensitive(false);
+ m_xBreakTypeLB->remove(0);
+ m_xBreakPositionFT->set_sensitive(false);
+ m_xBreakPositionLB->set_sensitive(false);
+ m_xApplyCollBtn->set_sensitive(false);
+ m_xApplyCollBox->set_sensitive(false);
+ m_xPageNumBox->set_sensitive(false);
+ m_xPagenumEdit->set_sensitive(false);
+}
+
+SvxExtParagraphTabPage::SvxExtParagraphTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttr)
+ : SfxTabPage(pPage, pController, "cui/ui/textflowpage.ui", "TextFlowPage", &rAttr)
+ , bPageBreak(true)
+ , bHtmlMode(false)
+ , nStdPos(0)
+ // Hyphenation
+ , m_xHyphenBox(m_xBuilder->weld_check_button("checkAuto"))
+ , m_xHyphenNoCapsBox(m_xBuilder->weld_check_button("checkNoCaps"))
+ , m_xHyphenNoLastWordBox(m_xBuilder->weld_check_button("checkNoLastWord"))
+ , m_xBeforeText(m_xBuilder->weld_label("labelLineBegin"))
+ , m_xExtHyphenBeforeBox(m_xBuilder->weld_spin_button("spinLineEnd"))
+ , m_xAfterText(m_xBuilder->weld_label("labelLineEnd"))
+ , m_xExtHyphenAfterBox(m_xBuilder->weld_spin_button("spinLineBegin"))
+ , m_xMaxHyphenLabel(m_xBuilder->weld_label("labelMaxNum"))
+ , m_xMaxHyphenEdit(m_xBuilder->weld_spin_button("spinMaxNum"))
+ , m_xMinWordLabel(m_xBuilder->weld_label("labelMinLen"))
+ , m_xMinWordLength(m_xBuilder->weld_spin_button("spinMinLen"))
+ , m_xHyphenZoneLabel(m_xBuilder->weld_label("labelHyphenZone"))
+ , m_aHyphenZone(m_xBuilder->weld_metric_spin_button("spinHyphenZone", FieldUnit::CM))
+ //Page break
+ , m_xPageBreakBox(m_xBuilder->weld_check_button("checkInsert"))
+ , m_xBreakTypeFT(m_xBuilder->weld_label("labelType"))
+ , m_xBreakTypeLB(m_xBuilder->weld_combo_box("comboBreakType"))
+ , m_xBreakPositionFT(m_xBuilder->weld_label("labelPosition"))
+ , m_xBreakPositionLB(m_xBuilder->weld_combo_box("comboBreakPosition"))
+ , m_xApplyCollBtn(m_xBuilder->weld_check_button("checkPageStyle"))
+ , m_xApplyCollBox(m_xBuilder->weld_combo_box("comboPageStyle"))
+ , m_xPageNumBox(m_xBuilder->weld_check_button("labelPageNum"))
+ , m_xPagenumEdit(m_xBuilder->weld_spin_button("spinPageNumber"))
+ // Options
+ , m_xAllowSplitBox(m_xBuilder->weld_check_button("checkSplitPara"))
+ , m_xKeepParaBox(m_xBuilder->weld_check_button("checkKeepPara"))
+ , m_xOrphanBox(m_xBuilder->weld_check_button("checkOrphan"))
+ , m_xOrphanRowNo(m_xBuilder->weld_spin_button("spinOrphan"))
+ , m_xOrphanRowLabel(m_xBuilder->weld_label("labelOrphan"))
+ , m_xWidowBox(m_xBuilder->weld_check_button("checkWidow"))
+ , m_xWidowRowNo(m_xBuilder->weld_spin_button("spinWidow"))
+ , m_xWidowRowLabel(m_xBuilder->weld_label("labelWidow"))
+{
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ m_xHyphenBox->connect_toggled(LINK(this, SvxExtParagraphTabPage, HyphenClickHdl_Impl));
+ m_xPageBreakBox->connect_toggled(LINK(this, SvxExtParagraphTabPage, PageBreakHdl_Impl));
+ m_xAllowSplitBox->connect_toggled(LINK(this, SvxExtParagraphTabPage, AllowSplitHdl_Impl));
+ m_xWidowBox->connect_toggled(LINK(this, SvxExtParagraphTabPage, WidowHdl_Impl));
+ m_xOrphanBox->connect_toggled(LINK(this, SvxExtParagraphTabPage, OrphanHdl_Impl));
+ m_xApplyCollBtn->connect_toggled(LINK(this, SvxExtParagraphTabPage, ApplyCollClickHdl_Impl));
+ m_xBreakTypeLB->connect_changed(LINK(this, SvxExtParagraphTabPage, PageBreakTypeHdl_Impl));
+ m_xBreakPositionLB->connect_changed(LINK(this, SvxExtParagraphTabPage, PageBreakPosHdl_Impl));
+ m_xPageNumBox->connect_toggled(LINK(this, SvxExtParagraphTabPage, PageNumBoxClickHdl_Impl));
+ m_xKeepParaBox->connect_toggled(LINK(this, SvxExtParagraphTabPage, KeepParaBoxClickHdl_Impl));
+
+ if (SfxObjectShell* pSh = SfxObjectShell::Current())
+ {
+ SfxStyleSheetBasePool* pPool = pSh->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyle = pPool->First(SfxStyleFamily::Page);
+ OUString aStdName;
+
+ // tdf139131 - sort page styles
+ m_xApplyCollBox->make_sorted();
+ while( pStyle )
+ {
+ if ( aStdName.isEmpty() )
+ // first style == standard style
+ aStdName = pStyle->GetName();
+ m_xApplyCollBox->append_text(pStyle->GetName());
+ pStyle = pPool->Next();
+ }
+ nStdPos = m_xApplyCollBox->find_text(aStdName);
+ }
+
+ sal_uInt16 nHtmlMode = GetHtmlMode_Impl( rAttr );
+ if ( !(nHtmlMode & HTMLMODE_ON) )
+ return;
+
+ bHtmlMode = true;
+ m_xHyphenBox->set_sensitive(false);
+ m_xHyphenNoCapsBox->set_sensitive(false);
+ m_xHyphenNoLastWordBox->set_sensitive(false);
+ m_xBeforeText->set_sensitive(false);
+ m_xExtHyphenBeforeBox->set_sensitive(false);
+ m_xAfterText->set_sensitive(false);
+ m_xExtHyphenAfterBox->set_sensitive(false);
+ m_xMaxHyphenLabel->set_sensitive(false);
+ m_xMaxHyphenEdit->set_sensitive(false);
+ m_xMinWordLabel->set_sensitive(false);
+ m_xMinWordLength->set_sensitive(false);
+ m_xHyphenZoneLabel->set_sensitive(false);
+ m_aHyphenZone.set_sensitive(false);
+ m_xPageNumBox->set_sensitive(false);
+ m_xPagenumEdit->set_sensitive(false);
+ // no column break in HTML
+ m_xBreakTypeLB->remove(1);
+}
+
+SvxExtParagraphTabPage::~SvxExtParagraphTabPage()
+{
+}
+
+void SvxExtParagraphTabPage::PageBreakHdl()
+{
+ switch (m_xPageBreakBox->get_state())
+ {
+ case TRISTATE_TRUE:
+ m_xBreakTypeFT->set_sensitive(true);
+ m_xBreakTypeLB->set_sensitive(true);
+ m_xBreakPositionFT->set_sensitive(true);
+ m_xBreakPositionLB->set_sensitive(true);
+
+ if (0 == m_xBreakTypeLB->get_active() && 0 == m_xBreakPositionLB->get_active())
+ {
+ m_xApplyCollBtn->set_sensitive(true);
+
+ bool bEnable = TRISTATE_TRUE == m_xApplyCollBtn->get_state() &&
+ m_xApplyCollBox->get_count();
+ m_xApplyCollBox->set_sensitive(bEnable);
+ if(!bHtmlMode)
+ {
+ m_xPageNumBox->set_sensitive(bEnable);
+ m_xPagenumEdit->set_sensitive(bEnable && m_xPageNumBox->get_state() == TRISTATE_TRUE);
+ }
+ }
+ break;
+
+ case TRISTATE_FALSE:
+ case TRISTATE_INDET:
+ m_xApplyCollBtn->set_state(TRISTATE_FALSE);
+ m_xApplyCollBtn->set_sensitive(false);
+ m_xApplyCollBox->set_sensitive(false);
+ m_xPageNumBox->set_sensitive(false);
+ m_xPagenumEdit->set_sensitive(false);
+ m_xBreakTypeFT->set_sensitive(false);
+ m_xBreakTypeLB->set_sensitive(false);
+ m_xBreakPositionFT->set_sensitive(false);
+ m_xBreakPositionLB->set_sensitive(false);
+ break;
+ }
+}
+
+IMPL_LINK(SvxExtParagraphTabPage, PageBreakHdl_Impl, weld::Toggleable&, rToggle, void)
+{
+ aPageBreakState.ButtonToggled(rToggle);
+ PageBreakHdl();
+}
+
+void SvxExtParagraphTabPage::AllowSplitHdl()
+{
+ bool bEnable = m_xAllowSplitBox->get_state() == TRISTATE_TRUE;
+ m_xWidowBox->set_sensitive(bEnable);
+ m_xOrphanBox->set_sensitive(bEnable);
+}
+
+IMPL_LINK(SvxExtParagraphTabPage, AllowSplitHdl_Impl, weld::Toggleable&, rToggle, void)
+{
+ aAllowSplitState.ButtonToggled(rToggle);
+ AllowSplitHdl();
+}
+
+void SvxExtParagraphTabPage::WidowHdl()
+{
+ switch (m_xWidowBox->get_state())
+ {
+ case TRISTATE_TRUE:
+ m_xWidowRowNo->set_sensitive(true);
+ m_xWidowRowLabel->set_sensitive(true);
+ m_xAllowSplitBox->set_sensitive(true);
+ break;
+ case TRISTATE_FALSE:
+ if (m_xOrphanBox->get_state() == TRISTATE_FALSE)
+ m_xAllowSplitBox->set_sensitive(false);
+ [[fallthrough]];
+ case TRISTATE_INDET:
+ m_xWidowRowNo->set_sensitive(false);
+ m_xWidowRowLabel->set_sensitive(false);
+ break;
+ }
+}
+
+IMPL_LINK(SvxExtParagraphTabPage, WidowHdl_Impl, weld::Toggleable&, rToggle, void)
+{
+ aWidowState.ButtonToggled(rToggle);
+ WidowHdl();
+}
+
+IMPL_LINK(SvxExtParagraphTabPage, OrphanHdl_Impl, weld::Toggleable&, rToggle, void)
+{
+ aOrphanState.ButtonToggled(rToggle);
+ OrphanHdl();
+}
+
+void SvxExtParagraphTabPage::OrphanHdl()
+{
+ switch (m_xOrphanBox->get_state())
+ {
+ case TRISTATE_TRUE:
+ m_xOrphanRowNo->set_sensitive(true);
+ m_xOrphanRowLabel->set_sensitive(true);
+ m_xAllowSplitBox->set_sensitive(true);
+ break;
+
+ case TRISTATE_FALSE:
+ if (m_xWidowBox->get_state() == TRISTATE_FALSE)
+ m_xAllowSplitBox->set_sensitive(true);
+ [[fallthrough]];
+ case TRISTATE_INDET:
+ m_xOrphanRowNo->set_sensitive(false);
+ m_xOrphanRowLabel->set_sensitive(false);
+ break;
+ }
+}
+
+void SvxExtParagraphTabPage::HyphenClickHdl()
+{
+ bool bEnable = m_xHyphenBox->get_state() == TRISTATE_TRUE;
+ m_xHyphenNoCapsBox->set_sensitive(bEnable);
+ m_xHyphenNoLastWordBox->set_sensitive(bEnable);
+ m_xBeforeText->set_sensitive(bEnable);
+ m_xExtHyphenBeforeBox->set_sensitive(bEnable);
+ m_xAfterText->set_sensitive(bEnable);
+ m_xExtHyphenAfterBox->set_sensitive(bEnable);
+ m_xMaxHyphenLabel->set_sensitive(bEnable);
+ m_xMaxHyphenEdit->set_sensitive(bEnable);
+ m_xMinWordLabel->set_sensitive(bEnable);
+ m_xMinWordLength->set_sensitive(bEnable);
+ m_xHyphenZoneLabel->set_sensitive(bEnable);
+ m_aHyphenZone.set_sensitive(bEnable);
+ m_xHyphenBox->set_state(bEnable ? TRISTATE_TRUE : TRISTATE_FALSE);
+}
+
+IMPL_LINK(SvxExtParagraphTabPage, HyphenClickHdl_Impl, weld::Toggleable&, rToggle, void)
+{
+ aHyphenState.ButtonToggled(rToggle);
+ HyphenClickHdl();
+}
+
+void SvxExtParagraphTabPage::ApplyCollClickHdl()
+{
+ bool bEnable = false;
+ if (m_xApplyCollBtn->get_state() == TRISTATE_TRUE && m_xApplyCollBox->get_count())
+ {
+ bEnable = true;
+ m_xApplyCollBox->set_active(nStdPos);
+ }
+ else
+ {
+ m_xApplyCollBox->set_active(-1);
+ }
+ m_xApplyCollBox->set_sensitive(bEnable);
+ if (!bHtmlMode)
+ {
+ m_xPageNumBox->set_sensitive(bEnable);
+ m_xPagenumEdit->set_sensitive(bEnable && m_xPageNumBox->get_state() == TRISTATE_TRUE);
+ }
+}
+
+IMPL_LINK(SvxExtParagraphTabPage, ApplyCollClickHdl_Impl, weld::Toggleable&, rToggle, void)
+{
+ aApplyCollState.ButtonToggled(rToggle);
+ ApplyCollClickHdl();
+}
+
+IMPL_LINK(SvxExtParagraphTabPage, PageBreakPosHdl_Impl, weld::ComboBox&, rListBox, void)
+{
+ if (0 == rListBox.get_active())
+ {
+ m_xApplyCollBtn->set_sensitive(true);
+
+ bool bEnable = m_xApplyCollBtn->get_state() == TRISTATE_TRUE && m_xApplyCollBox->get_count();
+
+ m_xApplyCollBox->set_sensitive(bEnable);
+ if (!bHtmlMode)
+ {
+ m_xPageNumBox->set_sensitive(bEnable);
+ m_xPagenumEdit->set_sensitive(bEnable && m_xPageNumBox->get_state() == TRISTATE_TRUE);
+ }
+ }
+ else if (1 == rListBox.get_active())
+ {
+ m_xApplyCollBtn->set_state(TRISTATE_FALSE);
+ m_xApplyCollBtn->set_sensitive(false);
+ m_xApplyCollBox->set_sensitive(false);
+ m_xPageNumBox->set_sensitive(false);
+ m_xPagenumEdit->set_sensitive(false);
+ }
+}
+
+IMPL_LINK(SvxExtParagraphTabPage, PageBreakTypeHdl_Impl, weld::ComboBox&, rListBox, void)
+{
+ //column break or break after
+ int nBreakPos = m_xBreakPositionLB->get_active();
+ if (rListBox.get_active() == 1 || 1 == nBreakPos)
+ {
+ m_xApplyCollBtn->set_state(TRISTATE_FALSE);
+ m_xApplyCollBtn->set_sensitive(false);
+ m_xApplyCollBox->set_sensitive(false);
+ m_xPageNumBox->set_sensitive(false);
+ m_xPagenumEdit->set_sensitive(false);
+ }
+ else
+ PageBreakPosHdl_Impl(*m_xBreakPositionLB);
+}
+
+void SvxExtParagraphTabPage::PageNumBoxClickHdl()
+{
+ m_xPagenumEdit->set_sensitive(m_xPageNumBox->get_state() == TRISTATE_TRUE);
+}
+
+IMPL_LINK(SvxExtParagraphTabPage, PageNumBoxClickHdl_Impl, weld::Toggleable&, rToggle, void)
+{
+ aPageNumState.ButtonToggled(rToggle);
+ PageNumBoxClickHdl();
+}
+
+IMPL_LINK(SvxExtParagraphTabPage, KeepParaBoxClickHdl_Impl, weld::Toggleable&, rToggle, void)
+{
+ aKeepParaState.ButtonToggled(rToggle);
+}
+
+void SvxExtParagraphTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxBoolItem* pDisablePageBreakItem = aSet.GetItem<SfxBoolItem>(SID_DISABLE_SVXEXTPARAGRAPHTABPAGE_PAGEBREAK, false);
+
+ if (pDisablePageBreakItem)
+ if ( pDisablePageBreakItem->GetValue())
+ DisablePageBreak();
+}
+
+SvxAsianTabPage::SvxAsianTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/asiantypography.ui", "AsianTypography", &rSet)
+ , m_xForbiddenRulesCB(m_xBuilder->weld_check_button("checkForbidList"))
+ , m_xHangingPunctCB(m_xBuilder->weld_check_button("checkHangPunct"))
+ , m_xScriptSpaceCB(m_xBuilder->weld_check_button("checkApplySpacing"))
+{
+}
+
+SvxAsianTabPage::~SvxAsianTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SvxAsianTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxAsianTabPage>(pPage, pController, *rSet);
+}
+
+WhichRangesContainer SvxAsianTabPage::GetRanges()
+{
+ return WhichRangesContainer(svl::Items<SID_ATTR_PARA_SCRIPTSPACE, SID_ATTR_PARA_FORBIDDEN_RULES>);
+}
+
+bool SvxAsianTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ bool bRet = false;
+ SfxItemPool* pPool = rSet->GetPool();
+ if (m_xScriptSpaceCB->get_sensitive() && m_xScriptSpaceCB->get_state_changed_from_saved())
+ {
+ std::unique_ptr<SfxBoolItem> pNewItem(static_cast<SfxBoolItem*>(rSet->Get(
+ pPool->GetWhich(SID_ATTR_PARA_SCRIPTSPACE)).Clone()));
+ pNewItem->SetValue(m_xScriptSpaceCB->get_active());
+ rSet->Put(std::move(pNewItem));
+ bRet = true;
+ }
+ if (m_xHangingPunctCB->get_sensitive() && m_xHangingPunctCB->get_state_changed_from_saved())
+ {
+ std::unique_ptr<SfxBoolItem> pNewItem(static_cast<SfxBoolItem*>(rSet->Get(
+ pPool->GetWhich(SID_ATTR_PARA_HANGPUNCTUATION)).Clone()));
+ pNewItem->SetValue(m_xHangingPunctCB->get_active());
+ rSet->Put(std::move(pNewItem));
+ bRet = true;
+ }
+ if (m_xForbiddenRulesCB->get_sensitive() && m_xForbiddenRulesCB->get_state_changed_from_saved())
+ {
+ std::unique_ptr<SfxBoolItem> pNewItem(static_cast<SfxBoolItem*>(rSet->Get(
+ pPool->GetWhich(SID_ATTR_PARA_FORBIDDEN_RULES)).Clone()));
+ pNewItem->SetValue(m_xForbiddenRulesCB->get_active());
+ rSet->Put(std::move(pNewItem));
+ bRet = true;
+ }
+ return bRet;
+}
+
+static void lcl_SetBox(const SfxItemSet& rSet, sal_uInt16 nSlotId, weld::CheckButton& rBox)
+{
+ sal_uInt16 _nWhich = rSet.GetPool()->GetWhich(nSlotId);
+ SfxItemState eState = rSet.GetItemState(_nWhich);
+ if( eState == SfxItemState::UNKNOWN || eState == SfxItemState::DISABLED )
+ rBox.set_sensitive(false);
+ else if(eState >= SfxItemState::DEFAULT)
+ rBox.set_active(static_cast<const SfxBoolItem&>(rSet.Get(_nWhich)).GetValue());
+ else
+ rBox.set_state(TRISTATE_INDET);
+ rBox.save_state();
+}
+
+void SvxAsianTabPage::Reset( const SfxItemSet* rSet )
+{
+ lcl_SetBox(*rSet, SID_ATTR_PARA_FORBIDDEN_RULES, *m_xForbiddenRulesCB );
+ lcl_SetBox(*rSet, SID_ATTR_PARA_HANGPUNCTUATION, *m_xHangingPunctCB );
+
+ //character distance not yet available
+ lcl_SetBox(*rSet, SID_ATTR_PARA_SCRIPTSPACE, *m_xScriptSpaceCB );
+}
+
+void SvxAsianTabPage::ChangesApplied()
+{
+ m_xForbiddenRulesCB->save_state();
+ m_xHangingPunctCB->save_state();
+ m_xScriptSpaceCB->save_state();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/swpossizetabpage.cxx b/cui/source/tabpages/swpossizetabpage.cxx
new file mode 100644
index 0000000000..060f7b44ce
--- /dev/null
+++ b/cui/source/tabpages/swpossizetabpage.cxx
@@ -0,0 +1,1879 @@
+/* -*- 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 <memory>
+#include <cstddef>
+#include <type_traits>
+#include <swpossizetabpage.hxx>
+#include <svx/dlgutil.hxx>
+#include <svx/anchorid.hxx>
+#include <svl/intitem.hxx>
+#include <svx/swframevalidation.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <svx/svdview.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/swframeposstrings.hxx>
+#include <svx/rectenum.hxx>
+#include <sal/macros.h>
+#include <com/sun/star/text/HoriOrientation.hpp>
+#include <com/sun/star/text/VertOrientation.hpp>
+#include <com/sun/star/text/RelOrientation.hpp>
+#include <svx/svxids.hrc>
+#include <svtools/unitconv.hxx>
+#include <osl/diagnose.h>
+
+using namespace ::com::sun::star::text;
+
+namespace {
+
+enum class LB;
+
+}
+
+struct FrmMap
+{
+ SvxSwFramePosString::StringId eStrId;
+ SvxSwFramePosString::StringId eMirrorStrId;
+ short nAlign;
+ LB nLBRelations;
+};
+
+namespace {
+
+struct RelationMap
+{
+ SvxSwFramePosString::StringId eStrId;
+ SvxSwFramePosString::StringId eMirrorStrId;
+ LB nLBRelation;
+ short nRelation;
+};
+struct StringIdPair_Impl
+{
+ SvxSwFramePosString::StringId eHori;
+ SvxSwFramePosString::StringId eVert;
+};
+
+enum class LB {
+ NONE = 0x000000,
+ Frame = 0x000001, // paragraph text area
+ PrintArea = 0x000002, // paragraph text area + indents
+ VertFrame = 0x000004, // vertical paragraph text area
+ VertPrintArea = 0x000008, // vertical paragraph text area + indents
+ RelFrameLeft = 0x000010, // left paragraph margin
+ RelFrameRight = 0x000020, // right paragraph margin
+
+ RelPageLeft = 0x000040, // left page margin
+ RelPageRight = 0x000080, // right page margin
+ RelPageFrame = 0x000100, // complete page
+ RelPagePrintArea = 0x000200, // text area of page
+
+ FlyRelPageLeft = 0x000400, // left frame margin
+ FlyRelPageRight = 0x000800, // right frame margin
+ FlyRelPageFrame = 0x001000, // complete frame
+ FlyRelPagePrintArea = 0x002000, // frame interior
+
+ RelBase = 0x004000, // as char, relative to baseline
+ RelChar = 0x008000, // as char, relative to character
+ RelRow = 0x010000, // as char, relative to line
+
+// #i22305#
+ FlyVertFrame = 0x020000, // vertical entire frame
+ FlyVertPrintArea = 0x040000, // vertical frame text area
+
+// #i22341#
+ VertLine = 0x080000, // vertical text line
+
+ RelPagePrintAreaBottom = 0x100000, // bottom of text area of page
+ RelPagePrintAreaTop = 0x200000,
+
+ LAST = 0x400000
+};
+
+}
+
+namespace o3tl {
+ template<> struct typed_flags<LB> : is_typed_flags<LB, 0x3fffff> {};
+}
+
+RelationMap const aRelationMap[] =
+{
+ {SvxSwFramePosString::FRAME, SvxSwFramePosString::FRAME, LB::Frame, RelOrientation::FRAME},
+ {SvxSwFramePosString::PRTAREA, SvxSwFramePosString::PRTAREA, LB::PrintArea, RelOrientation::PRINT_AREA},
+ {SvxSwFramePosString::REL_PG_LEFT, SvxSwFramePosString::MIR_REL_PG_LEFT, LB::RelPageLeft, RelOrientation::PAGE_LEFT},
+ {SvxSwFramePosString::REL_PG_RIGHT, SvxSwFramePosString::MIR_REL_PG_RIGHT, LB::RelPageRight, RelOrientation::PAGE_RIGHT},
+ {SvxSwFramePosString::REL_FRM_LEFT, SvxSwFramePosString::MIR_REL_FRM_LEFT, LB::RelFrameLeft, RelOrientation::FRAME_LEFT},
+ {SvxSwFramePosString::REL_FRM_RIGHT, SvxSwFramePosString::MIR_REL_FRM_RIGHT, LB::RelFrameRight, RelOrientation::FRAME_RIGHT},
+ {SvxSwFramePosString::REL_PG_FRAME, SvxSwFramePosString::REL_PG_FRAME, LB::RelPageFrame, RelOrientation::PAGE_FRAME},
+ {SvxSwFramePosString::REL_PG_PRTAREA,SvxSwFramePosString::REL_PG_PRTAREA, LB::RelPagePrintArea, RelOrientation::PAGE_PRINT_AREA},
+ {SvxSwFramePosString::REL_PG_PRTAREA_TOP,SvxSwFramePosString::REL_PG_PRTAREA_TOP, LB::RelPagePrintAreaTop, RelOrientation::PAGE_PRINT_AREA_TOP},
+ {SvxSwFramePosString::REL_PG_PRTAREA_BOTTOM,SvxSwFramePosString::REL_PG_PRTAREA_BOTTOM, LB::RelPagePrintAreaBottom, RelOrientation::PAGE_PRINT_AREA_BOTTOM},
+ {SvxSwFramePosString::REL_CHAR, SvxSwFramePosString::REL_CHAR, LB::RelChar, RelOrientation::CHAR},
+
+ {SvxSwFramePosString::FLY_REL_PG_LEFT, SvxSwFramePosString::FLY_MIR_REL_PG_LEFT, LB::FlyRelPageLeft, RelOrientation::PAGE_LEFT},
+ {SvxSwFramePosString::FLY_REL_PG_RIGHT, SvxSwFramePosString::FLY_MIR_REL_PG_RIGHT, LB::FlyRelPageRight, RelOrientation::PAGE_RIGHT},
+ {SvxSwFramePosString::FLY_REL_PG_FRAME, SvxSwFramePosString::FLY_REL_PG_FRAME, LB::FlyRelPageFrame, RelOrientation::PAGE_FRAME},
+ {SvxSwFramePosString::FLY_REL_PG_PRTAREA, SvxSwFramePosString::FLY_REL_PG_PRTAREA, LB::FlyRelPagePrintArea, RelOrientation::PAGE_PRINT_AREA},
+
+ {SvxSwFramePosString::REL_BORDER, SvxSwFramePosString::REL_BORDER, LB::VertFrame, RelOrientation::FRAME},
+ {SvxSwFramePosString::REL_PRTAREA, SvxSwFramePosString::REL_PRTAREA, LB::VertPrintArea, RelOrientation::PRINT_AREA},
+
+ // #i22305#
+ {SvxSwFramePosString::FLY_REL_PG_FRAME, SvxSwFramePosString::FLY_REL_PG_FRAME, LB::FlyVertFrame, RelOrientation::FRAME},
+ {SvxSwFramePosString::FLY_REL_PG_PRTAREA, SvxSwFramePosString::FLY_REL_PG_PRTAREA, LB::FlyVertPrintArea, RelOrientation::PRINT_AREA},
+
+ // #i22341#
+ {SvxSwFramePosString::REL_LINE, SvxSwFramePosString::REL_LINE, LB::VertLine, RelOrientation::TEXT_LINE}
+};
+
+RelationMap const aAsCharRelationMap[] =
+{
+ {SvxSwFramePosString::REL_BASE, SvxSwFramePosString::REL_BASE, LB::RelBase, RelOrientation::FRAME},
+ {SvxSwFramePosString::REL_CHAR, SvxSwFramePosString::REL_CHAR, LB::RelChar, RelOrientation::FRAME},
+ {SvxSwFramePosString::REL_ROW, SvxSwFramePosString::REL_ROW, LB::RelRow, RelOrientation::FRAME}
+};
+
+/*--------------------------------------------------------------------
+ Anchored at page
+ --------------------------------------------------------------------*/
+
+constexpr auto HORI_PAGE_REL = LB::RelPageFrame|LB::RelPagePrintArea|LB::RelPageLeft|
+ LB::RelPageRight;
+
+FrmMap const aHPageMap[] =
+{
+ {SvxSwFramePosString::LEFT, SvxSwFramePosString::MIR_LEFT, HoriOrientation::LEFT, HORI_PAGE_REL},
+ {SvxSwFramePosString::RIGHT, SvxSwFramePosString::MIR_RIGHT, HoriOrientation::RIGHT, HORI_PAGE_REL},
+ {SvxSwFramePosString::CENTER_HORI,SvxSwFramePosString::CENTER_HORI, HoriOrientation::CENTER, HORI_PAGE_REL},
+ {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, HORI_PAGE_REL}
+};
+
+FrmMap const aHPageHtmlMap[] =
+{
+ {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, LB::RelPageFrame}
+};
+
+#define VERT_PAGE_REL (LB::RelPageFrame|LB::RelPagePrintArea)
+
+FrmMap const aVPageMap[] =
+{
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, VERT_PAGE_REL},
+ {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::BOTTOM, VERT_PAGE_REL},
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CENTER, VERT_PAGE_REL},
+ {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, VERT_PAGE_REL}
+};
+
+FrmMap const aVPageHtmlMap[] =
+{
+ {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, LB::RelPageFrame}
+};
+
+/*--------------------------------------------------------------------
+ Anchored at frame
+ --------------------------------------------------------------------*/
+
+constexpr auto HORI_FRAME_REL = LB::FlyRelPageFrame|LB::FlyRelPagePrintArea|
+ LB::FlyRelPageLeft|LB::FlyRelPageRight;
+
+FrmMap const aHFrameMap[] =
+{
+ {SvxSwFramePosString::LEFT, SvxSwFramePosString::MIR_LEFT, HoriOrientation::LEFT, HORI_FRAME_REL},
+ {SvxSwFramePosString::RIGHT, SvxSwFramePosString::MIR_RIGHT, HoriOrientation::RIGHT, HORI_FRAME_REL},
+ {SvxSwFramePosString::CENTER_HORI, SvxSwFramePosString::CENTER_HORI, HoriOrientation::CENTER, HORI_FRAME_REL},
+ {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, HORI_FRAME_REL}
+};
+
+FrmMap const aHFlyHtmlMap[] =
+{
+ {SvxSwFramePosString::LEFT, SvxSwFramePosString::MIR_LEFT, HoriOrientation::LEFT, LB::FlyRelPageFrame},
+ {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, LB::FlyRelPageFrame}
+};
+
+// #i18732# - own vertical alignment map for to frame anchored objects
+// #i22305#
+#define VERT_FRAME_REL (LB::FlyVertFrame|LB::FlyVertPrintArea)
+
+FrmMap const aVFrameMap[] =
+{
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, VERT_FRAME_REL},
+ {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::BOTTOM, VERT_FRAME_REL},
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CENTER, VERT_FRAME_REL},
+ {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, VERT_FRAME_REL}
+};
+
+FrmMap const aVFlyHtmlMap[] =
+{
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, LB::FlyVertFrame},
+ {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, LB::FlyVertFrame}
+};
+
+FrmMap const aVMultiSelectionMap[] =
+{
+ {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, LB::NONE}
+};
+FrmMap const aHMultiSelectionMap[] =
+{
+ {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::FROMLEFT, HoriOrientation::NONE, LB::NONE}
+};
+
+/*--------------------------------------------------------------------
+ Anchored at paragraph
+ --------------------------------------------------------------------*/
+
+constexpr auto HORI_PARA_REL = LB::Frame|LB::PrintArea|LB::RelPageLeft|LB::RelPageRight|
+ LB::RelPageFrame|LB::RelPagePrintArea|LB::RelFrameLeft|
+ LB::RelFrameRight;
+
+FrmMap const aHParaMap[] =
+{
+ {SvxSwFramePosString::LEFT, SvxSwFramePosString::MIR_LEFT, HoriOrientation::LEFT, HORI_PARA_REL},
+ {SvxSwFramePosString::RIGHT, SvxSwFramePosString::MIR_RIGHT, HoriOrientation::RIGHT, HORI_PARA_REL},
+ {SvxSwFramePosString::CENTER_HORI, SvxSwFramePosString::CENTER_HORI, HoriOrientation::CENTER, HORI_PARA_REL},
+ {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, HORI_PARA_REL}
+};
+
+#define HTML_HORI_PARA_REL (LB::Frame|LB::PrintArea)
+
+FrmMap const aHParaHtmlMap[] =
+{
+ {SvxSwFramePosString::LEFT, SvxSwFramePosString::LEFT, HoriOrientation::LEFT, HTML_HORI_PARA_REL},
+ {SvxSwFramePosString::RIGHT, SvxSwFramePosString::RIGHT, HoriOrientation::RIGHT, HTML_HORI_PARA_REL}
+};
+
+FrmMap const aHParaHtmlAbsMap[] =
+{
+ {SvxSwFramePosString::LEFT, SvxSwFramePosString::MIR_LEFT, HoriOrientation::LEFT, HTML_HORI_PARA_REL},
+ {SvxSwFramePosString::RIGHT, SvxSwFramePosString::MIR_RIGHT, HoriOrientation::RIGHT, HTML_HORI_PARA_REL}
+};
+
+
+constexpr auto VERT_PARA_REL = LB::VertFrame|LB::VertPrintArea|
+ LB::RelPageFrame|LB::RelPagePrintArea| LB::RelPagePrintAreaTop |LB::RelPagePrintAreaBottom;
+
+FrmMap const aVParaMap[] =
+{
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, VERT_PARA_REL},
+ {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::BOTTOM, VERT_PARA_REL},
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CENTER, VERT_PARA_REL},
+ {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, VERT_PARA_REL}
+};
+
+FrmMap const aVParaHtmlMap[] =
+{
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, LB::VertPrintArea}
+};
+
+/*--------------------------------------------------------------------
+ Anchored at character
+ --------------------------------------------------------------------*/
+
+constexpr auto HORI_CHAR_REL = LB::Frame|LB::PrintArea|LB::RelPageLeft|LB::RelPageRight|
+ LB::RelPageFrame|LB::RelPagePrintArea|LB::RelFrameLeft|
+ LB::RelFrameRight|LB::RelChar;
+
+static FrmMap aHCharMap[] =
+{
+ {SvxSwFramePosString::LEFT, SvxSwFramePosString::MIR_LEFT, HoriOrientation::LEFT, HORI_CHAR_REL},
+ {SvxSwFramePosString::RIGHT, SvxSwFramePosString::MIR_RIGHT, HoriOrientation::RIGHT, HORI_CHAR_REL},
+ {SvxSwFramePosString::CENTER_HORI, SvxSwFramePosString::CENTER_HORI, HoriOrientation::CENTER, HORI_CHAR_REL},
+ {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, HORI_CHAR_REL}
+};
+
+#define HTML_HORI_CHAR_REL (LB::Frame|LB::PrintArea|LB::RelChar)
+
+static FrmMap aHCharHtmlMap[] =
+{
+ {SvxSwFramePosString::LEFT, SvxSwFramePosString::LEFT, HoriOrientation::LEFT, HTML_HORI_CHAR_REL},
+ {SvxSwFramePosString::RIGHT, SvxSwFramePosString::RIGHT, HoriOrientation::RIGHT, HTML_HORI_CHAR_REL}
+};
+
+static FrmMap aHCharHtmlAbsMap[] =
+{
+ {SvxSwFramePosString::LEFT, SvxSwFramePosString::MIR_LEFT, HoriOrientation::LEFT, LB::PrintArea|LB::RelChar},
+ {SvxSwFramePosString::RIGHT, SvxSwFramePosString::MIR_RIGHT, HoriOrientation::RIGHT, LB::PrintArea},
+ {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, LB::RelPageFrame}
+};
+
+// #i18732# - allow vertical alignment at page areas
+// #i22341# - handle <LB::RelChar> on its own
+constexpr auto VERT_CHAR_REL = LB::VertFrame|LB::VertPrintArea|
+ LB::RelPageFrame|LB::RelPagePrintArea|LB::RelPagePrintAreaBottom;
+
+static FrmMap aVCharMap[] =
+{
+ // #i22341#
+ // introduce mappings for new vertical alignment at top of line <LB::VertLine>
+ // and correct mapping for vertical alignment at character for position <FROM_BOTTOM>
+ // Note: because of these adjustments the map becomes ambiguous in its values
+ // <eStrId>/<eMirrorStrId> and <nAlign>. These ambiguities are considered
+ // in the methods <SwFrmPage::FillRelLB(..)>, <SwFrmPage::GetAlignment(..)>
+ // and <SwFrmPage::FillPosLB(..)>
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, VERT_CHAR_REL|LB::RelChar},
+ {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::BOTTOM, VERT_CHAR_REL|LB::RelChar},
+ {SvxSwFramePosString::BELOW, SvxSwFramePosString::BELOW, VertOrientation::CHAR_BOTTOM, LB::RelChar},
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CENTER, VERT_CHAR_REL|LB::RelChar},
+ {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, VERT_CHAR_REL},
+ {SvxSwFramePosString::FROMBOTTOM, SvxSwFramePosString::FROMBOTTOM, VertOrientation::NONE, LB::RelChar|LB::VertLine},
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::LINE_TOP, LB::VertLine},
+ {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::LINE_BOTTOM, LB::VertLine},
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::LINE_CENTER, LB::VertLine}
+};
+
+
+FrmMap const aVCharHtmlMap[] =
+{
+ {SvxSwFramePosString::BELOW, SvxSwFramePosString::BELOW, VertOrientation::CHAR_BOTTOM, LB::RelChar}
+};
+
+FrmMap const aVCharHtmlAbsMap[] =
+{
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, LB::RelChar},
+ {SvxSwFramePosString::BELOW, SvxSwFramePosString::BELOW, VertOrientation::CHAR_BOTTOM, LB::RelChar}
+};
+/*--------------------------------------------------------------------
+ anchored as character
+ --------------------------------------------------------------------*/
+
+FrmMap const aVAsCharMap[] =
+{
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, LB::RelBase},
+ {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::BOTTOM, LB::RelBase},
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CENTER, LB::RelBase},
+
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::CHAR_TOP, LB::RelChar},
+ {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::CHAR_BOTTOM, LB::RelChar},
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CHAR_CENTER, LB::RelChar},
+
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::LINE_TOP, LB::RelRow},
+ {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::LINE_BOTTOM, LB::RelRow},
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::LINE_CENTER, LB::RelRow},
+
+ {SvxSwFramePosString::FROMBOTTOM, SvxSwFramePosString::FROMBOTTOM, VertOrientation::NONE, LB::RelBase}
+};
+
+FrmMap const aVAsCharHtmlMap[] =
+{
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, LB::RelBase},
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CENTER, LB::RelBase},
+
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::CHAR_TOP, LB::RelChar},
+
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::LINE_TOP, LB::RelRow},
+ {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::LINE_BOTTOM, LB::RelRow},
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::LINE_CENTER, LB::RelRow}
+};
+
+static std::size_t lcl_GetFrmMapCount(const FrmMap* pMap)
+{
+ if( !pMap )
+ return 0;
+
+ if( pMap == aVParaHtmlMap )
+ return std::size(aVParaHtmlMap);
+ if( pMap == aVAsCharHtmlMap )
+ return std::size( aVAsCharHtmlMap );
+ if( pMap == aHParaHtmlMap )
+ return std::size( aHParaHtmlMap );
+ if( pMap == aHParaHtmlAbsMap )
+ return std::size( aHParaHtmlAbsMap );
+ if( pMap == aVPageMap )
+ return std::size( aVPageMap );
+ if( pMap == aVPageHtmlMap )
+ return std::size( aVPageHtmlMap );
+ if( pMap == aVAsCharMap )
+ return std::size( aVAsCharMap );
+ if( pMap == aVParaMap )
+ return std::size( aVParaMap );
+ if( pMap == aHParaMap )
+ return std::size( aHParaMap );
+ if( pMap == aHFrameMap )
+ return std::size( aHFrameMap );
+ if( pMap == aVFrameMap )
+ return std::size( aVFrameMap );
+ if( pMap == aHCharMap )
+ return std::size( aHCharMap );
+ if( pMap == aHCharHtmlMap )
+ return std::size( aHCharHtmlMap );
+ if( pMap == aHCharHtmlAbsMap )
+ return std::size( aHCharHtmlAbsMap );
+ if( pMap == aVCharMap )
+ return std::size( aVCharMap );
+ if( pMap == aVCharHtmlMap )
+ return std::size( aVCharHtmlMap );
+ if( pMap == aVCharHtmlAbsMap )
+ return std::size( aVCharHtmlAbsMap );
+ if( pMap == aHPageHtmlMap )
+ return std::size( aHPageHtmlMap );
+ if( pMap == aHFlyHtmlMap )
+ return std::size( aHFlyHtmlMap );
+ if( pMap == aVFlyHtmlMap )
+ return std::size( aVFlyHtmlMap );
+ if( pMap == aVMultiSelectionMap )
+ return std::size( aVMultiSelectionMap );
+ if( pMap == aHMultiSelectionMap )
+ return std::size( aHMultiSelectionMap );
+ return std::size(aHPageMap);
+}
+
+static SvxSwFramePosString::StringId lcl_ChangeResIdToVerticalOrRTL(
+ SvxSwFramePosString::StringId eStringId, bool bVertical, bool bRTL)
+{
+ //special handling of STR_FROMLEFT
+ if(SvxSwFramePosString::FROMLEFT == eStringId)
+ {
+ eStringId = bVertical ?
+ bRTL ? SvxSwFramePosString::FROMBOTTOM : SvxSwFramePosString::FROMTOP :
+ bRTL ? SvxSwFramePosString::FROMRIGHT : SvxSwFramePosString::FROMLEFT;
+ return eStringId;
+ }
+ if(bVertical)
+ {
+ //exchange horizontal strings with vertical strings and vice versa
+ static const StringIdPair_Impl aHoriIds[] =
+ {
+ {SvxSwFramePosString::LEFT, SvxSwFramePosString::TOP},
+ {SvxSwFramePosString::RIGHT, SvxSwFramePosString::BOTTOM},
+ {SvxSwFramePosString::CENTER_HORI, SvxSwFramePosString::CENTER_VERT},
+ {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMRIGHT},
+ {SvxSwFramePosString::REL_PG_LEFT, SvxSwFramePosString::REL_PG_TOP},
+ {SvxSwFramePosString::REL_PG_RIGHT, SvxSwFramePosString::REL_PG_BOTTOM} ,
+ {SvxSwFramePosString::REL_FRM_LEFT, SvxSwFramePosString::REL_FRM_TOP},
+ {SvxSwFramePosString::REL_FRM_RIGHT, SvxSwFramePosString::REL_FRM_BOTTOM}
+ };
+ static const StringIdPair_Impl aVertIds[] =
+ {
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::RIGHT},
+ {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::LEFT },
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_HORI},
+ {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMRIGHT },
+ {SvxSwFramePosString::REL_PG_TOP, SvxSwFramePosString::REL_PG_LEFT },
+ {SvxSwFramePosString::REL_PG_BOTTOM, SvxSwFramePosString::REL_PG_RIGHT } ,
+ {SvxSwFramePosString::REL_FRM_TOP, SvxSwFramePosString::REL_FRM_LEFT },
+ {SvxSwFramePosString::REL_FRM_BOTTOM, SvxSwFramePosString::REL_FRM_RIGHT }
+ };
+ for(const auto &a : aHoriIds)
+ {
+ if(a.eHori == eStringId)
+ {
+ eStringId = a.eVert;
+ return eStringId;
+ }
+ }
+ for(const auto &a : aVertIds)
+ {
+ if(a.eHori == eStringId)
+ {
+ eStringId = a.eVert;
+ break;
+ }
+ }
+ }
+ return eStringId;
+}
+// #i22341# - helper method in order to determine all possible
+// listbox relations in a relation map for a given relation
+static LB lcl_GetLBRelationsForRelations( const sal_uInt16 _nRel )
+{
+ LB nLBRelations = LB::NONE;
+
+ for (RelationMap const & nRelMapPos : aRelationMap)
+ {
+ if ( nRelMapPos.nRelation == _nRel )
+ {
+ nLBRelations |= nRelMapPos.nLBRelation;
+ }
+ }
+
+ return nLBRelations;
+}
+
+// #i22341# - helper method on order to determine all possible
+// listbox relations in a relation map for a given string ID
+static LB lcl_GetLBRelationsForStrID(const FrmMap* _pMap,
+ const SvxSwFramePosString::StringId _eStrId,
+ const bool _bUseMirrorStr )
+{
+ LB nLBRelations = LB::NONE;
+
+ std::size_t nRelMapSize = lcl_GetFrmMapCount( _pMap );
+ for ( std::size_t nRelMapPos = 0; nRelMapPos < nRelMapSize; ++nRelMapPos )
+ {
+ if ( ( !_bUseMirrorStr && _pMap[nRelMapPos].eStrId == _eStrId ) ||
+ ( _bUseMirrorStr && _pMap[nRelMapPos].eMirrorStrId == _eStrId ) )
+ {
+ nLBRelations |= _pMap[nRelMapPos].nLBRelations;
+ }
+ }
+
+ return nLBRelations;
+}
+
+SvxSwPosSizeTabPage::SvxSwPosSizeTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/swpossizepage.ui", "SwPosSizePage", &rInAttrs)
+ , m_pVMap(nullptr)
+ , m_pHMap(nullptr)
+ , m_pSdrView(nullptr)
+ , m_nOldH(HoriOrientation::CENTER)
+ , m_nOldHRel(RelOrientation::FRAME)
+ , m_nOldV(VertOrientation::TOP)
+ , m_nOldVRel(RelOrientation::PRINT_AREA)
+ , m_fWidthHeightRatio(1.0)
+ , m_bHtmlMode(false)
+ , m_bIsVerticalFrame(false)
+ , m_bPositioningDisabled(false)
+ , m_bIsMultiSelection(false)
+ , m_bIsInRightToLeft(false)
+ , m_nProtectSizeState(TRISTATE_FALSE)
+ , m_xWidthMF(m_xBuilder->weld_metric_spin_button("width", FieldUnit::CM))
+ , m_xHeightMF(m_xBuilder->weld_metric_spin_button("height", FieldUnit::CM))
+ , m_xKeepRatioCB(m_xBuilder->weld_check_button("ratio"))
+ , m_xToPageRB(m_xBuilder->weld_radio_button("topage"))
+ , m_xToParaRB(m_xBuilder->weld_radio_button("topara"))
+ , m_xToCharRB(m_xBuilder->weld_radio_button("tochar"))
+ , m_xAsCharRB(m_xBuilder->weld_radio_button("aschar"))
+ , m_xToFrameRB(m_xBuilder->weld_radio_button("toframe"))
+ , m_xPositionCB(m_xBuilder->weld_check_button("pos"))
+ , m_xSizeCB(m_xBuilder->weld_check_button("size"))
+ , m_xPosFrame(m_xBuilder->weld_widget("posframe"))
+ , m_xHoriFT(m_xBuilder->weld_label("horiposft"))
+ , m_xHoriLB(m_xBuilder->weld_combo_box("horipos"))
+ , m_xHoriByFT(m_xBuilder->weld_label("horibyft"))
+ , m_xHoriByMF(m_xBuilder->weld_metric_spin_button("byhori", FieldUnit::CM))
+ , m_xHoriToFT(m_xBuilder->weld_label("horitoft"))
+ , m_xHoriToLB(m_xBuilder->weld_combo_box("horianchor"))
+ , m_xHoriMirrorCB(m_xBuilder->weld_check_button("mirror"))
+ , m_xVertFT(m_xBuilder->weld_label("vertposft"))
+ , m_xVertLB(m_xBuilder->weld_combo_box("vertpos"))
+ , m_xVertByFT(m_xBuilder->weld_label("vertbyft"))
+ , m_xVertByMF(m_xBuilder->weld_metric_spin_button("byvert", FieldUnit::CM))
+ , m_xVertToFT(m_xBuilder->weld_label("verttoft"))
+ , m_xVertToLB(m_xBuilder->weld_combo_box("vertanchor"))
+ , m_xFollowCB(m_xBuilder->weld_check_button("followtextflow"))
+ , m_xExampleWN(new weld::CustomWeld(*m_xBuilder, "preview", m_aExampleWN))
+{
+ setOptimalFrmWidth();
+ setOptimalRelWidth();
+
+ FieldUnit eDlgUnit = GetModuleFieldUnit( rInAttrs );
+ SetFieldUnit(*m_xHoriByMF, eDlgUnit, true);
+ SetFieldUnit(*m_xVertByMF, eDlgUnit, true);
+ SetFieldUnit(*m_xWidthMF , eDlgUnit, true);
+ SetFieldUnit(*m_xHeightMF, eDlgUnit, true);
+
+ SetExchangeSupport();
+
+ Link<weld::Widget&,void> aLk3 = LINK(this, SvxSwPosSizeTabPage, RangeModifyHdl);
+ m_xWidthMF->connect_focus_out(aLk3);
+ m_xHeightMF->connect_focus_out(aLk3);
+ m_xHoriByMF->connect_focus_out(aLk3);
+ m_xVertByMF->connect_focus_out(aLk3);
+ m_xFollowCB->connect_toggled(LINK(this, SvxSwPosSizeTabPage, RangeModifyClickHdl));
+
+ Link<weld::MetricSpinButton&,void> aLk = LINK(this, SvxSwPosSizeTabPage, ModifyHdl);
+ m_xWidthMF->connect_value_changed( aLk );
+ m_xHeightMF->connect_value_changed( aLk );
+ m_xHoriByMF->connect_value_changed( aLk );
+ m_xVertByMF->connect_value_changed( aLk );
+
+ Link<weld::Toggleable&,void> aLk2 = LINK(this, SvxSwPosSizeTabPage, AnchorTypeHdl);
+ m_xToPageRB->connect_toggled( aLk2 );
+ m_xToParaRB->connect_toggled( aLk2 );
+ m_xToCharRB->connect_toggled( aLk2 );
+ m_xAsCharRB->connect_toggled( aLk2 );
+ m_xToFrameRB->connect_toggled( aLk2 );
+
+ m_xHoriLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, PosHdl));
+ m_xVertLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, PosHdl));
+
+ m_xHoriToLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, RelHdl));
+ m_xVertToLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, RelHdl));
+
+ m_xHoriMirrorCB->connect_toggled(LINK(this, SvxSwPosSizeTabPage, MirrorHdl));
+ m_xPositionCB->connect_toggled(LINK(this, SvxSwPosSizeTabPage, ProtectHdl));
+}
+
+SvxSwPosSizeTabPage::~SvxSwPosSizeTabPage()
+{
+ m_xWidthMF.reset();
+ m_xHeightMF.reset();
+ m_xHoriByMF.reset();
+ m_xVertByMF.reset();
+}
+
+namespace
+{
+ struct FrmMaps
+ {
+ FrmMap const *pMap;
+ size_t nCount;
+ };
+}
+
+void SvxSwPosSizeTabPage::setOptimalFrmWidth()
+{
+ static const FrmMaps aMaps[] = {
+ { aHPageMap, std::size(aHPageMap) },
+ { aHPageHtmlMap, std::size(aHPageHtmlMap) },
+ { aVPageMap, std::size(aVPageMap) },
+ { aVPageHtmlMap, std::size(aVPageHtmlMap) },
+ { aHFrameMap, std::size(aHFrameMap) },
+ { aHFlyHtmlMap, std::size(aHFlyHtmlMap) },
+ { aVFrameMap, std::size(aVFrameMap) },
+ { aVFlyHtmlMap, std::size(aVFlyHtmlMap) },
+ { aHParaMap, std::size(aHParaMap) },
+ { aHParaHtmlMap, std::size(aHParaHtmlMap) },
+ { aHParaHtmlAbsMap, std::size(aHParaHtmlAbsMap) },
+ { aVParaMap, std::size(aVParaMap) },
+ { aVParaHtmlMap, std::size(aVParaHtmlMap) },
+ { aHCharMap, std::size(aHCharMap) },
+ { aHCharHtmlMap, std::size(aHCharHtmlMap) },
+ { aHCharHtmlAbsMap, std::size(aHCharHtmlAbsMap) },
+ { aVCharMap, std::size(aVCharMap) },
+ { aVCharHtmlMap, std::size(aVCharHtmlMap) },
+ { aVCharHtmlAbsMap, std::size(aVCharHtmlAbsMap) },
+ { aVAsCharMap, std::size(aVAsCharMap) },
+ { aVAsCharHtmlMap, std::size(aVAsCharHtmlMap) }
+ };
+
+ std::vector<SvxSwFramePosString::StringId> aFrames;
+ for (const FrmMaps& aMap : aMaps)
+ {
+ for (size_t j = 0; j < aMap.nCount; ++j)
+ {
+ aFrames.push_back(aMap.pMap[j].eStrId);
+ aFrames.push_back(aMap.pMap[j].eMirrorStrId);
+ }
+ }
+
+ std::sort(aFrames.begin(), aFrames.end());
+ aFrames.erase(std::unique(aFrames.begin(), aFrames.end()), aFrames.end());
+
+ for (auto const& frame : aFrames)
+ {
+ m_xHoriLB->append_text(SvxSwFramePosString::GetString(frame));
+ }
+
+ Size aBiggest(m_xHoriLB->get_preferred_size());
+ m_xHoriLB->set_size_request(aBiggest.Width(), -1);
+ m_xVertLB->set_size_request(aBiggest.Width(), -1);
+ m_xHoriLB->clear();
+}
+
+namespace
+{
+ struct RelationMaps
+ {
+ RelationMap const *pMap;
+ size_t nCount;
+ };
+}
+
+void SvxSwPosSizeTabPage::setOptimalRelWidth()
+{
+ static const RelationMaps aMaps[] = {
+ { aRelationMap, std::size(aRelationMap) },
+ { aAsCharRelationMap, std::size(aAsCharRelationMap) }
+ };
+
+ std::vector<SvxSwFramePosString::StringId> aRels;
+ for (const RelationMaps& aMap : aMaps)
+ {
+ for (size_t j = 0; j < aMap.nCount; ++j)
+ {
+ aRels.push_back(aMap.pMap[j].eStrId);
+ aRels.push_back(aMap.pMap[j].eMirrorStrId);
+ }
+ }
+
+ std::sort(aRels.begin(), aRels.end());
+ aRels.erase(std::unique(aRels.begin(), aRels.end()), aRels.end());
+
+ for (auto const& elem : aRels)
+ {
+ m_xHoriLB->append_text(SvxSwFramePosString::GetString(elem));
+ }
+
+ Size aBiggest(m_xHoriLB->get_preferred_size());
+ m_xHoriLB->set_size_request(aBiggest.Width(), -1);
+ m_xVertLB->set_size_request(aBiggest.Width(), -1);
+ m_xHoriLB->clear();
+}
+
+std::unique_ptr<SfxTabPage> SvxSwPosSizeTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxSwPosSizeTabPage>(pPage, pController, *rSet);
+}
+
+WhichRangesContainer SvxSwPosSizeTabPage::GetRanges()
+{
+ static const WhichRangesContainer ranges(svl::Items<
+ SID_ATTR_TRANSFORM_POS_X, SID_ATTR_TRANSFORM_POS_Y,
+ SID_ATTR_TRANSFORM_WIDTH, SID_ATTR_TRANSFORM_SIZE_POINT,
+ SID_ATTR_TRANSFORM_PROTECT_POS, SID_ATTR_TRANSFORM_INTERN,
+ SID_ATTR_TRANSFORM_AUTOWIDTH, SID_ATTR_TRANSFORM_VERT_ORIENT,
+ SID_HTML_MODE, SID_HTML_MODE,
+ SID_SW_FOLLOW_TEXT_FLOW, SID_SW_FOLLOW_TEXT_FLOW,
+ SID_ATTR_TRANSFORM_HORI_POSITION, SID_ATTR_TRANSFORM_VERT_POSITION
+ >);
+ return ranges;
+}
+
+bool SvxSwPosSizeTabPage::FillItemSet( SfxItemSet* rSet)
+{
+ bool bAnchorChanged = false;
+ RndStdIds nAnchor = GetAnchorType(&bAnchorChanged);
+ bool bModified = false;
+ if(bAnchorChanged)
+ {
+ rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_ANCHOR, static_cast<sal_Int16>(nAnchor)));
+ bModified = true;
+ }
+ if (m_xPositionCB->get_state_changed_from_saved())
+ {
+ if (m_xPositionCB->get_inconsistent())
+ rSet->InvalidateItem( SID_ATTR_TRANSFORM_PROTECT_POS );
+ else
+ rSet->Put(
+ SfxBoolItem( SID_ATTR_TRANSFORM_PROTECT_POS,
+ m_xPositionCB->get_state() == TRISTATE_TRUE ) );
+ bModified = true;
+ }
+
+ if (m_xSizeCB->get_state_changed_from_saved())
+ {
+ if (m_xSizeCB->get_inconsistent())
+ rSet->InvalidateItem( SID_ATTR_TRANSFORM_PROTECT_SIZE );
+ else
+ rSet->Put(
+ SfxBoolItem( SID_ATTR_TRANSFORM_PROTECT_SIZE,
+ m_xSizeCB->get_state() == TRISTATE_TRUE ) );
+ bModified = true;
+ }
+
+ const SfxItemSet& rOldSet = GetItemSet();
+
+ if(!m_bPositioningDisabled)
+ {
+ //on multiple selections the positioning is set via SdrView
+ if (m_bIsMultiSelection)
+ {
+ if (m_xHoriByMF->get_value_changed_from_saved() || m_xVertByMF->get_value_changed_from_saved())
+ {
+ auto nHoriByPos = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
+ auto nVertByPos = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
+
+ // old rectangle with CoreUnit
+ m_aRect = m_pSdrView->GetAllMarkedRect();
+ m_pSdrView->GetSdrPageView()->LogicToPagePos( m_aRect );
+
+ nHoriByPos += m_aAnchorPos.X();
+ nVertByPos += m_aAnchorPos.Y();
+
+ rSet->Put( SfxInt32Item( SID_ATTR_TRANSFORM_POS_X, nHoriByPos ) );
+ rSet->Put( SfxInt32Item( SID_ATTR_TRANSFORM_POS_Y, nVertByPos ) );
+
+ bModified = true;
+ }
+ }
+ else
+ {
+ if ( m_pHMap )
+ {
+ const SfxInt16Item& rHoriOrient =
+ rOldSet.Get( SID_ATTR_TRANSFORM_HORI_ORIENT );
+ const SfxInt16Item& rHoriRelation =
+ rOldSet.Get( SID_ATTR_TRANSFORM_HORI_RELATION);
+ const SfxInt32Item& rHoriPosition =
+ rOldSet.Get( SID_ATTR_TRANSFORM_HORI_POSITION);
+
+ sal_uInt16 nMapPos = GetMapPos(m_pHMap, *m_xHoriLB);
+ short nAlign = GetAlignment(m_pHMap, nMapPos, *m_xHoriToLB);
+ short nRel = GetRelation(*m_xHoriToLB);
+ const auto nHoriByPos = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
+ if (
+ nAlign != rHoriOrient.GetValue() ||
+ nRel != rHoriRelation.GetValue() ||
+ (m_xHoriByMF->get_sensitive() && nHoriByPos != rHoriPosition.GetValue())
+ )
+ {
+ rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_HORI_ORIENT, nAlign));
+ rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_HORI_RELATION, nRel));
+ if(m_xHoriByMF->get_sensitive())
+ rSet->Put(SfxInt32Item(SID_ATTR_TRANSFORM_HORI_POSITION, nHoriByPos));
+ bModified = true;
+ }
+ }
+ if (m_xHoriMirrorCB->get_sensitive() && m_xHoriMirrorCB->get_state_changed_from_saved())
+ bModified |= nullptr != rSet->Put(SfxBoolItem(SID_ATTR_TRANSFORM_HORI_MIRROR, m_xHoriMirrorCB->get_active()));
+
+ if ( m_pVMap )
+ {
+ const SfxInt16Item& rVertOrient =
+ rOldSet.Get( SID_ATTR_TRANSFORM_VERT_ORIENT);
+ const SfxInt16Item& rVertRelation =
+ rOldSet.Get( SID_ATTR_TRANSFORM_VERT_RELATION);
+ const SfxInt32Item& rVertPosition =
+ rOldSet.Get( SID_ATTR_TRANSFORM_VERT_POSITION);
+
+ sal_uInt16 nMapPos = GetMapPos(m_pVMap, *m_xVertLB);
+ short nAlign = GetAlignment(m_pVMap, nMapPos, *m_xVertToLB);
+ short nRel = GetRelation(*m_xVertToLB);
+ // #i34055# - convert vertical position for
+ // as-character anchored objects
+ auto nVertByPos = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
+ if (GetAnchorType() == RndStdIds::FLY_AS_CHAR)
+ {
+ nVertByPos *= -1;
+ }
+ if ( nAlign != rVertOrient.GetValue() ||
+ nRel != rVertRelation.GetValue() ||
+ ( m_xVertByMF->get_sensitive() &&
+ nVertByPos != rVertPosition.GetValue() ) )
+ {
+ rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_VERT_ORIENT, nAlign));
+ rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_VERT_RELATION, nRel));
+ if(m_xVertByMF->get_sensitive())
+ rSet->Put(SfxInt32Item(SID_ATTR_TRANSFORM_VERT_POSITION, nVertByPos));
+ bModified = true;
+ }
+ }
+
+ // #i18732#
+ if (m_xFollowCB->get_state_changed_from_saved())
+ {
+ //Writer internal type - based on SfxBoolItem
+ const SfxPoolItem* pItem = GetItem( rOldSet, SID_SW_FOLLOW_TEXT_FLOW);
+ if(pItem)
+ {
+ std::unique_ptr<SfxBoolItem> pFollow(static_cast<SfxBoolItem*>(pItem->Clone()));
+ pFollow->SetValue(m_xFollowCB->get_active());
+ bModified |= nullptr != rSet->Put(std::move(pFollow));
+ }
+ }
+ }
+ }
+ if (m_xWidthMF->get_value_changed_from_saved() || m_xHeightMF->get_value_changed_from_saved())
+ {
+ sal_uInt32 nWidth = static_cast<sal_uInt32>(m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::TWIP)));
+ sal_uInt32 nHeight = static_cast<sal_uInt32>(m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::TWIP)));
+ rSet->Put( SfxUInt32Item( SID_ATTR_TRANSFORM_WIDTH, nWidth ) );
+ rSet->Put( SfxUInt32Item( SID_ATTR_TRANSFORM_HEIGHT, nHeight ) );
+ //this item is required by SdrEditView::SetGeoAttrToMarked()
+ rSet->Put( SfxUInt16Item( SID_ATTR_TRANSFORM_SIZE_POINT, sal_uInt16(RectPoint::LT) ) );
+
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+void SvxSwPosSizeTabPage::Reset( const SfxItemSet* rSet)
+{
+ const SfxPoolItem* pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_ANCHOR );
+ bool bInvalidateAnchor = false;
+ RndStdIds nAnchorType = RndStdIds::FLY_AT_PARA;
+ if(pItem)
+ {
+ nAnchorType = static_cast<RndStdIds>(static_cast<const SfxInt16Item*>(pItem)->GetValue());
+ switch(nAnchorType)
+ {
+ case RndStdIds::FLY_AT_PAGE: m_xToPageRB->set_active(true); break;
+ case RndStdIds::FLY_AT_PARA: m_xToParaRB->set_active(true); break;
+ case RndStdIds::FLY_AT_CHAR: m_xToCharRB->set_active(true); break;
+ case RndStdIds::FLY_AS_CHAR: m_xAsCharRB->set_active(true); break;
+ case RndStdIds::FLY_AT_FLY: m_xToFrameRB->set_active(true); break;
+ default : bInvalidateAnchor = true;
+ }
+ m_xToPageRB->save_state();
+ m_xToParaRB->save_state();
+ m_xToCharRB->save_state();
+ m_xAsCharRB->save_state();
+ m_xToFrameRB->save_state();
+ }
+ if (bInvalidateAnchor)
+ {
+ m_xToPageRB->set_sensitive( false );
+ m_xToParaRB->set_sensitive( false );
+ m_xToCharRB->set_sensitive( false );
+ m_xAsCharRB->set_sensitive( false );
+ m_xToFrameRB->set_sensitive( false );
+ }
+
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_PROTECT_POS );
+ if (pItem)
+ {
+ bool bProtected = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+ m_xPositionCB->set_active(bProtected);
+ m_xSizeCB->set_sensitive(!bProtected);
+ }
+ else
+ {
+ m_xPositionCB->set_inconsistent(true);
+ }
+
+ m_xPositionCB->save_state();
+
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_PROTECT_SIZE );
+
+ if (pItem)
+ {
+ m_xSizeCB->set_active(static_cast<const SfxBoolItem*>(pItem)->GetValue());
+ }
+ else
+ m_xSizeCB->set_inconsistent(true);
+ m_xSizeCB->save_state();
+
+ pItem = GetItem( *rSet, SID_HTML_MODE );
+ if(pItem)
+ {
+ m_bHtmlMode =
+ (static_cast<const SfxUInt16Item*>(pItem)->GetValue() & HTMLMODE_ON)
+ != 0;
+ }
+
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_IN_VERTICAL_TEXT );
+ if(pItem && static_cast<const SfxBoolItem*>(pItem)->GetValue())
+ {
+ OUString sHLabel = m_xHoriFT->get_label();
+ m_xHoriFT->set_label(m_xVertFT->get_label());
+ m_xVertFT->set_label(sHLabel);
+ m_bIsVerticalFrame = true;
+ }
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_IN_RTL_TEXT);
+ if(pItem)
+ m_bIsInRightToLeft = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+
+ pItem = GetItem( *rSet, SID_SW_FOLLOW_TEXT_FLOW);
+ if(pItem)
+ {
+ const bool bFollowTextFlow =
+ static_cast<const SfxBoolItem*>(pItem)->GetValue();
+ m_xFollowCB->set_active(bFollowTextFlow);
+ }
+ m_xFollowCB->save_state();
+
+ if(m_bHtmlMode)
+ {
+ m_xHoriMirrorCB->hide();
+ m_xKeepRatioCB->set_sensitive(false);
+ // #i18732# - hide checkbox in HTML mode
+ m_xFollowCB->hide();
+ }
+ else
+ {
+ // #i18732# correct enable/disable of check box 'Mirror on..'
+ m_xHoriMirrorCB->set_sensitive(!m_xAsCharRB->get_active() && !m_bIsMultiSelection);
+
+ // #i18732# - enable/disable check box 'Follow text flow'.
+ m_xFollowCB->set_sensitive(m_xToParaRB->get_active() ||
+ m_xToCharRB->get_active());
+ }
+
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_WIDTH );
+ sal_Int32 nWidth = std::max( pItem ? ( static_cast<const SfxUInt32Item*>(pItem)->GetValue()) : 0, sal_uInt32(1) );
+
+ m_xWidthMF->set_value(m_xWidthMF->normalize(nWidth), FieldUnit::TWIP);
+ m_xWidthMF->save_value();
+
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HEIGHT );
+ sal_Int32 nHeight = std::max( pItem ? ( static_cast<const SfxUInt32Item*>(pItem)->GetValue()) : 0, sal_uInt32(1) );
+ m_xHeightMF->set_value(m_xHeightMF->normalize(nHeight), FieldUnit::TWIP);
+ m_xHeightMF->save_value();
+ m_fWidthHeightRatio = double(nWidth) / double(nHeight);
+
+ if(m_bPositioningDisabled)
+ return;
+
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_ORIENT);
+ if(pItem)
+ {
+ short nHoriOrientation = static_cast< const SfxInt16Item*>(pItem)->GetValue();
+ m_nOldH = nHoriOrientation;
+ }
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_VERT_ORIENT);
+ if(pItem)
+ {
+ short nVertOrientation = static_cast< const SfxInt16Item*>(pItem)->GetValue();
+ m_nOldV = nVertOrientation;
+ }
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_RELATION);
+ if(pItem)
+ {
+ m_nOldHRel = static_cast< const SfxInt16Item*>(pItem)->GetValue();
+ }
+
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_VERT_RELATION);
+ if(pItem)
+ {
+ m_nOldVRel = static_cast< const SfxInt16Item*>(pItem)->GetValue();
+ }
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_MIRROR);
+ if(pItem)
+ m_xHoriMirrorCB->set_active(static_cast<const SfxBoolItem*>(pItem)->GetValue());
+ m_xHoriMirrorCB->save_state();
+
+ sal_Int32 nHoriPos = 0;
+ sal_Int32 nVertPos = 0;
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_POSITION);
+ if(pItem)
+ nHoriPos = static_cast<const SfxInt32Item*>(pItem)->GetValue();
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_VERT_POSITION);
+ if(pItem)
+ nVertPos = static_cast<const SfxInt32Item*>(pItem)->GetValue();
+
+ InitPos(nAnchorType, m_nOldH, m_nOldHRel, m_nOldV, m_nOldVRel, nHoriPos, nVertPos);
+
+ m_xVertByMF->save_value();
+ m_xHoriByMF->save_value();
+ // #i18732#
+ m_xFollowCB->save_state();
+
+ RangeModifyHdl(m_xWidthMF->get_widget()); // initially set maximum values
+}
+
+DeactivateRC SvxSwPosSizeTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if( _pSet )
+ {
+ _pSet->Put(SfxBoolItem( SID_ATTR_TRANSFORM_PROTECT_POS,
+ m_xPositionCB->get_active()));
+ _pSet->Put(SfxBoolItem( SID_ATTR_TRANSFORM_PROTECT_SIZE,
+ m_xSizeCB->get_active()));
+ FillItemSet( _pSet );
+ }
+ return DeactivateRC::LeavePage;
+}
+
+void SvxSwPosSizeTabPage::EnableAnchorTypes(SvxAnchorIds nAnchorEnable)
+{
+ if (nAnchorEnable & SvxAnchorIds::Fly)
+ m_xToFrameRB->show();
+ if (!(nAnchorEnable & SvxAnchorIds::Page))
+ m_xToPageRB->set_sensitive(false);
+}
+
+RndStdIds SvxSwPosSizeTabPage::GetAnchorType(bool* pbHasChanged)
+{
+ RndStdIds nRet = RndStdIds::UNKNOWN;
+ weld::RadioButton* pCheckedButton = nullptr;
+ if(m_xToParaRB->get_sensitive())
+ {
+ if(m_xToPageRB->get_active())
+ {
+ nRet = RndStdIds::FLY_AT_PAGE;
+ pCheckedButton = m_xToPageRB.get();
+ }
+ else if(m_xToParaRB->get_active())
+ {
+ nRet = RndStdIds::FLY_AT_PARA;
+ pCheckedButton = m_xToParaRB.get();
+ }
+ else if(m_xToCharRB->get_active())
+ {
+ nRet = RndStdIds::FLY_AT_CHAR;
+ pCheckedButton = m_xToCharRB.get();
+ }
+ else if(m_xAsCharRB->get_active())
+ {
+ nRet = RndStdIds::FLY_AS_CHAR;
+ pCheckedButton = m_xAsCharRB.get();
+ }
+ else if(m_xToFrameRB->get_active())
+ {
+ nRet = RndStdIds::FLY_AT_FLY;
+ pCheckedButton = m_xToFrameRB.get();
+ }
+ }
+ if(pbHasChanged)
+ {
+ if(pCheckedButton)
+ *pbHasChanged = pCheckedButton->get_state_changed_from_saved();
+ else
+ *pbHasChanged = false;
+ }
+ return nRet;
+}
+
+IMPL_LINK_NOARG(SvxSwPosSizeTabPage, RangeModifyClickHdl, weld::Toggleable&, void)
+{
+ RangeModifyHdl(m_xWidthMF->get_widget());
+}
+
+IMPL_LINK_NOARG(SvxSwPosSizeTabPage, RangeModifyHdl, weld::Widget&, void)
+{
+ if (m_bPositioningDisabled)
+ return;
+ SvxSwFrameValidation aVal;
+
+ aVal.nAnchorType = GetAnchorType();
+ aVal.bAutoHeight = false;
+ aVal.bMirror = m_xHoriMirrorCB->get_active();
+ // #i18732#
+ aVal.bFollowTextFlow = m_xFollowCB->get_active();
+
+ if ( m_pHMap )
+ {
+ // horizontal alignment
+ sal_uInt16 nMapPos = GetMapPos(m_pHMap, *m_xHoriToLB);
+ sal_uInt16 nAlign = GetAlignment(m_pHMap, nMapPos, *m_xHoriToLB);
+ sal_uInt16 nRel = GetRelation(*m_xHoriToLB);
+
+ aVal.nHoriOrient = static_cast<short>(nAlign);
+ aVal.nHRelOrient = static_cast<short>(nRel);
+ }
+ else
+ aVal.nHoriOrient = HoriOrientation::NONE;
+
+ if ( m_pVMap )
+ {
+ // vertical alignment
+ sal_uInt16 nMapPos = GetMapPos(m_pVMap, *m_xVertLB);
+ sal_uInt16 nAlign = GetAlignment(m_pVMap, nMapPos, *m_xVertToLB);
+ sal_uInt16 nRel = GetRelation(*m_xVertToLB);
+
+ aVal.nVertOrient = static_cast<short>(nAlign);
+ aVal.nVRelOrient = static_cast<short>(nRel);
+ }
+ else
+ aVal.nVertOrient = VertOrientation::NONE;
+
+ const auto nAtHorzPosVal = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
+ const auto nAtVertPosVal = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
+
+ aVal.nHPos = nAtHorzPosVal;
+ aVal.nVPos = nAtVertPosVal;
+
+ sal_Int32 nWidth = static_cast<sal_uInt32>(m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::TWIP)));
+ sal_Int32 nHeight = static_cast<sal_uInt32>(m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::TWIP)));
+ aVal.nWidth = nWidth;
+ aVal.nHeight = nHeight;
+
+ m_aValidateLink.Call(aVal);
+
+ // minimum width also for style
+ m_xHeightMF->set_min(m_xHeightMF->normalize(aVal.nMinHeight), FieldUnit::TWIP);
+ m_xWidthMF->set_min(m_xWidthMF->normalize(aVal.nMinWidth), FieldUnit::TWIP);
+
+ sal_Int32 nMaxWidth(aVal.nMaxWidth);
+ sal_Int32 nMaxHeight(aVal.nMaxHeight);
+
+ sal_Int64 nTmp = m_xHeightMF->normalize(nMaxHeight);
+ m_xHeightMF->set_max(nTmp, FieldUnit::TWIP);
+
+ nTmp = m_xWidthMF->normalize(nMaxWidth);
+ m_xWidthMF->set_max(nTmp, FieldUnit::TWIP);
+
+ m_xHoriByMF->set_range(m_xHoriByMF->normalize(aVal.nMinHPos),
+ m_xHoriByMF->normalize(aVal.nMaxHPos), FieldUnit::TWIP);
+ if ( aVal.nHPos != nAtHorzPosVal )
+ m_xHoriByMF->set_value(m_xHoriByMF->normalize(aVal.nHPos), FieldUnit::TWIP);
+
+ m_xVertByMF->set_range(m_xVertByMF->normalize(aVal.nMinVPos),
+ m_xVertByMF->normalize(aVal.nMaxVPos), FieldUnit::TWIP);
+ if ( aVal.nVPos != nAtVertPosVal )
+ m_xVertByMF->set_value(m_xVertByMF->normalize(aVal.nVPos), FieldUnit::TWIP);
+}
+
+IMPL_LINK_NOARG(SvxSwPosSizeTabPage, AnchorTypeHdl, weld::Toggleable&, void)
+{
+ m_xHoriMirrorCB->set_sensitive(!m_xAsCharRB->get_active() && !m_bIsMultiSelection);
+
+ // #i18732# - enable check box 'Follow text flow' for anchor
+ // type to-paragraph' and to-character
+ m_xFollowCB->set_sensitive(m_xToParaRB->get_active() || m_xToCharRB->get_active());
+
+ RndStdIds nId = GetAnchorType();
+
+ InitPos( nId, USHRT_MAX, 0, USHRT_MAX, 0, LONG_MAX, LONG_MAX);
+ RangeModifyHdl(m_xWidthMF->get_widget());
+
+ if(m_bHtmlMode)
+ {
+ PosHdl(*m_xHoriLB);
+ PosHdl(*m_xVertLB);
+ }
+}
+
+IMPL_LINK_NOARG(SvxSwPosSizeTabPage, MirrorHdl, weld::Toggleable&, void)
+{
+ RndStdIds nId = GetAnchorType();
+ InitPos( nId, USHRT_MAX, 0, USHRT_MAX, 0, LONG_MAX, LONG_MAX);
+}
+
+IMPL_LINK( SvxSwPosSizeTabPage, RelHdl, weld::ComboBox&, rLB, void )
+{
+ bool bHori = &rLB == m_xHoriToLB.get();
+
+ UpdateExample();
+
+ if (m_bHtmlMode && RndStdIds::FLY_AT_CHAR == GetAnchorType()) // again special treatment
+ {
+ if(bHori)
+ {
+ sal_uInt16 nRel = GetRelation(*m_xHoriToLB);
+ if(RelOrientation::PRINT_AREA == nRel && 0 == m_xVertLB->get_active())
+ {
+ m_xVertLB->set_active(1);
+ }
+ else if(RelOrientation::CHAR == nRel && 1 == m_xVertLB->get_active())
+ {
+ m_xVertLB->set_active(0);
+ }
+ }
+ }
+ RangeModifyHdl(m_xWidthMF->get_widget());
+}
+
+IMPL_LINK(SvxSwPosSizeTabPage, PosHdl, weld::ComboBox&, rLB, void)
+{
+ bool bHori = &rLB == m_xHoriLB.get();
+ weld::ComboBox* pRelLB = bHori ? m_xHoriToLB.get() : m_xVertToLB.get();
+ weld::Label* pRelFT = bHori ? m_xHoriToFT.get() : m_xVertToFT.get();
+ FrmMap const *pMap = bHori ? m_pHMap : m_pVMap;
+
+
+ sal_uInt16 nMapPos = GetMapPos(pMap, rLB);
+ sal_uInt16 nAlign = GetAlignment(pMap, nMapPos, *pRelLB);
+
+ if (bHori)
+ {
+ bool bEnable = HoriOrientation::NONE == nAlign;
+ m_xHoriByMF->set_sensitive( bEnable );
+ m_xHoriByFT->set_sensitive( bEnable );
+ }
+ else
+ {
+ bool bEnable = VertOrientation::NONE == nAlign;
+ m_xVertByMF->set_sensitive( bEnable );
+ m_xVertByFT->set_sensitive( bEnable );
+ }
+
+ RangeModifyHdl(m_xWidthMF->get_widget());
+
+ short nRel = 0;
+ if (rLB.get_active() != -1)
+ {
+ if (pRelLB->get_active() != -1)
+ nRel = weld::fromId<RelationMap*>(pRelLB->get_active_id())->nRelation;
+
+ FillRelLB(pMap, nMapPos, nAlign, nRel, *pRelLB, *pRelFT);
+ }
+ else
+ pRelLB->clear();
+
+ UpdateExample();
+
+ // special treatment for HTML-Mode with horz-vert-dependencies
+ if (!(m_bHtmlMode && RndStdIds::FLY_AT_CHAR == GetAnchorType()))
+ return;
+
+ bool bSet = false;
+ if(bHori)
+ {
+ // on the right only below is allowed - from the left only at the top
+ // from the left at the character -> below
+ if((HoriOrientation::LEFT == nAlign || HoriOrientation::RIGHT == nAlign) &&
+ 0 == m_xVertLB->get_active())
+ {
+ if(RelOrientation::FRAME == nRel)
+ m_xVertLB->set_active(1);
+ else
+ m_xVertLB->set_active(0);
+ bSet = true;
+ }
+ else if(HoriOrientation::LEFT == nAlign && 1 == m_xVertLB->get_active())
+ {
+ m_xVertLB->set_active(0);
+ bSet = true;
+ }
+ else if(HoriOrientation::NONE == nAlign && 1 == m_xVertLB->get_active())
+ {
+ m_xVertLB->set_active(0);
+ bSet = true;
+ }
+ if(bSet)
+ PosHdl(*m_xVertLB);
+ }
+ else
+ {
+ if(VertOrientation::TOP == nAlign)
+ {
+ if(1 == m_xHoriLB->get_active())
+ {
+ m_xHoriLB->set_active(0);
+ bSet = true;
+ }
+ m_xHoriToLB->set_active(1);
+ }
+ else if(VertOrientation::CHAR_BOTTOM == nAlign)
+ {
+ if(2 == m_xHoriLB->get_active())
+ {
+ m_xHoriLB->set_active(0);
+ bSet = true;
+ }
+ m_xHoriToLB->set_active(0) ;
+ }
+ if(bSet)
+ PosHdl(*m_xHoriLB);
+ }
+}
+
+IMPL_LINK( SvxSwPosSizeTabPage, ModifyHdl, weld::MetricSpinButton&, rEdit, void )
+{
+ auto nWidth = m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::TWIP));
+ auto nHeight = m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::TWIP));
+ if (m_xKeepRatioCB->get_active())
+ {
+ if ( &rEdit == m_xWidthMF.get() )
+ {
+ nHeight = int(static_cast<double>(nWidth) / m_fWidthHeightRatio);
+ m_xHeightMF->set_value(m_xHeightMF->normalize(nHeight), FieldUnit::TWIP);
+ }
+ else if(&rEdit == m_xHeightMF.get())
+ {
+ nWidth = int(static_cast<double>(nHeight) * m_fWidthHeightRatio);
+ m_xWidthMF->set_value(m_xWidthMF->normalize(nWidth), FieldUnit::TWIP);
+ }
+ }
+ m_fWidthHeightRatio = nHeight ? double(nWidth) / double(nHeight) : 1.0;
+ UpdateExample();
+}
+
+IMPL_LINK_NOARG(SvxSwPosSizeTabPage, ProtectHdl, weld::Toggleable&, void)
+{
+ if (m_xSizeCB->get_sensitive())
+ {
+ m_nProtectSizeState = m_xSizeCB->get_state();
+ }
+
+ m_xSizeCB->set_state(m_xPositionCB->get_state() == TRISTATE_TRUE ? TRISTATE_TRUE : m_nProtectSizeState);
+ m_xSizeCB->set_sensitive(m_xPositionCB->get_sensitive() && !m_xPositionCB->get_active());
+}
+
+short SvxSwPosSizeTabPage::GetRelation(const weld::ComboBox& rRelationLB)
+{
+ short nRel = 0;
+ int nPos = rRelationLB.get_active();
+ if (nPos != -1)
+ {
+ RelationMap *pEntry = weld::fromId<RelationMap*>(rRelationLB.get_id(nPos));
+ nRel = pEntry->nRelation;
+ }
+
+ return nRel;
+}
+
+short SvxSwPosSizeTabPage::GetAlignment(FrmMap const *pMap, sal_uInt16 nMapPos, const weld::ComboBox& rRelationLB)
+{
+ short nAlign = 0;
+
+ // #i22341# - special handling also for map <aVCharMap>,
+ // because it contains ambiguous items for alignment
+ if (pMap == aVAsCharHtmlMap || pMap == aVAsCharMap ||
+ pMap == aVCharMap )
+ {
+ if (rRelationLB.get_active() != -1)
+ {
+ LB nRel = weld::fromId<RelationMap*>(rRelationLB.get_active_id())->nLBRelation;
+ std::size_t nMapCount = ::lcl_GetFrmMapCount(pMap);
+ SvxSwFramePosString::StringId eStrId = pMap[nMapPos].eStrId;
+
+ for (std::size_t i = 0; i < nMapCount; i++)
+ {
+ if (pMap[i].eStrId == eStrId)
+ {
+ LB nLBRelations = pMap[i].nLBRelations;
+ if (nLBRelations & nRel)
+ {
+ nAlign = pMap[i].nAlign;
+ break;
+ }
+ }
+ }
+ }
+ }
+ else if (pMap)
+ nAlign = pMap[nMapPos].nAlign;
+
+ return nAlign;
+}
+
+sal_uInt16 SvxSwPosSizeTabPage::GetMapPos(FrmMap const *pMap, const weld::ComboBox& rAlignLB)
+{
+ sal_uInt16 nMapPos = 0;
+ int nLBSelPos = rAlignLB.get_active();
+
+ if (nLBSelPos != -1)
+ {
+ if (pMap == aVAsCharHtmlMap || pMap == aVAsCharMap)
+ {
+ std::size_t nMapCount = ::lcl_GetFrmMapCount(pMap);
+ OUString sSelEntry(rAlignLB.get_active_text());
+
+ for (std::size_t i = 0; i < nMapCount; i++)
+ {
+ SvxSwFramePosString::StringId eResId = pMap[i].eStrId;
+
+ OUString sEntry = SvxSwFramePosString::GetString(eResId);
+
+ if (sEntry == sSelEntry)
+ {
+ nMapPos = sal::static_int_cast< sal_uInt16 >(i);
+ break;
+ }
+ }
+ }
+ else
+ nMapPos = nLBSelPos;
+ }
+
+ return nMapPos;
+}
+
+void SvxSwPosSizeTabPage::InitPos(RndStdIds nAnchor,
+ sal_uInt16 nH,
+ sal_uInt16 nHRel,
+ sal_uInt16 nV,
+ sal_uInt16 nVRel,
+ tools::Long nX,
+ tools::Long nY)
+{
+ int nPos = m_xVertLB->get_active();
+ if (nPos != -1 && m_pVMap)
+ {
+ m_nOldV = m_pVMap[nPos].nAlign;
+ nPos = m_xVertToLB->get_active();
+ if (nPos != -1)
+ m_nOldVRel = weld::fromId<RelationMap*>(m_xVertToLB->get_id(nPos))->nRelation;
+ }
+
+ nPos = m_xHoriLB->get_active();
+ if (nPos != -1 && m_pHMap)
+ {
+ m_nOldH = m_pHMap[nPos].nAlign;
+
+ nPos = m_xHoriToLB->get_active();
+ if (nPos != -1)
+ m_nOldHRel = weld::fromId<RelationMap*>(m_xHoriToLB->get_id(nPos))->nRelation;
+ }
+
+ bool bEnable = true;
+ if( m_bIsMultiSelection )
+ {
+ m_pVMap = aVMultiSelectionMap;
+ m_pHMap = aHMultiSelectionMap;
+ }
+ else if (nAnchor == RndStdIds::FLY_AT_PAGE)
+ {
+ m_pVMap = m_bHtmlMode ? aVPageHtmlMap : aVPageMap;
+ m_pHMap = m_bHtmlMode ? aHPageHtmlMap : aHPageMap;
+ }
+ else if (nAnchor == RndStdIds::FLY_AT_FLY)
+ {
+ // #i18732# - own vertical alignment map for to frame
+ // anchored objects.
+ m_pVMap = m_bHtmlMode ? aVFlyHtmlMap : aVFrameMap;
+ m_pHMap = m_bHtmlMode ? aHFlyHtmlMap : aHFrameMap;
+ }
+ else if (nAnchor == RndStdIds::FLY_AT_PARA)
+ {
+ if(m_bHtmlMode)
+ {
+ m_pVMap = aVParaHtmlMap;
+ m_pHMap = aHParaHtmlAbsMap;
+ }
+ else
+ {
+ m_pVMap = aVParaMap;
+ m_pHMap = aHParaMap;
+ }
+ }
+ else if (nAnchor == RndStdIds::FLY_AT_CHAR)
+ {
+ if(m_bHtmlMode)
+ {
+ m_pVMap = aVCharHtmlAbsMap;
+ m_pHMap = aHCharHtmlAbsMap;
+ }
+ else
+ {
+ m_pVMap = aVCharMap;
+ m_pHMap = aHCharMap;
+ }
+ }
+ else if (nAnchor == RndStdIds::FLY_AS_CHAR)
+ {
+ m_pVMap = m_bHtmlMode ? aVAsCharHtmlMap : aVAsCharMap;
+ m_pHMap = nullptr;
+ bEnable = false;
+ }
+ m_xHoriLB->set_sensitive(bEnable);
+ m_xHoriFT->set_sensitive(bEnable);
+
+ // select current Pos
+ // horizontal
+ if ( nH == USHRT_MAX )
+ {
+ nH = m_nOldH;
+ nHRel = m_nOldHRel;
+ }
+ // #i22341# - pass <nHRel> as 3rd parameter to method <FillPosLB>
+ sal_uInt16 nMapPos = FillPosLB(m_pHMap, nH, nHRel, *m_xHoriLB);
+ FillRelLB(m_pHMap, nMapPos, nH, nHRel, *m_xHoriToLB, *m_xHoriToFT);
+
+ // vertical
+ if ( nV == USHRT_MAX )
+ {
+ nV = m_nOldV;
+ nVRel = m_nOldVRel;
+ }
+ // #i22341# - pass <nVRel> as 3rd parameter to method <FillPosLB>
+ nMapPos = FillPosLB(m_pVMap, nV, nVRel, *m_xVertLB);
+ FillRelLB(m_pVMap, nMapPos, nV, nVRel, *m_xVertToLB, *m_xVertToFT);
+
+ // Edits init
+ bEnable = nH == HoriOrientation::NONE && nAnchor != RndStdIds::FLY_AS_CHAR; //#61359# why not in formats&& !bFormat;
+ if (!bEnable)
+ {
+ m_xHoriByMF->set_value(0, FieldUnit::TWIP);
+ }
+ else if(m_bIsMultiSelection)
+ {
+ m_xHoriByMF->set_value(m_xHoriByMF->normalize(m_aRect.Left()), FieldUnit::TWIP);
+ }
+ else
+ {
+ if (nX != LONG_MAX)
+ m_xHoriByMF->set_value(m_xHoriByMF->normalize(nX), FieldUnit::TWIP);
+ }
+ m_xHoriByFT->set_sensitive(bEnable);
+ m_xHoriByMF->set_sensitive(bEnable);
+
+ bEnable = nV == VertOrientation::NONE;
+ if ( !bEnable )
+ {
+ m_xVertByMF->set_value( 0, FieldUnit::TWIP );
+ }
+ else if(m_bIsMultiSelection)
+ {
+ m_xVertByMF->set_value(m_xVertByMF->normalize(m_aRect.Top()), FieldUnit::TWIP);
+ }
+ else
+ {
+ if (nAnchor == RndStdIds::FLY_AS_CHAR)
+ {
+ if ( nY == LONG_MAX )
+ nY = 0;
+ else
+ nY *= -1;
+ }
+ if ( nY != LONG_MAX )
+ m_xVertByMF->set_value( m_xVertByMF->normalize(nY), FieldUnit::TWIP );
+ }
+ m_xVertByFT->set_sensitive( bEnable );
+ m_xVertByMF->set_sensitive( bEnable );
+ UpdateExample();
+}
+
+void SvxSwPosSizeTabPage::UpdateExample()
+{
+ int nPos = m_xHoriLB->get_active();
+ if (m_pHMap && nPos != -1)
+ {
+ sal_uInt16 nMapPos = GetMapPos(m_pHMap, *m_xHoriLB);
+ short nAlign = GetAlignment(m_pHMap, nMapPos, *m_xHoriToLB);
+ short nRel = GetRelation(*m_xHoriToLB);
+
+ m_aExampleWN.SetHAlign(nAlign);
+ m_aExampleWN.SetHoriRel(nRel);
+ }
+
+ nPos = m_xVertLB->get_active();
+ if (m_pVMap && nPos != -1)
+ {
+ sal_uInt16 nMapPos = GetMapPos(m_pVMap, *m_xVertLB);
+ sal_uInt16 nAlign = GetAlignment(m_pVMap, nMapPos, *m_xVertToLB);
+ sal_uInt16 nRel = GetRelation(*m_xVertToLB);
+
+ m_aExampleWN.SetVAlign(nAlign);
+ m_aExampleWN.SetVertRel(nRel);
+ }
+
+ // Size
+ auto nXPos = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
+ auto nYPos = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
+ m_aExampleWN.SetRelPos(Point(nXPos, nYPos));
+
+ m_aExampleWN.SetAnchor( GetAnchorType() );
+ m_aExampleWN.Invalidate();
+}
+
+void SvxSwPosSizeTabPage::FillRelLB(FrmMap const *pMap, sal_uInt16 nMapPos, sal_uInt16 nAlign,
+ sal_uInt16 nRel, weld::ComboBox& rLB, weld::Label& rFT)
+{
+ OUString sSelEntry;
+ LB nLBRelations = LB::NONE;
+ std::size_t nMapCount = ::lcl_GetFrmMapCount(pMap);
+
+ rLB.clear();
+
+ if (nMapPos < nMapCount)
+ {
+ if (pMap == aVAsCharHtmlMap || pMap == aVAsCharMap)
+ {
+ OUString sOldEntry(rLB.get_active_text());
+ SvxSwFramePosString::StringId eStrId = pMap[nMapPos].eStrId;
+
+ for (std::size_t _nMapPos = 0; _nMapPos < nMapCount; _nMapPos++)
+ {
+ if (pMap[_nMapPos].eStrId == eStrId)
+ {
+ nLBRelations = pMap[_nMapPos].nLBRelations;
+ for (size_t nRelPos = 0; nRelPos < std::size(aAsCharRelationMap); nRelPos++)
+ {
+ if (nLBRelations & aAsCharRelationMap[nRelPos].nLBRelation)
+ {
+ SvxSwFramePosString::StringId sStrId1 = aAsCharRelationMap[nRelPos].eStrId;
+
+ sStrId1 = lcl_ChangeResIdToVerticalOrRTL(sStrId1, m_bIsVerticalFrame, m_bIsInRightToLeft);
+ OUString sEntry = SvxSwFramePosString::GetString(sStrId1);
+ rLB.append(weld::toId(&aAsCharRelationMap[nRelPos]), sEntry);
+ if (pMap[_nMapPos].nAlign == nAlign)
+ sSelEntry = sEntry;
+ break;
+ }
+ }
+ }
+ }
+ if (!sSelEntry.isEmpty())
+ rLB.set_active_text(sSelEntry);
+ else
+ {
+ rLB.set_active_text(sOldEntry);
+ if (rLB.get_active() == -1)
+ {
+ for (int i = 0; i < rLB.get_count(); i++)
+ {
+ RelationMap *pEntry = weld::fromId<RelationMap*>(rLB.get_id(i));
+ if (pEntry->nLBRelation == LB::RelChar) // Default
+ {
+ rLB.set_active(i);
+ break;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ // #i22341# - special handling for map <aVCharMap>,
+ // because its ambiguous in its <eStrId>/<eMirrorStrId>.
+ if ( pMap == aVCharMap )
+ {
+ nLBRelations = ::lcl_GetLBRelationsForStrID( pMap,
+ ( m_xHoriMirrorCB->get_active()
+ ? pMap[nMapPos].eMirrorStrId
+ : pMap[nMapPos].eStrId ),
+ m_xHoriMirrorCB->get_active() );
+ }
+ else
+ {
+ nLBRelations = pMap[nMapPos].nLBRelations;
+ }
+
+ for (std::underlying_type_t<LB> nBit = 1; nBit < o3tl::to_underlying(LB::LAST) ; nBit <<= 1)
+ {
+ if (nLBRelations & static_cast<LB>(nBit))
+ {
+ for (size_t nRelPos = 0; nRelPos < std::size(aRelationMap); nRelPos++)
+ {
+ if (aRelationMap[nRelPos].nLBRelation == static_cast<LB>(nBit))
+ {
+ SvxSwFramePosString::StringId sStrId1 = m_xHoriMirrorCB->get_active() ? aRelationMap[nRelPos].eMirrorStrId : aRelationMap[nRelPos].eStrId;
+ sStrId1 = lcl_ChangeResIdToVerticalOrRTL(sStrId1, m_bIsVerticalFrame, m_bIsInRightToLeft);
+ OUString sEntry = SvxSwFramePosString::GetString(sStrId1);
+ rLB.append(weld::toId(&aRelationMap[nRelPos]), sEntry);
+ if (sSelEntry.isEmpty() && aRelationMap[nRelPos].nRelation == nRel)
+ sSelEntry = sEntry;
+ }
+ }
+ }
+ }
+ if (!sSelEntry.isEmpty())
+ rLB.set_active_text(sSelEntry);
+ else
+ {
+ // Probably anchor change. So look for a similar relation.
+ switch (nRel)
+ {
+ case RelOrientation::FRAME: nRel = RelOrientation::PAGE_FRAME; break;
+ case RelOrientation::PRINT_AREA: nRel = RelOrientation::PAGE_PRINT_AREA; break;
+ case RelOrientation::PAGE_LEFT: nRel = RelOrientation::FRAME_LEFT; break;
+ case RelOrientation::PAGE_RIGHT: nRel = RelOrientation::FRAME_RIGHT; break;
+ case RelOrientation::FRAME_LEFT: nRel = RelOrientation::PAGE_LEFT; break;
+ case RelOrientation::FRAME_RIGHT: nRel = RelOrientation::PAGE_RIGHT; break;
+ case RelOrientation::PAGE_FRAME: nRel = RelOrientation::FRAME; break;
+ case RelOrientation::PAGE_PRINT_AREA: nRel = RelOrientation::PRINT_AREA; break;
+
+ default:
+ if (rLB.get_count())
+ {
+ RelationMap *pEntry = weld::fromId<RelationMap*>(rLB.get_id(rLB.get_count() - 1));
+ nRel = pEntry->nRelation;
+ }
+ break;
+ }
+
+ for (int i = 0; i < rLB.get_count(); ++i)
+ {
+ RelationMap *pEntry = weld::fromId<RelationMap*>(rLB.get_id(i));
+ if (pEntry->nRelation == nRel)
+ {
+ rLB.set_active(i);
+ break;
+ }
+ }
+
+ if (rLB.get_active() == -1)
+ rLB.set_active(0);
+ }
+ }
+ }
+
+ rLB.set_sensitive(rLB.get_count() != 0);
+ rFT.set_sensitive(rLB.get_count() != 0);
+
+ RelHdl(rLB);
+}
+
+sal_uInt16 SvxSwPosSizeTabPage::FillPosLB(FrmMap const *_pMap,
+ sal_uInt16 _nAlign,
+ const sal_uInt16 _nRel,
+ weld::ComboBox& _rLB)
+{
+ OUString sSelEntry, sOldEntry;
+ sOldEntry = _rLB.get_active_text();
+
+ _rLB.clear();
+
+ // #i22341# - determine all possible listbox relations for
+ // given relation for map <aVCharMap>
+ const LB nLBRelations = (_pMap != aVCharMap)
+ ? LB::NONE
+ : ::lcl_GetLBRelationsForRelations( _nRel );
+
+ // fill listbox
+ std::size_t nCount = ::lcl_GetFrmMapCount(_pMap);
+ for (std::size_t i = 0; _pMap && i < nCount; ++i)
+ {
+ SvxSwFramePosString::StringId eStrId = m_xHoriMirrorCB->get_active() ? _pMap[i].eMirrorStrId : _pMap[i].eStrId;
+ eStrId = lcl_ChangeResIdToVerticalOrRTL(eStrId, m_bIsVerticalFrame, m_bIsInRightToLeft);
+ OUString sEntry(SvxSwFramePosString::GetString(eStrId));
+ if (_rLB.find_text(sEntry) == -1)
+ {
+ // don't insert duplicate entries at character wrapped borders
+ _rLB.append_text(sEntry);
+ }
+ // #i22341# - add condition to handle map <aVCharMap>
+ // that is ambiguous in the alignment.
+ if ( _pMap[i].nAlign == _nAlign &&
+ ( _pMap != aVCharMap || _pMap[i].nLBRelations & nLBRelations ) )
+ {
+ sSelEntry = sEntry;
+ }
+ }
+
+ _rLB.set_active_text(sSelEntry);
+ if (_rLB.get_active() == -1)
+ _rLB.set_active_text(sOldEntry);
+
+ if (_rLB.get_active() == -1)
+ _rLB.set_active(0);
+
+ PosHdl(_rLB);
+
+ return GetMapPos(_pMap, _rLB);
+}
+
+void SvxSwPosSizeTabPage::SetView( const SdrView* pSdrView )
+{
+ m_pSdrView = pSdrView;
+ if(!m_pSdrView)
+ {
+ OSL_FAIL("No SdrView* set");
+ return;
+ }
+
+ // setting of the rectangle and the working area
+ m_aRect = m_pSdrView->GetAllMarkedRect();
+ m_pSdrView->GetSdrPageView()->LogicToPagePos( m_aRect );
+
+ // get WorkArea
+ m_aWorkArea = m_pSdrView->GetWorkArea();
+
+ // consider anchor position (for Writer)
+ const SdrMarkList& rMarkList = m_pSdrView->GetMarkedObjectList();
+ if( rMarkList.GetMarkCount() > 0 )
+ {
+ const SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
+ m_aAnchorPos = pObj->GetAnchorPos();
+
+ if( m_aAnchorPos != Point(0,0) ) // -> Writer
+ {
+ for( size_t i = 1; i < rMarkList.GetMarkCount(); ++i )
+ {
+ pObj = rMarkList.GetMark( i )->GetMarkedSdrObj();
+ if( m_aAnchorPos != pObj->GetAnchorPos() )
+ {
+ // different anchor positions -> disable positioning
+ m_xPosFrame->set_sensitive(false);
+ m_bPositioningDisabled = true;
+ return;
+ }
+ }
+ }
+ Point aPt = m_aAnchorPos * -1;
+ Point aPt2 = aPt;
+
+ aPt += m_aWorkArea.TopLeft();
+ m_aWorkArea.SetPos( aPt );
+
+ aPt2 += m_aRect.TopLeft();
+ m_aRect.SetPos( aPt2 );
+ }
+
+ // this should happen via SID_ATTR_TRANSFORM_AUTOSIZE
+ if( rMarkList.GetMarkCount() != 1 )
+ m_bIsMultiSelection = true;
+#if OSL_DEBUG_LEVEL > 1
+ else
+ {
+ const SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
+ SdrObjKind eKind = (SdrObjKind) pObj->GetObjIdentifier();
+ if( ( pObj->GetObjInventor() == SdrInventor::Default ) &&
+ ( eKind==SdrObjKind::Text || eKind==SdrObjKind::TitleText || eKind==SdrObjKind::OutlineText) &&
+ pObj->HasText() )
+ {
+ OSL_FAIL("AutoWidth/AutoHeight should be enabled");
+ }
+ }
+#endif
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tabarea.cxx b/cui/source/tabpages/tabarea.cxx
new file mode 100644
index 0000000000..4b50b74b8b
--- /dev/null
+++ b/cui/source/tabpages/tabarea.cxx
@@ -0,0 +1,252 @@
+/* -*- 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 <sfx2/objsh.hxx>
+#include <unotools/pathoptions.hxx>
+#include <svx/svxids.hrc>
+
+#include <svx/xtable.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/drawitem.hxx>
+#include <cuitabarea.hxx>
+
+SvxAreaTabDialog::SvxAreaTabDialog
+(
+ weld::Window* pParent,
+ const SfxItemSet* pAttr,
+ SdrModel* pModel,
+ bool bShadow,
+ bool bSlideBackground
+)
+ : SfxTabDialogController(pParent, "cui/ui/areadialog.ui", "AreaDialog", pAttr)
+ , mpDrawModel ( pModel ),
+ mpColorList ( pModel->GetColorList() ),
+ mpNewColorList ( pModel->GetColorList() ),
+ mpGradientList ( pModel->GetGradientList() ),
+ mpNewGradientList ( pModel->GetGradientList() ),
+ mpHatchingList ( pModel->GetHatchList() ),
+ mpNewHatchingList ( pModel->GetHatchList() ),
+ mpBitmapList ( pModel->GetBitmapList() ),
+ mpNewBitmapList ( pModel->GetBitmapList() ),
+ mpPatternList ( pModel->GetPatternList() ),
+ mpNewPatternList ( pModel->GetPatternList() ),
+
+ mnColorListState ( ChangeType::NONE ),
+ mnBitmapListState ( ChangeType::NONE ),
+ mnPatternListState ( ChangeType::NONE ),
+ mnGradientListState ( ChangeType::NONE ),
+ mnHatchingListState ( ChangeType::NONE )
+{
+ if (bSlideBackground)
+ AddTabPage("RID_SVXPAGE_AREA", SvxAreaTabPage::CreateWithSlideBackground, nullptr);
+ else
+ AddTabPage("RID_SVXPAGE_AREA", SvxAreaTabPage::Create, nullptr);
+
+ if (bShadow)
+ {
+ AddTabPage("RID_SVXPAGE_SHADOW", SvxShadowTabPage::Create, nullptr);
+ }
+ else
+ {
+ RemoveTabPage( "RID_SVXPAGE_SHADOW" );
+ }
+
+ AddTabPage( "RID_SVXPAGE_TRANSPARENCE", SvxTransparenceTabPage::Create, nullptr);
+
+ weld::Button& rBtnCancel = GetCancelButton();
+ rBtnCancel.connect_clicked(LINK(this, SvxAreaTabDialog, CancelHdlImpl));
+}
+
+void SvxAreaTabDialog::SavePalettes()
+{
+ SfxObjectShell* pShell = SfxObjectShell::Current();
+ if( mpNewColorList != mpDrawModel->GetColorList() )
+ {
+ mpDrawModel->SetPropertyList( static_cast<XPropertyList *>(mpNewColorList.get()) );
+ SvxColorListItem aColorListItem( mpNewColorList, SID_COLOR_TABLE );
+ if ( pShell )
+ pShell->PutItem( aColorListItem );
+ else
+ mpDrawModel->GetItemPool().DirectPutItemInPool(aColorListItem,SID_COLOR_TABLE);
+ mpColorList = mpDrawModel->GetColorList();
+ }
+ if( mpNewGradientList != mpDrawModel->GetGradientList() )
+ {
+ mpDrawModel->SetPropertyList( static_cast<XPropertyList *>(mpNewGradientList.get()) );
+ SvxGradientListItem aItem( mpNewGradientList, SID_GRADIENT_LIST );
+ if ( pShell )
+ pShell->PutItem( aItem );
+ else
+ mpDrawModel->GetItemPool().DirectPutItemInPool(aItem,SID_GRADIENT_LIST);
+ mpGradientList = mpDrawModel->GetGradientList();
+ }
+ if( mpNewHatchingList != mpDrawModel->GetHatchList() )
+ {
+ mpDrawModel->SetPropertyList( static_cast<XPropertyList *>(mpNewHatchingList.get()) );
+ SvxHatchListItem aItem( mpNewHatchingList, SID_HATCH_LIST );
+ if ( pShell )
+ pShell->PutItem( aItem );
+ else
+ mpDrawModel->GetItemPool().DirectPutItemInPool(aItem,SID_HATCH_LIST);
+ mpHatchingList = mpDrawModel->GetHatchList();
+ }
+ if( mpNewBitmapList != mpDrawModel->GetBitmapList() )
+ {
+ mpDrawModel->SetPropertyList( static_cast<XPropertyList *>(mpNewBitmapList.get()) );
+ SvxBitmapListItem aItem( mpNewBitmapList, SID_BITMAP_LIST );
+ if ( pShell )
+ pShell->PutItem( aItem );
+ else
+ mpDrawModel->GetItemPool().DirectPutItemInPool(aItem,SID_BITMAP_LIST);
+ mpBitmapList = mpDrawModel->GetBitmapList();
+ }
+ if( mpNewPatternList != mpDrawModel->GetPatternList() )
+ {
+ mpDrawModel->SetPropertyList( static_cast<XPropertyList *>(mpNewPatternList.get()) );
+ SvxPatternListItem aItem( mpNewPatternList, SID_PATTERN_LIST );
+ if( pShell )
+ pShell->PutItem( aItem );
+ else
+ mpDrawModel->GetItemPool().DirectPutItemInPool(aItem,SID_PATTERN_LIST);
+ mpPatternList = mpDrawModel->GetPatternList();
+ }
+
+ // save the tables when they have been changed
+
+ OUString aPalettePath(SvtPathOptions().GetPalettePath());
+ OUString aPath;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ aPath = aPalettePath.getToken(0, ';', nIndex);
+ }
+ while (nIndex >= 0);
+
+ if( mnHatchingListState & ChangeType::MODIFIED )
+ {
+ mpHatchingList->SetPath( aPath );
+ mpHatchingList->Save();
+
+ SvxHatchListItem aItem( mpHatchingList, SID_HATCH_LIST );
+ // ToolBoxControls are informed:
+ if ( pShell )
+ pShell->PutItem( aItem );
+ else
+ mpDrawModel->GetItemPool().DirectPutItemInPool(aItem);
+ }
+
+ if( mnBitmapListState & ChangeType::MODIFIED )
+ {
+ mpBitmapList->SetPath( aPath );
+ mpBitmapList->Save();
+
+ SvxBitmapListItem aItem( mpBitmapList, SID_BITMAP_LIST );
+ // ToolBoxControls are informed:
+ if ( pShell )
+ pShell->PutItem( aItem );
+ else
+ {
+ mpDrawModel->GetItemPool().DirectPutItemInPool(aItem);
+ }
+ }
+
+ if( mnPatternListState & ChangeType::MODIFIED )
+ {
+ mpPatternList->SetPath( aPath );
+ mpPatternList->Save();
+
+ SvxPatternListItem aItem( mpPatternList, SID_PATTERN_LIST );
+ // ToolBoxControls are informed:
+ if( pShell )
+ pShell->PutItem( aItem );
+ else
+ mpDrawModel->GetItemPool().DirectPutItemInPool(aItem);
+ }
+
+ if( mnGradientListState & ChangeType::MODIFIED )
+ {
+ mpGradientList->SetPath( aPath );
+ mpGradientList->Save();
+
+ SvxGradientListItem aItem( mpGradientList, SID_GRADIENT_LIST );
+ // ToolBoxControls are informed:
+ if ( pShell )
+ pShell->PutItem( aItem );
+ else
+ {
+ mpDrawModel->GetItemPool().DirectPutItemInPool(aItem);
+ }
+ }
+
+ if (mnColorListState & ChangeType::MODIFIED && mpColorList.is())
+ {
+ SvxColorListItem aItem( mpColorList, SID_COLOR_TABLE );
+ // ToolBoxControls are informed:
+ if ( pShell )
+ pShell->PutItem( aItem );
+ else
+ {
+ mpDrawModel->GetItemPool().DirectPutItemInPool(aItem);
+ }
+ }
+}
+
+short SvxAreaTabDialog::Ok()
+{
+ SavePalettes();
+ // RET_OK is returned, if at least one
+ // TabPage returns sal_True in FillItemSet().
+ // This happens by default at the moment.
+ return SfxTabDialogController::Ok();
+}
+
+IMPL_LINK_NOARG(SvxAreaTabDialog, CancelHdlImpl, weld::Button&, void)
+{
+ SavePalettes();
+ m_xDialog->response(RET_CANCEL);
+}
+
+void SvxAreaTabDialog::PageCreated(const OUString& rId, SfxTabPage &rPage)
+{
+ if (rId == "RID_SVXPAGE_AREA")
+ {
+ static_cast<SvxAreaTabPage&>(rPage).SetColorList( mpColorList );
+ static_cast<SvxAreaTabPage&>(rPage).SetGradientList( mpGradientList );
+ static_cast<SvxAreaTabPage&>(rPage).SetHatchingList( mpHatchingList );
+ static_cast<SvxAreaTabPage&>(rPage).SetBitmapList( mpBitmapList );
+ static_cast<SvxAreaTabPage&>(rPage).SetPatternList( mpPatternList );
+ static_cast<SvxAreaTabPage&>(rPage).SetGrdChgd( &mnGradientListState );
+ static_cast<SvxAreaTabPage&>(rPage).SetHtchChgd( &mnHatchingListState );
+ static_cast<SvxAreaTabPage&>(rPage).SetBmpChgd( &mnBitmapListState );
+ static_cast<SvxAreaTabPage&>(rPage).SetPtrnChgd( &mnPatternListState );
+ static_cast<SvxAreaTabPage&>(rPage).SetColorChgd( &mnColorListState );
+ }
+ else if (rId == "RID_SVXPAGE_SHADOW")
+ {
+ static_cast<SvxShadowTabPage&>(rPage).SetColorList( mpColorList );
+ static_cast<SvxShadowTabPage&>(rPage).SetColorChgd( &mnColorListState );
+ }
+ else if (rId == "RID_SVXPAGE_TRANSPARENCE")
+ {
+ static_cast<SvxTransparenceTabPage&>(rPage).SetPageType( PageType::Area );
+ static_cast<SvxTransparenceTabPage&>(rPage).SetDlgType( 0 );
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tabline.cxx b/cui/source/tabpages/tabline.cxx
new file mode 100644
index 0000000000..ac6cadd511
--- /dev/null
+++ b/cui/source/tabpages/tabline.cxx
@@ -0,0 +1,207 @@
+/* -*- 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 <unotools/pathoptions.hxx>
+#include <sfx2/objsh.hxx>
+#include <svx/svxids.hrc>
+#include <cuitabarea.hxx>
+#include <cuitabline.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/xtable.hxx>
+#include <svx/drawitem.hxx>
+
+SvxLineTabDialog::SvxLineTabDialog(weld::Window* pParent, const SfxItemSet* pAttr,
+ SdrModel* pModel, const SdrObject* pSdrObj, bool bHasObj)
+ : SfxTabDialogController(pParent, "cui/ui/linedialog.ui", "LineDialog", pAttr)
+ , pDrawModel(pModel)
+ , pObj(pSdrObj)
+ , pColorList(pModel->GetColorList())
+ , mpNewColorList(pModel->GetColorList())
+ , pDashList(pModel->GetDashList())
+ , pNewDashList(pModel->GetDashList())
+ , pLineEndList(pModel->GetLineEndList())
+ , pNewLineEndList(pModel->GetLineEndList())
+ , bObjSelected(bHasObj)
+ , nLineEndListState(ChangeType::NONE)
+ , nDashListState(ChangeType::NONE)
+ , mnColorListState(ChangeType::NONE)
+ , nPageType(PageType::Area) // We use it here primarily to get the right attributes with FillItemSet
+ , nPosDashLb(0)
+ , nPosLineEndLb(0)
+{
+ bool bLineOnly = false;
+ if( pObj && pObj->GetObjInventor() == SdrInventor::Default )
+ {
+ switch( pObj->GetObjIdentifier() )
+ {
+ case SdrObjKind::Line:
+ case SdrObjKind::PolyLine:
+ case SdrObjKind::PathLine:
+ case SdrObjKind::FreehandLine:
+ case SdrObjKind::Measure:
+ case SdrObjKind::Edge:
+ bLineOnly = true;
+ break;
+
+ default:
+ break;
+ }
+
+ }
+
+ AddTabPage("RID_SVXPAGE_LINE", SvxLineTabPage::Create, nullptr);
+ if( bLineOnly )
+ AddTabPage("RID_SVXPAGE_SHADOW", SvxShadowTabPage::Create, nullptr);
+ else
+ RemoveTabPage( "RID_SVXPAGE_SHADOW" );
+
+ AddTabPage("RID_SVXPAGE_LINE_DEF", SvxLineDefTabPage::Create, nullptr);
+ AddTabPage("RID_SVXPAGE_LINEEND_DEF", SvxLineEndDefTabPage::Create, nullptr);
+
+ weld::Button& rBtnCancel = GetCancelButton();
+ rBtnCancel.connect_clicked(LINK(this, SvxLineTabDialog, CancelHdlImpl));
+}
+
+void SvxLineTabDialog::SavePalettes()
+{
+ SfxObjectShell* pShell = SfxObjectShell::Current();
+ if( mpNewColorList != pDrawModel->GetColorList() )
+ {
+ pDrawModel->SetPropertyList( static_cast<XPropertyList *>(mpNewColorList.get()) );
+ if ( pShell )
+ pShell->PutItem( SvxColorListItem( mpNewColorList, SID_COLOR_TABLE ) );
+ pColorList = pDrawModel->GetColorList();
+ }
+ if( pNewDashList != pDrawModel->GetDashList() )
+ {
+ pDrawModel->SetPropertyList( static_cast<XPropertyList *>(pNewDashList.get()) );
+ if ( pShell )
+ pShell->PutItem( SvxDashListItem( pNewDashList, SID_DASH_LIST ) );
+ pDashList = pDrawModel->GetDashList();
+ }
+ if( pNewLineEndList != pDrawModel->GetLineEndList() )
+ {
+ pDrawModel->SetPropertyList( static_cast<XPropertyList *>(pNewLineEndList.get()) );
+ if ( pShell )
+ pShell->PutItem( SvxLineEndListItem( pNewLineEndList, SID_LINEEND_LIST ) );
+ pLineEndList = pDrawModel->GetLineEndList();
+ }
+
+ // Save the tables when they have been changed
+ OUString aPalettePath(SvtPathOptions().GetPalettePath());
+ OUString aPath;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ aPath = aPalettePath.getToken(0, ';', nIndex);
+ }
+ while (nIndex >= 0);
+
+ if( nDashListState & ChangeType::MODIFIED )
+ {
+ pDashList->SetPath( aPath );
+ pDashList->Save();
+
+ // Notify ToolBoxControls
+ if ( pShell )
+ pShell->PutItem( SvxDashListItem( pDashList, SID_DASH_LIST ) );
+ }
+
+ if( nLineEndListState & ChangeType::MODIFIED )
+ {
+ pLineEndList->SetPath( aPath );
+ pLineEndList->Save();
+
+ // Notify ToolBoxControls
+ if ( pShell )
+ pShell->PutItem( SvxLineEndListItem( pLineEndList, SID_LINEEND_LIST ) );
+ }
+
+ if( mnColorListState & ChangeType::MODIFIED )
+ {
+ pColorList->SetPath( aPath );
+ pColorList->Save();
+
+ // Notify ToolBoxControls
+ if ( pShell )
+ pShell->PutItem( SvxColorListItem( pColorList, SID_COLOR_TABLE ) );
+ }
+}
+
+short SvxLineTabDialog::Ok()
+{
+ SavePalettes();
+
+ // We return RET_OK if at least one TabPage in FillItemSet() returns sal_True.
+ // We do this by default at the moment.
+ return SfxTabDialogController::Ok();
+}
+
+IMPL_LINK_NOARG(SvxLineTabDialog, CancelHdlImpl, weld::Button&, void)
+{
+ SavePalettes();
+
+ m_xDialog->response(RET_CANCEL);
+}
+
+void SvxLineTabDialog::PageCreated(const OUString& rId, SfxTabPage &rPage)
+{
+ if (rId == "RID_SVXPAGE_LINE")
+ {
+ static_cast<SvxLineTabPage&>(rPage).SetDashList( pDashList );
+ static_cast<SvxLineTabPage&>(rPage).SetLineEndList( pLineEndList );
+ static_cast<SvxLineTabPage&>(rPage).SetDlgType( 0 );
+ static_cast<SvxLineTabPage&>(rPage).SetPageType( nPageType );
+ static_cast<SvxLineTabPage&>(rPage).SetPosDashLb( &nPosDashLb );
+ static_cast<SvxLineTabPage&>(rPage).SetPosLineEndLb( &nPosLineEndLb );
+ static_cast<SvxLineTabPage&>(rPage).SetDashChgd( &nDashListState );
+ static_cast<SvxLineTabPage&>(rPage).SetLineEndChgd( &nLineEndListState );
+ static_cast<SvxLineTabPage&>(rPage).SetObjSelected( bObjSelected );
+ static_cast<SvxLineTabPage&>(rPage).Construct();
+ static_cast<SvxLineTabPage&>(rPage).SetColorChgd( &mnColorListState );
+ }
+ else if (rId == "RID_SVXPAGE_LINE_DEF")
+ {
+ static_cast<SvxLineDefTabPage&>(rPage).SetDashList( pDashList );
+ static_cast<SvxLineDefTabPage&>(rPage).SetDlgType( 0 );
+ static_cast<SvxLineDefTabPage&>(rPage).SetPageType( &nPageType );
+ static_cast<SvxLineDefTabPage&>(rPage).SetPosDashLb( &nPosDashLb );
+ static_cast<SvxLineDefTabPage&>(rPage).SetDashChgd( &nDashListState );
+ static_cast<SvxLineDefTabPage&>(rPage).Construct();
+ }
+ else if (rId == "RID_SVXPAGE_LINEEND_DEF")
+ {
+ static_cast<SvxLineEndDefTabPage&>(rPage).SetLineEndList( pLineEndList );
+ static_cast<SvxLineEndDefTabPage&>(rPage).SetPolyObj( pObj );
+ static_cast<SvxLineEndDefTabPage&>(rPage).SetDlgType( 0 );
+ static_cast<SvxLineEndDefTabPage&>(rPage).SetPageType( &nPageType );
+ static_cast<SvxLineEndDefTabPage&>(rPage).SetPosLineEndLb( &nPosLineEndLb );
+ static_cast<SvxLineEndDefTabPage&>(rPage).SetLineEndChgd( &nLineEndListState );
+ static_cast<SvxLineEndDefTabPage&>(rPage).Construct();
+ }
+ else if (rId == "RID_SVXPAGE_SHADOW")
+ {
+ static_cast<SvxShadowTabPage&>(rPage).SetColorList( pColorList );
+ static_cast<SvxShadowTabPage&>(rPage).SetPageType( nPageType );
+ static_cast<SvxShadowTabPage&>(rPage).SetDlgType( 0 );
+ static_cast<SvxShadowTabPage&>(rPage).SetColorChgd( &mnColorListState );
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tabstpge.cxx b/cui/source/tabpages/tabstpge.cxx
new file mode 100644
index 0000000000..b3a1745c26
--- /dev/null
+++ b/cui/source/tabpages/tabstpge.cxx
@@ -0,0 +1,663 @@
+/* -*- 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 <svtools/ruler.hxx>
+#include <svtools/unitconv.hxx>
+#include <svx/svxids.hrc>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+
+#include <editeng/lrspitem.hxx>
+#include <tabstpge.hxx>
+#include <svx/dlgutil.hxx>
+#include <svl/cjkoptions.hxx>
+#include <unotools/localedatawrapper.hxx>
+#include <svl/intitem.hxx>
+
+constexpr FieldUnit eDefUnit = FieldUnit::MM_100TH;
+
+const WhichRangesContainer SvxTabulatorTabPage::pRanges(
+ svl::Items<SID_ATTR_TABSTOP, SID_ATTR_TABSTOP_OFFSET>);
+
+static void FillUpWithDefTabs_Impl( tools::Long nDefDist, SvxTabStopItem& rTabs )
+{
+ if( rTabs.Count() )
+ return;
+ {
+ SvxTabStop aSwTabStop( nDefDist, SvxTabAdjust::Default );
+ rTabs.Insert( aSwTabStop );
+ }
+}
+
+void TabWin_Impl::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle&)
+{
+ // Paint tabulators
+ Point aPoint;
+ Size aSize(GetOutputSizePixel());
+ aPoint.setX( aSize.Width() / 2 );
+ aPoint.setY( aSize.Height() / 2 );
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ rRenderContext.SetLineColor(rStyleSettings.GetShadowColor());
+ rRenderContext.SetFillColor(rStyleSettings.GetDialogColor());
+ rRenderContext.DrawRect(tools::Rectangle(Point(0,0), rRenderContext.GetOutputSize()));
+ Ruler::DrawTab(rRenderContext, rStyleSettings.GetDialogTextColor(), aPoint, nTabStyle);
+}
+
+SvxTabulatorTabPage::SvxTabulatorTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttr)
+ : SfxTabPage(pPage, pController, "cui/ui/paratabspage.ui", "ParagraphTabsPage", &rAttr)
+ , aCurrentTab(0)
+ , aNewTabs(std::make_unique<SvxTabStopItem>(0, 0, SvxTabAdjust::Left, GetWhich(SID_ATTR_TABSTOP)))
+ , nDefDist(0)
+ , m_xTabSpin(m_xBuilder->weld_metric_spin_button("SP_TABPOS", FieldUnit::CM))
+ , m_xTabBox(m_xBuilder->weld_entry_tree_view("tabgrid", "ED_TABPOS", "LB_TABPOS"))
+ , m_xCenterTab(m_xBuilder->weld_radio_button("radiobuttonBTN_TABTYPE_CENTER"))
+ , m_xDezTab(m_xBuilder->weld_radio_button("radiobuttonBTN_TABTYPE_DECIMAL"))
+ , m_xDezChar(m_xBuilder->weld_entry("entryED_TABTYPE_DECCHAR"))
+ , m_xDezCharLabel(m_xBuilder->weld_label("labelFT_TABTYPE_DECCHAR"))
+ // lower radio buttons
+ , m_xNoFillChar(m_xBuilder->weld_radio_button("radiobuttonBTN_FILLCHAR_NO"))
+ , m_xFillPoints(m_xBuilder->weld_radio_button("radiobuttonBTN_FILLCHAR_POINTS"))
+ , m_xFillDashLine(m_xBuilder->weld_radio_button("radiobuttonBTN_FILLCHAR_DASHLINE"))
+ , m_xFillSolidLine(m_xBuilder->weld_radio_button("radiobuttonBTN_FILLCHAR_UNDERSCORE"))
+ , m_xFillSpecial(m_xBuilder->weld_radio_button("radiobuttonBTN_FILLCHAR_OTHER"))
+ , m_xFillChar(m_xBuilder->weld_entry("entryED_FILLCHAR_OTHER"))
+ // button bar
+ , m_xNewBtn(m_xBuilder->weld_button("buttonBTN_NEW"))
+ , m_xDelAllBtn(m_xBuilder->weld_button("buttonBTN_DELALL"))
+ , m_xDelBtn(m_xBuilder->weld_button("buttonBTN_DEL"))
+ , m_xTypeFrame(m_xBuilder->weld_container("frameFL_TABTYPE"))
+ , m_xFillFrame(m_xBuilder->weld_container("frameFL_FILLCHAR"))
+ // the tab images
+ , m_xLeftWin(new weld::CustomWeld(*m_xBuilder, "drawingareaWIN_TABLEFT", m_aLeftWin))
+ , m_xRightWin(new weld::CustomWeld(*m_xBuilder, "drawingareaWIN_TABRIGHT", m_aRightWin))
+ , m_xCenterWin(new weld::CustomWeld(*m_xBuilder, "drawingareaWIN_TABCENTER", m_aCenterWin))
+ , m_xDezWin(new weld::CustomWeld(*m_xBuilder, "drawingareaWIN_TABDECIMAL", m_aDezWin))
+{
+ m_aLeftWin.SetTabStyle(sal_uInt16(RULER_TAB_LEFT|WB_HORZ));
+ m_aRightWin.SetTabStyle(sal_uInt16(RULER_TAB_RIGHT|WB_HORZ));
+ m_aCenterWin.SetTabStyle(sal_uInt16(RULER_TAB_CENTER|WB_HORZ));
+ m_aDezWin.SetTabStyle(sal_uInt16(RULER_TAB_DECIMAL|WB_HORZ));
+ //upper radiobuttons
+ m_xLeftTab = m_xBuilder->weld_radio_button(SvtCJKOptions::IsAsianTypographyEnabled() ? "radiobuttonST_LEFTTAB_ASIAN" : "radiobuttonBTN_TABTYPE_LEFT");
+ m_xRightTab = m_xBuilder->weld_radio_button(SvtCJKOptions::IsAsianTypographyEnabled() ? "radiobuttonST_RIGHTTAB_ASIAN" : "radiobuttonBTN_TABTYPE_RIGHT");
+ m_xLeftTab->show();
+ m_xRightTab->show();
+
+ // This page needs ExchangeSupport
+ SetExchangeSupport();
+
+ // Set metric
+ FieldUnit eFUnit = GetModuleFieldUnit( rAttr );
+ SetFieldUnit(*m_xTabSpin, eFUnit);
+
+ // Initialize buttons
+ m_xNewBtn->connect_clicked(LINK(this,SvxTabulatorTabPage, NewHdl_Impl));
+ m_xDelBtn->connect_clicked(LINK(this,SvxTabulatorTabPage, DelHdl_Impl));
+ m_xDelAllBtn->connect_clicked(LINK(this,SvxTabulatorTabPage, DelAllHdl_Impl));
+
+ Link<weld::Toggleable&,void> aLink = LINK(this, SvxTabulatorTabPage, TabTypeCheckHdl_Impl);
+ m_xLeftTab->connect_toggled(aLink);
+ m_xRightTab->connect_toggled(aLink);
+ m_xDezTab->connect_toggled(aLink);
+ m_xCenterTab->connect_toggled(aLink);
+
+ m_xDezChar->connect_focus_out(LINK(this, SvxTabulatorTabPage, GetDezCharHdl_Impl));
+ m_xDezChar->set_sensitive(false);
+ m_xDezCharLabel->set_sensitive(false);
+
+ aLink = LINK(this, SvxTabulatorTabPage, FillTypeCheckHdl_Impl);
+ m_xNoFillChar->connect_toggled(aLink);
+ m_xFillPoints->connect_toggled(aLink);
+ m_xFillDashLine->connect_toggled(aLink);
+ m_xFillSolidLine->connect_toggled(aLink);
+ m_xFillSpecial->connect_toggled(aLink);
+ m_xFillChar->connect_focus_out(LINK(this, SvxTabulatorTabPage, GetFillCharHdl_Impl));
+ m_xFillChar->set_sensitive(false);
+
+ m_xTabBox->connect_row_activated(LINK(this, SvxTabulatorTabPage, SelectHdl_Impl));
+ m_xTabBox->connect_changed(LINK(this, SvxTabulatorTabPage, ModifyHdl_Impl));
+ m_xTabBox->connect_focus_out(LINK(this, SvxTabulatorTabPage, ReformatHdl_Impl));
+
+ // Get the default decimal char from the system
+ const LocaleDataWrapper& rLocaleWrapper( Application::GetSettings().GetLocaleDataWrapper() );
+ aCurrentTab.GetDecimal() = rLocaleWrapper.getNumDecimalSep()[0];
+}
+
+SvxTabulatorTabPage::~SvxTabulatorTabPage()
+{
+ m_xDezWin.reset();
+ m_xCenterWin.reset();
+ m_xRightWin.reset();
+ m_xLeftWin.reset();
+ m_xFillChar.reset();
+ m_xDezChar.reset();
+ m_xTabBox.reset();
+}
+
+bool SvxTabulatorTabPage::FillItemSet(SfxItemSet* rSet)
+{
+ bool bModified = false;
+
+ // Put the controls' values in here
+ if (m_xNewBtn->get_sensitive())
+ NewHdl_Impl(nullptr);
+
+ // Call the LoseFocus-Handler first
+ GetDezCharHdl_Impl(*m_xDezChar);
+ GetFillCharHdl_Impl(*m_xFillChar);
+
+ FillUpWithDefTabs_Impl(nDefDist, *aNewTabs);
+ SfxItemPool* pPool = rSet->GetPool();
+ MapUnit eUnit = pPool->GetMetric(GetWhich(SID_ATTR_TABSTOP));
+ const SfxPoolItem* pOld = GetOldItem(*rSet, SID_ATTR_TABSTOP);
+
+ if (MapUnit::Map100thMM != eUnit)
+ {
+ // If the ItemSet contains a LRSpaceItem with negative first line indent,
+ // the TabStopItem needs to have a DefTab at position 0.
+ const SfxPoolItem* pLRSpace;
+ // If not in the new set, then maybe in the old one
+ if (SfxItemState::SET != rSet->GetItemState(GetWhich(SID_ATTR_LRSPACE), true, &pLRSpace))
+ pLRSpace = GetOldItem(*rSet, SID_ATTR_LRSPACE);
+
+ if (pLRSpace && static_cast<const SvxLRSpaceItem*>(pLRSpace)->GetTextFirstLineOffset() < 0)
+ {
+ SvxTabStop aNull(0, SvxTabAdjust::Default);
+ aNewTabs->Insert(aNull);
+ }
+
+ std::unique_ptr<SvxTabStopItem> aTmp(aNewTabs->Clone());
+ aTmp->Remove(0, aTmp->Count());
+
+ for (sal_uInt16 i = 0; i < aNewTabs->Count(); ++i)
+ {
+ SvxTabStop aTmpStop = (*aNewTabs)[i];
+ aTmpStop.GetTabPos() = OutputDevice::LogicToLogic(aTmpStop.GetTabPos(), MapUnit::Map100thMM, eUnit);
+ aTmp->Insert(aTmpStop);
+ }
+
+ if (!pOld || *static_cast<const SvxTabStopItem*>(pOld) != *aTmp)
+ {
+ rSet->Put(std::move(aTmp));
+ bModified = true;
+ }
+ }
+ else if (!pOld || *static_cast<const SvxTabStopItem*>(pOld) != *aNewTabs)
+ {
+ rSet->Put(*aNewTabs);
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+std::unique_ptr<SfxTabPage> SvxTabulatorTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxTabulatorTabPage>(pPage, pController, *rSet);
+}
+
+void SvxTabulatorTabPage::Reset(const SfxItemSet* rSet)
+{
+ SfxItemPool* pPool = rSet->GetPool();
+ MapUnit eUnit = pPool->GetMetric(GetWhich(SID_ATTR_TABSTOP));
+
+ // Current tabs
+ const SfxPoolItem* pItem = GetItem(*rSet, SID_ATTR_TABSTOP);
+
+ if (pItem)
+ {
+ if (MapUnit::Map100thMM != eUnit)
+ {
+ std::unique_ptr<SvxTabStopItem> aTmp(static_cast<SvxTabStopItem*>(pItem->Clone()));
+ aNewTabs->Remove(0, aNewTabs->Count());
+
+ for (sal_uInt16 i = 0; i < aTmp->Count(); ++i)
+ {
+ SvxTabStop aTmpStop = (*aTmp)[i];
+ aTmpStop.GetTabPos() = OutputDevice::LogicToLogic(aTmpStop.GetTabPos(), eUnit, MapUnit::Map100thMM);
+ aNewTabs->Insert(aTmpStop);
+ }
+ }
+ else
+ {
+ aNewTabs.reset(static_cast<SvxTabStopItem*>(pItem->Clone()));
+ }
+ }
+ else
+ {
+ aNewTabs->Remove(0, aNewTabs->Count());
+ }
+
+ // Default tab distance
+ nDefDist = SVX_TAB_DEFDIST;
+ pItem = GetItem(*rSet, SID_ATTR_TABSTOP_DEFAULTS);
+
+ if (pItem)
+ nDefDist = OutputDevice::LogicToLogic(tools::Long(static_cast<const SfxUInt16Item*>(pItem)->GetValue()), eUnit, MapUnit::Map100thMM);
+
+ // Tab pos currently selected
+ sal_uInt16 nTabPos = 0;
+ pItem = GetItem(*rSet, SID_ATTR_TABSTOP_POS);
+
+ if (pItem)
+ nTabPos = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
+
+ InitTabPos_Impl(nTabPos);
+}
+
+void SvxTabulatorTabPage::DisableControls(const TabulatorDisableFlags nFlag)
+{
+ if (TabulatorDisableFlags::TypeLeft & nFlag)
+ {
+ m_xLeftTab->set_sensitive(false);
+ m_xLeftWin->set_sensitive(false);
+ }
+ if (TabulatorDisableFlags::TypeRight & nFlag)
+ {
+ m_xRightTab->set_sensitive(false);
+ m_xRightWin->set_sensitive(false);
+ }
+ if (TabulatorDisableFlags::TypeCenter & nFlag)
+ {
+ m_xCenterTab->set_sensitive(false);
+ m_xCenterWin->set_sensitive(false);
+ }
+ if (TabulatorDisableFlags::TypeDecimal & nFlag)
+ {
+ m_xDezTab->set_sensitive(false);
+ m_xDezWin->set_sensitive(false);
+ m_xDezCharLabel->set_sensitive(false);
+ m_xDezChar->set_sensitive(false);
+ }
+ if (TabulatorDisableFlags::TypeMask & nFlag)
+ m_xTypeFrame->set_sensitive(false);
+ if (TabulatorDisableFlags::FillNone & nFlag)
+ m_xNoFillChar->set_sensitive(false);
+ if (TabulatorDisableFlags::FillPoint & nFlag)
+ m_xFillPoints->set_sensitive(false);
+ if (TabulatorDisableFlags::FillDashLine & nFlag)
+ m_xFillDashLine->set_sensitive(false);
+ if (TabulatorDisableFlags::FillSolidLine & nFlag)
+ m_xFillSolidLine->set_sensitive(false);
+ if (TabulatorDisableFlags::FillSpecial & nFlag)
+ {
+ m_xFillSpecial->set_sensitive(false);
+ m_xFillChar->set_sensitive(false);
+ }
+ if (TabulatorDisableFlags::FillMask & nFlag)
+ m_xFillFrame->set_sensitive(false);
+}
+
+DeactivateRC SvxTabulatorTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if ( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+void SvxTabulatorTabPage::InitTabPos_Impl( sal_uInt16 nTabPos )
+{
+ m_xTabBox->clear();
+
+ tools::Long nOffset = 0;
+ if (const SfxInt32Item* pOffSetItem = GetItemSet().GetItemIfSet(SID_ATTR_TABSTOP_OFFSET))
+ {
+ nOffset = pOffSetItem->GetValue();
+ MapUnit eUnit = GetItemSet().GetPool()->GetMetric(GetWhich(SID_ATTR_TABSTOP));
+ nOffset = OutputDevice::LogicToLogic(nOffset, eUnit, MapUnit::Map100thMM);
+ }
+
+ // Correct current TabPos and default tabs
+ for ( sal_uInt16 i = 0; i < aNewTabs->Count(); i++ )
+ {
+ if ( (*aNewTabs)[i].GetAdjustment() != SvxTabAdjust::Default )
+ {
+ m_xTabSpin->set_value(m_xTabSpin->normalize((*aNewTabs)[i].GetTabPos() + nOffset ), eDefUnit);
+ m_xTabBox->append_text(m_xTabSpin->get_text());
+ }
+ else
+ {
+ aNewTabs->Remove( i-- );
+ }
+ }
+
+ // Select current tabulator
+ const sal_uInt16 nSize = aNewTabs->Count();
+
+ if ( nTabPos >= nSize )
+ nTabPos = 0;
+
+ // Switch off all RadioButtons for a start
+ m_xLeftTab->set_active(true);
+ m_xNoFillChar->set_active(true);
+
+ if (m_xTabBox->get_count() > 0)
+ {
+ m_xTabBox->set_active(nTabPos);
+ aCurrentTab = (*aNewTabs)[nTabPos];
+
+ SetFillAndTabType_Impl();
+ m_xNewBtn->set_sensitive(false);
+ m_xDelBtn->set_sensitive(true);
+ }
+ else
+ { // If no entry, 0 is the default value
+ m_xTabSpin->set_value(0, eDefUnit);
+ m_xTabBox->set_entry_text(m_xTabSpin->get_text());
+
+ m_xNewBtn->set_sensitive(true);
+ m_xDelBtn->set_sensitive(false);
+ }
+}
+
+void SvxTabulatorTabPage::SetFillAndTabType_Impl()
+{
+ weld::RadioButton* pTypeBtn = nullptr;
+ weld::RadioButton* pFillBtn = nullptr;
+
+ m_xDezChar->set_sensitive(false);
+ m_xDezCharLabel->set_sensitive(false);
+
+ if ( aCurrentTab.GetAdjustment() == SvxTabAdjust::Left )
+ pTypeBtn = m_xLeftTab.get();
+ else if ( aCurrentTab.GetAdjustment() == SvxTabAdjust::Right )
+ pTypeBtn = m_xRightTab.get();
+ else if ( aCurrentTab.GetAdjustment() == SvxTabAdjust::Decimal )
+ {
+ pTypeBtn = m_xDezTab.get();
+ m_xDezChar->set_sensitive(true);
+ m_xDezCharLabel->set_sensitive(true);
+ m_xDezChar->set_text(OUString(aCurrentTab.GetDecimal()));
+ }
+ else if ( aCurrentTab.GetAdjustment() == SvxTabAdjust::Center )
+ pTypeBtn = m_xCenterTab.get();
+
+ if (pTypeBtn)
+ pTypeBtn->set_active(true);
+
+ m_xFillChar->set_sensitive(false);
+ m_xFillChar->set_text("");
+
+ if ( aCurrentTab.GetFill() == ' ' )
+ pFillBtn = m_xNoFillChar.get();
+ else if ( aCurrentTab.GetFill() == '-' )
+ pFillBtn = m_xFillDashLine.get();
+ else if ( aCurrentTab.GetFill() == '_' )
+ pFillBtn = m_xFillSolidLine.get();
+ else if ( aCurrentTab.GetFill() == '.' )
+ pFillBtn = m_xFillPoints.get();
+ else
+ {
+ pFillBtn = m_xFillSpecial.get();
+ m_xFillChar->set_sensitive(true);
+ m_xFillChar->set_text(OUString(aCurrentTab.GetFill()));
+ }
+ pFillBtn->set_active(true);
+}
+
+IMPL_LINK(SvxTabulatorTabPage, NewHdl_Impl, weld::Button&, rBtn, void)
+{
+ NewHdl_Impl(&rBtn);
+}
+
+void SvxTabulatorTabPage::NewHdl_Impl(const weld::Button* pBtn)
+{
+ // Add a new one and select it
+ // Get the value from the display
+ ReformatHdl_Impl(*m_xTabBox);
+ m_xTabSpin->set_text(m_xTabBox->get_active_text());
+ auto nVal = m_xTabSpin->denormalize(m_xTabSpin->get_value(eDefUnit));
+
+ // If the pBtn == 0 && the value == 0 then do not create a tab, because we create via OK
+ if (nVal == 0 && pBtn == nullptr)
+ return;
+
+ tools::Long nOffset = 0;
+
+ if ( const SfxInt32Item* pOffsetItem = GetItemSet().GetItemIfSet( SID_ATTR_TABSTOP_OFFSET ) )
+ {
+ nOffset = pOffsetItem->GetValue();
+ MapUnit eUnit = GetItemSet().GetPool()->GetMetric( GetWhich( SID_ATTR_TABSTOP ) );
+ nOffset = OutputDevice::LogicToLogic( nOffset, eUnit, MapUnit::Map100thMM );
+ }
+ const tools::Long nReal = nVal - nOffset;
+ sal_Int32 nSize = m_xTabBox->get_count();
+
+ sal_Int32 i;
+ for( i = 0; i < nSize; i++ )
+ {
+ if ( nReal < (*aNewTabs)[i].GetTabPos() )
+ break;
+ }
+
+ // Make ListBox entry
+ m_xTabSpin->set_value(m_xTabSpin->normalize(nVal), eDefUnit);
+ m_xTabBox->insert_text(i, m_xTabSpin->get_text());
+
+ aCurrentTab.GetTabPos() = nReal;
+ SvxTabAdjust eAdj = SvxTabAdjust::Left;
+
+ if (m_xRightTab->get_active())
+ eAdj = SvxTabAdjust::Right;
+ else if (m_xCenterTab->get_active())
+ eAdj = SvxTabAdjust::Center;
+ else if (m_xDezTab->get_active())
+ eAdj = SvxTabAdjust::Decimal;
+
+ aCurrentTab.GetAdjustment() = eAdj;
+ aNewTabs->Insert( aCurrentTab );
+
+ m_xNewBtn->set_sensitive(false);
+ m_xDelBtn->set_sensitive(true);
+ m_xTabBox->grab_focus();
+
+ // Set the selection into the position Edit
+ m_xTabBox->select_entry_region(0, -1);
+}
+
+int SvxTabulatorTabPage::FindCurrentTab()
+{
+ return m_xTabBox->find_text(FormatTab());
+}
+
+IMPL_LINK_NOARG(SvxTabulatorTabPage, DelHdl_Impl, weld::Button&, void)
+{
+ int nPos = FindCurrentTab();
+ if (nPos == -1)
+ return;
+
+ if (m_xTabBox->get_count() == 1)
+ {
+ DelAllHdl_Impl(*m_xDelAllBtn);
+ return;
+ }
+
+ // Delete Tab
+ m_xTabBox->remove(nPos);
+ aNewTabs->Remove( nPos );
+
+ // Reset aCurrentTab
+ const sal_uInt16 nSize = aNewTabs->Count();
+
+ if ( nSize > 0 )
+ {
+ // Correct Pos
+ nPos = ( ( nSize - 1 ) >= nPos) ? nPos : nPos - 1;
+ m_xTabBox->set_active(nPos);
+ aCurrentTab = (*aNewTabs)[nPos];
+ }
+
+ // If no Tabs Enable Disable Controls
+ if (m_xTabBox->get_count() == 0)
+ {
+ m_xDelBtn->set_sensitive(false);
+ m_xNewBtn->set_sensitive(true);
+ m_xTabBox->grab_focus();
+ }
+}
+
+IMPL_LINK_NOARG(SvxTabulatorTabPage, DelAllHdl_Impl, weld::Button&, void)
+{
+ if ( aNewTabs->Count() )
+ {
+ aNewTabs = std::make_unique<SvxTabStopItem>(GetWhich(SID_ATTR_TABSTOP));
+ InitTabPos_Impl();
+ }
+}
+
+IMPL_LINK(SvxTabulatorTabPage, TabTypeCheckHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ if (!rBox.get_active())
+ return;
+
+ SvxTabAdjust eAdj;
+ m_xDezChar->set_sensitive(false);
+ m_xDezCharLabel->set_sensitive(false);
+ m_xDezChar->set_text("");
+
+ if (&rBox == m_xLeftTab.get())
+ eAdj = SvxTabAdjust::Left;
+ else if (&rBox == m_xRightTab.get())
+ eAdj = SvxTabAdjust::Right;
+ else if (&rBox == m_xCenterTab.get())
+ eAdj = SvxTabAdjust::Center;
+ else
+ {
+ eAdj = SvxTabAdjust::Decimal;
+ m_xDezChar->set_sensitive(true);
+ m_xDezCharLabel->set_sensitive(true);
+ m_xDezChar->set_text(OUString(aCurrentTab.GetDecimal()));
+ }
+
+ aCurrentTab.GetAdjustment() = eAdj;
+ int nPos = FindCurrentTab();
+ if (nPos != -1)
+ {
+ aNewTabs->Remove( nPos );
+ aNewTabs->Insert( aCurrentTab );
+ }
+}
+
+IMPL_LINK(SvxTabulatorTabPage, FillTypeCheckHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ if (!rBox.get_active())
+ return;
+
+ sal_uInt8 cFill = ' ';
+ m_xFillChar->set_text( "" );
+ m_xFillChar->set_sensitive(false);
+
+ if (&rBox == m_xFillSpecial.get())
+ m_xFillChar->set_sensitive(true);
+ else if (&rBox == m_xNoFillChar.get())
+ cFill = ' ';
+ else if (&rBox == m_xFillSolidLine.get())
+ cFill = '_';
+ else if (&rBox == m_xFillPoints.get())
+ cFill = '.';
+ else if (&rBox == m_xFillDashLine.get())
+ cFill = '-';
+
+ aCurrentTab.GetFill() = cFill;
+ int nPos = FindCurrentTab();
+ if (nPos != -1)
+ {
+ aNewTabs->Remove( nPos );
+ aNewTabs->Insert( aCurrentTab );
+ }
+}
+
+IMPL_LINK_NOARG(SvxTabulatorTabPage, GetFillCharHdl_Impl, weld::Widget&, void)
+{
+ OUString aChar(m_xFillChar->get_text());
+ if ( !aChar.isEmpty() )
+ aCurrentTab.GetFill() = aChar[0];
+
+ const int nPos = FindCurrentTab();
+ if (nPos != -1)
+ {
+ aNewTabs->Remove( nPos );
+ aNewTabs->Insert( aCurrentTab );
+ }
+}
+
+IMPL_LINK_NOARG(SvxTabulatorTabPage, GetDezCharHdl_Impl, weld::Widget&, void)
+{
+ OUString aChar(m_xDezChar->get_text());
+ if ( !aChar.isEmpty() && ( aChar[0] >= ' '))
+ aCurrentTab.GetDecimal() = aChar[0];
+
+ const int nPos = FindCurrentTab();
+ if (nPos != -1)
+ {
+ aNewTabs->Remove( nPos );
+ aNewTabs->Insert( aCurrentTab );
+ }
+}
+
+IMPL_LINK_NOARG(SvxTabulatorTabPage, SelectHdl_Impl, weld::TreeView&, bool)
+{
+ const int nPos = FindCurrentTab();
+ if (nPos != -1)
+ {
+ aCurrentTab = (*aNewTabs)[nPos];
+ m_xNewBtn->set_sensitive(false);
+ SetFillAndTabType_Impl();
+ }
+ return true;
+}
+
+OUString SvxTabulatorTabPage::FormatTab()
+{
+ m_xTabSpin->set_text(m_xTabBox->get_active_text());
+ m_xTabSpin->reformat();
+ return m_xTabSpin->get_text();
+}
+
+IMPL_LINK_NOARG(SvxTabulatorTabPage, ReformatHdl_Impl, weld::Widget&, void)
+{
+ m_xTabBox->set_entry_text(FormatTab());
+}
+
+IMPL_LINK_NOARG(SvxTabulatorTabPage, ModifyHdl_Impl, weld::ComboBox&, void)
+{
+ const int nPos = FindCurrentTab();
+ if (nPos != -1)
+ {
+ aCurrentTab = (*aNewTabs)[nPos];
+ SetFillAndTabType_Impl();
+
+ m_xTabSpin->set_text(m_xTabBox->get_active_text());
+ aCurrentTab.GetTabPos() = m_xTabSpin->denormalize(m_xTabSpin->get_value(eDefUnit));
+ m_xNewBtn->set_sensitive(false);
+ m_xDelBtn->set_sensitive(true);
+ return;
+ }
+ m_xNewBtn->set_sensitive(true);
+ m_xDelBtn->set_sensitive(false);
+}
+
+void SvxTabulatorTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxUInt16Item* pControlItem = aSet.GetItem<SfxUInt16Item>(SID_SVXTABULATORTABPAGE_DISABLEFLAGS, false);
+ if (pControlItem)
+ DisableControls(static_cast<TabulatorDisableFlags>(pControlItem->GetValue()));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/textanim.cxx b/cui/source/tabpages/textanim.cxx
new file mode 100644
index 0000000000..b5ba3d90ce
--- /dev/null
+++ b/cui/source/tabpages/textanim.cxx
@@ -0,0 +1,534 @@
+/* -*- 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 <textanim.hxx>
+#include <textattr.hxx>
+#include <TextColumnsPage.hxx>
+#include <svx/dlgutil.hxx>
+#include <svx/svdmark.hxx>
+#include <svx/svdview.hxx>
+#include <svx/sdtaaitm.hxx>
+#include <svx/sdtacitm.hxx>
+#include <svx/sdtaiitm.hxx>
+#include <svx/sdtayitm.hxx>
+#include <svtools/unitconv.hxx>
+
+const WhichRangesContainer SvxTextAnimationPage::pRanges(
+ svl::Items<SDRATTR_TEXT_ANIKIND, SDRATTR_TEXT_ANIAMOUNT>);
+
+/*************************************************************************
+|*
+|* constructor of the tab dialog: adds pages to the dialog
+|*
+\************************************************************************/
+
+SvxTextTabDialog::SvxTextTabDialog(weld::Window* pParent, const SfxItemSet* pAttr, const SdrView* pSdrView)
+ : SfxTabDialogController(pParent, "cui/ui/textdialog.ui", "TextDialog", pAttr)
+ , pView(pSdrView)
+{
+ AddTabPage("RID_SVXPAGE_TEXTATTR", SvxTextAttrPage::Create, nullptr);
+ AddTabPage("RID_SVXPAGE_TEXTANIMATION", SvxTextAnimationPage::Create, nullptr);
+ AddTabPage("RID_SVXPAGE_TEXTCOLUMNS", SvxTextColumnsPage::Create, nullptr);
+}
+
+/*************************************************************************
+|*
+|* PageCreated()
+|*
+\************************************************************************/
+
+void SvxTextTabDialog::PageCreated(const OUString& rId, SfxTabPage &rPage)
+{
+ if (rId != "RID_SVXPAGE_TEXTATTR")
+ return;
+
+ SdrObjKind eKind = SdrObjKind::NONE;
+ if (pView)
+ {
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ bool bHasMarked = rMarkList.GetMarkCount() > 0;
+ if (bHasMarked)
+ {
+ if (rMarkList.GetMarkCount() == 1)
+ {
+ const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ eKind = pObj->GetObjIdentifier();
+ }
+ }
+ }
+ static_cast<SvxTextAttrPage&>(rPage).SetObjKind(eKind);
+ static_cast<SvxTextAttrPage&>(rPage).Construct();
+}
+
+/*************************************************************************
+|*
+|* Page
+|*
+\************************************************************************/
+SvxTextAnimationPage::SvxTextAnimationPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/textanimtabpage.ui", "TextAnimation", &rInAttrs)
+ , eAniKind(SdrTextAniKind::NONE)
+ , m_aUpState(TRISTATE_INDET)
+ , m_aLeftState(TRISTATE_INDET)
+ , m_aRightState(TRISTATE_INDET)
+ , m_aDownState(TRISTATE_INDET)
+ , m_xLbEffect(m_xBuilder->weld_combo_box("LB_EFFECT"))
+ , m_xBoxDirection(m_xBuilder->weld_widget("boxDIRECTION"))
+ , m_xBtnUp(m_xBuilder->weld_toggle_button("BTN_UP"))
+ , m_xBtnLeft(m_xBuilder->weld_toggle_button("BTN_LEFT"))
+ , m_xBtnRight(m_xBuilder->weld_toggle_button("BTN_RIGHT"))
+ , m_xBtnDown(m_xBuilder->weld_toggle_button("BTN_DOWN"))
+ , m_xFlProperties(m_xBuilder->weld_frame("FL_PROPERTIES"))
+ , m_xTsbStartInside(m_xBuilder->weld_check_button("TSB_START_INSIDE"))
+ , m_xTsbStopInside(m_xBuilder->weld_check_button("TSB_STOP_INSIDE"))
+ , m_xBoxCount(m_xBuilder->weld_widget("boxCOUNT"))
+ , m_xTsbEndless(m_xBuilder->weld_check_button("TSB_ENDLESS"))
+ , m_xNumFldCount(m_xBuilder->weld_spin_button("NUM_FLD_COUNT"))
+ , m_xTsbPixel(m_xBuilder->weld_check_button("TSB_PIXEL"))
+ , m_xMtrFldAmount(m_xBuilder->weld_metric_spin_button("MTR_FLD_AMOUNT", FieldUnit::PIXEL))
+ , m_xTsbAuto(m_xBuilder->weld_check_button("TSB_AUTO"))
+ , m_xMtrFldDelay(m_xBuilder->weld_metric_spin_button("MTR_FLD_DELAY", FieldUnit::MILLISECOND))
+{
+ eFUnit = GetModuleFieldUnit( rInAttrs );
+ SfxItemPool* pPool = rInAttrs.GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ eUnit = pPool->GetMetric( SDRATTR_TEXT_LEFTDIST );
+
+ m_xLbEffect->connect_changed( LINK( this, SvxTextAnimationPage, SelectEffectHdl_Impl ) );
+ m_xTsbEndless->connect_toggled( LINK( this, SvxTextAnimationPage, ClickEndlessHdl_Impl ) );
+ m_xTsbAuto->connect_toggled( LINK( this, SvxTextAnimationPage, ClickAutoHdl_Impl ) );
+ m_xTsbPixel->connect_toggled( LINK( this, SvxTextAnimationPage, ClickPixelHdl_Impl ) );
+
+ Link<weld::Button&,void> aLink( LINK( this, SvxTextAnimationPage, ClickDirectionHdl_Impl ) );
+ m_xBtnUp->connect_clicked( aLink );
+ m_xBtnLeft->connect_clicked( aLink );
+ m_xBtnRight->connect_clicked( aLink );
+ m_xBtnDown->connect_clicked( aLink );
+}
+
+SvxTextAnimationPage::~SvxTextAnimationPage()
+{
+}
+
+/*************************************************************************
+|*
+|* reads the passed item set
+|*
+\************************************************************************/
+
+void SvxTextAnimationPage::Reset( const SfxItemSet* rAttrs )
+{
+ const SfxItemPool* pPool = rAttrs->GetPool();
+
+ // animation type
+ const SfxPoolItem* pItem = GetItem( *rAttrs, SDRATTR_TEXT_ANIKIND );
+
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_ANIKIND );
+
+ eAniKind = static_cast<const SdrTextAniKindItem*>(pItem)->GetValue();
+ m_xLbEffect->set_active(sal::static_int_cast<sal_Int32>(eAniKind));
+ m_xLbEffect->save_value();
+
+ // animation direction
+ pItem = GetItem( *rAttrs, SDRATTR_TEXT_ANIDIRECTION );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_ANIDIRECTION );
+
+ SelectDirection(static_cast<const SdrTextAniDirectionItem*>(pItem)->GetValue());
+ m_aUpState = m_xBtnUp->get_state();
+ m_aLeftState = m_xBtnLeft->get_state();
+ m_aRightState = m_xBtnRight->get_state();
+ m_aDownState = m_xBtnDown->get_state();
+
+ // Start inside
+ pItem = GetItem( *rAttrs, SDRATTR_TEXT_ANISTARTINSIDE );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_ANISTARTINSIDE );
+
+ if (static_cast<const SdrTextAniStartInsideItem*>(pItem)->GetValue())
+ m_xTsbStartInside->set_state(TRISTATE_TRUE);
+ else
+ m_xTsbStartInside->set_state(TRISTATE_FALSE);
+ m_xTsbStartInside->save_state();
+
+ // Stop inside
+ pItem = GetItem( *rAttrs, SDRATTR_TEXT_ANISTOPINSIDE );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_ANISTOPINSIDE );
+
+ if (static_cast<const SdrTextAniStopInsideItem*>(pItem)->GetValue())
+ m_xTsbStopInside->set_state(TRISTATE_TRUE);
+ else
+ m_xTsbStopInside->set_state(TRISTATE_FALSE);
+ m_xTsbStopInside->save_state();
+
+ // quantity
+ pItem = GetItem( *rAttrs, SDRATTR_TEXT_ANICOUNT );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_ANICOUNT );
+
+ tools::Long nValue = static_cast<tools::Long>(static_cast<const SdrTextAniCountItem*>(pItem)->GetValue());
+ m_xNumFldCount->set_value(nValue);
+ if (nValue == 0)
+ {
+ if (eAniKind == SdrTextAniKind::Slide)
+ {
+ m_xTsbEndless->set_state(TRISTATE_FALSE);
+ m_xTsbEndless->set_sensitive(false);
+ }
+ else
+ {
+ m_xTsbEndless->set_state(TRISTATE_TRUE);
+ m_xNumFldCount->set_text("");
+ }
+ }
+ else
+ m_xTsbEndless->set_state(TRISTATE_FALSE);
+ m_xTsbEndless->save_state();
+ m_xNumFldCount->save_value();
+
+ // delay
+ pItem = GetItem( *rAttrs, SDRATTR_TEXT_ANIDELAY );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_ANIDELAY );
+
+ nValue = static_cast<tools::Long>(static_cast<const SdrTextAniDelayItem*>(pItem)->GetValue());
+ m_xMtrFldDelay->set_value(nValue, FieldUnit::NONE);
+ if (nValue == 0)
+ {
+ m_xTsbAuto->set_state(TRISTATE_TRUE);
+ m_xMtrFldDelay->set_text("");
+ }
+ else
+ m_xTsbAuto->set_state(TRISTATE_FALSE);
+ m_xTsbAuto->save_state();
+ m_xMtrFldDelay->save_value();
+
+ // step size
+ pItem = GetItem( *rAttrs, SDRATTR_TEXT_ANIAMOUNT );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_ANIAMOUNT );
+
+ nValue = static_cast<tools::Long>(static_cast<const SdrTextAniAmountItem*>(pItem)->GetValue());
+ if (nValue <= 0)
+ {
+ m_xTsbPixel->set_state(TRISTATE_TRUE);
+ nValue = -nValue;
+ if (nValue == 0)
+ nValue++;
+ m_xMtrFldAmount->set_unit(FieldUnit::CUSTOM);
+ m_xMtrFldAmount->set_digits(0);
+
+ m_xMtrFldAmount->set_increments(1, 10, FieldUnit::NONE);
+ m_xMtrFldAmount->set_range(1, 100, FieldUnit::NONE);
+ m_xMtrFldAmount->set_value(nValue, FieldUnit::NONE);
+ }
+ else
+ {
+ m_xTsbPixel->set_state(TRISTATE_FALSE);
+ m_xMtrFldAmount->set_unit(eFUnit);
+ m_xMtrFldAmount->set_digits(2);
+
+ m_xMtrFldAmount->set_increments(10, 100, FieldUnit::NONE);
+ m_xMtrFldAmount->set_range(1, 10000, FieldUnit::NONE);
+
+ SetMetricValue(*m_xMtrFldAmount, nValue, eUnit);
+ }
+ m_xTsbPixel->save_state();
+ m_xMtrFldAmount->save_value();
+
+ SelectEffectHdl_Impl(*m_xLbEffect);
+ ClickEndlessHdl_Impl(*m_xTsbEndless);
+ ClickAutoHdl_Impl(*m_xTsbAuto);
+}
+
+/*************************************************************************
+|*
+|* fills the passed item set with dialog box attributes
+|*
+\************************************************************************/
+
+bool SvxTextAnimationPage::FillItemSet( SfxItemSet* rAttrs)
+{
+ bool bModified = false;
+ TriState eState;
+
+ // animation type
+ int nPos = m_xLbEffect->get_active();
+ if( nPos != -1 &&
+ m_xLbEffect->get_value_changed_from_saved() )
+ {
+ rAttrs->Put( SdrTextAniKindItem( static_cast<SdrTextAniKind>(nPos) ) );
+ bModified = true;
+ }
+
+ // animation direction
+ if (m_aUpState != m_xBtnUp->get_state() ||
+ m_aLeftState != m_xBtnLeft->get_state() ||
+ m_aRightState != m_xBtnRight->get_state() ||
+ m_aDownState != m_xBtnDown->get_state())
+ {
+ SdrTextAniDirection eValue = static_cast<SdrTextAniDirection>(GetSelectedDirection());
+ rAttrs->Put( SdrTextAniDirectionItem( eValue ) );
+ bModified = true;
+ }
+
+ // Start inside
+ eState = m_xTsbStartInside->get_state();
+ if (m_xTsbStartInside->get_state_changed_from_saved())
+ {
+ rAttrs->Put( SdrTextAniStartInsideItem( TRISTATE_TRUE == eState ) );
+ bModified = true;
+ }
+
+ // Stop inside
+ eState = m_xTsbStopInside->get_state();
+ if (m_xTsbStopInside->get_state_changed_from_saved())
+ {
+ rAttrs->Put( SdrTextAniStopInsideItem( TRISTATE_TRUE == eState ) );
+ bModified = true;
+ }
+
+ // quantity
+ eState = m_xTsbEndless->get_state();
+ if (m_xTsbEndless->get_state_changed_from_saved() ||
+ m_xNumFldCount->get_value_changed_from_saved())
+ {
+ sal_Int64 nValue = 0;
+ if( eState == TRISTATE_TRUE /*#89844#*/ && m_xTsbEndless->get_sensitive())
+ bModified = true;
+ else
+ {
+ if( m_xNumFldCount->get_value_changed_from_saved() )
+ {
+ nValue = m_xNumFldCount->get_value();
+ bModified = true;
+ }
+ }
+ if( bModified )
+ rAttrs->Put( SdrTextAniCountItem( static_cast<sal_uInt16>(nValue) ) );
+ }
+
+ // delay
+ eState = m_xTsbAuto->get_state();
+ if (m_xTsbAuto->get_state_changed_from_saved() ||
+ m_xMtrFldDelay->get_value_changed_from_saved())
+ {
+ sal_Int64 nValue = 0;
+ if( eState == TRISTATE_TRUE )
+ bModified = true;
+ else
+ {
+ if( m_xMtrFldDelay->get_value_changed_from_saved() )
+ {
+ nValue = m_xMtrFldDelay->get_value(FieldUnit::NONE);
+ bModified = true;
+ }
+ }
+ if( bModified )
+ rAttrs->Put( SdrTextAniDelayItem( static_cast<sal_uInt16>(nValue) ) );
+ }
+
+ // step size
+ eState = m_xTsbPixel->get_state();
+ if (m_xTsbPixel->get_state_changed_from_saved() ||
+ m_xMtrFldAmount->get_value_changed_from_saved())
+ {
+ sal_Int64 nValue = 0;
+ if( eState == TRISTATE_TRUE )
+ {
+ nValue = m_xMtrFldAmount->get_value(FieldUnit::NONE);
+ nValue = -nValue;
+ }
+ else
+ {
+ nValue = GetCoreValue( *m_xMtrFldAmount, eUnit );
+ }
+ rAttrs->Put( SdrTextAniAmountItem( static_cast<sal_Int16>(nValue) ) );
+
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+/*************************************************************************
+|*
+|* creates the page
+|*
+\************************************************************************/
+
+std::unique_ptr<SfxTabPage> SvxTextAnimationPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrs)
+{
+ return std::make_unique<SvxTextAnimationPage>(pPage, pController, *rAttrs);
+}
+
+IMPL_LINK_NOARG(SvxTextAnimationPage, SelectEffectHdl_Impl, weld::ComboBox&, void)
+{
+ int nPos = m_xLbEffect->get_active();
+ if (nPos == -1)
+ return;
+
+ eAniKind = static_cast<SdrTextAniKind>(nPos);
+ switch( eAniKind )
+ {
+ case SdrTextAniKind::NONE:
+ {
+ m_xBoxDirection->set_sensitive(false);
+ m_xFlProperties->set_sensitive(false);
+ }
+ break;
+
+ case SdrTextAniKind::Blink:
+ case SdrTextAniKind::Scroll:
+ case SdrTextAniKind::Alternate:
+ case SdrTextAniKind::Slide:
+ {
+ m_xFlProperties->set_sensitive(true);
+ if( eAniKind == SdrTextAniKind::Slide )
+ {
+ m_xTsbStartInside->set_sensitive(false);
+ m_xTsbStopInside->set_sensitive(false);
+ m_xTsbEndless->set_sensitive(false);
+ m_xNumFldCount->set_sensitive(true);
+ m_xNumFldCount->set_value(m_xNumFldCount->get_value());
+ }
+ else
+ {
+ m_xTsbStartInside->set_sensitive(true);
+ m_xTsbStopInside->set_sensitive(true);
+ m_xTsbEndless->set_sensitive(true);
+ ClickEndlessHdl_Impl(*m_xTsbEndless);
+ }
+
+ m_xTsbAuto->set_sensitive(true);
+ ClickAutoHdl_Impl(*m_xTsbAuto);
+
+ if( eAniKind == SdrTextAniKind::Blink )
+ {
+ m_xBoxDirection->set_sensitive(false);
+ m_xBoxCount->set_sensitive(false);
+ }
+ else
+ {
+ m_xBoxDirection->set_sensitive(true);
+ m_xBoxCount->set_sensitive(true);
+ }
+ }
+ break;
+ }
+}
+
+IMPL_LINK_NOARG(SvxTextAnimationPage, ClickEndlessHdl_Impl, weld::Toggleable&, void)
+{
+ if( eAniKind == SdrTextAniKind::Slide )
+ return;
+
+ TriState eState = m_xTsbEndless->get_state();
+ if( eState != TRISTATE_FALSE )
+ {
+ m_xNumFldCount->set_sensitive(false);
+ m_xNumFldCount->set_text("");
+ }
+ else
+ {
+ m_xNumFldCount->set_sensitive(true);
+ m_xNumFldCount->set_value(m_xNumFldCount->get_value());
+ }
+}
+
+IMPL_LINK_NOARG(SvxTextAnimationPage, ClickAutoHdl_Impl, weld::Toggleable&, void)
+{
+ TriState eState = m_xTsbAuto->get_state();
+ if( eState != TRISTATE_FALSE )
+ {
+ m_xMtrFldDelay->set_sensitive(false);
+ m_xMtrFldDelay->set_text("");
+ }
+ else
+ {
+ m_xMtrFldDelay->set_sensitive(true);
+ m_xMtrFldDelay->set_value(m_xMtrFldDelay->get_value(FieldUnit::NONE), FieldUnit::NONE); //to-do
+ }
+}
+
+IMPL_LINK_NOARG(SvxTextAnimationPage, ClickPixelHdl_Impl, weld::Toggleable&, void)
+{
+ TriState eState = m_xTsbPixel->get_state();
+ if (eState == TRISTATE_TRUE)
+ {
+ int nValue = m_xMtrFldAmount->get_value(FieldUnit::NONE) / 10;
+ m_xMtrFldAmount->set_sensitive(true);
+ m_xMtrFldAmount->set_unit(FieldUnit::CUSTOM);
+ m_xMtrFldAmount->set_digits(0);
+
+ m_xMtrFldAmount->set_increments(1, 10, FieldUnit::NONE);
+ m_xMtrFldAmount->set_range(1, 100, FieldUnit::NONE);
+
+ m_xMtrFldAmount->set_value(nValue, FieldUnit::NONE);
+ }
+ else if( eState == TRISTATE_FALSE )
+ {
+ int nValue = m_xMtrFldAmount->get_value(FieldUnit::NONE) * 10;
+ m_xMtrFldAmount->set_sensitive(true);
+ m_xMtrFldAmount->set_unit(eFUnit);
+ m_xMtrFldAmount->set_digits(2);
+
+ m_xMtrFldAmount->set_increments(10, 100, FieldUnit::NONE);
+ m_xMtrFldAmount->set_range(1, 10000, FieldUnit::NONE);
+
+ m_xMtrFldAmount->set_value(nValue, FieldUnit::NONE);
+ }
+}
+
+IMPL_LINK(SvxTextAnimationPage, ClickDirectionHdl_Impl, weld::Button&, rBtn, void)
+{
+ m_xBtnUp->set_active(&rBtn == m_xBtnUp.get());
+ m_xBtnLeft->set_active(&rBtn == m_xBtnLeft.get());
+ m_xBtnRight->set_active(&rBtn == m_xBtnRight.get());
+ m_xBtnDown->set_active(&rBtn == m_xBtnDown.get());
+}
+
+void SvxTextAnimationPage::SelectDirection( SdrTextAniDirection nValue )
+{
+ m_xBtnUp->set_active( nValue == SdrTextAniDirection::Up );
+ m_xBtnLeft->set_active( nValue == SdrTextAniDirection::Left );
+ m_xBtnRight->set_active( nValue == SdrTextAniDirection::Right );
+ m_xBtnDown->set_active( nValue == SdrTextAniDirection::Down );
+}
+
+sal_uInt16 SvxTextAnimationPage::GetSelectedDirection() const
+{
+ SdrTextAniDirection nValue = SdrTextAniDirection::Left;
+
+ if( m_xBtnUp->get_active() )
+ nValue = SdrTextAniDirection::Up;
+ else if( m_xBtnLeft->get_active() )
+ nValue = SdrTextAniDirection::Left;
+ else if( m_xBtnRight->get_active() )
+ nValue = SdrTextAniDirection::Right;
+ else if( m_xBtnDown->get_active() )
+ nValue = SdrTextAniDirection::Down;
+
+ return static_cast<sal_uInt16>(nValue);
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/textattr.cxx b/cui/source/tabpages/textattr.cxx
new file mode 100644
index 0000000000..f773be6b8c
--- /dev/null
+++ b/cui/source/tabpages/textattr.cxx
@@ -0,0 +1,665 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svx/svddef.hxx>
+#include <svx/sdasitm.hxx>
+#include <svx/sdtditm.hxx>
+#include <svx/sdtagitm.hxx>
+#include <svx/sdtaitm.hxx>
+#include <svx/sdtfsitm.hxx>
+#include <svx/sdtcfitm.hxx>
+#include <svx/svxids.hrc>
+
+#include <textattr.hxx>
+#include <svx/dlgutil.hxx>
+#include <editeng/writingmodeitem.hxx>
+#include <svtools/unitconv.hxx>
+#include <osl/diagnose.h>
+
+using namespace ::com::sun::star;
+
+const WhichRangesContainer SvxTextAttrPage::pRanges(
+ svl::Items<
+ SDRATTR_MISC_FIRST ,SDRATTR_TEXT_HORZADJUST,
+ SDRATTR_TEXT_WORDWRAP, SDRATTR_TEXT_WORDWRAP
+>);
+
+/*************************************************************************
+|*
+|* dialog (page) for copying objects
+|*
+\************************************************************************/
+SvxTextAttrPage::SvxTextAttrPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SvxTabPage(pPage, pController, "cui/ui/textattrtabpage.ui", "TextAttributesPage", rInAttrs)
+ , rOutAttrs(rInAttrs)
+ , m_eObjKind(SdrObjKind::NONE)
+ , bAutoGrowSizeEnabled(false)
+ , bContourEnabled(false)
+ , bAutoGrowWidthEnabled(false)
+ , bAutoGrowHeightEnabled(false)
+ , bWordWrapTextEnabled(false)
+ , bFitToSizeEnabled(false)
+ , m_aCtlPosition(this)
+ , m_xDrawingText(m_xBuilder->weld_widget("drawingtext"))
+ , m_xCustomShapeText(m_xBuilder->weld_widget("customshapetext"))
+ , m_xTsbAutoGrowWidth(m_xBuilder->weld_check_button("TSB_AUTOGROW_WIDTH"))
+ , m_xTsbAutoGrowHeight(m_xBuilder->weld_check_button("TSB_AUTOGROW_HEIGHT"))
+ , m_xTsbFitToSize(m_xBuilder->weld_check_button("TSB_FIT_TO_SIZE"))
+ , m_xTsbContour(m_xBuilder->weld_check_button("TSB_CONTOUR"))
+ , m_xTsbWordWrapText(m_xBuilder->weld_check_button("TSB_WORDWRAP_TEXT"))
+ , m_xTsbAutoGrowSize(m_xBuilder->weld_check_button("TSB_AUTOGROW_SIZE"))
+ , m_xFlDistance(m_xBuilder->weld_frame("FL_DISTANCE"))
+ , m_xMtrFldLeft(m_xBuilder->weld_metric_spin_button("MTR_FLD_LEFT", FieldUnit::CM))
+ , m_xMtrFldRight(m_xBuilder->weld_metric_spin_button("MTR_FLD_RIGHT", FieldUnit::CM))
+ , m_xMtrFldTop(m_xBuilder->weld_metric_spin_button("MTR_FLD_TOP", FieldUnit::CM))
+ , m_xMtrFldBottom(m_xBuilder->weld_metric_spin_button("MTR_FLD_BOTTOM", FieldUnit::CM))
+ , m_xFlPosition(m_xBuilder->weld_frame("FL_POSITION"))
+ , m_xCtlPosition(new weld::CustomWeld(*m_xBuilder, "CTL_POSITION", m_aCtlPosition))
+ , m_xTsbFullWidth(m_xBuilder->weld_check_button("TSB_FULL_WIDTH"))
+{
+ m_aCtlPosition.SetControlSettings(RectPoint::MM, 240);
+
+ FieldUnit eFUnit = GetModuleFieldUnit( rInAttrs );
+ SetFieldUnit( *m_xMtrFldLeft, eFUnit );
+ SetFieldUnit( *m_xMtrFldRight, eFUnit );
+ SetFieldUnit( *m_xMtrFldTop, eFUnit );
+ SetFieldUnit( *m_xMtrFldBottom, eFUnit );
+
+ Link<weld::Toggleable&,void> aLink( LINK( this, SvxTextAttrPage, ClickHdl_Impl ) );
+ m_xTsbAutoGrowWidth->connect_toggled( aLink );
+ m_xTsbAutoGrowHeight->connect_toggled( aLink );
+ m_xTsbAutoGrowSize->connect_toggled( aLink );
+ m_xTsbFitToSize->connect_toggled( aLink );
+ m_xTsbContour->connect_toggled( aLink );
+
+ m_xTsbFullWidth->connect_toggled(LINK( this, SvxTextAttrPage, ClickFullWidthHdl_Impl ) );
+}
+
+SvxTextAttrPage::~SvxTextAttrPage()
+{
+}
+
+/*************************************************************************
+|*
+|* reads the passed item set
+|*
+\************************************************************************/
+
+void SvxTextAttrPage::Reset( const SfxItemSet* rAttrs )
+{
+ SfxItemPool* pPool = rAttrs->GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ MapUnit eUnit = pPool->GetMetric( SDRATTR_TEXT_LEFTDIST );
+
+ const SdrMetricItem* pItem = GetItem(*rAttrs, SDRATTR_TEXT_LEFTDIST);
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_LEFTDIST );
+
+ SetMetricValue(*m_xMtrFldLeft, pItem->GetValue(), eUnit);
+ m_xMtrFldLeft->save_value();
+
+ pItem = GetItem( *rAttrs, SDRATTR_TEXT_RIGHTDIST );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_RIGHTDIST );
+
+ SetMetricValue(*m_xMtrFldRight, pItem->GetValue(), eUnit);
+ m_xMtrFldRight->save_value();
+
+ pItem = GetItem( *rAttrs, SDRATTR_TEXT_UPPERDIST );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_UPPERDIST );
+
+ SetMetricValue(*m_xMtrFldTop, pItem->GetValue(), eUnit);
+ m_xMtrFldTop->save_value();
+
+ pItem = GetItem( *rAttrs, SDRATTR_TEXT_LOWERDIST );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_LOWERDIST );
+
+ SetMetricValue(*m_xMtrFldBottom, pItem->GetValue(), eUnit);
+ m_xMtrFldBottom->save_value();
+
+ // adjust to height and autogrowsize
+ if ( rAttrs->GetItemState( SDRATTR_TEXT_AUTOGROWHEIGHT ) != SfxItemState::DONTCARE )
+ {
+ m_xTsbAutoGrowHeight->set_state( rAttrs->Get( SDRATTR_TEXT_AUTOGROWHEIGHT ).
+ GetValue() ? TRISTATE_TRUE : TRISTATE_FALSE );
+
+ m_xTsbAutoGrowSize->set_state( rAttrs->Get( SDRATTR_TEXT_AUTOGROWHEIGHT ).
+ GetValue() ? TRISTATE_TRUE : TRISTATE_FALSE );
+ }
+ else
+ {
+ m_xTsbAutoGrowHeight->set_state( TRISTATE_INDET );
+ m_xTsbAutoGrowSize->set_state( TRISTATE_INDET );
+ }
+ m_xTsbAutoGrowHeight->save_state();
+ m_xTsbAutoGrowSize->save_state();
+
+ // adjust to width
+ if ( rAttrs->GetItemState( SDRATTR_TEXT_AUTOGROWWIDTH ) != SfxItemState::DONTCARE )
+ {
+ m_xTsbAutoGrowWidth->set_state( rAttrs->Get( SDRATTR_TEXT_AUTOGROWWIDTH ).
+ GetValue() ? TRISTATE_TRUE : TRISTATE_FALSE );
+ }
+ else
+ m_xTsbAutoGrowWidth->set_state( TRISTATE_INDET );
+ m_xTsbAutoGrowWidth->save_state();
+
+ // wordwrap text
+ if ( rAttrs->GetItemState( SDRATTR_TEXT_WORDWRAP ) != SfxItemState::DONTCARE )
+ {
+ m_xTsbWordWrapText->set_state( rAttrs->Get( SDRATTR_TEXT_WORDWRAP ).
+ GetValue() ? TRISTATE_TRUE : TRISTATE_FALSE );
+ }
+ else
+ m_xTsbWordWrapText->set_state( TRISTATE_INDET );
+ m_xTsbWordWrapText->save_state();
+
+
+ // #103516# Do the setup based on states of hor/ver adjust
+ // Setup center field and FullWidth
+ SfxItemState eVState = rAttrs->GetItemState( SDRATTR_TEXT_VERTADJUST );
+ SfxItemState eHState = rAttrs->GetItemState( SDRATTR_TEXT_HORZADJUST );
+
+ if(SfxItemState::DONTCARE != eVState && SfxItemState::DONTCARE != eHState)
+ {
+ // VertAdjust and HorAdjust are unequivocal, thus
+ SdrTextVertAdjust eTVA = rAttrs->Get(SDRATTR_TEXT_VERTADJUST).GetValue();
+ SdrTextHorzAdjust eTHA = rAttrs->Get(SDRATTR_TEXT_HORZADJUST).GetValue();
+ RectPoint eRP = RectPoint::LB;
+
+ if (m_xTsbFullWidth->get_state() == TRISTATE_INDET)
+ m_xTsbFullWidth->set_state(TRISTATE_FALSE);
+
+ // Translate item values into local anchor position.
+ switch (eTVA)
+ {
+ case SDRTEXTVERTADJUST_TOP:
+ {
+ switch (eTHA)
+ {
+ case SDRTEXTHORZADJUST_LEFT: eRP = RectPoint::LT; break;
+ case SDRTEXTHORZADJUST_BLOCK:
+ case SDRTEXTHORZADJUST_CENTER: eRP = RectPoint::MT; break;
+ case SDRTEXTHORZADJUST_RIGHT: eRP = RectPoint::RT; break;
+ }
+ break;
+ }
+ case SDRTEXTVERTADJUST_BLOCK:
+ case SDRTEXTVERTADJUST_CENTER:
+ {
+ switch (eTHA)
+ {
+ case SDRTEXTHORZADJUST_LEFT: eRP = RectPoint::LM; break;
+ case SDRTEXTHORZADJUST_BLOCK:
+ case SDRTEXTHORZADJUST_CENTER: eRP = RectPoint::MM; break;
+ case SDRTEXTHORZADJUST_RIGHT: eRP = RectPoint::RM; break;
+ }
+ break;
+ }
+ case SDRTEXTVERTADJUST_BOTTOM:
+ {
+ switch (eTHA)
+ {
+ case SDRTEXTHORZADJUST_LEFT: eRP = RectPoint::LB; break;
+ case SDRTEXTHORZADJUST_BLOCK:
+ case SDRTEXTHORZADJUST_CENTER: eRP = RectPoint::MB; break;
+ case SDRTEXTHORZADJUST_RIGHT: eRP = RectPoint::RB; break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ // See if we have to check the "full width" check button.
+ bool bLeftToRight(IsTextDirectionLeftToRight());
+
+ if((bLeftToRight && (SDRTEXTHORZADJUST_BLOCK == eTHA)) || (!bLeftToRight && (SDRTEXTVERTADJUST_BLOCK == eTVA)))
+ {
+ // Move anchor to valid position.
+ ClickFullWidthHdl_Impl(*m_xTsbFullWidth);
+ m_xTsbFullWidth->set_state(TRISTATE_TRUE);
+ }
+
+ m_aCtlPosition.SetActualRP( eRP );
+ }
+ else
+ {
+ // VertAdjust or HorAdjust is not unequivocal
+ m_aCtlPosition.Reset();
+
+ m_aCtlPosition.SetState(CTL_STATE::NOVERT);
+ m_aCtlPosition.DoCompletelyDisable(true);
+
+ m_xTsbFullWidth->set_state(TRISTATE_INDET);
+ m_xFlPosition->set_sensitive( false );
+ }
+
+ // adjust to border
+ if (rAttrs->GetItemState(SDRATTR_TEXT_FITTOSIZE) != SfxItemState::DONTCARE)
+ {
+ drawing::TextFitToSizeType const eFTS =
+ rAttrs->Get( SDRATTR_TEXT_FITTOSIZE ).GetValue();
+ if (eFTS == drawing::TextFitToSizeType_AUTOFIT || eFTS == drawing::TextFitToSizeType_NONE)
+ m_xTsbFitToSize->set_state( TRISTATE_FALSE );
+ else
+ m_xTsbFitToSize->set_state( TRISTATE_TRUE );
+ }
+ else
+ m_xTsbFitToSize->set_state( TRISTATE_INDET );
+ m_xTsbFitToSize->save_state();
+
+ if( rAttrs->GetItemState( SDRATTR_TEXT_CONTOURFRAME ) != SfxItemState::DONTCARE )
+ {
+ bool bContour = rAttrs->Get( SDRATTR_TEXT_CONTOURFRAME ).GetValue();
+ m_xTsbContour->set_state( bContour ? TRISTATE_TRUE : TRISTATE_FALSE );
+ }
+ else
+ m_xTsbContour->set_state( TRISTATE_INDET );
+ m_xTsbContour->save_state();
+
+ ClickHdl_Impl(*m_xTsbContour);
+}
+
+/*************************************************************************
+|*
+|* fills the passed item set with dialog box attributes
+|*
+\************************************************************************/
+
+bool SvxTextAttrPage::FillItemSet( SfxItemSet* rAttrs)
+{
+ SfxItemPool* pPool = rAttrs->GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ MapUnit eUnit = pPool->GetMetric( SDRATTR_TEXT_LEFTDIST );
+
+ sal_Int32 nValue;
+ TriState eState;
+
+ if( m_xMtrFldLeft->get_value_changed_from_saved() )
+ {
+ nValue = GetCoreValue( *m_xMtrFldLeft, eUnit );
+ rAttrs->Put( makeSdrTextLeftDistItem( nValue ) );
+ }
+
+ if( m_xMtrFldRight->get_value_changed_from_saved() )
+ {
+ nValue = GetCoreValue( *m_xMtrFldRight, eUnit );
+ rAttrs->Put( makeSdrTextRightDistItem( nValue ) );
+ }
+
+ if( m_xMtrFldTop->get_value_changed_from_saved() )
+ {
+ nValue = GetCoreValue( *m_xMtrFldTop, eUnit );
+ rAttrs->Put( makeSdrTextUpperDistItem( nValue ) );
+ }
+
+ if( m_xMtrFldBottom->get_value_changed_from_saved() )
+ {
+ nValue = GetCoreValue( *m_xMtrFldBottom, eUnit );
+ rAttrs->Put( makeSdrTextLowerDistItem( nValue ) );
+ }
+
+ eState = m_xTsbAutoGrowHeight->get_state();
+ if( m_xTsbAutoGrowHeight->get_state_changed_from_saved() )
+ {
+ rAttrs->Put( makeSdrTextAutoGrowHeightItem( TRISTATE_TRUE == eState ) );
+ }
+
+ eState = m_xTsbAutoGrowWidth->get_state();
+ if( m_xTsbAutoGrowWidth->get_state_changed_from_saved() )
+ {
+ rAttrs->Put( makeSdrTextAutoGrowWidthItem( TRISTATE_TRUE == eState ) );
+ }
+
+ eState = m_xTsbAutoGrowSize->get_state();
+ if( m_xTsbAutoGrowSize->get_state_changed_from_saved() )
+ {
+ rAttrs->Put( makeSdrTextAutoGrowHeightItem( TRISTATE_TRUE == eState ) );
+ }
+
+ eState = m_xTsbWordWrapText->get_state();
+ if( m_xTsbWordWrapText->get_state_changed_from_saved() )
+ {
+ rAttrs->Put( makeSdrTextWordWrapItem( TRISTATE_TRUE == eState ) );
+ }
+
+ eState = m_xTsbContour->get_state();
+ if( m_xTsbContour->get_state_changed_from_saved() )
+ {
+ rAttrs->Put( makeSdrTextContourFrameItem( TRISTATE_TRUE == eState ) );
+ }
+
+ eState = m_xTsbFitToSize->get_state();
+ if( m_xTsbFitToSize->get_state_changed_from_saved() )
+ {
+ drawing::TextFitToSizeType eFTS;
+ switch( eState )
+ {
+ default: ; //prevent warning
+ OSL_FAIL( "svx::SvxTextAttrPage::FillItemSet(), unhandled state!" );
+ [[fallthrough]];
+ case TRISTATE_FALSE: eFTS = drawing::TextFitToSizeType_AUTOFIT; break;
+ case TRISTATE_TRUE: eFTS = drawing::TextFitToSizeType_PROPORTIONAL; break;
+ }
+ rAttrs->Put( SdrTextFitToSizeTypeItem( eFTS ) );
+ }
+
+ // centered
+ RectPoint eRP = m_aCtlPosition.GetActualRP();
+ SdrTextVertAdjust eTVA;
+ SdrTextHorzAdjust eTHA;
+
+ switch( eRP )
+ {
+ default:
+ case RectPoint::LT: eTVA = SDRTEXTVERTADJUST_TOP;
+ eTHA = SDRTEXTHORZADJUST_LEFT; break;
+ case RectPoint::LM: eTVA = SDRTEXTVERTADJUST_CENTER;
+ eTHA = SDRTEXTHORZADJUST_LEFT; break;
+ case RectPoint::LB: eTVA = SDRTEXTVERTADJUST_BOTTOM;
+ eTHA = SDRTEXTHORZADJUST_LEFT; break;
+ case RectPoint::MT: eTVA = SDRTEXTVERTADJUST_TOP;
+ eTHA = SDRTEXTHORZADJUST_CENTER; break;
+ case RectPoint::MM: eTVA = SDRTEXTVERTADJUST_CENTER;
+ eTHA = SDRTEXTHORZADJUST_CENTER; break;
+ case RectPoint::MB: eTVA = SDRTEXTVERTADJUST_BOTTOM;
+ eTHA = SDRTEXTHORZADJUST_CENTER; break;
+ case RectPoint::RT: eTVA = SDRTEXTVERTADJUST_TOP;
+ eTHA = SDRTEXTHORZADJUST_RIGHT; break;
+ case RectPoint::RM: eTVA = SDRTEXTVERTADJUST_CENTER;
+ eTHA = SDRTEXTHORZADJUST_RIGHT; break;
+ case RectPoint::RB: eTVA = SDRTEXTVERTADJUST_BOTTOM;
+ eTHA = SDRTEXTHORZADJUST_RIGHT; break;
+ }
+
+ // #103516# Do not change values if adjust controls were disabled.
+ bool bIsDisabled(m_aCtlPosition.IsCompletelyDisabled());
+
+ if(bIsDisabled)
+ return true;
+
+ if( m_xTsbFullWidth->get_state() == TRISTATE_TRUE )
+ {
+ if (IsTextDirectionLeftToRight())
+ eTHA = SDRTEXTHORZADJUST_BLOCK;
+ else
+ eTVA = SDRTEXTVERTADJUST_BLOCK;
+ }
+
+ if ( rOutAttrs.GetItemState( SDRATTR_TEXT_VERTADJUST ) != SfxItemState::DONTCARE )
+ {
+ SdrTextVertAdjust eOldTVA = rOutAttrs.Get( SDRATTR_TEXT_VERTADJUST ).GetValue();
+ if( eOldTVA != eTVA )
+ rAttrs->Put( SdrTextVertAdjustItem( eTVA ) );
+ }
+ else
+ rAttrs->Put( SdrTextVertAdjustItem( eTVA ) );
+
+ if ( rOutAttrs.GetItemState( SDRATTR_TEXT_HORZADJUST ) != SfxItemState::DONTCARE )
+ {
+ SdrTextHorzAdjust eOldTHA = rOutAttrs.Get( SDRATTR_TEXT_HORZADJUST ).GetValue();
+ if( eOldTHA != eTHA )
+ rAttrs->Put( SdrTextHorzAdjustItem( eTHA ) );
+ }
+ else
+ rAttrs->Put( SdrTextHorzAdjustItem( eTHA ) );
+
+ return true;
+}
+
+void SvxTextAttrPage::Construct()
+{
+ switch (m_eObjKind)
+ {
+ case SdrObjKind::NONE:
+ // indeterminate, show them all
+ bFitToSizeEnabled = bContourEnabled = bWordWrapTextEnabled =
+ bAutoGrowSizeEnabled = bAutoGrowWidthEnabled = bAutoGrowHeightEnabled = true;
+ m_xCustomShapeText->show();
+ m_xDrawingText->show();
+ break;
+ case SdrObjKind::Text:
+ case SdrObjKind::TitleText:
+ case SdrObjKind::OutlineText:
+ case SdrObjKind::Caption:
+ // contour NOT possible for pure text objects
+ bContourEnabled = bWordWrapTextEnabled = bAutoGrowSizeEnabled = false;
+
+ // adjusting width and height is ONLY possible for pure text objects
+ bFitToSizeEnabled = bAutoGrowWidthEnabled = bAutoGrowHeightEnabled = true;
+ m_xCustomShapeText->hide();
+ m_xDrawingText->show();
+ break;
+ case SdrObjKind::CustomShape:
+ bFitToSizeEnabled = bContourEnabled = bAutoGrowWidthEnabled = bAutoGrowHeightEnabled = false;
+ bWordWrapTextEnabled = bAutoGrowSizeEnabled = true;
+ m_xDrawingText->hide();
+ m_xCustomShapeText->show();
+ break;
+ default:
+ bFitToSizeEnabled = bContourEnabled = true;
+ bWordWrapTextEnabled = bAutoGrowSizeEnabled = bAutoGrowWidthEnabled = bAutoGrowHeightEnabled = false;
+ m_xCustomShapeText->hide();
+ m_xDrawingText->show();
+ break;
+ }
+
+ m_xTsbAutoGrowHeight->set_visible( bAutoGrowHeightEnabled );
+ m_xTsbAutoGrowWidth->set_visible( bAutoGrowWidthEnabled );
+ m_xTsbFitToSize->set_visible( bFitToSizeEnabled );
+ m_xTsbContour->set_visible( bContourEnabled );
+ m_xTsbAutoGrowSize->set_visible( bAutoGrowSizeEnabled );
+ m_xTsbWordWrapText->set_visible( bWordWrapTextEnabled );
+}
+
+std::unique_ptr<SfxTabPage> SvxTextAttrPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrs)
+{
+ return std::make_unique<SvxTextAttrPage>(pPage, pController, *rAttrs);
+}
+
+/** Check whether we have to uncheck the "Full width" check box.
+*/
+void SvxTextAttrPage::PointChanged(weld::DrawingArea*, RectPoint eRP)
+{
+ if (m_xTsbFullWidth->get_state() != TRISTATE_TRUE)
+ return;
+
+ // Depending on write direction and currently checked anchor we have
+ // to uncheck the "full width" button.
+ if (IsTextDirectionLeftToRight())
+ switch( eRP )
+ {
+ case RectPoint::LT:
+ case RectPoint::LM:
+ case RectPoint::LB:
+ case RectPoint::RT:
+ case RectPoint::RM:
+ case RectPoint::RB:
+ m_xTsbFullWidth->set_state( TRISTATE_FALSE );
+ break;
+ default: ;//prevent warning
+ }
+ else
+ switch (eRP)
+ {
+ case RectPoint::LT:
+ case RectPoint::MT:
+ case RectPoint::RT:
+ case RectPoint::LB:
+ case RectPoint::MB:
+ case RectPoint::RB:
+ m_xTsbFullWidth->set_state( TRISTATE_FALSE );
+ break;
+ default: ;//prevent warning
+ }
+}
+
+
+/*************************************************************************
+|*
+|* possibly changes the position of the position-control
+|*
+\************************************************************************/
+
+/** When switching the "full width" check button on the text anchor may have
+ to be moved to a valid and adjacent position. This position depends on
+ the current anchor position and the text writing direction.
+*/
+IMPL_LINK_NOARG(SvxTextAttrPage, ClickFullWidthHdl_Impl, weld::Toggleable&, void)
+{
+ if( m_xTsbFullWidth->get_state() != TRISTATE_TRUE )
+ return;
+
+ if (IsTextDirectionLeftToRight())
+ {
+ // Move text anchor to horizontal middle axis.
+ switch( m_aCtlPosition.GetActualRP() )
+ {
+ case RectPoint::LT:
+ case RectPoint::RT:
+ m_aCtlPosition.SetActualRP( RectPoint::MT );
+ break;
+
+ case RectPoint::LM:
+ case RectPoint::RM:
+ m_aCtlPosition.SetActualRP( RectPoint::MM );
+ break;
+
+ case RectPoint::LB:
+ case RectPoint::RB:
+ m_aCtlPosition.SetActualRP( RectPoint::MB );
+ break;
+ default: ;//prevent warning
+ }
+ }
+ else
+ {
+ // Move text anchor to vertical middle axis.
+ switch( m_aCtlPosition.GetActualRP() )
+ {
+ case RectPoint::LT:
+ case RectPoint::LB:
+ m_aCtlPosition.SetActualRP( RectPoint::LM );
+ break;
+
+ case RectPoint::MT:
+ case RectPoint::MB:
+ m_aCtlPosition.SetActualRP( RectPoint::MM );
+ break;
+
+ case RectPoint::RT:
+ case RectPoint::RB:
+ m_aCtlPosition.SetActualRP( RectPoint::RM );
+ break;
+ default: ;//prevent warning
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* enables/disables "size at text" or "adjust to frame"
+|*
+\************************************************************************/
+
+IMPL_LINK(SvxTextAttrPage, ClickHdl_Impl, weld::Toggleable&, rButton, void)
+{
+ if (&rButton == m_xTsbAutoGrowSize.get())
+ {
+ m_xTsbAutoGrowHeight->set_state(m_xTsbAutoGrowSize->get_state());
+ if (m_xTsbAutoGrowSize->get_state() == TRISTATE_TRUE)
+ {
+ m_xTsbFitToSize->set_state(TRISTATE_FALSE);
+ m_xTsbContour->set_state(TRISTATE_FALSE);
+ }
+ }
+ else if (&rButton == m_xTsbAutoGrowHeight.get())
+ m_xTsbAutoGrowSize->set_state(m_xTsbAutoGrowHeight->get_state());
+
+ bool bAutoGrowWidth = m_xTsbAutoGrowWidth->get_state() == TRISTATE_TRUE;
+ bool bAutoGrowHeight = m_xTsbAutoGrowHeight->get_state() == TRISTATE_TRUE;
+ bool bFitToSize = m_xTsbFitToSize->get_state() == TRISTATE_TRUE;
+ bool bContour = m_xTsbContour->get_state() == TRISTATE_TRUE;
+
+ m_xTsbContour->set_sensitive( !bFitToSize &&
+ !( ( bAutoGrowWidth && bAutoGrowWidthEnabled ) || ( bAutoGrowHeight && bAutoGrowHeightEnabled ) ) &&
+ bContourEnabled );
+
+ m_xTsbAutoGrowWidth->set_sensitive( !bFitToSize &&
+ !( bContour && bContourEnabled ) &&
+ bAutoGrowWidthEnabled );
+
+ m_xTsbAutoGrowHeight->set_sensitive( !bFitToSize &&
+ !( bContour && bContourEnabled ) &&
+ bAutoGrowHeightEnabled );
+
+ m_xTsbFitToSize->set_sensitive( !( ( bAutoGrowWidth && bAutoGrowWidthEnabled ) || ( bAutoGrowHeight && bAutoGrowHeightEnabled ) ) &&
+ !( bContour && bContourEnabled ) &&
+ bFitToSizeEnabled );
+
+ // #101901# enable/disable metric fields and decorations dependent of contour
+ m_xFlDistance->set_sensitive(!bContour);
+
+ if( bContour && bContourEnabled )
+ {
+ m_xMtrFldLeft->set_value(0, FieldUnit::NONE);
+ m_xMtrFldRight->set_value(0, FieldUnit::NONE);
+ m_xMtrFldTop->set_value(0, FieldUnit::NONE);
+ m_xMtrFldBottom->set_value(0, FieldUnit::NONE);
+ }
+
+ // #103516# Do the setup based on states of hor/ver adjust
+ SfxItemState eVState = rOutAttrs.GetItemState( SDRATTR_TEXT_VERTADJUST );
+ SfxItemState eHState = rOutAttrs.GetItemState( SDRATTR_TEXT_HORZADJUST );
+ bool bHorAndVer(SfxItemState::DONTCARE == eVState || SfxItemState::DONTCARE == eHState);
+
+ // #83698# enable/disable text anchoring dependent of contour
+ m_xFlPosition->set_sensitive(!bContour && !bHorAndVer);
+}
+
+
+bool SvxTextAttrPage::IsTextDirectionLeftToRight() const
+{
+ // Determine the text writing direction with left to right as default.
+ bool bLeftToRightDirection = true;
+ SfxItemState eState = rOutAttrs.GetItemState(SDRATTR_TEXTDIRECTION);
+
+ if(SfxItemState::DONTCARE != eState)
+ {
+ const SvxWritingModeItem& rItem = rOutAttrs.Get(SDRATTR_TEXTDIRECTION);
+ if (rItem.GetValue() == css::text::WritingMode_TB_RL)
+ bLeftToRightDirection = false;
+ }
+ return bLeftToRightDirection;
+}
+
+void SvxTextAttrPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const CntUInt16Item* pObjTypeItem = aSet.GetItem<CntUInt16Item>(SID_SVXTEXTATTRPAGE_OBJKIND, false);
+
+ if (pObjTypeItem)
+ SetObjKind(static_cast<SdrObjKind>(pObjTypeItem->GetValue()));
+
+ Construct();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tparea.cxx b/cui/source/tabpages/tparea.cxx
new file mode 100644
index 0000000000..fa6db41d25
--- /dev/null
+++ b/cui/source/tabpages/tparea.cxx
@@ -0,0 +1,524 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svx/svxids.hrc>
+#include <svx/xfillit0.hxx>
+#include <svx/xfilluseslidebackgrounditem.hxx>
+#include <svx/xflbckit.hxx>
+#include <svx/drawitem.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xflgrit.hxx>
+#include <svx/xflhtit.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/xgrscit.hxx>
+#include <cuitabarea.hxx>
+#include <sfx2/tabdlg.hxx>
+
+using namespace com::sun::star;
+
+// static ----------------------------------------------------------------
+
+namespace {
+
+enum FillType
+{
+ TRANSPARENT,
+ SOLID,
+ GRADIENT,
+ HATCH,
+ BITMAP,
+ PATTERN,
+ USE_BACKGROUND_FILL
+};
+
+}
+
+const WhichRangesContainer SvxAreaTabPage::pAreaRanges(
+ svl::Items<
+ XATTR_GRADIENTSTEPCOUNT, XATTR_GRADIENTSTEPCOUNT,
+ SID_ATTR_FILL_STYLE, SID_ATTR_FILL_BITMAP>);
+
+namespace
+{
+
+void lclExtendSize(Size& rSize, const Size& rInputSize)
+{
+ if (rSize.Width() < rInputSize.Width())
+ rSize.setWidth( rInputSize.Width() );
+ if (rSize.Height() < rInputSize.Height())
+ rSize.setHeight( rInputSize.Height() );
+}
+
+} // end anonymous namespace
+
+/*************************************************************************
+|*
+|* Dialog to modify fill-attributes
+|*
+\************************************************************************/
+
+SvxAreaTabPage::SvxAreaTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rInAttrs, bool bSlideBackground)
+ : SfxTabPage(pPage, pController, "cui/ui/areatabpage.ui", "AreaTabPage", &rInAttrs)
+ // local fixed not o be changed values for local pointers
+ , maFixed_ChangeType(ChangeType::NONE)
+ // init with pointers to fixed ChangeType
+ , m_pnColorListState(&maFixed_ChangeType)
+ , m_pnBitmapListState(&maFixed_ChangeType)
+ , m_pnPatternListState(&maFixed_ChangeType)
+ , m_pnGradientListState(&maFixed_ChangeType)
+ , m_pnHatchingListState(&maFixed_ChangeType)
+ , m_aXFillAttr(rInAttrs.GetPool())
+ , m_rXFSet(m_aXFillAttr.GetItemSet())
+ , m_xFillTab(m_xBuilder->weld_container("fillstylebox"))
+ , m_xBtnNone(m_xBuilder->weld_toggle_button("btnnone"))
+ , m_xBtnColor(m_xBuilder->weld_toggle_button("btncolor"))
+ , m_xBtnGradient(m_xBuilder->weld_toggle_button("btngradient"))
+ , m_xBtnHatch(m_xBuilder->weld_toggle_button("btnhatch"))
+ , m_xBtnBitmap(m_xBuilder->weld_toggle_button("btnbitmap"))
+ , m_xBtnPattern(m_xBuilder->weld_toggle_button("btnpattern"))
+ , m_xBtnUseBackground(m_xBuilder->weld_toggle_button("btnusebackground"))
+{
+ maBox.AddButton(m_xBtnNone.get());
+ maBox.AddButton(m_xBtnColor.get());
+ maBox.AddButton(m_xBtnGradient.get());
+ maBox.AddButton(m_xBtnHatch.get());
+ maBox.AddButton(m_xBtnBitmap.get());
+ maBox.AddButton(m_xBtnPattern.get());
+
+ Link<weld::Toggleable&, void> aLink = LINK(this, SvxAreaTabPage, SelectFillTypeHdl_Impl);
+ m_xBtnNone->connect_toggled(aLink);
+ m_xBtnColor->connect_toggled(aLink);
+ m_xBtnGradient->connect_toggled(aLink);
+ m_xBtnHatch->connect_toggled(aLink);
+ m_xBtnBitmap->connect_toggled(aLink);
+ m_xBtnPattern->connect_toggled(aLink);
+ if (bSlideBackground)
+ {
+ maBox.AddButton(m_xBtnUseBackground.get());
+ m_xBtnUseBackground->connect_toggled(aLink);
+ }
+ else
+ m_xBtnUseBackground->hide();
+
+ SetExchangeSupport();
+}
+
+void SvxAreaTabPage::SetOptimalSize(weld::DialogController* pController)
+{
+ m_xFillTab->set_size_request(-1, -1);
+
+ // Calculate optimal size of all pages...
+ m_xFillTabPage = SvxColorTabPage::Create(m_xFillTab.get(), pController, &m_rXFSet);
+ Size aSize(m_xFillTab->get_preferred_size());
+
+ if (m_xBtnGradient->get_visible())
+ {
+ m_xFillTabPage = SvxGradientTabPage::Create(m_xFillTab.get(), pController, &m_rXFSet);
+ Size aGradientSize = m_xFillTab->get_preferred_size();
+ lclExtendSize(aSize, aGradientSize);
+ }
+ if (m_xBtnBitmap->get_visible())
+ {
+ m_xFillTabPage = SvxBitmapTabPage::Create(m_xFillTab.get(), pController, &m_rXFSet);
+ Size aBitmapSize = m_xFillTab->get_preferred_size();
+ lclExtendSize(aSize, aBitmapSize);
+ }
+ if (m_xBtnHatch->get_visible())
+ {
+ m_xFillTabPage = SvxHatchTabPage::Create(m_xFillTab.get(), pController, &m_rXFSet);
+ Size aHatchSize = m_xFillTab->get_preferred_size();
+ lclExtendSize(aSize, aHatchSize);
+ }
+ if (m_xBtnPattern->get_visible())
+ {
+ m_xFillTabPage = SvxPatternTabPage::Create(m_xFillTab.get(), pController, &m_rXFSet);
+ Size aPatternSize = m_xFillTab->get_preferred_size();
+ lclExtendSize(aSize, aPatternSize);
+ }
+ m_xFillTabPage.reset();
+
+ aSize.extendBy(10, 10); // apply a bit of margin
+
+ m_xFillTab->set_size_request(aSize.Width(), aSize.Height());
+}
+
+SvxAreaTabPage::~SvxAreaTabPage()
+{
+ m_xFillTabPage.reset();
+}
+
+void SvxAreaTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ drawing::FillStyle eXFS = drawing::FillStyle_NONE;
+ if( rSet.GetItemState( XATTR_FILLSTYLE ) != SfxItemState::DONTCARE )
+ {
+ XFillStyleItem aFillStyleItem( rSet.Get( GetWhich( XATTR_FILLSTYLE ) ) );
+ eXFS = aFillStyleItem.GetValue();
+ m_rXFSet.Put( aFillStyleItem );
+ }
+
+ switch(eXFS)
+ {
+ default:
+ case drawing::FillStyle_NONE:
+ {
+ XFillUseSlideBackgroundItem aBckItem( rSet.Get(XATTR_FILLUSESLIDEBACKGROUND));
+ if (aBckItem.GetValue())
+ SelectFillType(*m_xBtnUseBackground);
+ else
+ SelectFillType(*m_xBtnNone);
+ break;
+ }
+ case drawing::FillStyle_SOLID:
+ {
+ m_rXFSet.Put( rSet.Get( GetWhich( XATTR_FILLCOLOR ) ) );
+ SelectFillType(*m_xBtnColor);
+ break;
+ }
+ case drawing::FillStyle_GRADIENT:
+ {
+ m_rXFSet.Put( rSet.Get( GetWhich( XATTR_FILLGRADIENT ) ) );
+ m_rXFSet.Put(rSet.Get(GetWhich(XATTR_GRADIENTSTEPCOUNT)));
+ SelectFillType(*m_xBtnGradient);
+ break;
+ }
+ case drawing::FillStyle_HATCH:
+ {
+ m_rXFSet.Put( rSet.Get(XATTR_FILLHATCH) );
+ m_rXFSet.Put( rSet.Get(XATTR_FILLUSESLIDEBACKGROUND) );
+ m_rXFSet.Put( rSet.Get(XATTR_FILLCOLOR) );
+ SelectFillType(*m_xBtnHatch);
+ break;
+ }
+ case drawing::FillStyle_BITMAP:
+ {
+ const bool bPattern = rSet.Get(GetWhich(XATTR_FILLBITMAP)).isPattern();
+ // pass full item set here, bitmap fill has many attributes (tiling, size, offset etc.)
+ m_rXFSet.Put( rSet );
+ if (!bPattern)
+ SelectFillType(*m_xBtnBitmap);
+ else
+ SelectFillType(*m_xBtnPattern);
+ break;
+ }
+ }
+}
+
+template< typename TTabPage >
+DeactivateRC SvxAreaTabPage::DeactivatePage_Impl( SfxItemSet* _pSet )
+{
+ return static_cast<TTabPage&>(*m_xFillTabPage).DeactivatePage(_pSet);
+}
+
+DeactivateRC SvxAreaTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ FillType eFillType = static_cast<FillType>(maBox.GetCurrentButtonPos());
+ switch( eFillType )
+ {
+ case TRANSPARENT:
+ {
+ // Fill: None doesn't have its own tabpage and thus
+ // implementation of FillItemSet, so we supply it here
+ if ( m_bBtnClicked )
+ {
+ XFillStyleItem aStyleItem( drawing::FillStyle_NONE );
+ _pSet->Put( aStyleItem );
+ XFillUseSlideBackgroundItem aFillBgItem( false );
+ _pSet->Put( aFillBgItem );
+ }
+ break;
+ }
+ case SOLID:
+ return DeactivatePage_Impl<SvxColorTabPage>(_pSet);
+ case GRADIENT:
+ return DeactivatePage_Impl<SvxGradientTabPage>(_pSet);
+ case HATCH:
+ return DeactivatePage_Impl<SvxHatchTabPage>(_pSet);
+ case BITMAP:
+ return DeactivatePage_Impl<SvxBitmapTabPage&>(_pSet);
+ case PATTERN:
+ return DeactivatePage_Impl<SvxPatternTabPage>(_pSet);
+ case USE_BACKGROUND_FILL:
+ {
+ if ( m_bBtnClicked )
+ {
+ XFillStyleItem aStyleItem( drawing::FillStyle_NONE );
+ _pSet->Put( aStyleItem );
+ XFillUseSlideBackgroundItem aFillBgItem( true );
+ _pSet->Put( aFillBgItem );
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return DeactivateRC::LeavePage;
+}
+
+template< typename TTabPage >
+bool SvxAreaTabPage::FillItemSet_Impl( SfxItemSet* rAttrs)
+{
+ return static_cast<TTabPage&>( *m_xFillTabPage ).FillItemSet( rAttrs );
+}
+
+OUString SvxAreaTabPage::GetAllStrings()
+{
+ OUString sAllStrings;
+ OUString toggleButton[] = { "btnnone", "btncolor", "btngradient", "btnbitmap",
+ "btnpattern", "btnhatch", "btnusebackground" };
+
+ for (const auto& toggle : toggleButton)
+ {
+ if (const auto& pString = m_xBuilder->weld_toggle_button(toggle))
+ sAllStrings += pString->get_label() + " ";
+ }
+
+ return sAllStrings.replaceAll("_", "");
+}
+
+bool SvxAreaTabPage::FillItemSet( SfxItemSet* rAttrs )
+{
+ FillType eFillType = static_cast<FillType>(maBox.GetCurrentButtonPos());
+ switch( eFillType )
+ {
+ case TRANSPARENT:
+ {
+ rAttrs->Put( XFillStyleItem( drawing::FillStyle_NONE ) );
+ rAttrs->Put( XFillUseSlideBackgroundItem( false ) );
+ return true;
+ }
+ case SOLID:
+ {
+ return FillItemSet_Impl<SvxColorTabPage>( rAttrs );
+ }
+ case GRADIENT:
+ {
+ return FillItemSet_Impl<SvxGradientTabPage>( rAttrs );
+ }
+ case HATCH:
+ {
+ return FillItemSet_Impl<SvxHatchTabPage>( rAttrs );
+ }
+ case BITMAP:
+ {
+ return FillItemSet_Impl<SvxBitmapTabPage>( rAttrs );
+ }
+ case PATTERN:
+ {
+ return FillItemSet_Impl<SvxPatternTabPage>( rAttrs );
+ }
+ case USE_BACKGROUND_FILL:
+ {
+ rAttrs->Put( XFillStyleItem( drawing::FillStyle_NONE ) );
+ rAttrs->Put( XFillUseSlideBackgroundItem( true ) );
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+template< typename TTabPage >
+void SvxAreaTabPage::Reset_Impl( const SfxItemSet* rAttrs )
+{
+ static_cast<TTabPage&>( *m_xFillTabPage ).Reset( rAttrs );
+}
+
+void SvxAreaTabPage::Reset( const SfxItemSet* rAttrs )
+{
+ m_bBtnClicked = false;
+ auto eFillType = maBox.GetCurrentButtonPos();
+ switch(eFillType)
+ {
+ case SOLID:
+ {
+ Reset_Impl<SvxColorTabPage>( rAttrs );
+ break;
+ }
+ case GRADIENT:
+ {
+ Reset_Impl<SvxGradientTabPage>( rAttrs );
+ break;
+ }
+ case HATCH:
+ {
+ Reset_Impl<SvxHatchTabPage>( rAttrs );
+ break;
+ }
+ case BITMAP:
+ {
+ Reset_Impl<SvxBitmapTabPage>( rAttrs );
+ break;
+ }
+ case PATTERN:
+ {
+ Reset_Impl<SvxPatternTabPage>( rAttrs );
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+std::unique_ptr<SfxTabPage> SvxAreaTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrs)
+{
+ auto xRet = std::make_unique<SvxAreaTabPage>(pPage, pController, *rAttrs);
+ xRet->SetOptimalSize(pController);
+ return xRet;
+}
+
+std::unique_ptr<SfxTabPage> SvxAreaTabPage::CreateWithSlideBackground(
+ weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrs)
+{
+ auto xRet = std::make_unique<SvxAreaTabPage>(pPage, pController, *rAttrs, true);
+ xRet->SetOptimalSize(pController);
+ return xRet;
+}
+
+namespace {
+
+std::unique_ptr<SfxTabPage> lcl_CreateFillStyleTabPage(sal_uInt16 nId, weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+{
+ CreateTabPage fnCreate = nullptr;
+ switch(nId)
+ {
+ case TRANSPARENT: fnCreate = nullptr; break;
+ case SOLID: fnCreate = &SvxColorTabPage::Create; break;
+ case GRADIENT: fnCreate = &SvxGradientTabPage::Create; break;
+ case HATCH: fnCreate = &SvxHatchTabPage::Create; break;
+ case BITMAP: fnCreate = &SvxBitmapTabPage::Create; break;
+ case PATTERN: fnCreate = &SvxPatternTabPage::Create; break;
+ case USE_BACKGROUND_FILL: fnCreate = nullptr; break;
+ }
+ return fnCreate ? (*fnCreate)( pPage, pController, &rSet ) : nullptr;
+}
+
+}
+
+IMPL_LINK(SvxAreaTabPage, SelectFillTypeHdl_Impl, weld::Toggleable&, rButton, void)
+{
+ //tdf#124549 - If the button is already active do not toggle it back.
+ if(!rButton.get_active())
+ rButton.set_active(true);
+
+ SelectFillType(rButton);
+ m_bBtnClicked = true;
+}
+
+void SvxAreaTabPage::SelectFillType(weld::Toggleable& rButton, const SfxItemSet* _pSet)
+{
+ if (_pSet)
+ m_rXFSet.Set(*_pSet);
+
+ sal_Int32 nPos = maBox.GetButtonPos(&rButton);
+ if (nPos != -1 && (_pSet || nPos != maBox.GetCurrentButtonPos()))
+ {
+ maBox.SelectButton(&rButton);
+ FillType eFillType = static_cast<FillType>(maBox.GetCurrentButtonPos());
+ m_xFillTabPage = lcl_CreateFillStyleTabPage(eFillType, m_xFillTab.get(), GetDialogController(), m_rXFSet);
+ if (m_xFillTabPage)
+ {
+ m_xFillTabPage->SetDialogController(GetDialogController());
+ CreatePage(eFillType, *m_xFillTabPage);
+ }
+ }
+}
+
+void SvxAreaTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SvxColorListItem* pColorListItem = aSet.GetItem<SvxColorListItem>(SID_COLOR_TABLE, false);
+ const SvxGradientListItem* pGradientListItem = aSet.GetItem<SvxGradientListItem>(SID_GRADIENT_LIST, false);
+ const SvxHatchListItem* pHatchingListItem = aSet.GetItem<SvxHatchListItem>(SID_HATCH_LIST, false);
+ const SvxBitmapListItem* pBitmapListItem = aSet.GetItem<SvxBitmapListItem>(SID_BITMAP_LIST, false);
+ const SvxPatternListItem* pPatternListItem = aSet.GetItem<SvxPatternListItem>(SID_PATTERN_LIST, false);
+
+ if (pColorListItem)
+ SetColorList(pColorListItem->GetColorList());
+ if (pGradientListItem)
+ SetGradientList(pGradientListItem->GetGradientList());
+ if (pHatchingListItem)
+ SetHatchingList(pHatchingListItem->GetHatchList());
+ if (pBitmapListItem)
+ SetBitmapList(pBitmapListItem->GetBitmapList());
+ if (pPatternListItem)
+ SetPatternList(pPatternListItem->GetPatternList());
+}
+
+void SvxAreaTabPage::CreatePage(sal_Int32 nId, SfxTabPage& rTab)
+{
+ if(nId == SOLID )
+ {
+ auto& rColorTab = static_cast<SvxColorTabPage&>(rTab);
+ rColorTab.SetColorList(m_pColorList);
+ rColorTab.SetColorChgd(m_pnColorListState);
+ rColorTab.Construct();
+ rColorTab.ActivatePage(m_rXFSet);
+ rColorTab.Reset(&m_rXFSet);
+ rColorTab.set_visible(true);
+ }
+ else if(nId == GRADIENT)
+ {
+ auto& rGradientTab = static_cast<SvxGradientTabPage&>(rTab);
+ rGradientTab.SetColorList(m_pColorList);
+ rGradientTab.SetGradientList(m_pGradientList);
+ rGradientTab.SetGrdChgd(m_pnGradientListState);
+ rGradientTab.SetColorChgd(m_pnColorListState);
+ rGradientTab.Construct();
+ rGradientTab.ActivatePage(m_rXFSet);
+ rGradientTab.Reset(&m_rXFSet);
+ rGradientTab.set_visible(true);
+ }
+ else if(nId == HATCH)
+ {
+ auto& rHatchTab = static_cast<SvxHatchTabPage&>(rTab);
+ rHatchTab.SetColorList(m_pColorList);
+ rHatchTab.SetHatchingList(m_pHatchingList);
+ rHatchTab.SetHtchChgd(m_pnHatchingListState);
+ rHatchTab.SetColorChgd(m_pnColorListState);
+ rHatchTab.Construct();
+ rHatchTab.ActivatePage(m_rXFSet);
+ rHatchTab.Reset(&m_rXFSet);
+ rHatchTab.set_visible(true);
+ }
+ else if(nId == BITMAP)
+ {
+ auto& rBitmapTab = static_cast<SvxBitmapTabPage&>(rTab);
+ rBitmapTab.SetBitmapList(m_pBitmapList);
+ rBitmapTab.SetBmpChgd(m_pnBitmapListState);
+ rBitmapTab.Construct();
+ rBitmapTab.ActivatePage(m_rXFSet);
+ rBitmapTab.Reset(&m_rXFSet);
+ rBitmapTab.set_visible(true);
+ }
+ else if(nId == PATTERN)
+ {
+ auto& rPatternTab = static_cast<SvxPatternTabPage&>(rTab);
+ rPatternTab.SetColorList(m_pColorList);
+ rPatternTab.SetPatternList(m_pPatternList);
+ rPatternTab.SetPtrnChgd(m_pnPatternListState);
+ rPatternTab.SetColorChgd(m_pnColorListState);
+ rPatternTab.Construct();
+ rPatternTab.ActivatePage(m_rXFSet);
+ rPatternTab.Reset(&m_rXFSet);
+ rPatternTab.set_visible(true);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tpbitmap.cxx b/cui/source/tabpages/tpbitmap.cxx
new file mode 100644
index 0000000000..390fe1c771
--- /dev/null
+++ b/cui/source/tabpages/tpbitmap.cxx
@@ -0,0 +1,820 @@
+/* -*- 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 <memory>
+#include <stdlib.h>
+#include <tools/urlobj.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/svxids.hrc>
+#include <strings.hrc>
+#include <svx/xfillit0.hxx>
+#include <svx/xtable.hxx>
+#include <svx/xflbmsxy.hxx>
+#include <svx/xflbmtit.hxx>
+#include <svx/xflbstit.hxx>
+#include <svx/xflbmsli.hxx>
+#include <svx/xflbmpit.hxx>
+#include <svx/xflboxy.hxx>
+#include <svx/xflbtoxy.hxx>
+#include <cuitabarea.hxx>
+#include <dialmgr.hxx>
+#include <svx/dlgutil.hxx>
+#include <svl/intitem.hxx>
+#include <sfx2/opengrf.hxx>
+#include <vcl/image.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <svx/svxdlg.hxx>
+#include <sfx2/viewsh.hxx>
+#include <sfx2/dialoghelper.hxx>
+#include <sal/log.hxx>
+#include <comphelper/lok.hxx>
+#include <svtools/unitconv.hxx>
+
+using namespace com::sun::star;
+
+namespace {
+
+enum BitmapStyle
+{
+ CUSTOM,
+ TILED,
+ STRETCHED
+};
+
+enum TileOffset
+{
+ ROW,
+ COLUMN
+};
+
+}
+
+SvxBitmapTabPage::SvxBitmapTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/imagetabpage.ui", "ImageTabPage", &rInAttrs)
+ , m_rOutAttrs(rInAttrs)
+ , m_pnBitmapListState(nullptr)
+ , m_fObjectWidth(0.0)
+ , m_fObjectHeight(0.0)
+ , m_bLogicalSize(false)
+ , m_aXFillAttr(rInAttrs.GetPool())
+ , m_rXFSet(m_aXFillAttr.GetItemSet())
+ , mpView(nullptr)
+ , m_xBitmapLB(new SvxPresetListBox(m_xBuilder->weld_scrolled_window("imagewin", true)))
+ , m_xBitmapStyleLB(m_xBuilder->weld_combo_box("imagestyle"))
+ , m_xSizeBox(m_xBuilder->weld_container("sizebox"))
+ , m_xTsbScale(m_xBuilder->weld_check_button("scaletsb"))
+ , m_xBitmapWidth(m_xBuilder->weld_metric_spin_button("width", FieldUnit::PERCENT))
+ , m_xBitmapHeight(m_xBuilder->weld_metric_spin_button("height", FieldUnit::PERCENT))
+ , m_xPositionBox(m_xBuilder->weld_container("posbox"))
+ , m_xPositionLB(m_xBuilder->weld_combo_box("positionlb"))
+ , m_xPositionOffBox(m_xBuilder->weld_container("posoffbox"))
+ , m_xPositionOffX(m_xBuilder->weld_metric_spin_button("posoffx", FieldUnit::PERCENT))
+ , m_xPositionOffY(m_xBuilder->weld_metric_spin_button("posoffy", FieldUnit::PERCENT))
+ , m_xTileOffBox(m_xBuilder->weld_container("tileoffbox"))
+ , m_xTileOffLB(m_xBuilder->weld_combo_box("tileofflb"))
+ , m_xTileOffset(m_xBuilder->weld_metric_spin_button("tileoffmtr", FieldUnit::PERCENT))
+ , m_xBtnImport(m_xBuilder->weld_button("BTN_IMPORT"))
+ , m_xCtlBitmapPreview(new weld::CustomWeld(*m_xBuilder, "CTL_IMAGE_PREVIEW", m_aCtlBitmapPreview))
+ , m_xBitmapLBWin(new weld::CustomWeld(*m_xBuilder, "IMAGE", *m_xBitmapLB))
+{
+ // setting the output device
+ m_rXFSet.Put( XFillStyleItem(drawing::FillStyle_BITMAP) );
+ m_rXFSet.Put( XFillBitmapItem(OUString(), Graphic()) );
+ m_aCtlBitmapPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+
+ m_xBitmapLB->SetSelectHdl( LINK(this, SvxBitmapTabPage, ModifyBitmapHdl) );
+ m_xBitmapLB->SetRenameHdl( LINK(this, SvxBitmapTabPage, ClickRenameHdl) );
+ m_xBitmapLB->SetDeleteHdl( LINK(this, SvxBitmapTabPage, ClickDeleteHdl) );
+ m_xBitmapStyleLB->connect_changed( LINK(this, SvxBitmapTabPage, ModifyBitmapStyleHdl) );
+ Link<weld::MetricSpinButton&, void> aLink1( LINK(this, SvxBitmapTabPage, ModifyBitmapSizeHdl) );
+ m_xBitmapWidth->connect_value_changed( aLink1 );
+ m_xBitmapHeight->connect_value_changed( aLink1 );
+ m_xTsbScale->connect_toggled(LINK(this, SvxBitmapTabPage, ClickScaleHdl));
+ m_xPositionLB->connect_changed( LINK( this, SvxBitmapTabPage, ModifyBitmapPositionHdl ) );
+ Link<weld::MetricSpinButton&, void> aLink( LINK( this, SvxBitmapTabPage, ModifyPositionOffsetHdl ) );
+ m_xPositionOffX->connect_value_changed(aLink);
+ m_xPositionOffY->connect_value_changed(aLink);
+ m_xTileOffset->connect_value_changed( LINK( this, SvxBitmapTabPage, ModifyTileOffsetHdl ) );
+ m_xBtnImport->connect_clicked( LINK(this, SvxBitmapTabPage, ClickImportHdl) );
+ if (comphelper::LibreOfficeKit::isActive())
+ m_xBtnImport->hide();
+
+ // Calculate size of display boxes
+ Size aSize = getDrawPreviewOptimalSize(m_aCtlBitmapPreview.GetDrawingArea()->get_ref_device());
+ m_xBitmapLB->set_size_request(aSize.Width(), aSize.Height());
+ m_xCtlBitmapPreview->set_size_request(aSize.Width(), aSize.Height());
+
+ SfxItemPool* pPool = m_rXFSet.GetPool();
+ mePoolUnit = pPool->GetMetric( XATTR_FILLBMP_SIZEX );
+ meFieldUnit = GetModuleFieldUnit( rInAttrs );
+ SetFieldUnit( *m_xBitmapWidth, meFieldUnit, true );
+ SetFieldUnit( *m_xBitmapHeight, meFieldUnit, true );
+
+ m_xBitmapLB->SetStyle(WB_FLATVALUESET | WB_NO_DIRECTSELECT | WB_TABSTOP);
+
+ SfxViewShell* pViewShell = SfxViewShell::Current();
+ if( pViewShell )
+ mpView = pViewShell->GetDrawView();
+ DBG_ASSERT( mpView, "no valid view (!)" );
+}
+
+SvxBitmapTabPage::~SvxBitmapTabPage()
+{
+ m_xBitmapLBWin.reset();
+ m_xBitmapLB.reset();
+ m_xCtlBitmapPreview.reset();
+}
+
+void SvxBitmapTabPage::Construct()
+{
+ m_xBitmapLB->FillPresetListBox( *m_pBitmapList );
+}
+
+void SvxBitmapTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ XFillBitmapItem aItem( rSet.Get(XATTR_FILLBITMAP) );
+
+ sal_Int32 nPos( 0 );
+ if ( !aItem.isPattern() )
+ {
+ nPos = SearchBitmapList( aItem.GetGraphicObject() );
+ if (nPos == -1)
+ return;
+ }
+ else
+ {
+ m_xBitmapWidth->set_value( 100, FieldUnit::NONE );
+ m_xBitmapHeight->set_value( 100, FieldUnit::NONE );
+ const_cast<SfxItemSet&>(rSet).Put( XFillBmpSizeXItem( GetCoreValue( *m_xBitmapWidth, mePoolUnit ) ) );
+ const_cast<SfxItemSet&>(rSet).Put( XFillBmpSizeYItem( GetCoreValue( *m_xBitmapHeight, mePoolUnit ) ) );
+ }
+
+ sal_uInt16 nId = m_xBitmapLB->GetItemId( static_cast<size_t>( nPos ) );
+ m_xBitmapLB->SelectItem( nId );
+}
+
+DeactivateRC SvxBitmapTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+
+bool SvxBitmapTabPage::FillItemSet( SfxItemSet* rAttrs )
+{
+ rAttrs->Put(XFillStyleItem(drawing::FillStyle_BITMAP));
+ size_t nPos = m_xBitmapLB->GetSelectItemPos();
+ if(VALUESET_ITEM_NOTFOUND != nPos)
+ {
+ const XBitmapEntry* pXBitmapEntry = m_pBitmapList->GetBitmap(nPos);
+ const OUString aString(m_xBitmapLB->GetItemText( m_xBitmapLB->GetSelectedItemId() ));
+ rAttrs->Put(XFillBitmapItem(aString, pXBitmapEntry->GetGraphicObject()));
+ }
+
+ BitmapStyle eStylePos = static_cast<BitmapStyle>(m_xBitmapStyleLB->get_active());
+ bool bIsStretched( eStylePos == STRETCHED );
+ bool bIsTiled( eStylePos == TILED );
+
+ rAttrs->Put( XFillBmpTileItem(bIsTiled) );
+ rAttrs->Put( XFillBmpStretchItem(bIsStretched) );
+
+ if(!bIsStretched)
+ {
+ Size aSetBitmapSize;
+ switch(eStylePos)
+ {
+ case CUSTOM:
+ case TILED:
+ {
+ sal_Int64 nWidthPercent = m_xBitmapWidth->get_value(FieldUnit::NONE);
+ sal_Int64 nHeightPercent = m_xBitmapHeight->get_value(FieldUnit::NONE);
+ if (m_xTsbScale->get_sensitive() && m_xTsbScale->get_state() == TRISTATE_TRUE)
+ {
+ aSetBitmapSize.setWidth( -nWidthPercent );
+ aSetBitmapSize.setHeight( -nHeightPercent );
+ }
+ else if (!m_bLogicalSize)
+ {
+ aSetBitmapSize.setWidth( GetCoreValue(*m_xBitmapWidth, mePoolUnit) );
+ aSetBitmapSize.setHeight( GetCoreValue(*m_xBitmapHeight, mePoolUnit) );
+ }
+ else
+ {
+ rAttrs->Put( XFillBmpSizeLogItem(true) );
+ aSetBitmapSize.setWidth( 0 );
+ aSetBitmapSize.setHeight( 0 );
+ }
+
+ break;
+ }
+ default:
+ break;
+ }
+
+ rAttrs->Put( XFillBmpSizeXItem( aSetBitmapSize.Width() ) );
+ rAttrs->Put( XFillBmpSizeYItem( aSetBitmapSize.Height() ) );
+ }
+
+ if (m_xPositionLB->get_sensitive())
+ rAttrs->Put( XFillBmpPosItem( static_cast<RectPoint>( m_xPositionLB->get_active() ) ) );
+ if (m_xPositionOffX->get_sensitive())
+ rAttrs->Put( XFillBmpPosOffsetXItem(m_xPositionOffX->get_value(FieldUnit::PERCENT)));
+ if (m_xPositionOffY->get_sensitive())
+ rAttrs->Put( XFillBmpPosOffsetYItem(m_xPositionOffY->get_value(FieldUnit::PERCENT)));
+ if (m_xTileOffBox->get_sensitive())
+ {
+ TileOffset eValue = static_cast<TileOffset>(m_xTileOffLB->get_active());
+ sal_uInt16 nOffsetValue = static_cast<sal_uInt16>(m_xTileOffset->get_value(FieldUnit::PERCENT));
+ sal_uInt16 nRowOff = (eValue == ROW) ? nOffsetValue : 0;
+ sal_uInt16 nColOff = (eValue == COLUMN) ? nOffsetValue : 0;
+ rAttrs->Put( XFillBmpTileOffsetXItem(nRowOff) );
+ rAttrs->Put( XFillBmpTileOffsetYItem(nColOff) );
+ }
+ return true;
+}
+
+
+void SvxBitmapTabPage::Reset( const SfxItemSet* rAttrs )
+{
+ double transfWidth = 0.0;
+ double transfHeight = 0.0;
+ double fUIScale = 1.0;
+ if (mpView)
+ {
+ fUIScale = double(mpView->GetModel().GetUIScale());
+
+
+ if (mpView->AreObjectsMarked())
+ {
+ SfxItemSet rGeoAttr(mpView->GetGeoAttrFromMarked());
+ transfWidth = static_cast<double>(GetItem( rGeoAttr, SID_ATTR_TRANSFORM_WIDTH )->GetValue());
+ transfHeight= static_cast<double>(GetItem( rGeoAttr, SID_ATTR_TRANSFORM_HEIGHT )->GetValue());
+ }
+ }
+ m_fObjectWidth = std::max( transfWidth, 1.0 );
+ m_fObjectHeight = std::max( transfHeight, 1.0 );
+ double fTmpWidth((OutputDevice::LogicToLogic(static_cast<sal_Int32>(m_fObjectWidth), mePoolUnit, MapUnit::Map100thMM )) / fUIScale);
+ m_fObjectWidth = fTmpWidth;
+
+ double fTmpHeight((OutputDevice::LogicToLogic(static_cast<sal_Int32>(m_fObjectHeight), mePoolUnit, MapUnit::Map100thMM )) / fUIScale);
+ m_fObjectHeight = fTmpHeight;
+
+ XFillBitmapItem aItem( rAttrs->Get(XATTR_FILLBITMAP) );
+
+ if(!aItem.isPattern())
+ {
+ m_rXFSet.Put( aItem );
+ m_aCtlBitmapPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlBitmapPreview.Invalidate();
+ }
+ else
+ m_xCtlBitmapPreview->set_sensitive(false);
+
+ std::unique_ptr<GraphicObject> pGraphicObject;
+ pGraphicObject.reset( new GraphicObject(aItem.GetGraphicObject()) );
+
+ BitmapEx aBmpEx(pGraphicObject->GetGraphic().GetBitmapEx());
+ Size aTempBitmapSize = aBmpEx.GetSizePixel();
+ rBitmapSize = Application::GetDefaultDevice()->PixelToLogic(aTempBitmapSize, MapMode(MapUnit::Map100thMM));
+ CalculateBitmapPresetSize();
+
+ bool bTiled = false; bool bStretched = false;
+ if(rAttrs->GetItemState( XATTR_FILLBMP_TILE ) != SfxItemState::DONTCARE)
+ bTiled = rAttrs->Get( XATTR_FILLBMP_TILE ).GetValue();
+ if(rAttrs->GetItemState( XATTR_FILLBMP_STRETCH ) != SfxItemState::DONTCARE)
+ bStretched = rAttrs->Get( XATTR_FILLBMP_STRETCH ).GetValue();
+
+ if (bTiled)
+ m_xBitmapStyleLB->set_active(static_cast<sal_Int32>(TILED));
+ else if (bStretched)
+ m_xBitmapStyleLB->set_active(static_cast<sal_Int32>(STRETCHED));
+ else
+ m_xBitmapStyleLB->set_active(static_cast<sal_Int32>(CUSTOM));
+
+ tools::Long nWidth = 0;
+ tools::Long nHeight = 0;
+
+ if(rAttrs->GetItemState(XATTR_FILLBMP_SIZELOG) != SfxItemState::DONTCARE)
+ {
+ if (rAttrs->Get( XATTR_FILLBMP_SIZELOG ).GetValue())
+ m_xTsbScale->set_state(TRISTATE_FALSE);
+ else
+ m_xTsbScale->set_state(TRISTATE_TRUE);
+ }
+ else
+ m_xTsbScale->set_state(TRISTATE_INDET);
+
+ TriState eRelative = TRISTATE_FALSE;
+ if(rAttrs->GetItemState(XATTR_FILLBMP_SIZEX) != SfxItemState::DONTCARE)
+ {
+ nWidth = static_cast<const XFillBmpSizeXItem&>( rAttrs->Get( XATTR_FILLBMP_SIZEX ) ).GetValue();
+ if(nWidth == 0)
+ nWidth = rBitmapSize.Width();
+ else if(nWidth < 0)
+ {
+ m_bLogicalSize = true;
+ eRelative = TRISTATE_TRUE;
+ nWidth = std::abs(nWidth);
+ }
+ }
+
+ if(rAttrs->GetItemState( XATTR_FILLBMP_SIZEY ) != SfxItemState::DONTCARE)
+ {
+ nHeight = rAttrs->Get( XATTR_FILLBMP_SIZEY ).GetValue();
+ if(nHeight == 0)
+ nHeight = rBitmapSize.Height();
+ else if(nHeight < 0)
+ {
+ m_bLogicalSize = true;
+ eRelative = TRISTATE_TRUE;
+ nHeight = std::abs(nHeight);
+ }
+ }
+ m_xTsbScale->set_state(eRelative);
+ ClickScaleHdl(*m_xTsbScale);
+
+
+ if(!rBitmapSize.IsEmpty())
+ {
+ if (eRelative == TRISTATE_TRUE)
+ {
+ m_xBitmapWidth->set_value(nWidth, FieldUnit::NONE);
+ m_xBitmapHeight->set_value(nHeight, FieldUnit::NONE);
+ }
+ else
+ {
+ SetMetricValue(*m_xBitmapWidth, nWidth, mePoolUnit);
+ SetMetricValue(*m_xBitmapHeight, nHeight, mePoolUnit);
+ }
+ }
+
+ if( rAttrs->GetItemState( XATTR_FILLBMP_POS ) != SfxItemState::DONTCARE )
+ {
+ RectPoint eValue = rAttrs->Get( XATTR_FILLBMP_POS ).GetValue();
+ m_xPositionLB->set_active( static_cast< sal_Int32 >(eValue) );
+ }
+
+ if( rAttrs->GetItemState( XATTR_FILLBMP_POSOFFSETX ) != SfxItemState::DONTCARE )
+ {
+ sal_Int32 nValue = rAttrs->Get( XATTR_FILLBMP_POSOFFSETX ).GetValue();
+ m_xPositionOffX->set_value(nValue, FieldUnit::PERCENT);
+ }
+ else
+ m_xPositionOffX->set_text("");
+
+ if( rAttrs->GetItemState( XATTR_FILLBMP_POSOFFSETY ) != SfxItemState::DONTCARE )
+ {
+ sal_Int32 nValue = rAttrs->Get( XATTR_FILLBMP_POSOFFSETY ).GetValue();
+ m_xPositionOffY->set_value(nValue, FieldUnit::PERCENT);
+ }
+ else
+ m_xPositionOffY->set_text("");
+
+ if( rAttrs->GetItemState( XATTR_FILLBMP_TILEOFFSETX ) != SfxItemState::DONTCARE)
+ {
+ sal_Int32 nValue = rAttrs->Get( XATTR_FILLBMP_TILEOFFSETX ).GetValue();
+ if(nValue > 0)
+ {
+ m_xTileOffLB->set_active(static_cast<sal_Int32>(ROW));
+ m_xTileOffset->set_value(nValue, FieldUnit::PERCENT);
+ }
+ }
+
+ if( rAttrs->GetItemState( XATTR_FILLBMP_TILEOFFSETY ) != SfxItemState::DONTCARE )
+ {
+ sal_Int32 nValue = rAttrs->Get( XATTR_FILLBMP_TILEOFFSETY ).GetValue();
+ if(nValue > 0)
+ {
+ m_xTileOffLB->set_active(static_cast<sal_Int32>(COLUMN));
+ m_xTileOffset->set_value(nValue, FieldUnit::PERCENT);
+ }
+ }
+
+ ClickBitmapHdl_Impl();
+}
+
+std::unique_ptr<SfxTabPage> SvxBitmapTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrs)
+{
+ return std::make_unique<SvxBitmapTabPage>(pPage, pController, *rAttrs);
+}
+
+void SvxBitmapTabPage::ClickBitmapHdl_Impl()
+{
+ m_xBitmapLBWin->set_sensitive(true);
+ m_xCtlBitmapPreview->set_sensitive(true);
+
+ ModifyBitmapHdl(m_xBitmapLB.get());
+}
+
+void SvxBitmapTabPage::CalculateBitmapPresetSize()
+{
+ if(rBitmapSize.IsEmpty())
+ return;
+
+ tools::Long nObjectWidth = static_cast<tools::Long>(m_fObjectWidth);
+ tools::Long nObjectHeight = static_cast<tools::Long>(m_fObjectHeight);
+
+ if(std::abs(rBitmapSize.Width() - nObjectWidth) < std::abs(rBitmapSize.Height() - nObjectHeight))
+ {
+ rFilledSize.setWidth( nObjectWidth );
+ rFilledSize.setHeight( rBitmapSize.Height()*nObjectWidth/rBitmapSize.Width() );
+ rZoomedSize.setWidth( rBitmapSize.Width()*nObjectHeight/rBitmapSize.Height() );
+ rZoomedSize.setHeight( nObjectHeight );
+ }
+ else
+ {
+ rFilledSize.setWidth( rBitmapSize.Width()*nObjectHeight/rBitmapSize.Height() );
+ rFilledSize.setHeight( nObjectHeight );
+ rZoomedSize.setWidth( nObjectWidth );
+ rZoomedSize.setHeight( rBitmapSize.Height()*nObjectWidth/rBitmapSize.Width() );
+ }
+}
+
+IMPL_LINK_NOARG(SvxBitmapTabPage, ModifyBitmapHdl, ValueSet*, void)
+{
+ std::unique_ptr<GraphicObject> pGraphicObject;
+ size_t nPos = m_xBitmapLB->GetSelectItemPos();
+
+ if( nPos != VALUESET_ITEM_NOTFOUND )
+ {
+ pGraphicObject.reset(new GraphicObject(m_pBitmapList->GetBitmap( static_cast<sal_uInt16>(nPos) )->GetGraphicObject()));
+ }
+ else
+ {
+ if(const XFillStyleItem* pFillStyleItem = m_rOutAttrs.GetItemIfSet(GetWhich(XATTR_FILLSTYLE)))
+ {
+ const drawing::FillStyle eXFS(pFillStyleItem->GetValue());
+
+ const XFillBitmapItem* pBitmapItem;
+ if((drawing::FillStyle_BITMAP == eXFS) && (pBitmapItem = m_rOutAttrs.GetItemIfSet(GetWhich(XATTR_FILLBITMAP))))
+ {
+ pGraphicObject.reset(new GraphicObject(pBitmapItem->GetGraphicObject()));
+ }
+ }
+
+ if(!pGraphicObject)
+ {
+ sal_uInt16 nId = m_xBitmapLB->GetItemId(0);
+ m_xBitmapLB->SelectItem(nId);
+
+ if(0 != nId)
+ {
+ pGraphicObject.reset(new GraphicObject(m_pBitmapList->GetBitmap(0)->GetGraphicObject()));
+ }
+ }
+ }
+
+ if(pGraphicObject)
+ {
+ BitmapEx aBmpEx(pGraphicObject->GetGraphic().GetBitmapEx());
+ Size aTempBitmapSize = aBmpEx.GetSizePixel();
+ const double fUIScale = mpView ? double(mpView->GetModel().GetUIScale()) : 1.0;
+ Size aBitmapSize100mm = o3tl::convert(aTempBitmapSize, o3tl::Length::pt, o3tl::Length::mm100);
+
+ rBitmapSize.setWidth(aBitmapSize100mm.Width() / fUIScale);
+ rBitmapSize.setHeight(aBitmapSize100mm.Height() / fUIScale);
+ CalculateBitmapPresetSize();
+ ModifyBitmapStyleHdl( *m_xBitmapStyleLB );
+ ModifyBitmapPositionHdl( *m_xPositionLB );
+
+ m_rXFSet.ClearItem(XATTR_FILLBITMAP);
+ m_rXFSet.Put(XFillStyleItem(drawing::FillStyle_BITMAP));
+ m_rXFSet.Put(XFillBitmapItem(OUString(), *pGraphicObject));
+
+ m_aCtlBitmapPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlBitmapPreview.Invalidate();
+ }
+ else
+ {
+ SAL_WARN("cui.tabpages", "SvxBitmapTabPage::ModifyBitmapHdl(): null pGraphicObject");
+ }
+
+}
+
+IMPL_LINK_NOARG(SvxBitmapTabPage, ClickRenameHdl, SvxPresetListBox*, void)
+{
+ sal_uInt16 nId = m_xBitmapLB->GetSelectedItemId();
+ size_t nPos = m_xBitmapLB->GetSelectItemPos();
+
+ if( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ OUString aDesc( CuiResId( RID_CUISTR_DESC_NEW_BITMAP ) );
+ OUString aName( m_pBitmapList->GetBitmap( nPos )->GetName() );
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+
+ bool bLoop = true;
+ while( bLoop && pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+ sal_Int32 nBitmapPos = SearchBitmapList( aName );
+ bool bValidBitmapName = (nBitmapPos == static_cast<sal_Int32>(nPos) ) || (nBitmapPos == -1);
+
+ if(bValidBitmapName)
+ {
+ bLoop = false;
+ m_pBitmapList->GetBitmap(nPos)->SetName(aName);
+
+ m_xBitmapLB->SetItemText(nId, aName);
+ m_xBitmapLB->SelectItem( nId );
+
+ *m_pnBitmapListState |= ChangeType::MODIFIED;
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ xBox->run();
+ }
+ }
+}
+
+IMPL_LINK_NOARG(SvxBitmapTabPage, ClickDeleteHdl, SvxPresetListBox*, void)
+{
+ sal_uInt16 nId = m_xBitmapLB->GetSelectedItemId();
+ size_t nPos = m_xBitmapLB->GetSelectItemPos();
+
+ if( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querydeletebitmapdialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("AskDelBitmapDialog"));
+
+ if (xQueryBox->run() != RET_YES)
+ return;
+
+ sal_uInt16 nNextId = m_xBitmapLB->GetItemId(nPos + 1);
+ if (!nNextId)
+ nNextId = m_xBitmapLB->GetItemId(nPos - 1);
+
+ m_pBitmapList->Remove( static_cast<sal_uInt16>(nPos) );
+ m_xBitmapLB->RemoveItem( nId );
+
+ m_xBitmapLB->SelectItem(nNextId);
+
+ m_aCtlBitmapPreview.Invalidate();
+ ModifyBitmapHdl(m_xBitmapLB.get());
+ *m_pnBitmapListState |= ChangeType::MODIFIED;
+}
+
+IMPL_LINK_NOARG( SvxBitmapTabPage, ModifyBitmapSizeHdl, weld::MetricSpinButton&, void )
+{
+ m_bLogicalSize = false;
+ if (m_xTsbScale->get_state() != TRISTATE_TRUE && static_cast<BitmapStyle>(m_xBitmapStyleLB->get_active()) != TILED)
+ {
+ sal_Int64 nWidthPercent = m_xBitmapWidth->denormalize(m_xBitmapWidth->get_value(FieldUnit::NONE));
+ sal_Int64 nHeightPercent = m_xBitmapHeight->denormalize(m_xBitmapHeight->get_value(FieldUnit::NONE));
+ if (nWidthPercent == 100 && nHeightPercent == 100)
+ m_xBitmapStyleLB->set_active(static_cast<sal_Int32>(CUSTOM));
+ }
+ ModifyBitmapStyleHdl(*m_xBitmapStyleLB);
+
+ m_aCtlBitmapPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlBitmapPreview.Invalidate();
+}
+
+IMPL_LINK_NOARG( SvxBitmapTabPage, ClickScaleHdl, weld::Toggleable&, void )
+{
+ if (m_xTsbScale->get_state() == TRISTATE_TRUE)
+ {
+ m_xBitmapWidth->set_digits( 0 );
+ m_xBitmapWidth->set_unit(FieldUnit::PERCENT);
+ m_xBitmapWidth->set_value(100, FieldUnit::NONE);
+ m_xBitmapWidth->set_range(0, 100, FieldUnit::NONE);
+
+ m_xBitmapHeight->set_digits( 0 );
+ m_xBitmapHeight->set_unit(FieldUnit::PERCENT);
+ m_xBitmapHeight->set_value(100, FieldUnit::NONE);
+ m_xBitmapHeight->set_range(0, 100, FieldUnit::NONE);
+ }
+ else
+ {
+ m_xBitmapWidth->set_digits( 2 );
+ m_xBitmapWidth->set_unit(meFieldUnit);
+ m_xBitmapWidth->set_value(100, FieldUnit::NONE);
+ m_xBitmapWidth->set_range(0, 999900, FieldUnit::NONE);
+
+ m_xBitmapHeight->set_digits( 2 );
+ m_xBitmapHeight->set_unit(meFieldUnit);
+ m_xBitmapHeight->set_value(100, FieldUnit::NONE);
+ m_xBitmapHeight->set_range(0, 999900, FieldUnit::NONE);
+ }
+
+ ModifyBitmapStyleHdl( *m_xBitmapStyleLB );
+}
+
+IMPL_LINK_NOARG( SvxBitmapTabPage, ModifyBitmapStyleHdl, weld::ComboBox&, void )
+{
+ BitmapStyle eStylePos = static_cast<BitmapStyle>(m_xBitmapStyleLB->get_active());
+ bool bIsStretched( eStylePos == STRETCHED );
+ bool bIsTiled( eStylePos == TILED );
+
+ m_xSizeBox->set_sensitive( !bIsStretched );
+ m_xPositionBox->set_sensitive( !bIsStretched );
+ m_xPositionOffBox->set_sensitive( bIsTiled );
+ m_xTileOffBox->set_sensitive( bIsTiled );
+
+ m_rXFSet.Put( XFillBmpTileItem( bIsTiled ) );
+ m_rXFSet.Put( XFillBmpStretchItem( bIsStretched ) );
+
+ if(!bIsStretched)
+ {
+ Size aSetBitmapSize;
+ switch(eStylePos)
+ {
+ case CUSTOM:
+ case TILED:
+ {
+ if (m_xTsbScale->get_sensitive() && m_xTsbScale->get_state() == TRISTATE_TRUE)
+ {
+ aSetBitmapSize.setWidth(-m_xBitmapWidth->get_value(FieldUnit::NONE));
+ aSetBitmapSize.setHeight(-m_xBitmapHeight->get_value(FieldUnit::NONE));
+ }
+ else
+ {
+ aSetBitmapSize.setWidth( GetCoreValue( *m_xBitmapWidth, mePoolUnit ) );
+ aSetBitmapSize.setHeight( GetCoreValue( *m_xBitmapHeight, mePoolUnit ) );
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ m_rXFSet.Put( XFillBmpSizeXItem( aSetBitmapSize.Width() ) );
+ m_rXFSet.Put( XFillBmpSizeYItem( aSetBitmapSize.Height() ) );
+ }
+
+ m_aCtlBitmapPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlBitmapPreview.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxBitmapTabPage, ModifyBitmapPositionHdl, weld::ComboBox&, void)
+{
+ if (m_xPositionLB->get_sensitive())
+ m_rXFSet.Put( XFillBmpPosItem( static_cast< RectPoint >( m_xPositionLB->get_active() ) ) );
+
+ m_aCtlBitmapPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlBitmapPreview.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxBitmapTabPage, ModifyPositionOffsetHdl, weld::MetricSpinButton&, void)
+{
+ if (m_xPositionOffX->get_sensitive())
+ m_rXFSet.Put( XFillBmpPosOffsetXItem( m_xPositionOffX->get_value(FieldUnit::PERCENT) ) );
+
+ if (m_xPositionOffY->get_sensitive())
+ m_rXFSet.Put( XFillBmpPosOffsetYItem( m_xPositionOffY->get_value(FieldUnit::PERCENT) ) );
+
+ m_aCtlBitmapPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlBitmapPreview.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxBitmapTabPage, ModifyTileOffsetHdl, weld::MetricSpinButton&, void)
+{
+ sal_uInt16 nTileXOff = 0;
+ sal_uInt16 nTileYOff = 0;
+
+ if(m_xTileOffLB->get_active() == static_cast<sal_Int32>(ROW))
+ nTileXOff = m_xTileOffset->get_value(FieldUnit::PERCENT);
+
+ if(m_xTileOffLB->get_active() == static_cast<sal_Int32>(COLUMN))
+ nTileYOff = m_xTileOffset->get_value(FieldUnit::PERCENT);
+
+ m_rXFSet.Put( XFillBmpTileOffsetXItem(nTileXOff) );
+ m_rXFSet.Put( XFillBmpTileOffsetYItem(nTileYOff) );
+
+ m_aCtlBitmapPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlBitmapPreview.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxBitmapTabPage, ClickImportHdl, weld::Button&, void)
+{
+ weld::Window* pDialogFrameWeld = GetFrameWeld();
+
+ SvxOpenGraphicDialog aDlg(CuiResId(RID_CUISTR_ADD_IMAGE), pDialogFrameWeld);
+ aDlg.EnableLink(false);
+ tools::Long nCount = m_pBitmapList->Count();
+
+ if( aDlg.Execute() )
+ return;
+
+ Graphic aGraphic;
+
+ std::unique_ptr<weld::WaitObject> xWait(new weld::WaitObject(pDialogFrameWeld));
+ ErrCode nError = aDlg.GetGraphic( aGraphic );
+ xWait.reset();
+
+ if( !nError )
+ {
+ OUString aDesc(CuiResId(RID_CUISTR_DESC_EXT_BITMAP));
+
+ // convert file URL to UI name
+ OUString aName;
+ INetURLObject aURL( aDlg.GetPath() );
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(
+ pDialogFrameWeld, aURL.GetLastName().getToken(0, '.'), aDesc));
+ nError = ErrCode(1);
+
+ while( pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+
+ bool bDifferent = true;
+
+ for( tools::Long i = 0; i < nCount && bDifferent; i++ )
+ if( aName == m_pBitmapList->GetBitmap( i )->GetName() )
+ bDifferent = false;
+
+ if( bDifferent ) {
+ nError = ERRCODE_NONE;
+ break;
+ }
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pDialogFrameWeld, "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ if (xBox->run() != RET_OK)
+ break;
+ }
+
+ pDlg.disposeAndClear();
+
+ if( !nError )
+ {
+ m_pBitmapList->Insert(std::make_unique<XBitmapEntry>(aGraphic, aName), nCount);
+
+ sal_Int32 nId = m_xBitmapLB->GetItemId( nCount - 1 );
+ BitmapEx aBitmap = m_pBitmapList->GetBitmapForPreview( nCount, m_xBitmapLB->GetIconSize() );
+
+ m_xBitmapLB->InsertItem( nId + 1, Image(aBitmap), aName );
+ m_xBitmapLB->SelectItem( nId + 1 );
+ *m_pnBitmapListState |= ChangeType::MODIFIED;
+
+ ModifyBitmapHdl(m_xBitmapLB.get());
+ }
+ }
+ else
+ {
+ // graphic couldn't be loaded
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pDialogFrameWeld, "cui/ui/querynoloadedfiledialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("NoLoadedFileDialog"));
+ xBox->run();
+ }
+}
+
+sal_Int32 SvxBitmapTabPage::SearchBitmapList(const GraphicObject& rGraphicObject)
+{
+ tools::Long nCount = m_pBitmapList->Count();
+ sal_Int32 nPos = -1;
+
+ for(tools::Long i = 0;i < nCount;i++)
+ {
+ if(rGraphicObject.GetUniqueID() == m_pBitmapList->GetBitmap( i )->GetGraphicObject().GetUniqueID())
+ {
+ nPos = i;
+ break;
+ }
+ }
+ return nPos;
+}
+
+sal_Int32 SvxBitmapTabPage::SearchBitmapList(std::u16string_view rBitmapName)
+{
+ tools::Long nCount = m_pBitmapList->Count();
+ bool bValidBitmapName = true;
+ sal_Int32 nPos = -1;
+
+ for(tools::Long i = 0;i < nCount && bValidBitmapName;i++)
+ {
+ if(rBitmapName == m_pBitmapList->GetBitmap( i )->GetName())
+ {
+ nPos = i;
+ bValidBitmapName = false;
+ }
+ }
+ return nPos;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tpcolor.cxx b/cui/source/tabpages/tpcolor.cxx
new file mode 100644
index 0000000000..8df09ff098
--- /dev/null
+++ b/cui/source/tabpages/tpcolor.cxx
@@ -0,0 +1,795 @@
+/* -*- 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 <memory>
+#include <i18nutil/unicode.hxx>
+#include <svtools/colrdlg.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+
+#include <strings.hrc>
+#include <svx/xfillit0.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xtable.hxx>
+#include <cuitabarea.hxx>
+#include <svx/svxdlg.hxx>
+#include <dialmgr.hxx>
+#include <cuitabline.hxx>
+#include <svx/dialmgr.hxx>
+#include <svx/strings.hrc>
+#include <officecfg/Office/Common.hxx>
+#include <osl/diagnose.h>
+#include <comphelper/dispatchcommand.hxx>
+#include <comphelper/lok.hxx>
+#include <comphelper/propertyvalue.hxx>
+
+using namespace com::sun::star;
+
+SvxColorTabPage::SvxColorTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/colorpage.ui", "ColorPage", &rInAttrs)
+ , rOutAttrs ( rInAttrs )
+ // All the horrific pointers we store and should not
+ , pnColorListState( nullptr )
+ , aXFillAttr( rInAttrs.GetPool() )
+ , rXFSet( aXFillAttr.GetItemSet() )
+ , eCM( ColorModel::RGB )
+ , m_xValSetColorList(new SvxColorValueSet(m_xBuilder->weld_scrolled_window("colorsetwin", true)))
+ , m_xValSetRecentList(new SvxColorValueSet(nullptr))
+ , m_xSelectPalette(m_xBuilder->weld_combo_box("paletteselector"))
+ , m_xRbRGB(m_xBuilder->weld_radio_button("RGB"))
+ , m_xRbCMYK(m_xBuilder->weld_radio_button("CMYK"))
+ , m_xRGBcustom(m_xBuilder->weld_widget("rgbcustom"))
+ , m_xRGBpreset(m_xBuilder->weld_widget("rgbpreset"))
+ , m_xRpreset(m_xBuilder->weld_entry("R_preset"))
+ , m_xGpreset(m_xBuilder->weld_entry("G_preset"))
+ , m_xBpreset(m_xBuilder->weld_entry("B_preset"))
+ , m_xRcustom(m_xBuilder->weld_spin_button("R_custom"))
+ , m_xGcustom(m_xBuilder->weld_spin_button("G_custom"))
+ , m_xBcustom(m_xBuilder->weld_spin_button("B_custom"))
+ , m_xHexpreset(new weld::HexColorControl(m_xBuilder->weld_entry("hex_preset")))
+ , m_xHexcustom(new weld::HexColorControl(m_xBuilder->weld_entry("hex_custom")))
+ , m_xCMYKcustom(m_xBuilder->weld_widget("cmykcustom"))
+ , m_xCMYKpreset(m_xBuilder->weld_widget("cmykpreset"))
+ , m_xCpreset(m_xBuilder->weld_entry("C_preset"))
+ , m_xYpreset(m_xBuilder->weld_entry("Y_preset"))
+ , m_xMpreset(m_xBuilder->weld_entry("M_preset"))
+ , m_xKpreset(m_xBuilder->weld_entry("K_preset"))
+ , m_xCcustom(m_xBuilder->weld_metric_spin_button("C_custom", FieldUnit::PERCENT))
+ , m_xYcustom(m_xBuilder->weld_metric_spin_button("Y_custom", FieldUnit::PERCENT))
+ , m_xMcustom(m_xBuilder->weld_metric_spin_button("M_custom", FieldUnit::PERCENT))
+ , m_xKcustom(m_xBuilder->weld_metric_spin_button("K_custom", FieldUnit::PERCENT))
+ , m_xBtnAdd(m_xBuilder->weld_button("add"))
+ , m_xBtnDelete(m_xBuilder->weld_button("delete"))
+ , m_xBtnWorkOn(m_xBuilder->weld_button("edit"))
+ , m_xMoreColors(m_xBuilder->weld_button("btnMoreColors"))
+ , m_xCtlPreviewOld(new weld::CustomWeld(*m_xBuilder, "oldpreview", m_aCtlPreviewOld))
+ , m_xCtlPreviewNew(new weld::CustomWeld(*m_xBuilder, "newpreview", m_aCtlPreviewNew))
+ , m_xValSetColorListWin(new weld::CustomWeld(*m_xBuilder, "colorset", *m_xValSetColorList))
+ , m_xValSetRecentListWin(new weld::CustomWeld(*m_xBuilder, "recentcolorset", *m_xValSetRecentList))
+{
+ Size aSize(m_xBtnWorkOn->get_approximate_digit_width() * 25,
+ m_xBtnWorkOn->get_text_height() * 10);
+ m_xValSetColorList->set_size_request(aSize.Width(), aSize.Height());
+ aSize = Size(m_xBtnWorkOn->get_approximate_digit_width() * 8,
+ m_xBtnWorkOn->get_text_height() * 3);
+ m_aCtlPreviewOld.set_size_request(aSize.Width(), aSize.Height());
+ m_aCtlPreviewNew.set_size_request(aSize.Width(), aSize.Height());
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ // setting the output device
+ rXFSet.Put( XFillStyleItem(drawing::FillStyle_SOLID) );
+ rXFSet.Put( XFillColorItem(OUString(), COL_BLACK) );
+ m_aCtlPreviewOld.SetAttributes( aXFillAttr.GetItemSet() );
+ m_aCtlPreviewNew.SetAttributes( aXFillAttr.GetItemSet() );
+
+ // set handler
+ m_xSelectPalette->connect_changed(LINK(this, SvxColorTabPage, SelectPaletteLBHdl));
+ Link<ValueSet*, void> aValSelectLink = LINK(this, SvxColorTabPage, SelectValSetHdl_Impl);
+ m_xValSetColorList->SetSelectHdl(aValSelectLink);
+ m_xValSetRecentList->SetSelectHdl(aValSelectLink);
+
+ Link<weld::SpinButton&,void> aSpinLink = LINK(this, SvxColorTabPage, SpinValueHdl_Impl);
+ m_xRcustom->connect_value_changed(aSpinLink);
+ m_xGcustom->connect_value_changed(aSpinLink);
+ m_xBcustom->connect_value_changed(aSpinLink);
+ Link<weld::Entry&,void> aEntryLink = LINK(this, SvxColorTabPage, ModifiedHdl_Impl);
+ m_xHexcustom->connect_changed(aEntryLink);
+ Link<weld::MetricSpinButton&,void> aMetricSpinLink = LINK(this, SvxColorTabPage, MetricSpinValueHdl_Impl);
+ m_xCcustom->connect_value_changed(aMetricSpinLink);
+ m_xYcustom->connect_value_changed(aMetricSpinLink);
+ m_xMcustom->connect_value_changed(aMetricSpinLink);
+ m_xKcustom->connect_value_changed(aMetricSpinLink);
+
+ Link<weld::Toggleable&,void> aLink2 = LINK( this, SvxColorTabPage, SelectColorModeHdl_Impl );
+ m_xRbRGB->connect_toggled(aLink2);
+ m_xRbCMYK->connect_toggled(aLink2);
+ SetColorModel( eCM );
+ ChangeColorModel();
+
+ m_xBtnAdd->connect_clicked( LINK( this, SvxColorTabPage, ClickAddHdl_Impl ) );
+ m_xBtnWorkOn->connect_clicked( LINK( this, SvxColorTabPage, ClickWorkOnHdl_Impl ) );
+ m_xBtnDelete->connect_clicked( LINK( this, SvxColorTabPage, ClickDeleteHdl_Impl ) );
+ // disable modify buttons
+ // Color palettes can't be modified
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnDelete->set_tooltip_text( CuiResId(RID_CUISTR_DELETEUSERCOLOR1) );
+
+ m_xMoreColors->connect_clicked(LINK(this, SvxColorTabPage, OnMoreColorsClick));
+
+ // disable preset color values
+ m_xRGBpreset->set_sensitive(false);
+ m_xCMYKpreset->set_sensitive(false);
+
+ // ValueSet
+ m_xValSetColorList->SetStyle(m_xValSetColorList->GetStyle() |
+ WB_FLATVALUESET | WB_ITEMBORDER | WB_NO_DIRECTSELECT | WB_TABSTOP);
+ m_xValSetColorList->Show();
+
+ m_xValSetRecentList->SetStyle(m_xValSetRecentList->GetStyle() |
+ WB_FLATVALUESET | WB_ITEMBORDER | WB_NO_DIRECTSELECT | WB_TABSTOP);
+ m_xValSetRecentList->Show();
+
+ maPaletteManager.ReloadRecentColorSet(*m_xValSetRecentList);
+ aSize = m_xValSetRecentList->layoutAllVisible(maPaletteManager.GetRecentColorCount());
+ m_xValSetRecentList->set_size_request(aSize.Width(), aSize.Height());
+
+ // it is not possible to install color palette extensions in Online or mobile apps
+ if(comphelper::LibreOfficeKit::isActive())
+ {
+ m_xMoreColors->hide();
+ }
+}
+
+SvxColorTabPage::~SvxColorTabPage()
+{
+ m_xValSetRecentListWin.reset();
+ m_xValSetRecentList.reset();
+ m_xValSetColorListWin.reset();
+ m_xValSetColorList.reset();
+}
+
+void SvxColorTabPage::ImpColorCountChanged()
+{
+ if (!pColorList.is())
+ return;
+ m_xValSetColorList->SetColCount(SvxColorValueSet::getColumnCount());
+ m_xValSetRecentList->SetColCount(SvxColorValueSet::getColumnCount());
+}
+
+void SvxColorTabPage::FillPaletteLB()
+{
+ m_xSelectPalette->clear();
+ std::vector<OUString> aPaletteList = maPaletteManager.GetPaletteList();
+ for (auto const& palette : aPaletteList)
+ {
+ m_xSelectPalette->append_text(palette);
+ }
+ OUString aPaletteName( officecfg::Office::Common::UserColors::PaletteName::get() );
+ m_xSelectPalette->set_active_text(aPaletteName);
+ if (m_xSelectPalette->get_active() != -1)
+ {
+ SelectPaletteLBHdl(*m_xSelectPalette);
+ }
+}
+
+void SvxColorTabPage::Construct()
+{
+ if (pColorList.is())
+ {
+ FillPaletteLB();
+ ImpColorCountChanged();
+ }
+}
+
+void SvxColorTabPage::ActivatePage( const SfxItemSet& )
+{
+ if( !pColorList.is() )
+ return;
+
+ if( const XFillColorItem* pFillColorItem = rOutAttrs.GetItemIfSet( GetWhich( XATTR_FILLCOLOR ) ) )
+ {
+ SetColorModel( ColorModel::RGB );
+ ChangeColorModel();
+
+ const Color aColor = pFillColorItem->GetColorValue();
+ NamedColor aNamedColor;
+ aNamedColor.m_aColor = aColor;
+ ChangeColor(aNamedColor);
+ sal_Int32 nPos = FindInPalette( aColor );
+
+ if ( nPos != -1 )
+ m_xValSetColorList->SelectItem(m_xValSetColorList->GetItemId(nPos));
+ // else search in other palettes?
+
+ }
+
+ m_aCtlPreviewOld.SetAttributes(aXFillAttr.GetItemSet());
+ m_aCtlPreviewOld.Invalidate();
+
+ SelectValSetHdl_Impl(m_xValSetColorList.get());
+}
+
+DeactivateRC SvxColorTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+bool SvxColorTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ Color aColor = m_xValSetColorList->GetItemColor( m_xValSetColorList->GetSelectedItemId() );
+ OUString sColorName;
+ if (m_aCurrentColor.m_aColor == aColor)
+ sColorName = m_xValSetColorList->GetItemText( m_xValSetColorList->GetSelectedItemId() );
+ else
+ sColorName = "#" + m_aCurrentColor.m_aColor.AsRGBHexString().toAsciiUpperCase();
+
+ maPaletteManager.AddRecentColor(m_aCurrentColor.m_aColor, sColorName);
+ XFillColorItem aColorItem(sColorName, m_aCurrentColor.m_aColor);
+ aColorItem.setComplexColor(m_aCurrentColor.getComplexColor());
+ rSet->Put(aColorItem);
+ rSet->Put(XFillStyleItem(drawing::FillStyle_SOLID));
+ return true;
+}
+
+void SvxColorTabPage::UpdateModified()
+{
+ bool bEnable = pColorList.is() && pColorList->Count();
+ m_xBtnWorkOn->set_sensitive(bEnable);
+}
+
+void SvxColorTabPage::Reset( const SfxItemSet* rSet )
+{
+ SfxItemState nState = rSet->GetItemState( XATTR_FILLCOLOR );
+
+ Color aNewColor;
+
+ if ( nState >= SfxItemState::DEFAULT )
+ {
+ XFillColorItem aColorItem( rSet->Get( XATTR_FILLCOLOR ) );
+ m_aPreviousColor = aColorItem.GetColorValue();
+ aNewColor = aColorItem.GetColorValue();
+ }
+
+ // set color model
+ OUString aStr = GetUserData();
+ eCM = static_cast<ColorModel>(aStr.toInt32());
+ SetColorModel( eCM );
+ ChangeColorModel();
+
+ NamedColor aColor;
+ aColor.m_aColor = aNewColor;
+ ChangeColor(aColor);
+
+ UpdateModified();
+}
+
+std::unique_ptr<SfxTabPage> SvxColorTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rOutAttrs)
+{
+ return std::make_unique<SvxColorTabPage>(pPage, pController, *rOutAttrs);
+}
+
+// is called when the content of the MtrFields is changed for color values
+IMPL_LINK_NOARG(SvxColorTabPage, SpinValueHdl_Impl, weld::SpinButton&, void)
+{
+ // read current MtrFields, if cmyk, then k-value as transparency
+ m_aCurrentColor.m_aColor = Color(static_cast<sal_uInt8>(PercentToColor_Impl(m_xRcustom->get_value())),
+ static_cast<sal_uInt8>(PercentToColor_Impl(m_xGcustom->get_value())),
+ static_cast<sal_uInt8>(PercentToColor_Impl(m_xBcustom->get_value())));
+ UpdateColorValues();
+
+ rXFSet.Put( XFillColorItem( OUString(), m_aCurrentColor.m_aColor ) );
+ m_aCtlPreviewNew.SetAttributes( aXFillAttr.GetItemSet() );
+
+ m_aCtlPreviewNew.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxColorTabPage, MetricSpinValueHdl_Impl, weld::MetricSpinButton&, void)
+{
+ // read current MtrFields, if cmyk, then k-value as transparency
+ m_aCurrentColor.m_aColor = Color(ColorTransparency, static_cast<sal_uInt8>(PercentToColor_Impl(m_xKcustom->get_value(FieldUnit::NONE))),
+ static_cast<sal_uInt8>(PercentToColor_Impl(m_xCcustom->get_value(FieldUnit::NONE))),
+ static_cast<sal_uInt8>(PercentToColor_Impl(m_xYcustom->get_value(FieldUnit::NONE))),
+ static_cast<sal_uInt8>(PercentToColor_Impl(m_xMcustom->get_value(FieldUnit::NONE))));
+ ConvertColorValues (m_aCurrentColor.m_aColor, ColorModel::RGB);
+
+ rXFSet.Put( XFillColorItem( OUString(), m_aCurrentColor.m_aColor ) );
+ m_aCtlPreviewNew.SetAttributes( aXFillAttr.GetItemSet() );
+
+ m_aCtlPreviewNew.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxColorTabPage, ModifiedHdl_Impl, weld::Entry&, void)
+{
+ m_aCurrentColor.m_aColor = m_xHexcustom->GetColor();
+ UpdateColorValues();
+
+ rXFSet.Put( XFillColorItem( OUString(), m_aCurrentColor.m_aColor ) );
+ m_aCtlPreviewNew.SetAttributes( aXFillAttr.GetItemSet() );
+
+ m_aCtlPreviewNew.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxColorTabPage, ClickAddHdl_Impl, weld::Button&, void)
+{
+ OUString aNewName( SvxResId( RID_SVXSTR_COLOR ) );
+ OUString aDesc( CuiResId( RID_CUISTR_DESC_COLOR ) );
+ OUString aName;
+
+ tools::Long j = 1;
+ bool bValidColorName = false;
+ // check if name is already existing
+ while (!bValidColorName)
+ {
+ aName = aNewName + " " + OUString::number( j++ );
+ bValidColorName = (FindInCustomColors(aName) == -1);
+ }
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+ sal_uInt16 nError = 1;
+
+ while (pDlg->Execute() == RET_OK)
+ {
+ pDlg->GetName( aName );
+
+ bValidColorName = (FindInCustomColors(aName) == -1);
+ if (bValidColorName)
+ {
+ nError = 0;
+ break;
+ }
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xWarnBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ if (xWarnBox->run() != RET_OK)
+ break;
+ }
+
+ pDlg.disposeAndClear();
+
+ if (!nError)
+ {
+ m_xSelectPalette->set_active(0);
+ SelectPaletteLBHdl(*m_xSelectPalette);
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
+ css::uno::Sequence< sal_Int32 > aCustomColorList(officecfg::Office::Common::UserColors::CustomColor::get());
+ css::uno::Sequence< OUString > aCustomColorNameList(officecfg::Office::Common::UserColors::CustomColorName::get());
+ sal_Int32 nSize = aCustomColorList.getLength();
+ aCustomColorList.realloc( nSize + 1 );
+ aCustomColorNameList.realloc( nSize + 1 );
+ aCustomColorList.getArray()[nSize] = sal_Int32(m_aCurrentColor.m_aColor);
+ aCustomColorNameList.getArray()[nSize] = aName;
+ officecfg::Office::Common::UserColors::CustomColor::set(aCustomColorList, batch);
+ officecfg::Office::Common::UserColors::CustomColorName::set(aCustomColorNameList, batch);
+ batch->commit();
+ sal_uInt16 nId = m_xValSetColorList->GetItemId(nSize - 1);
+ m_xValSetColorList->InsertItem( nId + 1 , m_aCurrentColor.m_aColor, aName );
+ m_xValSetColorList->SelectItem( nId + 1 );
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnDelete->set_tooltip_text( CuiResId(RID_CUISTR_DELETEUSERCOLOR2) );
+ ImpColorCountChanged();
+ }
+
+ UpdateModified();
+}
+
+IMPL_LINK_NOARG(SvxColorTabPage, ClickWorkOnHdl_Impl, weld::Button&, void)
+{
+ SvColorDialog aColorDlg;
+
+ aColorDlg.SetColor (m_aCurrentColor.m_aColor);
+ aColorDlg.SetMode( svtools::ColorPickerMode::Modify );
+
+ if (aColorDlg.Execute(GetFrameWeld()) == RET_OK)
+ {
+ Color aPreviewColor = aColorDlg.GetColor();
+ m_aCurrentColor.m_aColor = aPreviewColor;
+ UpdateColorValues( false );
+ // fill ItemSet and pass it on to XOut
+ rXFSet.Put( XFillColorItem( OUString(), aPreviewColor ) );
+ //m_aCtlPreviewOld.SetAttributes( aXFillAttr );
+ m_aCtlPreviewNew.SetAttributes( aXFillAttr.GetItemSet() );
+
+ m_aCtlPreviewNew.Invalidate();
+ }
+}
+
+IMPL_LINK_NOARG(SvxColorTabPage, ClickDeleteHdl_Impl, weld::Button&, void)
+{
+ sal_uInt16 nId = m_xValSetColorList->GetSelectedItemId();
+ size_t nPos = m_xValSetColorList->GetSelectItemPos();
+ if (m_xSelectPalette->get_active() != 0 || nPos == VALUESET_ITEM_NOTFOUND)
+ return;
+
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
+ css::uno::Sequence< sal_Int32 > aCustomColorList(officecfg::Office::Common::UserColors::CustomColor::get());
+ auto aCustomColorListRange = asNonConstRange(aCustomColorList);
+ css::uno::Sequence< OUString > aCustomColorNameList(officecfg::Office::Common::UserColors::CustomColorName::get());
+ auto aCustomColorNameListRange = asNonConstRange(aCustomColorNameList);
+ sal_Int32 nSize = aCustomColorList.getLength() - 1;
+ for(sal_Int32 nIndex = static_cast<sal_Int32>(nPos);nIndex < nSize;nIndex++)
+ {
+ aCustomColorListRange[nIndex] = aCustomColorList[nIndex+1];
+ aCustomColorNameListRange[nIndex] = aCustomColorNameList[nIndex+1];
+ }
+ aCustomColorList.realloc(nSize);
+ aCustomColorNameList.realloc(nSize);
+ officecfg::Office::Common::UserColors::CustomColor::set(aCustomColorList, batch);
+ officecfg::Office::Common::UserColors::CustomColorName::set(aCustomColorNameList, batch);
+ batch->commit();
+ m_xValSetColorList->RemoveItem(nId);
+ if (m_xValSetColorList->GetItemCount() != 0)
+ {
+ nId = m_xValSetColorList->GetItemId(0);
+ m_xValSetColorList->SelectItem(nId);
+ SelectValSetHdl_Impl(m_xValSetColorList.get());
+ }
+ else
+ {
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnDelete->set_tooltip_text( CuiResId(RID_CUISTR_DELETEUSERCOLOR2) );
+ }
+}
+
+IMPL_LINK_NOARG(SvxColorTabPage, SelectPaletteLBHdl, weld::ComboBox&, void)
+{
+ m_xValSetColorList->Clear();
+ sal_Int32 nPos = m_xSelectPalette->get_active();
+ maPaletteManager.SetPalette( nPos );
+ maPaletteManager.ReloadColorSet(*m_xValSetColorList);
+
+ if(nPos != maPaletteManager.GetPaletteCount() - 1 && nPos != 0)
+ {
+ XColorListRef pList = XPropertyList::AsColorList(
+ XPropertyList::CreatePropertyListFromURL(
+ XPropertyListType::Color, maPaletteManager.GetSelectedPalettePath()));
+ pList->SetName(maPaletteManager.GetPaletteName());
+ if(pList->Load())
+ {
+ SfxOkDialogController* pController = GetDialogController();
+ SvxAreaTabDialog* pArea = dynamic_cast<SvxAreaTabDialog*>(pController);
+ SvxLineTabDialog* pLine = dynamic_cast<SvxLineTabDialog*>(pController);
+ pColorList = pList;
+ if( pArea )
+ pArea->SetNewColorList(pList);
+ else if( pLine )
+ pLine->SetNewColorList(pList);
+ else
+ SetColorList(pList);
+ *pnColorListState |= ChangeType::CHANGED;
+ *pnColorListState &= ~ChangeType::MODIFIED;
+ }
+ }
+ if (nPos != 0)
+ {
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnDelete->set_tooltip_text( CuiResId(RID_CUISTR_DELETEUSERCOLOR1) );
+ }
+
+ m_xValSetColorList->Resize();
+}
+
+IMPL_LINK(SvxColorTabPage, SelectValSetHdl_Impl, ValueSet*, pValSet, void)
+{
+ sal_Int32 nPos = pValSet->GetSelectedItemId();
+ if( nPos == 0 )
+ return;
+
+ Color aColor = pValSet->GetItemColor( nPos );
+
+ rXFSet.Put( XFillColorItem( OUString(), aColor ) );
+ m_aCtlPreviewNew.SetAttributes( aXFillAttr.GetItemSet() );
+ m_aCtlPreviewNew.Invalidate();
+
+ NamedColor aNamedColor;
+ aNamedColor.m_aColor = aColor;
+
+ if (pValSet == m_xValSetColorList.get() && maPaletteManager.IsThemePaletteSelected())
+ {
+ sal_uInt16 nThemeIndex;
+ sal_uInt16 nEffectIndex;
+ if (PaletteManager::GetThemeAndEffectIndex(nPos, nThemeIndex, nEffectIndex))
+ {
+ aNamedColor.m_nThemeIndex = nThemeIndex;
+ maPaletteManager.GetLumModOff(nThemeIndex, nEffectIndex, aNamedColor.m_nLumMod, aNamedColor.m_nLumOff);
+ }
+ }
+
+ ChangeColor(aNamedColor, false);
+
+ if (pValSet == m_xValSetColorList.get())
+ {
+ m_xValSetRecentList->SetNoSelection();
+ if (m_xSelectPalette->get_active() == 0 && m_xValSetColorList->GetSelectedItemId() != 0)
+ {
+ m_xBtnDelete->set_sensitive(true);
+ m_xBtnDelete->set_tooltip_text("");
+ }
+ else
+ {
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnDelete->set_tooltip_text( CuiResId(RID_CUISTR_DELETEUSERCOLOR1) );
+ }
+ }
+ if (pValSet == m_xValSetRecentList.get())
+ {
+ m_xValSetColorList->SetNoSelection();
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnDelete->set_tooltip_text( CuiResId(RID_CUISTR_DELETEUSERCOLOR2) );
+ }
+}
+
+void SvxColorTabPage::ConvertColorValues (Color& rColor, ColorModel eModell)
+{
+ switch (eModell)
+ {
+ case ColorModel::RGB:
+ {
+ CmykToRgb_Impl (rColor, static_cast<sal_uInt16>(255 - rColor.GetAlpha()) );
+ rColor.SetAlpha (255);
+ }
+ break;
+
+ case ColorModel::CMYK:
+ {
+ sal_uInt16 nK;
+ RgbToCmyk_Impl (rColor, nK );
+ rColor.SetAlpha (255 - static_cast<sal_uInt8>(nK));
+ }
+ break;
+ }
+}
+
+IMPL_LINK_NOARG(SvxColorTabPage, SelectColorModeHdl_Impl, weld::Toggleable&, void)
+{
+ if (m_xRbRGB->get_active())
+ eCM = ColorModel::RGB;
+ else if (m_xRbCMYK->get_active())
+ eCM = ColorModel::CMYK;
+ ChangeColorModel();
+ UpdateColorValues();
+}
+
+
+IMPL_STATIC_LINK_NOARG(SvxColorTabPage, OnMoreColorsClick, weld::Button&, void)
+{
+ css::uno::Sequence<css::beans::PropertyValue> aArgs{ comphelper::makePropertyValue(
+ "AdditionsTag", OUString("Color Palette")) };
+ comphelper::dispatchCommand(".uno:AdditionsDialog", aArgs);
+}
+
+void SvxColorTabPage::ChangeColor(const NamedColor &rNewColor, bool bUpdatePreset )
+{
+ m_aPreviousColor = rNewColor.m_aColor;
+ m_aCurrentColor = rNewColor;
+ UpdateColorValues( bUpdatePreset );
+ // fill ItemSet and pass it on to XOut
+ XFillColorItem aItem(OUString(), m_aCurrentColor.m_aColor);
+ aItem.setComplexColor(m_aCurrentColor.getComplexColor());
+ rXFSet.Put(aItem);
+
+ m_aCtlPreviewNew.SetAttributes(aXFillAttr.GetItemSet());
+ m_aCtlPreviewNew.Invalidate();
+}
+
+void SvxColorTabPage::SetColorModel( ColorModel eModel )
+{
+ if (eModel == ColorModel::RGB)
+ m_xRbRGB->set_active(true);
+ else if (eModel == ColorModel::CMYK)
+ m_xRbCMYK->set_active(true);
+}
+
+void SvxColorTabPage::ChangeColorModel()
+{
+ switch( eCM )
+ {
+ case ColorModel::RGB:
+ {
+ m_xRGBcustom->show();
+ m_xRGBpreset->show();
+ m_xCMYKcustom->hide();
+ m_xCMYKpreset->hide();
+ }
+ break;
+
+ case ColorModel::CMYK:
+ {
+ m_xCMYKcustom->show();
+ m_xCMYKpreset->show();
+ m_xRGBcustom->hide();
+ m_xRGBpreset->hide();
+ }
+ break;
+ }
+}
+
+void SvxColorTabPage::UpdateColorValues( bool bUpdatePreset )
+{
+ if (eCM != ColorModel::RGB)
+ {
+ ConvertColorValues (m_aPreviousColor, eCM );
+ ConvertColorValues (m_aCurrentColor.m_aColor, eCM);
+
+ m_xCcustom->set_value( ColorToPercent_Impl( m_aCurrentColor.m_aColor.GetRed() ), FieldUnit::PERCENT );
+ m_xMcustom->set_value( ColorToPercent_Impl( m_aCurrentColor.m_aColor.GetBlue() ), FieldUnit::PERCENT );
+ m_xYcustom->set_value( ColorToPercent_Impl( m_aCurrentColor.m_aColor.GetGreen() ), FieldUnit::PERCENT );
+ m_xKcustom->set_value( ColorToPercent_Impl( 255 - m_aCurrentColor.m_aColor.GetAlpha() ), FieldUnit::PERCENT );
+
+ if( bUpdatePreset )
+ {
+ m_xCpreset->set_text(unicode::formatPercent(ColorToPercent_Impl(m_aPreviousColor.GetRed()),
+ Application::GetSettings().GetUILanguageTag()));
+ m_xMpreset->set_text(unicode::formatPercent(ColorToPercent_Impl(m_aPreviousColor.GetBlue()),
+ Application::GetSettings().GetUILanguageTag()));
+ m_xYpreset->set_text(unicode::formatPercent(ColorToPercent_Impl(m_aPreviousColor.GetGreen()),
+ Application::GetSettings().GetUILanguageTag()));
+ m_xKpreset->set_text(unicode::formatPercent(ColorToPercent_Impl(255 - m_aPreviousColor.GetAlpha()),
+ Application::GetSettings().GetUILanguageTag()));
+ }
+
+ ConvertColorValues (m_aPreviousColor, ColorModel::RGB);
+ ConvertColorValues (m_aCurrentColor.m_aColor, ColorModel::RGB);
+ }
+ else
+ {
+ m_xRcustom->set_value( ColorToPercent_Impl( m_aCurrentColor.m_aColor.GetRed() ) );
+ m_xGcustom->set_value( ColorToPercent_Impl( m_aCurrentColor.m_aColor.GetGreen() ) );
+ m_xBcustom->set_value( ColorToPercent_Impl( m_aCurrentColor.m_aColor.GetBlue() ) );
+ m_xHexcustom->SetColor( m_aCurrentColor.m_aColor );
+
+ if( bUpdatePreset )
+ {
+ m_xRpreset->set_text(OUString::number(ColorToPercent_Impl(m_aPreviousColor.GetRed())));
+ m_xGpreset->set_text(OUString::number(ColorToPercent_Impl(m_aPreviousColor.GetGreen())));
+ m_xBpreset->set_text(OUString::number(ColorToPercent_Impl(m_aPreviousColor.GetBlue())));
+ m_xHexpreset->SetColor( m_aPreviousColor );
+ }
+ }
+}
+
+sal_Int32 SvxColorTabPage::FindInCustomColors(std::u16string_view aColorName)
+{
+ css::uno::Sequence< OUString > aCustomColorNameList(officecfg::Office::Common::UserColors::CustomColorName::get());
+ tools::Long nCount = aCustomColorNameList.getLength();
+ bool bValidColorName = true;
+ sal_Int32 nPos = -1;
+
+ for(tools::Long i = 0;i < nCount && bValidColorName;i++)
+ {
+ if(aColorName == aCustomColorNameList[i])
+ {
+ nPos = i;
+ bValidColorName = false;
+ }
+ }
+ return nPos;
+}
+
+sal_Int32 SvxColorTabPage::FindInPalette( const Color& rColor )
+{
+ return pColorList->GetIndexOfColor(rColor);
+}
+
+// A RGB value is converted to a CMYK value - not in an ideal way as
+// R is converted into C, G into M and B into Y. The K value is held in an
+// extra variable. For further color models one should develop own
+// classes which should contain the respective casts.
+
+void SvxColorTabPage::RgbToCmyk_Impl( Color& rColor, sal_uInt16& rK )
+{
+ sal_uInt16 const nColor1 = 255 - rColor.GetRed();
+ sal_uInt16 const nColor2 = 255 - rColor.GetGreen();
+ sal_uInt16 const nColor3 = 255 - rColor.GetBlue();
+
+ rK = std::min( std::min( nColor1, nColor2 ), nColor3 );
+
+ rColor.SetRed( sal::static_int_cast< sal_uInt8 >( nColor1 - rK ) );
+ rColor.SetGreen( sal::static_int_cast< sal_uInt8 >( nColor2 - rK ) );
+ rColor.SetBlue( sal::static_int_cast< sal_uInt8 >( nColor3 - rK ) );
+}
+
+
+// reverse case to RgbToCmyk_Impl (see above)
+
+void SvxColorTabPage::CmykToRgb_Impl( Color& rColor, const sal_uInt16 nK )
+{
+ tools::Long lTemp;
+
+ lTemp = 255 - ( rColor.GetRed() + nK );
+
+ if( lTemp < 0 )
+ lTemp = 0;
+ rColor.SetRed( static_cast<sal_uInt8>(lTemp) );
+
+ lTemp = 255 - ( rColor.GetGreen() + nK );
+
+ if( lTemp < 0 )
+ lTemp = 0;
+ rColor.SetGreen( static_cast<sal_uInt8>(lTemp) );
+
+ lTemp = 255 - ( rColor.GetBlue() + nK );
+
+ if( lTemp < 0 )
+ lTemp = 0;
+ rColor.SetBlue( static_cast<sal_uInt8>(lTemp) );
+}
+
+
+sal_uInt16 SvxColorTabPage::ColorToPercent_Impl( sal_uInt16 nColor )
+{
+ sal_uInt16 nValue = 0;
+
+ switch (eCM)
+ {
+ case ColorModel::RGB :
+ nValue = nColor;
+ break;
+
+ case ColorModel::CMYK:
+ nValue = static_cast<sal_uInt16>( static_cast<double>(nColor) * 100.0 / 255.0 + 0.5 );
+ break;
+ }
+
+ return nValue;
+}
+
+
+sal_uInt16 SvxColorTabPage::PercentToColor_Impl( sal_uInt16 nPercent )
+{
+ sal_uInt16 nValue = 0;
+
+ switch (eCM)
+ {
+ case ColorModel::RGB :
+ nValue = nPercent;
+ break;
+
+ case ColorModel::CMYK:
+ nValue = static_cast<sal_uInt16>( static_cast<double>(nPercent) * 255.0 / 100.0 + 0.5 );
+ break;
+ }
+
+ return nValue;
+}
+
+
+void SvxColorTabPage::FillUserData()
+{
+ // the color model is saved in the Ini-file
+ SetUserData( OUString::number( static_cast<int>(eCM) ) );
+}
+
+
+void SvxColorTabPage::SetPropertyList( XPropertyListType t, const XPropertyListRef &xRef )
+{
+ OSL_ASSERT( t == XPropertyListType::Color );
+ pColorList = XColorListRef( static_cast<XColorList *>(xRef.get() ) );
+}
+
+void SvxColorTabPage::SetColorList( const XColorListRef& pColList )
+{
+ SetPropertyList( XPropertyListType::Color, XPropertyListRef( ( pColList.get() ) ) );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tpgradnt.cxx b/cui/source/tabpages/tpgradnt.cxx
new file mode 100644
index 0000000000..df629a154f
--- /dev/null
+++ b/cui/source/tabpages/tpgradnt.cxx
@@ -0,0 +1,674 @@
+/* -*- 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 <memory>
+#include <tools/urlobj.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <sfx2/dialoghelper.hxx>
+
+#include <strings.hrc>
+#include <svx/xfillit0.hxx>
+#include <svx/xflgrit.hxx>
+#include <svx/colorbox.hxx>
+#include <svx/xtable.hxx>
+#include <svx/xgrscit.hxx>
+#include <cuitabarea.hxx>
+#include <svx/svxdlg.hxx>
+#include <dialmgr.hxx>
+#include <svx/dialmgr.hxx>
+#include <svx/strings.hrc>
+#include <basegfx/utils/gradienttools.hxx>
+#include <sal/log.hxx>
+
+using namespace com::sun::star;
+
+SvxGradientTabPage::SvxGradientTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/gradientpage.ui", "GradientPage", &rInAttrs)
+ , m_rOutAttrs(rInAttrs)
+ , m_pnGradientListState(nullptr)
+ , m_pnColorListState(nullptr)
+ , m_aXFillAttr(rInAttrs.GetPool())
+ , m_rXFSet(m_aXFillAttr.GetItemSet())
+ , m_xLbGradientType(m_xBuilder->weld_combo_box("gradienttypelb"))
+ , m_xFtCenter(m_xBuilder->weld_label("centerft"))
+ , m_xMtrCenterX(m_xBuilder->weld_metric_spin_button("centerxmtr", FieldUnit::PERCENT))
+ , m_xMtrCenterY(m_xBuilder->weld_metric_spin_button("centerymtr", FieldUnit::PERCENT))
+ , m_xFtAngle(m_xBuilder->weld_label("angleft"))
+ , m_xMtrAngle(m_xBuilder->weld_metric_spin_button("anglemtr", FieldUnit::DEGREE))
+ , m_xSliderAngle(m_xBuilder->weld_scale("angleslider"))
+ , m_xMtrBorder(m_xBuilder->weld_metric_spin_button("bordermtr", FieldUnit::PERCENT))
+ , m_xSliderBorder(m_xBuilder->weld_scale("borderslider"))
+ , m_xLbColorFrom(new ColorListBox(m_xBuilder->weld_menu_button("colorfromlb"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xMtrColorFrom(m_xBuilder->weld_metric_spin_button("colorfrommtr", FieldUnit::PERCENT))
+ , m_xLbColorTo(new ColorListBox(m_xBuilder->weld_menu_button("colortolb"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xMtrColorTo(m_xBuilder->weld_metric_spin_button("colortomtr", FieldUnit::PERCENT))
+ , m_xGradientLB(new SvxPresetListBox(m_xBuilder->weld_scrolled_window("gradientpresetlistwin", true)))
+ , m_xMtrIncrement(m_xBuilder->weld_spin_button("incrementmtr"))
+ , m_xCbIncrement(m_xBuilder->weld_check_button("autoincrement"))
+ , m_xBtnAdd(m_xBuilder->weld_button("add"))
+ , m_xBtnModify(m_xBuilder->weld_button("modify"))
+ , m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, "previewctl", m_aCtlPreview))
+ , m_xGradientLBWin(new weld::CustomWeld(*m_xBuilder, "gradientpresetlist", *m_xGradientLB))
+{
+ Size aSize = getDrawPreviewOptimalSize(m_aCtlPreview.GetDrawingArea()->get_ref_device());
+ m_xGradientLB->set_size_request(aSize.Width(), aSize.Height());
+ m_xCtlPreview->set_size_request(aSize.Width(), aSize.Height());
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ // as long as NOT supported by the item
+
+ m_xMtrColorTo->set_value(100, FieldUnit::PERCENT);
+ m_xMtrColorFrom->set_value(100, FieldUnit::PERCENT);
+
+ // setting the output device
+ m_rXFSet.Put( XFillStyleItem(drawing::FillStyle_GRADIENT) );
+ m_rXFSet.Put( XFillGradientItem(OUString(), basegfx::BGradient()));
+ m_aCtlPreview.SetAttributes(m_aXFillAttr.GetItemSet());
+
+ // set handler
+ m_xGradientLB->SetSelectHdl( LINK( this, SvxGradientTabPage, ChangeGradientHdl ) );
+ m_xGradientLB->SetRenameHdl( LINK( this, SvxGradientTabPage, ClickRenameHdl_Impl ) );
+ m_xGradientLB->SetDeleteHdl( LINK( this, SvxGradientTabPage, ClickDeleteHdl_Impl ) );
+ m_xBtnAdd->connect_clicked(LINK(this, SvxGradientTabPage, ClickAddHdl_Impl));
+ m_xBtnModify->connect_clicked(LINK(this, SvxGradientTabPage, ClickModifyHdl_Impl));
+
+ Link<weld::MetricSpinButton&,void> aLink = LINK( this, SvxGradientTabPage, ModifiedMetricHdl_Impl );
+ Link<weld::ComboBox&,void> aLink2 = LINK( this, SvxGradientTabPage, ModifiedListBoxHdl_Impl );
+ m_xLbGradientType->connect_changed( aLink2 );
+ m_xCbIncrement->connect_toggled(LINK(this, SvxGradientTabPage, ChangeAutoStepHdl_Impl));
+ m_xMtrIncrement->connect_value_changed(LINK(this, SvxGradientTabPage, ModifiedEditHdl_Impl));
+ m_xMtrCenterX->connect_value_changed( aLink );
+ m_xMtrCenterY->connect_value_changed( aLink );
+ m_xMtrAngle->connect_value_changed( aLink );
+ m_xSliderAngle->connect_value_changed(LINK(this, SvxGradientTabPage, ModifiedSliderHdl_Impl));
+ m_xMtrBorder->connect_value_changed( aLink );
+ m_xSliderBorder->connect_value_changed(LINK(this, SvxGradientTabPage, ModifiedSliderHdl_Impl));
+ m_xMtrColorFrom->connect_value_changed( aLink );
+ Link<ColorListBox&,void> aLink3 = LINK( this, SvxGradientTabPage, ModifiedColorListBoxHdl_Impl );
+ m_xLbColorFrom->SetSelectHdl( aLink3 );
+ m_xMtrColorTo->connect_value_changed( aLink );
+ m_xLbColorTo->SetSelectHdl( aLink3 );
+
+ m_xGradientLB->SetStyle(WB_FLATVALUESET | WB_NO_DIRECTSELECT | WB_TABSTOP);
+
+ // #i76307# always paint the preview in LTR, because this is what the document does
+ m_aCtlPreview.EnableRTL(false);
+}
+
+SvxGradientTabPage::~SvxGradientTabPage()
+{
+ m_xCtlPreview.reset();
+ m_xGradientLBWin.reset();
+ m_xGradientLB.reset();
+ m_xLbColorTo.reset();
+ m_xLbColorFrom.reset();
+}
+
+void SvxGradientTabPage::Construct()
+{
+ m_xGradientLB->FillPresetListBox( *m_pGradientList );
+}
+
+void SvxGradientTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ if( !m_pColorList.is() )
+ return;
+
+ // ColorList
+ if( *m_pnColorListState & ChangeType::CHANGED ||
+ *m_pnColorListState & ChangeType::MODIFIED )
+ {
+ SvxAreaTabDialog* pArea = (*m_pnColorListState & ChangeType::CHANGED) ?
+ dynamic_cast<SvxAreaTabDialog*>(GetDialogController()) : nullptr;
+ if (pArea)
+ m_pColorList = pArea->GetNewColorList();
+
+ ModifiedHdl_Impl( this );
+ }
+
+ // determining (and possibly cutting) the name and
+ // displaying it in the GroupBox
+ OUString aString = CuiResId( RID_CUISTR_TABLE ) + ": ";
+ INetURLObject aURL( m_pGradientList->GetPath() );
+
+ aURL.Append( m_pGradientList->GetName() );
+ SAL_WARN_IF( aURL.GetProtocol() == INetProtocol::NotValid, "cui.tabpages", "invalid URL" );
+
+ if ( aURL.getBase().getLength() > 18 )
+ {
+ aString += OUString::Concat(aURL.getBase().subView( 0, 15 )) + "...";
+ }
+ else
+ aString += aURL.getBase();
+
+ sal_Int32 nPos = SearchGradientList( rSet.Get(XATTR_FILLGRADIENT).GetName() );
+ if ( nPos != -1)
+ {
+ sal_uInt16 nId = m_xGradientLB->GetItemId( static_cast<size_t>( nPos ) );
+ m_xGradientLB->SelectItem( nId );
+ }
+ // colors could have been deleted
+ ChangeGradientHdl_Impl();
+}
+
+
+DeactivateRC SvxGradientTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+bool SvxGradientTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ std::unique_ptr<basegfx::BGradient> pBGradient;
+ size_t nPos = m_xGradientLB->IsNoSelection() ? VALUESET_ITEM_NOTFOUND : m_xGradientLB->GetSelectItemPos();
+
+ sal_uInt16 nValue = 0; // automatic step count
+ if (!m_xCbIncrement->get_active())
+ nValue = m_xMtrIncrement->get_value();
+
+ if( nPos != VALUESET_ITEM_NOTFOUND )
+ {
+ pBGradient.reset(new basegfx::BGradient( m_pGradientList->GetGradient( static_cast<sal_uInt16>(nPos) )->GetGradient() ));
+ OUString aString = m_xGradientLB->GetItemText( m_xGradientLB->GetSelectedItemId() );
+ // update StepCount to current value to be in sync with FillGradientStepCount
+ pBGradient->SetSteps(nValue);
+ rSet->Put( XFillGradientItem( aString, *pBGradient ) );
+ }
+ else
+ // gradient was passed (unidentified)
+ {
+ pBGradient.reset(new basegfx::BGradient(
+ createColorStops(),
+ static_cast<css::awt::GradientStyle>(m_xLbGradientType->get_active()),
+ Degree10(static_cast<sal_Int16>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10)), // should be changed in resource
+ static_cast<sal_uInt16>(m_xMtrCenterX->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrCenterY->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrBorder->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrColorFrom->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrColorTo->get_value(FieldUnit::NONE)),
+ nValue));
+ rSet->Put( XFillGradientItem( OUString(), *pBGradient ) );
+ }
+
+ assert( pBGradient && "basegfx::BGradient could not be created" );
+ rSet->Put( XFillStyleItem( drawing::FillStyle_GRADIENT ) );
+ rSet->Put( XGradientStepCountItem( nValue ) );
+ return true;
+}
+
+void SvxGradientTabPage::Reset( const SfxItemSet* )
+{
+ ChangeGradientHdl_Impl(); // includes setting m_xCbIncrement and m_xMtrIncrement
+
+ // determine state of the buttons
+ if( m_pGradientList->Count() )
+ m_xBtnModify->set_sensitive(true);
+ else
+ m_xBtnModify->set_sensitive(false);
+}
+
+std::unique_ptr<SfxTabPage> SvxGradientTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rOutAttrs )
+{
+ return std::make_unique<SvxGradientTabPage>(pPage, pController, *rOutAttrs);
+}
+
+IMPL_LINK( SvxGradientTabPage, ModifiedListBoxHdl_Impl, weld::ComboBox&, rListBox, void )
+{
+ ModifiedHdl_Impl(&rListBox);
+ // gradient params changed, it is no longer one of the presets
+ m_xGradientLB->SetNoSelection();
+}
+
+IMPL_LINK( SvxGradientTabPage, ModifiedColorListBoxHdl_Impl, ColorListBox&, rListBox, void )
+{
+ ModifiedHdl_Impl(&rListBox);
+ m_xGradientLB->SetNoSelection();
+}
+
+IMPL_LINK( SvxGradientTabPage, ModifiedEditHdl_Impl, weld::SpinButton&, rBox, void )
+{
+ ModifiedHdl_Impl(&rBox);
+ m_xGradientLB->SetNoSelection();
+}
+
+IMPL_LINK( SvxGradientTabPage, ModifiedMetricHdl_Impl, weld::MetricSpinButton&, rBox, void )
+{
+ ModifiedHdl_Impl(&rBox);
+ m_xGradientLB->SetNoSelection();
+}
+
+IMPL_LINK( SvxGradientTabPage, ModifiedSliderHdl_Impl, weld::Scale&, rSlider, void )
+{
+ ModifiedHdl_Impl(&rSlider);
+ m_xGradientLB->SetNoSelection();
+}
+
+IMPL_LINK_NOARG( SvxGradientTabPage, ChangeAutoStepHdl_Impl, weld::Toggleable&, void )
+{
+ if (m_xCbIncrement->get_active())
+ {
+ m_xMtrIncrement->set_sensitive(false);
+ }
+ else
+ {
+ m_xMtrIncrement->set_sensitive(true);
+ }
+ ModifiedHdl_Impl(m_xMtrIncrement.get());
+}
+
+void SvxGradientTabPage::ModifiedHdl_Impl( void const * pControl )
+{
+ if (pControl == m_xMtrBorder.get())
+ m_xSliderBorder->set_value(m_xMtrBorder->get_value(FieldUnit::NONE));
+ if (pControl == m_xSliderBorder.get())
+ m_xMtrBorder->set_value(m_xSliderBorder->get_value(), FieldUnit::NONE);
+ if (pControl == m_xMtrAngle.get())
+ m_xSliderAngle->set_value(m_xMtrAngle->get_value(FieldUnit::NONE));
+ if (pControl == m_xSliderAngle.get())
+ m_xMtrAngle->set_value(m_xSliderAngle->get_value(), FieldUnit::NONE);
+
+ css::awt::GradientStyle eXGS = static_cast<css::awt::GradientStyle>(m_xLbGradientType->get_active());
+
+ sal_uInt16 nValue = 0; // automatic
+ if (!m_xCbIncrement->get_active())
+ nValue = static_cast<sal_uInt16>(m_xMtrIncrement->get_value());
+
+ basegfx::BGradient aBGradient(
+ createColorStops(),
+ eXGS,
+ Degree10(static_cast<sal_Int16>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10)), // should be changed in resource
+ static_cast<sal_uInt16>(m_xMtrCenterX->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrCenterY->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrBorder->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrColorFrom->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrColorTo->get_value(FieldUnit::NONE)),
+ nValue);
+
+ // enable/disable controls
+ if (pControl == m_xLbGradientType.get() || pControl == this)
+ SetControlState_Impl( eXGS );
+
+ m_rXFSet.Put( XGradientStepCountItem( nValue ) );
+
+ // displaying in XOutDev
+ m_rXFSet.Put( XFillGradientItem( OUString(), aBGradient ) );
+ m_aCtlPreview.SetAttributes(m_aXFillAttr.GetItemSet());
+ m_aCtlPreview.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxGradientTabPage, ClickAddHdl_Impl, weld::Button&, void)
+{
+ OUString aNewName( SvxResId( RID_SVXSTR_GRADIENT ) );
+ OUString aDesc( CuiResId( RID_CUISTR_DESC_GRADIENT ) );
+ OUString aName;
+
+ tools::Long nCount = m_pGradientList->Count();
+ tools::Long j = 1;
+ bool bValidGradientName = false;
+
+ while( !bValidGradientName )
+ {
+ aName = aNewName + " " + OUString::number( j++ );
+ bValidGradientName = (SearchGradientList(aName) == -1);
+ }
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+ sal_uInt16 nError = 1;
+
+ while (pDlg->Execute() == RET_OK)
+ {
+ pDlg->GetName( aName );
+
+ bValidGradientName = (SearchGradientList(aName) == -1);
+
+ if (bValidGradientName)
+ {
+ nError = 0;
+ break;
+ }
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xWarnBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ if (xWarnBox->run() != RET_OK)
+ break;
+ }
+ pDlg.disposeAndClear();
+
+ if( !nError )
+ {
+ sal_uInt16 nValue = 0; // automatic step count
+ if (!m_xCbIncrement->get_active())
+ nValue = m_xMtrIncrement->get_value();
+ basegfx::BGradient aBGradient(
+ createColorStops(),
+ static_cast<css::awt::GradientStyle>(m_xLbGradientType->get_active()),
+ Degree10(static_cast<sal_Int16>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10)), // should be changed in resource
+ static_cast<sal_uInt16>(m_xMtrCenterX->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrCenterY->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrBorder->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrColorFrom->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrColorTo->get_value(FieldUnit::NONE)),
+ nValue);
+
+ m_pGradientList->Insert(std::make_unique<XGradientEntry>(aBGradient, aName), nCount);
+
+ sal_Int32 nId = m_xGradientLB->GetItemId(nCount - 1); //calculate the last ID
+ BitmapEx aBitmap = m_pGradientList->GetBitmapForPreview( nCount, m_xGradientLB->GetIconSize() );
+ m_xGradientLB->InsertItem( nId + 1, Image(aBitmap), aName );
+ m_xGradientLB->SelectItem( nId + 1 );
+ m_xGradientLB->Resize();
+
+ *m_pnGradientListState |= ChangeType::MODIFIED;
+
+ ChangeGradientHdl_Impl();
+ }
+
+ // determine button state
+ if (m_pGradientList->Count())
+ m_xBtnModify->set_sensitive(true);
+}
+
+
+IMPL_LINK_NOARG(SvxGradientTabPage, ClickModifyHdl_Impl, weld::Button&, void)
+{
+ sal_uInt16 nId = m_xGradientLB->GetSelectedItemId();
+ size_t nPos = m_xGradientLB->GetSelectItemPos();
+
+ if ( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ OUString aName( m_pGradientList->GetGradient( static_cast<sal_uInt16>(nPos) )->GetName() );
+
+ sal_uInt16 nValue = 0; // automatic step count
+ if (!m_xCbIncrement->get_active())
+ nValue = m_xMtrIncrement->get_value();
+
+ basegfx::BGradient aBGradient(
+ createColorStops(),
+ static_cast<css::awt::GradientStyle>(m_xLbGradientType->get_active()),
+ Degree10(static_cast<sal_Int16>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10)), // should be changed in resource
+ static_cast<sal_uInt16>(m_xMtrCenterX->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrCenterY->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrBorder->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrColorFrom->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrColorTo->get_value(FieldUnit::NONE)),
+ nValue);
+
+ m_pGradientList->Replace(std::make_unique<XGradientEntry>(aBGradient, aName), nPos);
+
+ BitmapEx aBitmap = m_pGradientList->GetBitmapForPreview( static_cast<sal_uInt16>(nPos), m_xGradientLB->GetIconSize() );
+ m_xGradientLB->RemoveItem( nId );
+ m_xGradientLB->InsertItem( nId, Image(aBitmap), aName, static_cast<sal_uInt16>(nPos) );
+ m_xGradientLB->SelectItem( nId );
+
+ *m_pnGradientListState |= ChangeType::MODIFIED;
+}
+
+IMPL_LINK_NOARG(SvxGradientTabPage, ClickDeleteHdl_Impl, SvxPresetListBox*, void)
+{
+ sal_uInt16 nId = m_xGradientLB->GetSelectedItemId();
+ size_t nPos = m_xGradientLB->GetSelectItemPos();
+
+ if( nPos != VALUESET_ITEM_NOTFOUND )
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querydeletegradientdialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("AskDelGradientDialog"));
+ if (xQueryBox->run() == RET_YES)
+ {
+ m_pGradientList->Remove(nPos);
+ m_xGradientLB->RemoveItem( nId );
+ nId = m_xGradientLB->GetItemId( 0 );
+ m_xGradientLB->SelectItem( nId );
+ m_xGradientLB->Resize();
+
+ m_aCtlPreview.Invalidate();
+
+ ChangeGradientHdl_Impl();
+
+ *m_pnGradientListState |= ChangeType::MODIFIED;
+ }
+ }
+ // determine button state
+ if( !m_pGradientList->Count() )
+ m_xBtnModify->set_sensitive(false);
+}
+
+IMPL_LINK_NOARG(SvxGradientTabPage, ClickRenameHdl_Impl, SvxPresetListBox*, void)
+{
+ sal_uInt16 nId = m_xGradientLB->GetSelectedItemId();
+ size_t nPos = m_xGradientLB->GetSelectItemPos();
+
+ if ( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ OUString aDesc( CuiResId( RID_CUISTR_DESC_GRADIENT ) );
+ OUString aName( m_pGradientList->GetGradient( nPos )->GetName() );
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+
+ bool bLoop = true;
+ while( bLoop && pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+ sal_Int32 nGradientPos = SearchGradientList(aName);
+ bool bValidGradientName = (nGradientPos == static_cast<sal_Int32>(nPos) ) || (nGradientPos == -1);
+
+ if( bValidGradientName )
+ {
+ bLoop = false;
+ m_pGradientList->GetGradient(nPos)->SetName(aName);
+
+ m_xGradientLB->SetItemText( nId, aName );
+ m_xGradientLB->SelectItem( nId );
+
+ *m_pnGradientListState |= ChangeType::MODIFIED;
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ xBox->run();
+ }
+ }
+}
+
+IMPL_LINK_NOARG(SvxGradientTabPage, ChangeGradientHdl, ValueSet*, void)
+{
+ ChangeGradientHdl_Impl();
+}
+
+void SvxGradientTabPage::ChangeGradientHdl_Impl()
+{
+ std::unique_ptr<basegfx::BGradient> pGradient;
+ size_t nPos = m_xGradientLB->GetSelectItemPos();
+
+ if( nPos != VALUESET_ITEM_NOTFOUND )
+ pGradient.reset(new basegfx::BGradient( m_pGradientList->GetGradient( static_cast<sal_uInt16>( nPos ) )->GetGradient() ));
+ else
+ {
+ if( const XFillStyleItem* pFillStyleItem = m_rOutAttrs.GetItemIfSet( GetWhich( XATTR_FILLSTYLE ) ) )
+ {
+ const XFillGradientItem* pGradientItem;
+ if( ( drawing::FillStyle_GRADIENT == pFillStyleItem->GetValue() ) &&
+ ( pGradientItem = m_rOutAttrs.GetItemIfSet( GetWhich( XATTR_FILLGRADIENT ) ) ) )
+ {
+ pGradient.reset(new basegfx::BGradient( pGradientItem->GetGradientValue() ));
+ }
+ }
+ if( !pGradient )
+ {
+ sal_uInt16 nPosition = m_xGradientLB->GetItemId(0);
+ m_xGradientLB->SelectItem( nPosition );
+ if( nPosition != 0 )
+ pGradient.reset(new basegfx::BGradient( m_pGradientList->GetGradient( 0 )->GetGradient() ));
+ }
+ }
+
+ if( !pGradient )
+ return;
+
+ css::awt::GradientStyle eXGS = pGradient->GetGradientStyle();
+ sal_uInt16 nValue = pGradient->GetSteps();
+ if (const XGradientStepCountItem* pGradientStepCountItem = m_rOutAttrs.GetItemIfSet(GetWhich(XATTR_GRADIENTSTEPCOUNT)))
+ {
+ nValue = pGradientStepCountItem->GetValue();
+ }
+ if( nValue == 0 )
+ {
+ m_xCbIncrement->set_state(TRISTATE_TRUE);
+ m_xMtrIncrement->set_sensitive(false);
+ }
+ else
+ {
+ m_xCbIncrement->set_state(TRISTATE_FALSE);
+ m_xMtrIncrement->set_sensitive(true);
+ m_xMtrIncrement->set_value( nValue );
+ }
+ m_xLbGradientType->set_active(
+ sal::static_int_cast< sal_Int32 >( eXGS ) );
+ // if the entry is not in the listbox,
+ // colors are added temporarily
+ m_xLbColorFrom->SetNoSelection();
+ m_xLbColorFrom->SelectEntry(Color(pGradient->GetColorStops().front().getStopColor()));
+
+ m_xLbColorTo->SetNoSelection();
+ m_xLbColorTo->SelectEntry(Color(pGradient->GetColorStops().back().getStopColor()));
+
+ // MCGR: preserve ColorStops if given.
+ // tdf#155901 We need offset of first and last stop, so include them.
+ if (pGradient->GetColorStops().size() >= 2)
+ m_aColorStops = pGradient->GetColorStops();
+ else
+ m_aColorStops.clear();
+
+ m_xMtrAngle->set_value(pGradient->GetAngle().get() / 10, FieldUnit::NONE); // should be changed in resource
+ m_xSliderAngle->set_value(pGradient->GetAngle().get() / 10);
+ m_xMtrBorder->set_value(pGradient->GetBorder(), FieldUnit::NONE);
+ m_xSliderBorder->set_value(pGradient->GetBorder());
+ m_xMtrCenterX->set_value(pGradient->GetXOffset(), FieldUnit::NONE);
+ m_xMtrCenterY->set_value(pGradient->GetYOffset(), FieldUnit::NONE);
+ m_xMtrColorFrom->set_value(pGradient->GetStartIntens(), FieldUnit::NONE);
+ m_xMtrColorTo->set_value(pGradient->GetEndIntens(), FieldUnit::NONE);
+
+ // disable/enable controls
+ SetControlState_Impl( eXGS );
+
+ // fill ItemSet and pass it on to aCtlPreview
+ m_rXFSet.Put( XFillGradientItem( OUString(), *pGradient ) );
+ m_rXFSet.Put( XGradientStepCountItem( nValue ) );
+ m_aCtlPreview.SetAttributes(m_aXFillAttr.GetItemSet());
+
+ m_aCtlPreview.Invalidate();
+}
+
+void SvxGradientTabPage::SetControlState_Impl( css::awt::GradientStyle eXGS )
+{
+ switch( eXGS )
+ {
+ case css::awt::GradientStyle_LINEAR:
+ case css::awt::GradientStyle_AXIAL:
+ m_xFtCenter->set_sensitive(false);
+ m_xMtrCenterX->set_sensitive(false);
+ m_xMtrCenterY->set_sensitive(false);
+ m_xFtAngle->set_sensitive(true);
+ m_xMtrAngle->set_sensitive(true);
+ m_xSliderAngle->set_sensitive(true);
+ break;
+
+ case css::awt::GradientStyle_RADIAL:
+ m_xFtCenter->set_sensitive(true);
+ m_xMtrCenterX->set_sensitive(true);
+ m_xMtrCenterY->set_sensitive(true);
+ m_xFtAngle->set_sensitive(false);
+ m_xMtrAngle->set_sensitive(false);
+ m_xSliderAngle->set_sensitive(false);
+ break;
+
+ case css::awt::GradientStyle_ELLIPTICAL:
+ m_xFtCenter->set_sensitive(true);
+ m_xMtrCenterX->set_sensitive(true);
+ m_xMtrCenterY->set_sensitive(true);
+ m_xFtAngle->set_sensitive(true);
+ m_xMtrAngle->set_sensitive(true);
+ m_xSliderAngle->set_sensitive(true);
+ break;
+
+ case css::awt::GradientStyle_SQUARE:
+ case css::awt::GradientStyle_RECT:
+ m_xFtCenter->set_sensitive(true);
+ m_xMtrCenterX->set_sensitive(true);
+ m_xMtrCenterY->set_sensitive(true);
+ m_xFtAngle->set_sensitive(true);
+ m_xMtrAngle->set_sensitive(true);
+ m_xSliderAngle->set_sensitive(true);
+ break;
+ default:
+ break;
+ }
+}
+
+sal_Int32 SvxGradientTabPage::SearchGradientList(std::u16string_view rGradientName)
+{
+ tools::Long nCount = m_pGradientList->Count();
+ bool bValidGradientName = true;
+ sal_Int32 nPos = -1;
+
+ for(tools::Long i = 0;i < nCount && bValidGradientName;i++)
+ {
+ if(rGradientName == m_pGradientList->GetGradient( i )->GetName())
+ {
+ nPos = i;
+ bValidGradientName = false;
+ }
+ }
+ return nPos;
+}
+
+basegfx::BColorStops SvxGradientTabPage::createColorStops()
+{
+ basegfx::BColorStops aColorStops;
+
+ if(m_aColorStops.size() >= 2)
+ {
+ aColorStops = m_aColorStops;
+ aColorStops.front() = basegfx::BColorStop(m_aColorStops.front().getStopOffset(),
+ m_xLbColorFrom->GetSelectEntryColor().getBColor());
+ aColorStops.back() = basegfx::BColorStop(m_aColorStops.back().getStopOffset(),
+ m_xLbColorTo->GetSelectEntryColor().getBColor());
+ }
+ else
+ {
+ aColorStops.emplace_back(0.0, m_xLbColorFrom->GetSelectEntryColor().getBColor());
+ aColorStops.emplace_back(1.0, m_xLbColorTo->GetSelectEntryColor().getBColor());
+ }
+
+ return aColorStops;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tphatch.cxx b/cui/source/tabpages/tphatch.cxx
new file mode 100644
index 0000000000..879e68a046
--- /dev/null
+++ b/cui/source/tabpages/tphatch.cxx
@@ -0,0 +1,562 @@
+/* -*- 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 <memory>
+#include <tools/urlobj.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <sfx2/dialoghelper.hxx>
+
+#include <strings.hrc>
+#include <svx/xfillit0.hxx>
+#include <svx/xflhtit.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/colorbox.hxx>
+#include <svx/xtable.hxx>
+#include <svx/xflbckit.hxx>
+#include <cuitabarea.hxx>
+#include <svx/svxdlg.hxx>
+#include <dialmgr.hxx>
+#include <svx/dlgutil.hxx>
+#include <svx/dialmgr.hxx>
+#include <svx/strings.hrc>
+#include <svx/svxids.hrc>
+#include <sal/log.hxx>
+#include <svtools/unitconv.hxx>
+
+using namespace com::sun::star;
+
+SvxHatchTabPage::SvxHatchTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/hatchpage.ui", "HatchPage", &rInAttrs)
+ , m_rOutAttrs(rInAttrs)
+ , m_pnHatchingListState(nullptr)
+ , m_pnColorListState(nullptr)
+ , m_aXFillAttr(rInAttrs.GetPool())
+ , m_rXFSet(m_aXFillAttr.GetItemSet())
+ , m_xMtrDistance(m_xBuilder->weld_metric_spin_button("distancemtr", FieldUnit::MM))
+ , m_xMtrAngle(m_xBuilder->weld_metric_spin_button("anglemtr", FieldUnit::DEGREE))
+ , m_xSliderAngle(m_xBuilder->weld_scale("angleslider"))
+ , m_xLbLineType(m_xBuilder->weld_combo_box("linetypelb"))
+ , m_xLbLineColor(new ColorListBox(m_xBuilder->weld_menu_button("linecolorlb"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xCbBackgroundColor(m_xBuilder->weld_check_button("backgroundcolor"))
+ , m_xLbBackgroundColor(new ColorListBox(m_xBuilder->weld_menu_button("backgroundcolorlb"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xHatchLB(new SvxPresetListBox(m_xBuilder->weld_scrolled_window("hatchpresetlistwin", true)))
+ , m_xBtnAdd(m_xBuilder->weld_button("add"))
+ , m_xBtnModify(m_xBuilder->weld_button("modify"))
+ , m_xHatchLBWin(new weld::CustomWeld(*m_xBuilder, "hatchpresetlist", *m_xHatchLB))
+ , m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, "previewctl", m_aCtlPreview))
+{
+ Size aSize = getDrawPreviewOptimalSize(m_aCtlPreview.GetDrawingArea()->get_ref_device());
+ m_xHatchLBWin->set_size_request(aSize.Width(), aSize.Height());
+ m_xCtlPreview->set_size_request(aSize.Width(), aSize.Height());
+
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ // adjust metric
+ FieldUnit eFUnit = GetModuleFieldUnit( rInAttrs );
+
+ switch ( eFUnit )
+ {
+ case FieldUnit::M:
+ case FieldUnit::KM:
+ eFUnit = FieldUnit::MM;
+ break;
+ default: ;//prevent warning
+ }
+ SetFieldUnit( *m_xMtrDistance, eFUnit );
+
+ // determine PoolUnit
+ SfxItemPool* pPool = m_rOutAttrs.GetPool();
+ assert( pPool && "Where is the pool?" );
+ m_ePoolUnit = pPool->GetMetric( SID_ATTR_FILL_HATCH );
+
+ // setting the output device
+ m_rXFSet.Put( XFillStyleItem(drawing::FillStyle_HATCH) );
+ m_rXFSet.Put( XFillHatchItem(OUString(), XHatch()) );
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_xHatchLB->SetSelectHdl( LINK( this, SvxHatchTabPage, ChangeHatchHdl ) );
+ m_xHatchLB->SetRenameHdl( LINK( this, SvxHatchTabPage, ClickRenameHdl_Impl ) );
+ m_xHatchLB->SetDeleteHdl( LINK( this, SvxHatchTabPage, ClickDeleteHdl_Impl ) );
+
+ Link<weld::MetricSpinButton&,void> aLink = LINK( this, SvxHatchTabPage, ModifiedEditHdl_Impl );
+ Link<weld::ComboBox&,void> aLink2 = LINK( this, SvxHatchTabPage, ModifiedListBoxHdl_Impl );
+ m_xMtrDistance->connect_value_changed( aLink );
+ m_xMtrAngle->connect_value_changed( aLink );
+ m_xSliderAngle->connect_value_changed(LINK(this, SvxHatchTabPage, ModifiedSliderHdl_Impl));
+ m_xLbLineType->connect_changed( aLink2 );
+ Link<ColorListBox&,void> aLink3 = LINK( this, SvxHatchTabPage, ModifiedColorListBoxHdl_Impl );
+ m_xLbLineColor->SetSelectHdl( aLink3 );
+ m_xCbBackgroundColor->connect_toggled( LINK( this, SvxHatchTabPage, ToggleHatchBackgroundColor_Impl ) );
+ m_xLbBackgroundColor->SetSelectHdl( LINK( this, SvxHatchTabPage, ModifiedBackgroundHdl_Impl ) );
+
+ m_xBtnAdd->connect_clicked( LINK( this, SvxHatchTabPage, ClickAddHdl_Impl ) );
+ m_xBtnModify->connect_clicked( LINK( this, SvxHatchTabPage, ClickModifyHdl_Impl ) );
+
+ m_xHatchLB->SetStyle(WB_FLATVALUESET | WB_NO_DIRECTSELECT | WB_TABSTOP);
+
+ m_aCtlPreview.SetDrawMode(Application::GetSettings().GetStyleSettings().GetHighContrastMode() ? OUTPUT_DRAWMODE_CONTRAST : OUTPUT_DRAWMODE_COLOR);
+}
+
+SvxHatchTabPage::~SvxHatchTabPage()
+{
+ m_xCtlPreview.reset();
+ m_xHatchLBWin.reset();
+ m_xHatchLB.reset();
+ m_xLbBackgroundColor.reset();
+ m_xLbLineColor.reset();
+}
+
+void SvxHatchTabPage::Construct()
+{
+ m_xHatchLB->FillPresetListBox(*m_pHatchingList);
+}
+
+void SvxHatchTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ if( m_pColorList.is() )
+ {
+ // ColorList
+ if( *m_pnColorListState & ChangeType::CHANGED ||
+ *m_pnColorListState & ChangeType::MODIFIED )
+ {
+ SvxAreaTabDialog* pArea = (*m_pnColorListState & ChangeType::CHANGED) ?
+ dynamic_cast<SvxAreaTabDialog*>(GetDialogController()) : nullptr;
+ if (pArea)
+ m_pColorList = pArea->GetNewColorList();
+
+ ModifiedHdl_Impl( this );
+ }
+
+ // determining (possibly cutting) the name
+ // and displaying it in the GroupBox
+ OUString aString = CuiResId( RID_CUISTR_TABLE ) + ": ";
+ INetURLObject aURL( m_pHatchingList->GetPath() );
+
+ aURL.Append( m_pHatchingList->GetName() );
+ SAL_WARN_IF( aURL.GetProtocol() == INetProtocol::NotValid, "cui.tabpages", "invalid URL" );
+
+ if ( aURL.getBase().getLength() > 18 )
+ {
+ aString += OUString::Concat(aURL.getBase().subView( 0, 15 )) + "...";
+ }
+ else
+ aString += aURL.getBase();
+
+ sal_Int32 nPos = SearchHatchList( rSet.Get(XATTR_FILLHATCH).GetName() );
+ if( nPos != -1)
+ {
+ sal_uInt16 nId = m_xHatchLB->GetItemId( static_cast<size_t>( nPos ) );
+ m_xHatchLB->SelectItem( nId );
+ }
+ // colors could have been deleted
+ ChangeHatchHdl_Impl();
+ }
+
+ XFillBackgroundItem aBckItem( rSet.Get(XATTR_FILLBACKGROUND));
+ m_rXFSet.Put( aBckItem );
+
+ if (aBckItem.GetValue())
+ {
+ m_xCbBackgroundColor->set_state(TRISTATE_TRUE);
+ XFillColorItem aColorItem( rSet.Get(XATTR_FILLCOLOR) );
+ Color aColor(aColorItem.GetColorValue());
+ m_xLbBackgroundColor->SelectEntry(aColor);
+ m_xLbBackgroundColor->set_sensitive(true);
+ m_rXFSet.Put( aColorItem );
+ }
+ else
+ {
+ m_xCbBackgroundColor->set_state(TRISTATE_FALSE);
+ m_xLbBackgroundColor->SelectEntry(COL_AUTO);
+ m_xLbBackgroundColor->set_sensitive(false);
+ }
+
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlPreview.Invalidate();
+}
+
+DeactivateRC SvxHatchTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+sal_Int32 SvxHatchTabPage::SearchHatchList(std::u16string_view rHatchName)
+{
+ tools::Long nCount = m_pHatchingList->Count();
+ bool bValidHatchName = true;
+ sal_Int32 nPos = -1;
+
+ for(tools::Long i = 0;i < nCount && bValidHatchName;i++)
+ {
+ if(rHatchName == m_pHatchingList->GetHatch( i )->GetName())
+ {
+ nPos = i;
+ bValidHatchName = false;
+ }
+ }
+ return nPos;
+}
+
+bool SvxHatchTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ std::unique_ptr<XHatch> pXHatch;
+ OUString aString;
+ size_t nPos = m_xHatchLB->IsNoSelection() ? VALUESET_ITEM_NOTFOUND : m_xHatchLB->GetSelectItemPos();
+ if( nPos != VALUESET_ITEM_NOTFOUND )
+ {
+ pXHatch.reset(new XHatch( m_pHatchingList->GetHatch( static_cast<sal_uInt16>(nPos) )->GetHatch() ));
+ aString = m_xHatchLB->GetItemText( m_xHatchLB->GetSelectedItemId() );
+ }
+ // unidentified hatch has been passed
+ else
+ {
+ pXHatch.reset(new XHatch( m_xLbLineColor->GetSelectEntryColor(),
+ static_cast<css::drawing::HatchStyle>(m_xLbLineType->get_active()),
+ GetCoreValue( *m_xMtrDistance, m_ePoolUnit ),
+ Degree10(static_cast<sal_Int16>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10)) ));
+ }
+ assert( pXHatch && "XHatch couldn't be created" );
+ rSet->Put( XFillStyleItem( drawing::FillStyle_HATCH ) );
+ rSet->Put( XFillHatchItem( aString, *pXHatch ) );
+ rSet->Put( XFillBackgroundItem( m_xCbBackgroundColor->get_active() ) );
+ if (m_xCbBackgroundColor->get_active())
+ {
+ NamedColor aColor = m_xLbBackgroundColor->GetSelectedEntry();
+ rSet->Put(XFillColorItem(aColor.m_aName, aColor.m_aColor));
+ }
+ return true;
+}
+
+void SvxHatchTabPage::Reset( const SfxItemSet* rSet )
+{
+ ChangeHatchHdl_Impl();
+
+ XFillColorItem aColItem( rSet->Get(XATTR_FILLCOLOR) );
+ m_xLbBackgroundColor->SelectEntry(aColItem.GetColorValue());
+ m_rXFSet.Put( aColItem );
+
+ XFillBackgroundItem aBckItem( rSet->Get(XATTR_FILLBACKGROUND) );
+ if(aBckItem.GetValue())
+ m_xCbBackgroundColor->set_state(TRISTATE_TRUE);
+ else
+ m_xCbBackgroundColor->set_state(TRISTATE_FALSE);
+ m_rXFSet.Put( aBckItem );
+
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlPreview.Invalidate();
+}
+
+std::unique_ptr<SfxTabPage> SvxHatchTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rSet )
+{
+ return std::make_unique<SvxHatchTabPage>(pPage, pController, *rSet);
+}
+
+IMPL_LINK( SvxHatchTabPage, ModifiedListBoxHdl_Impl, weld::ComboBox&, rListBox, void )
+{
+ ModifiedHdl_Impl(&rListBox);
+ // hatch params have changed, it is no longer one of the presets
+ m_xHatchLB->SetNoSelection();
+}
+
+IMPL_LINK( SvxHatchTabPage, ModifiedColorListBoxHdl_Impl, ColorListBox&, rListBox, void )
+{
+ ModifiedHdl_Impl(&rListBox);
+ m_xHatchLB->SetNoSelection();
+}
+
+IMPL_LINK_NOARG( SvxHatchTabPage, ToggleHatchBackgroundColor_Impl, weld::Toggleable&, void )
+{
+ if (m_xCbBackgroundColor->get_active())
+ m_xLbBackgroundColor->set_sensitive(true);
+ else
+ m_xLbBackgroundColor->set_sensitive(false);
+ m_rXFSet.Put( XFillBackgroundItem( m_xCbBackgroundColor->get_active() ) );
+ ModifiedBackgroundHdl_Impl(*m_xLbBackgroundColor);
+}
+
+IMPL_LINK_NOARG( SvxHatchTabPage, ModifiedBackgroundHdl_Impl, ColorListBox&, void )
+{
+ Color aColor(COL_TRANSPARENT);
+ if (m_xCbBackgroundColor->get_active())
+ {
+ aColor = m_xLbBackgroundColor->GetSelectEntryColor();
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlPreview.Invalidate();
+ }
+ m_rXFSet.Put(XFillColorItem( OUString(), aColor ));
+
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlPreview.Invalidate();
+}
+
+IMPL_LINK( SvxHatchTabPage, ModifiedEditHdl_Impl, weld::MetricSpinButton&, rEdit, void )
+{
+ ModifiedHdl_Impl(&rEdit);
+ m_xHatchLB->SetNoSelection();
+}
+
+IMPL_LINK( SvxHatchTabPage, ModifiedSliderHdl_Impl, weld::Scale&, rSlider, void )
+{
+ ModifiedHdl_Impl(&rSlider);
+ m_xHatchLB->SetNoSelection();
+}
+
+void SvxHatchTabPage::ModifiedHdl_Impl( void const * p )
+{
+ if (p == m_xMtrAngle.get())
+ m_xSliderAngle->set_value(m_xMtrAngle->get_value(FieldUnit::NONE));
+
+ if (p == m_xSliderAngle.get())
+ m_xMtrAngle->set_value(m_xSliderAngle->get_value(), FieldUnit::NONE);
+
+ XHatch aXHatch( m_xLbLineColor->GetSelectEntryColor(),
+ static_cast<css::drawing::HatchStyle>(m_xLbLineType->get_active()),
+ GetCoreValue( *m_xMtrDistance, m_ePoolUnit ),
+ Degree10(static_cast<sal_Int16>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10)) );
+
+ m_rXFSet.Put( XFillHatchItem( OUString(), aXHatch ) );
+
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlPreview.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxHatchTabPage, ChangeHatchHdl, ValueSet*, void)
+{
+ ChangeHatchHdl_Impl();
+}
+
+void SvxHatchTabPage::ChangeHatchHdl_Impl()
+{
+ std::unique_ptr<XHatch> pHatch;
+ size_t nPos = m_xHatchLB->GetSelectItemPos();
+
+ if( nPos != VALUESET_ITEM_NOTFOUND )
+ pHatch.reset(new XHatch( m_pHatchingList->GetHatch( static_cast<sal_uInt16>(nPos) )->GetHatch() ));
+ else
+ {
+ if( const XFillStyleItem* pFillStyleItem = m_rOutAttrs.GetItemIfSet( GetWhich( XATTR_FILLSTYLE ) ) )
+ {
+ const XFillHatchItem* pFillHatchItem;
+ if( ( drawing::FillStyle_HATCH == pFillStyleItem->GetValue() ) &&
+ ( pFillHatchItem = m_rOutAttrs.GetItemIfSet( GetWhich( XATTR_FILLHATCH ) ) ) )
+ {
+ pHatch.reset(new XHatch( pFillHatchItem->GetHatchValue() ));
+ }
+ }
+ if( !pHatch )
+ {
+ sal_uInt16 nPosition = m_xHatchLB->GetItemId( 0 );
+ m_xHatchLB->SelectItem( nPosition );
+ if( nPosition != 0 )
+ pHatch.reset( new XHatch( m_pHatchingList->GetHatch( 0 )->GetHatch() ) );
+ }
+ }
+ if( pHatch )
+ {
+ m_xLbLineType->set_active(
+ sal::static_int_cast< sal_Int32 >( pHatch->GetHatchStyle() ) );
+ m_xLbLineColor->SetNoSelection();
+ m_xLbLineColor->SelectEntry( pHatch->GetColor() );
+ SetMetricValue( *m_xMtrDistance, pHatch->GetDistance(), m_ePoolUnit );
+ tools::Long nHatchAngle = pHatch->GetAngle().get() / 10;
+ m_xMtrAngle->set_value(nHatchAngle, FieldUnit::NONE);
+ m_xSliderAngle->set_value(nHatchAngle);
+
+ // fill ItemSet and pass it on to m_aCtlPreview
+ m_rXFSet.Put( XFillHatchItem( OUString(), *pHatch ) );
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+
+ m_aCtlPreview.Invalidate();
+ pHatch.reset();
+ }
+ m_xMtrDistance->save_value();
+ m_xMtrAngle->save_value();
+ m_xLbLineType->save_value();
+ m_xLbLineColor->SaveValue();
+ m_xLbBackgroundColor->SaveValue();
+}
+
+IMPL_LINK_NOARG(SvxHatchTabPage, ClickAddHdl_Impl, weld::Button&, void)
+{
+ OUString aNewName( SvxResId( RID_SVXSTR_HATCH ) );
+ OUString aDesc( CuiResId( RID_CUISTR_DESC_HATCH ) );
+ OUString aName;
+
+ tools::Long nCount = m_pHatchingList->Count();
+ tools::Long j = 1;
+ bool bValidHatchName = false;
+
+ while( !bValidHatchName )
+ {
+ aName = aNewName + " " + OUString::number( j++ );
+ bValidHatchName = (SearchHatchList(aName) == -1);
+ }
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+ sal_uInt16 nError = 1;
+
+ while( pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+
+ bValidHatchName = (SearchHatchList(aName) == -1);
+ if( bValidHatchName )
+ {
+ nError = 0;
+ break;
+ }
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xWarnBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ if (xWarnBox->run() != RET_OK)
+ break;
+ }
+ pDlg.disposeAndClear();
+
+ if( nError )
+ return;
+
+ XHatch aXHatch( m_xLbLineColor->GetSelectEntryColor(),
+ static_cast<css::drawing::HatchStyle>(m_xLbLineType->get_active()),
+ GetCoreValue( *m_xMtrDistance, m_ePoolUnit ),
+ Degree10(static_cast<sal_Int16>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10)) );
+
+ m_pHatchingList->Insert(std::make_unique<XHatchEntry>(aXHatch, aName), nCount);
+
+ sal_Int32 nId = m_xHatchLB->GetItemId(nCount - 1); // calculate the last ID
+ BitmapEx aBitmap = m_pHatchingList->GetBitmapForPreview( nCount, m_xHatchLB->GetIconSize() );
+ // Insert the new entry at the next ID
+ m_xHatchLB->InsertItem( nId + 1, Image(aBitmap), aName );
+ m_xHatchLB->SelectItem( nId + 1 );
+ m_xHatchLB->Resize();
+
+ *m_pnHatchingListState |= ChangeType::MODIFIED;
+
+ ChangeHatchHdl_Impl();
+}
+
+IMPL_LINK_NOARG(SvxHatchTabPage, ClickModifyHdl_Impl, weld::Button&, void)
+{
+ sal_uInt16 nId = m_xHatchLB->GetSelectedItemId();
+ size_t nPos = m_xHatchLB->GetSelectItemPos();
+
+ if( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ OUString aName( m_pHatchingList->GetHatch( static_cast<sal_uInt16>(nPos) )->GetName() );
+
+ XHatch aXHatch( m_xLbLineColor->GetSelectEntryColor(),
+ static_cast<css::drawing::HatchStyle>(m_xLbLineType->get_active()),
+ GetCoreValue( *m_xMtrDistance, m_ePoolUnit ),
+ Degree10(static_cast<sal_Int16>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10)) );
+
+ m_pHatchingList->Replace(std::make_unique<XHatchEntry>(aXHatch, aName), nPos);
+
+ BitmapEx aBitmap = m_pHatchingList->GetBitmapForPreview( static_cast<sal_uInt16>(nPos), m_xHatchLB->GetIconSize() );
+ m_xHatchLB->RemoveItem( nId );
+ m_xHatchLB->InsertItem( nId, Image(aBitmap), aName, static_cast<sal_uInt16>(nPos) );
+ m_xHatchLB->SelectItem( nId );
+
+ // save values for changes recognition (-> method)
+ m_xMtrDistance->save_value();
+ m_xMtrAngle->save_value();
+ m_xLbLineType->save_value();
+ m_xLbLineColor->SaveValue();
+ m_xLbBackgroundColor->SaveValue();
+
+ *m_pnHatchingListState |= ChangeType::MODIFIED;
+}
+
+IMPL_LINK_NOARG(SvxHatchTabPage, ClickDeleteHdl_Impl, SvxPresetListBox*, void)
+{
+ sal_uInt16 nId = m_xHatchLB->GetSelectedItemId();
+ size_t nPos = m_xHatchLB->GetSelectItemPos();
+
+ if( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querydeletehatchdialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("AskDelHatchDialog"));
+ if (xQueryBox->run() != RET_YES)
+ return;
+
+ m_pHatchingList->Remove(nPos);
+ m_xHatchLB->RemoveItem( nId );
+ nId = m_xHatchLB->GetItemId(0);
+ m_xHatchLB->SelectItem( nId );
+ m_xHatchLB->Resize();
+
+ m_aCtlPreview.Invalidate();
+
+ ChangeHatchHdl_Impl();
+
+ *m_pnHatchingListState |= ChangeType::MODIFIED;
+}
+
+IMPL_LINK_NOARG(SvxHatchTabPage, ClickRenameHdl_Impl, SvxPresetListBox*, void )
+{
+ sal_uInt16 nId = m_xHatchLB->GetSelectedItemId();
+ size_t nPos = m_xHatchLB->GetSelectItemPos();
+
+ if( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ OUString aDesc( CuiResId( RID_CUISTR_DESC_HATCH ) );
+ OUString aName( m_pHatchingList->GetHatch( nPos )->GetName() );
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+
+ bool bLoop = true;
+ while( bLoop && pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+ sal_Int32 nHatchPos = SearchHatchList( aName );
+ bool bValidHatchName = (nHatchPos == static_cast<sal_Int32>(nPos) ) || (nHatchPos == -1);
+
+ if(bValidHatchName)
+ {
+ bLoop = false;
+ m_pHatchingList->GetHatch(nPos)->SetName(aName);
+
+ m_xHatchLB->SetItemText(nId, aName);
+ m_xHatchLB->SelectItem( nId );
+
+ *m_pnHatchingListState |= ChangeType::MODIFIED;
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ xBox->run();
+ }
+ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tpline.cxx b/cui/source/tabpages/tpline.cxx
new file mode 100644
index 0000000000..37fe8ef913
--- /dev/null
+++ b/cui/source/tabpages/tpline.cxx
@@ -0,0 +1,1699 @@
+/* -*- 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 <memory>
+#include <editeng/sizeitem.hxx>
+#include <osl/file.hxx>
+#include <tools/urlobj.hxx>
+
+#include <strings.hrc>
+#include <svx/colorbox.hxx>
+#include <svx/dlgctrl.hxx>
+#include <svx/xlineit0.hxx>
+#include <svx/xlinjoit.hxx>
+#include <svx/xlncapit.hxx>
+#include <svx/xlndsit.hxx>
+#include <svx/xlnwtit.hxx>
+#include <svx/xlnstwit.hxx>
+#include <svx/xlnedwit.hxx>
+#include <svx/xlnclit.hxx>
+#include <svx/xlnstit.hxx>
+#include <svx/xlnedit.hxx>
+#include <svx/xlnstcit.hxx>
+#include <svx/xlnedcit.hxx>
+
+
+#include <svx/tabline.hxx>
+#include <svx/xtable.hxx>
+#include <svx/drawitem.hxx>
+#include <cuitabline.hxx>
+#include <dialmgr.hxx>
+#include <svx/dlgutil.hxx>
+#include <svx/svxgraphicitem.hxx>
+#include <svx/ofaitem.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdview.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/xlntrit.hxx>
+#include <svx/xfltrit.hxx>
+#include <editeng/numitem.hxx>
+#include <editeng/brushitem.hxx>
+#include <svx/gallery.hxx>
+#include <sfx2/opengrf.hxx>
+#include <svx/dialmgr.hxx>
+#include <svx/svxids.hrc>
+#include <svx/strings.hrc>
+#include <cuitabarea.hxx>
+#include <svtools/unitconv.hxx>
+#include <comphelper/lok.hxx>
+
+#define MAX_BMP_WIDTH 16
+#define MAX_BMP_HEIGHT 16
+
+using namespace com::sun::star;
+
+// static ----------------------------------------------------------------
+
+const WhichRangesContainer SvxLineTabPage::pLineRanges(svl::Items<
+ XATTR_LINETRANSPARENCE, XATTR_LINETRANSPARENCE,
+ SID_ATTR_LINE_STYLE, SID_ATTR_LINE_ENDCENTER
+>);
+
+SvxLineTabPage::SvxLineTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/linetabpage.ui", "LineTabPage", &rInAttrs)
+ , m_pSymbolList(nullptr)
+ , m_bNewSize(false)
+ , m_nSymbolType(SVX_SYMBOLTYPE_UNKNOWN) // unknown respectively unchanged
+ , m_bLastWidthModified(false)
+ , m_aSymbolLastSize(Size(0,0))
+ , m_bSymbols(false)
+ , m_rOutAttrs(rInAttrs)
+ , m_bObjSelected(false)
+ , m_aXLineAttr(rInAttrs.GetPool())
+ , m_rXLSet(m_aXLineAttr.GetItemSet())
+ , m_pnLineEndListState(nullptr)
+ , m_pnDashListState(nullptr)
+ , m_pnColorListState(nullptr)
+ , m_nPageType(PageType::Area)
+ , m_nDlgType(0)
+ , m_pPosDashLb(nullptr)
+ , m_pPosLineEndLb(nullptr)
+ , m_xBoxColor(m_xBuilder->weld_widget("boxCOLOR"))
+ , m_xLbLineStyle(new SvxLineLB(m_xBuilder->weld_combo_box("LB_LINE_STYLE")))
+ , m_xLbColor(new ColorListBox(m_xBuilder->weld_menu_button("LB_COLOR"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xBoxWidth(m_xBuilder->weld_widget("boxWIDTH"))
+ , m_xMtrLineWidth(m_xBuilder->weld_metric_spin_button("MTR_FLD_LINE_WIDTH", FieldUnit::CM))
+ , m_xBoxTransparency(m_xBuilder->weld_widget("boxTRANSPARENCY"))
+ , m_xMtrTransparent(m_xBuilder->weld_metric_spin_button("MTR_LINE_TRANSPARENT", FieldUnit::PERCENT))
+ , m_xFlLineEnds(m_xBuilder->weld_widget("FL_LINE_ENDS"))
+ , m_xBoxArrowStyles(m_xBuilder->weld_widget("boxARROW_STYLES"))
+ , m_xLbStartStyle(new SvxLineEndLB(m_xBuilder->weld_combo_box("LB_START_STYLE")))
+ , m_xBoxStart(m_xBuilder->weld_widget("boxSTART"))
+ , m_xMtrStartWidth(m_xBuilder->weld_metric_spin_button("MTR_FLD_START_WIDTH", FieldUnit::CM))
+ , m_xTsbCenterStart(m_xBuilder->weld_check_button("TSB_CENTER_START"))
+ , m_xBoxEnd(m_xBuilder->weld_widget("boxEND"))
+ , m_xLbEndStyle(new SvxLineEndLB(m_xBuilder->weld_combo_box("LB_END_STYLE")))
+ , m_xMtrEndWidth(m_xBuilder->weld_metric_spin_button("MTR_FLD_END_WIDTH", FieldUnit::CM))
+ , m_xTsbCenterEnd(m_xBuilder->weld_check_button("TSB_CENTER_END"))
+ , m_xCbxSynchronize(m_xBuilder->weld_check_button("CBX_SYNCHRONIZE"))
+ , m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, "CTL_PREVIEW", m_aCtlPreview))
+ , m_xFLEdgeStyle(m_xBuilder->weld_widget("FL_EDGE_STYLE"))
+ , m_xGridEdgeCaps(m_xBuilder->weld_widget("gridEDGE_CAPS"))
+ , m_xLBEdgeStyle(m_xBuilder->weld_combo_box("LB_EDGE_STYLE"))
+ , m_xLBCapStyle(m_xBuilder->weld_combo_box("LB_CAP_STYLE")) // LineCaps
+ , m_xFlSymbol(m_xBuilder->weld_widget("FL_SYMBOL_FORMAT")) //#58425# Symbols on a line (e.g. StarChart)
+ , m_xGridIconSize(m_xBuilder->weld_widget("gridICON_SIZE"))
+ , m_xSymbolMB(m_xBuilder->weld_menu_button("MB_SYMBOL_BITMAP"))
+ , m_xSymbolWidthMF(m_xBuilder->weld_metric_spin_button("MF_SYMBOL_WIDTH", FieldUnit::CM))
+ , m_xSymbolHeightMF(m_xBuilder->weld_metric_spin_button("MF_SYMBOL_HEIGHT", FieldUnit::CM))
+ , m_xSymbolRatioCB(m_xBuilder->weld_check_button("CB_SYMBOL_RATIO"))
+{
+ // This Page requires ExchangeSupport
+ SetExchangeSupport();
+
+ // Metric set
+ FieldUnit eFUnit = GetModuleFieldUnit( rInAttrs );
+
+ switch ( eFUnit )
+ {
+ case FieldUnit::M:
+ case FieldUnit::KM:
+ eFUnit = FieldUnit::MM;
+ [[fallthrough]]; // we now have mm
+ case FieldUnit::MM:
+ m_xMtrLineWidth->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrStartWidth->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrEndWidth->set_increments(50, 500, FieldUnit::NONE);
+ break;
+
+ case FieldUnit::INCH:
+ m_xMtrLineWidth->set_increments(2, 20, FieldUnit::NONE);
+ m_xMtrStartWidth->set_increments(2, 20, FieldUnit::NONE);
+ m_xMtrEndWidth->set_increments(2, 20, FieldUnit::NONE);
+ break;
+ default: ;// prevent warning
+ }
+ SetFieldUnit( *m_xMtrLineWidth, eFUnit );
+ SetFieldUnit( *m_xMtrStartWidth, eFUnit );
+ SetFieldUnit( *m_xMtrEndWidth, eFUnit );
+
+ // determine PoolUnit
+ SfxItemPool* pPool = m_rOutAttrs.GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ m_ePoolUnit = pPool->GetMetric( SID_ATTR_LINE_WIDTH );
+
+ m_xLbLineStyle->connect_changed(LINK(this, SvxLineTabPage, ClickInvisibleHdl_Impl));
+ m_xLbColor->SetSelectHdl( LINK( this, SvxLineTabPage, ChangePreviewListBoxHdl_Impl ) );
+ m_xMtrLineWidth->connect_value_changed(LINK(this, SvxLineTabPage, ChangePreviewModifyHdl_Impl));
+ m_xMtrTransparent->connect_value_changed(LINK( this, SvxLineTabPage, ChangeTransparentHdl_Impl));
+
+ m_xLbStartStyle->connect_changed(LINK(this, SvxLineTabPage, ChangeStartListBoxHdl_Impl));
+ m_xLbEndStyle->connect_changed(LINK(this, SvxLineTabPage, ChangeEndListBoxHdl_Impl));
+ m_xMtrStartWidth->connect_value_changed(LINK(this, SvxLineTabPage, ChangeStartModifyHdl_Impl));
+ m_xMtrEndWidth->connect_value_changed(LINK( this, SvxLineTabPage, ChangeEndModifyHdl_Impl));
+ m_xTsbCenterStart->connect_toggled(LINK(this, SvxLineTabPage, ChangeStartClickHdl_Impl));
+ m_xTsbCenterEnd->connect_toggled(LINK(this, SvxLineTabPage, ChangeEndClickHdl_Impl));
+
+ Link<weld::ComboBox&,void> aEdgeStyle = LINK(this, SvxLineTabPage, ChangeEdgeStyleHdl_Impl);
+ m_xLBEdgeStyle->connect_changed(aEdgeStyle);
+
+ // LineCaps
+ Link<weld::ComboBox&,void> aCapStyle = LINK(this, SvxLineTabPage, ChangeCapStyleHdl_Impl);
+ m_xLBCapStyle->connect_changed(aCapStyle);
+
+ // Symbols on a line (eg star charts), MB-handler set
+ m_xSymbolMB->connect_selected(LINK(this, SvxLineTabPage, GraphicHdl_Impl));
+ m_xSymbolMB->connect_toggled(LINK(this, SvxLineTabPage, MenuCreateHdl_Impl));
+ m_xSymbolWidthMF->connect_value_changed(LINK(this, SvxLineTabPage, SizeHdl_Impl));
+ m_xSymbolHeightMF->connect_value_changed(LINK(this, SvxLineTabPage, SizeHdl_Impl));
+ m_xSymbolRatioCB->connect_toggled(LINK(this, SvxLineTabPage, RatioHdl_Impl));
+
+ m_xSymbolRatioCB->set_active(true);
+ ShowSymbolControls(false);
+
+ m_nActLineWidth = -1;
+}
+
+void SvxLineTabPage::ShowSymbolControls(bool bOn)
+{
+ // Symbols on a line (e.g. StarCharts), symbol-enable controls
+
+ m_bSymbols=bOn;
+ m_xFlSymbol->set_visible(bOn);
+ m_aCtlPreview.ShowSymbol(bOn);
+}
+
+SvxLineTabPage::~SvxLineTabPage()
+{
+ m_xCtlPreview.reset();
+ m_xLbEndStyle.reset();
+ m_xLbStartStyle.reset();
+ m_xLbColor.reset();
+ m_xLbLineStyle.reset();
+ m_aGalleryBrushItems.clear();
+ m_aSymbolBrushItems.clear();
+}
+
+void SvxLineTabPage::Construct()
+{
+ FillListboxes();
+}
+
+void SvxLineTabPage::FillListboxes()
+{
+ // Line styles
+ auto nOldSelect = m_xLbLineStyle->get_active();
+ // aLbLineStyle.FillStyles();
+ m_xLbLineStyle->Fill( m_pDashList );
+ m_xLbLineStyle->set_active( nOldSelect );
+
+ // Line end style
+ OUString sNone( comphelper::LibreOfficeKit::isActive() ? SvxResId( RID_SVXSTR_INVISIBLE )
+ : SvxResId( RID_SVXSTR_NONE ) );
+ nOldSelect = m_xLbStartStyle->get_active();
+ m_xLbStartStyle->clear();
+ m_xLbStartStyle->append_text(sNone);
+ m_xLbStartStyle->Fill(m_pLineEndList);
+ m_xLbStartStyle->set_active(nOldSelect);
+ nOldSelect = m_xLbEndStyle->get_active();
+ m_xLbEndStyle->clear();
+ m_xLbEndStyle->append_text(sNone);
+ m_xLbEndStyle->Fill(m_pLineEndList, false);
+ m_xLbEndStyle->set_active(nOldSelect);
+}
+
+void SvxLineTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ const SfxUInt16Item* pPageTypeItem = rSet.GetItem<SfxUInt16Item>(SID_PAGE_TYPE, false);
+ if (pPageTypeItem)
+ SetPageType(static_cast<PageType>(pPageTypeItem->GetValue()));
+ if( m_nDlgType == 0 && m_pDashList.is() )
+ {
+ sal_Int32 nPos;
+ sal_Int32 nCount;
+
+ // Dash list
+ if( ( *m_pnDashListState & ChangeType::MODIFIED ) ||
+ ( *m_pnDashListState & ChangeType::CHANGED ) )
+ {
+ if( *m_pnDashListState & ChangeType::CHANGED )
+ m_pDashList = static_cast<SvxLineTabDialog*>(GetDialogController() )->GetNewDashList();
+
+ *m_pnDashListState = ChangeType::NONE;
+
+ // Style list
+ nPos = m_xLbLineStyle->get_active();
+
+ m_xLbLineStyle->clear();
+ m_xLbLineStyle->append_text(SvxResId(RID_SVXSTR_INVISIBLE));
+ m_xLbLineStyle->append_text(SvxResId(RID_SVXSTR_SOLID));
+ m_xLbLineStyle->Fill(m_pDashList);
+ nCount = m_xLbLineStyle->get_count();
+
+ if ( nCount == 0 )
+ ; // This case should never occur
+ else if( nCount <= nPos )
+ m_xLbLineStyle->set_active(0);
+ else
+ m_xLbLineStyle->set_active(nPos);
+ }
+
+ INetURLObject aDashURL( m_pDashList->GetPath() );
+
+ aDashURL.Append( m_pDashList->GetName() );
+ DBG_ASSERT( aDashURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
+ // LineEnd list
+ if( ( *m_pnLineEndListState & ChangeType::MODIFIED ) || ( *m_pnLineEndListState & ChangeType::CHANGED ) )
+ {
+ if( *m_pnLineEndListState & ChangeType::CHANGED )
+ m_pLineEndList = static_cast<SvxLineTabDialog*>(GetDialogController())->GetNewLineEndList();
+
+ *m_pnLineEndListState = ChangeType::NONE;
+
+ nPos = m_xLbLineStyle->get_active();
+ OUString sNone( comphelper::LibreOfficeKit::isActive() ? SvxResId( RID_SVXSTR_INVISIBLE )
+ : SvxResId( RID_SVXSTR_NONE ) );
+
+ m_xLbStartStyle->clear();
+ m_xLbStartStyle->append_text(sNone);
+
+ m_xLbStartStyle->Fill( m_pLineEndList );
+ nCount = m_xLbStartStyle->get_count();
+ if( nCount == 0 )
+ ; // This case should never occur
+ else if( nCount <= nPos )
+ m_xLbStartStyle->set_active(0);
+ else
+ m_xLbStartStyle->set_active(nPos);
+
+ m_xLbEndStyle->clear();
+ m_xLbEndStyle->append_text(sNone);
+
+ m_xLbEndStyle->Fill( m_pLineEndList, false );
+ nCount = m_xLbEndStyle->get_count();
+
+ if( nCount == 0 )
+ ; // This case should never occur
+ else if( nCount <= nPos )
+ m_xLbEndStyle->set_active(0);
+ else
+ m_xLbEndStyle->set_active(nPos);
+ }
+ INetURLObject aLineURL( m_pLineEndList->GetPath() );
+
+ aLineURL.Append( m_pLineEndList->GetName() );
+ DBG_ASSERT( aLineURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
+ // Evaluate if another TabPage set another fill type
+ if( m_xLbLineStyle->get_active() != 0 )
+ {
+ if( m_nPageType == PageType::Hatch ) // 1
+ {
+ m_xLbLineStyle->set_active(*m_pPosDashLb + 2); // +2 due to SOLID and INVISIBLE
+ ChangePreviewHdl_Impl( nullptr );
+ }
+ if( m_nPageType == PageType::Bitmap )
+ {
+ m_xLbStartStyle->set_active(*m_pPosLineEndLb + 1);// +1 due to SOLID
+ m_xLbEndStyle->set_active(*m_pPosLineEndLb + 1);// +1 due to SOLID
+ ChangePreviewHdl_Impl( nullptr );
+ }
+ }
+
+ // ColorList
+ if( *m_pnColorListState != ChangeType::NONE )
+ {
+ ChangePreviewHdl_Impl( nullptr );
+ }
+
+ m_nPageType = PageType::Area;
+ }
+ // Page does not yet exist in the ctor, that's why we do it here!
+
+ else if (m_nDlgType == 1101) // nNoArrowNoShadowDlg from chart2/source/controller/dialogs/dlg_ObjectProperties.cxx
+ {
+ m_xFlLineEnds->hide();
+ m_xFLEdgeStyle->hide();
+ }
+}
+
+
+DeactivateRC SvxLineTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if( m_nDlgType == 0 ) // Line dialog
+ {
+ m_nPageType = PageType::Gradient; // possibly for extensions
+ *m_pPosDashLb = m_xLbLineStyle->get_active() - 2;// First entry SOLID!!!
+ sal_Int32 nPos = m_xLbStartStyle->get_active();
+ if (nPos != -1)
+ nPos--;
+ *m_pPosLineEndLb = nPos;
+ }
+
+ if( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+
+bool SvxLineTabPage::FillItemSet( SfxItemSet* rAttrs )
+{
+ const SfxPoolItem* pOld = nullptr;
+ sal_Int32 nPos;
+ bool bModified = false;
+
+ // To prevent modifications to the list, we do not set other page's items.
+ if( m_nDlgType != 0 || m_nPageType != PageType::Hatch )
+ {
+ nPos = m_xLbLineStyle->get_active();
+ if( nPos != -1 &&
+ m_xLbLineStyle->get_value_changed_from_saved() )
+ {
+ std::unique_ptr<XLineStyleItem> pStyleItem;
+
+ if( nPos == 0 )
+ pStyleItem.reset(new XLineStyleItem( drawing::LineStyle_NONE ));
+ else if( nPos == 1 )
+ pStyleItem.reset(new XLineStyleItem( drawing::LineStyle_SOLID ));
+ else
+ {
+ pStyleItem.reset(new XLineStyleItem( drawing::LineStyle_DASH ));
+
+ // For added security
+ if( m_pDashList->Count() > static_cast<tools::Long>( nPos - 2 ) )
+ {
+ XLineDashItem aDashItem( m_xLbLineStyle->get_active_text(),
+ m_pDashList->GetDash( nPos - 2 )->GetDash() );
+ pOld = GetOldItem( *rAttrs, XATTR_LINEDASH );
+ if ( !pOld || !( *static_cast<const XLineDashItem*>(pOld) == aDashItem ) )
+ {
+ rAttrs->Put( aDashItem );
+ bModified = true;
+ }
+ }
+ }
+ pOld = GetOldItem( *rAttrs, XATTR_LINESTYLE );
+ if ( !pOld || !( *static_cast<const XLineStyleItem*>(pOld) == *pStyleItem ) )
+ {
+ rAttrs->Put( std::move(pStyleItem) );
+ bModified = true;
+ }
+ }
+ }
+ // Line width
+ // GetSavedValue() returns OUString!
+ if( m_xMtrLineWidth->get_value_changed_from_saved() )
+ {
+ XLineWidthItem aItem( GetCoreValue( *m_xMtrLineWidth, m_ePoolUnit ) );
+ pOld = GetOldItem( *rAttrs, XATTR_LINEWIDTH );
+ if ( !pOld || !( *static_cast<const XLineWidthItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+ // Width line start
+ if( m_xMtrStartWidth->get_value_changed_from_saved() )
+ {
+ XLineStartWidthItem aItem( GetCoreValue( *m_xMtrStartWidth, m_ePoolUnit ) );
+ pOld = GetOldItem( *rAttrs, XATTR_LINESTARTWIDTH );
+ if ( !pOld || !( *static_cast<const XLineStartWidthItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+ // Width line end
+ if( m_xMtrEndWidth->get_value_changed_from_saved() )
+ {
+ XLineEndWidthItem aItem( GetCoreValue( *m_xMtrEndWidth, m_ePoolUnit ) );
+ pOld = GetOldItem( *rAttrs, XATTR_LINEENDWIDTH );
+ if ( !pOld || !( *static_cast<const XLineEndWidthItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+
+ // Line color
+ if (m_xLbColor->IsValueChangedFromSaved())
+ {
+ NamedColor aNamedColor = m_xLbColor->GetSelectedEntry();
+ XLineColorItem aItem(aNamedColor.m_aName, aNamedColor.m_aColor);
+ aItem.setComplexColor(aNamedColor.getComplexColor());
+
+ pOld = GetOldItem( *rAttrs, XATTR_LINECOLOR );
+ if ( !pOld || !( *static_cast<const XLineColorItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+
+ if( m_nDlgType != 0 || m_nPageType != PageType::Bitmap )
+ {
+ // Line start
+ nPos = m_xLbStartStyle->get_active();
+ if( nPos != -1 && m_xLbStartStyle->get_value_changed_from_saved() )
+ {
+ std::unique_ptr<XLineStartItem> pItem;
+ if( nPos == 0 )
+ pItem.reset(new XLineStartItem());
+ else if( m_pLineEndList->Count() > static_cast<tools::Long>( nPos - 1 ) )
+ pItem.reset(new XLineStartItem( m_xLbStartStyle->get_active_text(), m_pLineEndList->GetLineEnd( nPos - 1 )->GetLineEnd() ));
+ pOld = GetOldItem( *rAttrs, XATTR_LINESTART );
+ if( pItem && ( !pOld || *pOld != *pItem ) )
+ {
+ rAttrs->Put( std::move(pItem) );
+ bModified = true;
+ }
+ }
+ // Line end
+ nPos = m_xLbEndStyle->get_active();
+ if( nPos != -1 && m_xLbEndStyle->get_value_changed_from_saved() )
+ {
+ std::unique_ptr<XLineEndItem> pItem;
+ if( nPos == 0 )
+ pItem.reset(new XLineEndItem());
+ else if( m_pLineEndList->Count() > static_cast<tools::Long>( nPos - 1 ) )
+ pItem.reset(new XLineEndItem( m_xLbEndStyle->get_active_text(), m_pLineEndList->GetLineEnd( nPos - 1 )->GetLineEnd() ));
+ pOld = GetOldItem( *rAttrs, XATTR_LINEEND );
+ if( pItem &&
+ ( !pOld || !( *static_cast<const XLineEndItem*>(pOld) == *pItem ) ) )
+ {
+ rAttrs->Put( std::move(pItem) );
+ bModified = true;
+ }
+ }
+ }
+
+ // Centered line end
+ TriState eState = m_xTsbCenterStart->get_state();
+ if( m_xTsbCenterStart->get_state_changed_from_saved() )
+ {
+ XLineStartCenterItem aItem( eState != TRISTATE_FALSE );
+ pOld = GetOldItem( *rAttrs, XATTR_LINESTARTCENTER );
+ if ( !pOld || !( *static_cast<const XLineStartCenterItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+ eState = m_xTsbCenterEnd->get_state();
+ if( m_xTsbCenterEnd->get_state_changed_from_saved() )
+ {
+ XLineEndCenterItem aItem( eState != TRISTATE_FALSE );
+ pOld = GetOldItem( *rAttrs, XATTR_LINEENDCENTER );
+ if ( !pOld || !( *static_cast<const XLineEndCenterItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+
+ // Transparency
+ sal_uInt16 nVal = m_xMtrTransparent->get_value(FieldUnit::PERCENT);
+ if( m_xMtrTransparent->get_value_changed_from_saved() )
+ {
+ XLineTransparenceItem aItem( nVal );
+ pOld = GetOldItem( *rAttrs, XATTR_LINETRANSPARENCE );
+ if ( !pOld || !( *static_cast<const XLineTransparenceItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+
+ nPos = m_xLBEdgeStyle->get_active();
+ if (nPos != -1 && m_xLBEdgeStyle->get_value_changed_from_saved())
+ {
+ std::unique_ptr<XLineJointItem> pNew;
+
+ switch(nPos)
+ {
+ case 0: // Rounded, default
+ {
+ pNew.reset(new XLineJointItem(css::drawing::LineJoint_ROUND));
+ break;
+ }
+ case 1: // - none -
+ {
+ pNew.reset(new XLineJointItem(css::drawing::LineJoint_NONE));
+ break;
+ }
+ case 2: // Miter
+ {
+ pNew.reset(new XLineJointItem(css::drawing::LineJoint_MITER));
+ break;
+ }
+ case 3: // Bevel
+ {
+ pNew.reset(new XLineJointItem(css::drawing::LineJoint_BEVEL));
+ break;
+ }
+ }
+
+ if(pNew)
+ {
+ pOld = GetOldItem( *rAttrs, XATTR_LINEJOINT );
+
+ if(!pOld || !(*static_cast<const XLineJointItem*>(pOld) == *pNew))
+ {
+ rAttrs->Put( std::move(pNew) );
+ bModified = true;
+ }
+ }
+ }
+
+ // LineCaps
+ nPos = m_xLBCapStyle->get_active();
+ if (nPos != -1 && m_xLBCapStyle->get_value_changed_from_saved())
+ {
+ std::unique_ptr<XLineCapItem> pNew;
+
+ switch(nPos)
+ {
+ case 0: // Butt (=Flat), default
+ {
+ pNew.reset(new XLineCapItem(css::drawing::LineCap_BUTT));
+ break;
+ }
+ case 1: // Round
+ {
+ pNew.reset(new XLineCapItem(css::drawing::LineCap_ROUND));
+ break;
+ }
+ case 2: // Square
+ {
+ pNew.reset(new XLineCapItem(css::drawing::LineCap_SQUARE));
+ break;
+ }
+ }
+
+ if(pNew)
+ {
+ pOld = GetOldItem( *rAttrs, XATTR_LINECAP );
+
+ if(!pOld || !(*static_cast<const XLineCapItem*>(pOld) == *pNew))
+ {
+ rAttrs->Put( std::move(pNew) );
+ bModified = true;
+ }
+ }
+ }
+
+ if(m_nSymbolType!=SVX_SYMBOLTYPE_UNKNOWN || m_bNewSize)
+ {
+ // Was set by selection or the size is different
+ SvxSizeItem aSItem(rAttrs->GetPool()->GetWhich(SID_ATTR_SYMBOLSIZE),m_aSymbolSize);
+ const SfxPoolItem* pSOld = GetOldItem( *rAttrs, rAttrs->GetPool()->GetWhich(SID_ATTR_SYMBOLSIZE) );
+ m_bNewSize = pSOld ? *static_cast<const SvxSizeItem *>(pSOld) != aSItem : m_bNewSize ;
+ if(m_bNewSize)
+ {
+ rAttrs->Put(aSItem);
+ bModified=true;
+ }
+
+ SfxInt32Item aTItem(rAttrs->GetPool()->GetWhich(SID_ATTR_SYMBOLTYPE),m_nSymbolType);
+ const SfxPoolItem* pTOld = GetOldItem( *rAttrs, rAttrs->GetPool()->GetWhich(SID_ATTR_SYMBOLTYPE) );
+ bool bNewType = pTOld == nullptr || *static_cast<const SfxInt32Item*>(pTOld) != aTItem;
+ if(bNewType && m_nSymbolType==SVX_SYMBOLTYPE_UNKNOWN)
+ bNewType=false; // a small fix, type wasn't set -> don't create a type item after all!
+ if(bNewType)
+ {
+ rAttrs->Put(aTItem);
+ bModified=true;
+ }
+
+ if(m_nSymbolType!=SVX_SYMBOLTYPE_NONE)
+ {
+ SvxBrushItem aBItem(m_aSymbolGraphic,GPOS_MM,rAttrs->GetPool()->GetWhich(SID_ATTR_BRUSH));
+ const SfxPoolItem* pBOld = GetOldItem( *rAttrs, rAttrs->GetPool()->GetWhich(SID_ATTR_BRUSH) );
+ bool bNewBrush =
+ pBOld == nullptr || *static_cast<const SvxBrushItem*>(pBOld) != aBItem;
+ if(bNewBrush)
+ {
+ rAttrs->Put(aBItem);
+ bModified=true;
+ }
+ }
+ }
+ rAttrs->Put (CntUInt16Item(SID_PAGE_TYPE, static_cast<sal_uInt16>(m_nPageType)));
+ return bModified;
+}
+
+
+void SvxLineTabPage::FillXLSet_Impl()
+{
+ sal_Int32 nPos;
+
+ if (m_xLbLineStyle->get_active() == -1)
+ {
+ m_rXLSet.Put( XLineStyleItem( drawing::LineStyle_NONE ) );
+ }
+ else if (m_xLbLineStyle->get_active() == 0)
+ m_rXLSet.Put( XLineStyleItem( drawing::LineStyle_NONE ) );
+ else if (m_xLbLineStyle->get_active() == 1)
+ m_rXLSet.Put( XLineStyleItem( drawing::LineStyle_SOLID ) );
+ else
+ {
+ m_rXLSet.Put( XLineStyleItem( drawing::LineStyle_DASH ) );
+
+ nPos = m_xLbLineStyle->get_active();
+ if (nPos != -1)
+ {
+ m_rXLSet.Put( XLineDashItem( m_xLbLineStyle->get_active_text(),
+ m_pDashList->GetDash( nPos - 2 )->GetDash() ) );
+ }
+ }
+
+ nPos = m_xLbStartStyle->get_active();
+ if (nPos != -1)
+ {
+ if( nPos == 0 )
+ m_rXLSet.Put( XLineStartItem() );
+ else
+ m_rXLSet.Put( XLineStartItem( m_xLbStartStyle->get_active_text(),
+ m_pLineEndList->GetLineEnd( nPos - 1 )->GetLineEnd() ) );
+ }
+ nPos = m_xLbEndStyle->get_active();
+ if (nPos != -1)
+ {
+ if( nPos == 0 )
+ m_rXLSet.Put( XLineEndItem() );
+ else
+ m_rXLSet.Put( XLineEndItem( m_xLbEndStyle->get_active_text(),
+ m_pLineEndList->GetLineEnd( nPos - 1 )->GetLineEnd() ) );
+ }
+
+ nPos = m_xLBEdgeStyle->get_active();
+ if (nPos != -1)
+ {
+ switch(nPos)
+ {
+ case 0: // Rounded, default
+ {
+ m_rXLSet.Put(XLineJointItem(css::drawing::LineJoint_ROUND));
+ break;
+ }
+ case 1: // - none -
+ {
+ m_rXLSet.Put(XLineJointItem(css::drawing::LineJoint_NONE));
+ break;
+ }
+ case 2: // Miter
+ {
+ m_rXLSet.Put(XLineJointItem(css::drawing::LineJoint_MITER));
+ break;
+ }
+ case 3: // Bevel
+ {
+ m_rXLSet.Put(XLineJointItem(css::drawing::LineJoint_BEVEL));
+ break;
+ }
+ }
+ }
+
+ // LineCaps
+ nPos = m_xLBCapStyle->get_active();
+ if (nPos != -1)
+ {
+ switch(nPos)
+ {
+ case 0: // Butt (=Flat), default
+ {
+ m_rXLSet.Put(XLineCapItem(css::drawing::LineCap_BUTT));
+ break;
+ }
+ case 1: // Round
+ {
+ m_rXLSet.Put(XLineCapItem(css::drawing::LineCap_ROUND));
+ break;
+ }
+ case 2: // Square
+ {
+ m_rXLSet.Put(XLineCapItem(css::drawing::LineCap_SQUARE));
+ break;
+ }
+ }
+ }
+
+ m_rXLSet.Put( XLineStartWidthItem( GetCoreValue( *m_xMtrStartWidth, m_ePoolUnit ) ) );
+ m_rXLSet.Put( XLineEndWidthItem( GetCoreValue( *m_xMtrEndWidth, m_ePoolUnit ) ) );
+
+ m_rXLSet.Put( XLineWidthItem( GetCoreValue( *m_xMtrLineWidth, m_ePoolUnit ) ) );
+ NamedColor aNamedColor = m_xLbColor->GetSelectedEntry();
+ XLineColorItem aLineColor(aNamedColor.m_aName, aNamedColor.m_aColor);
+ aLineColor.setComplexColor(aNamedColor.getComplexColor());
+ m_rXLSet.Put(aLineColor);
+
+ // Centered line end
+ if( m_xTsbCenterStart->get_state() == TRISTATE_TRUE )
+ m_rXLSet.Put( XLineStartCenterItem( true ) );
+ else if( m_xTsbCenterStart->get_state() == TRISTATE_FALSE )
+ m_rXLSet.Put( XLineStartCenterItem( false ) );
+
+ if( m_xTsbCenterEnd->get_state() == TRISTATE_TRUE )
+ m_rXLSet.Put( XLineEndCenterItem( true ) );
+ else if( m_xTsbCenterEnd->get_state() == TRISTATE_FALSE )
+ m_rXLSet.Put( XLineEndCenterItem( false ) );
+
+ // Transparency
+ sal_uInt16 nVal = m_xMtrTransparent->get_value(FieldUnit::PERCENT);
+ m_rXLSet.Put( XLineTransparenceItem( nVal ) );
+
+ m_aCtlPreview.SetLineAttributes(m_aXLineAttr.GetItemSet());
+}
+
+
+void SvxLineTabPage::Reset( const SfxItemSet* rAttrs )
+{
+ drawing::LineStyle eXLS; // drawing::LineStyle_NONE, drawing::LineStyle_SOLID, drawing::LineStyle_DASH
+
+ // Line style
+ tools::Long nSymType=SVX_SYMBOLTYPE_UNKNOWN;
+ bool bPrevSym=false;
+ bool bEnable=true;
+ bool bIgnoreGraphic=false;
+ bool bIgnoreSize=false;
+ if(const SfxInt32Item* pSymbolTypeItem = rAttrs->GetItemIfSet(rAttrs->GetPool()->GetWhich(SID_ATTR_SYMBOLTYPE)))
+ {
+ nSymType = pSymbolTypeItem->GetValue();
+ }
+
+ if(nSymType == SVX_SYMBOLTYPE_AUTO)
+ {
+ m_aSymbolGraphic=m_aAutoSymbolGraphic;
+ m_aSymbolSize=m_aSymbolLastSize=m_aAutoSymbolGraphic.GetPrefSize();
+ bPrevSym=true;
+ }
+ else if(nSymType == SVX_SYMBOLTYPE_NONE)
+ {
+ bEnable=false;
+ bIgnoreGraphic=true;
+ bIgnoreSize=true;
+ }
+ else if(nSymType >= 0)
+ {
+ ScopedVclPtrInstance< VirtualDevice > pVDev;
+ pVDev->SetMapMode(MapMode(MapUnit::Map100thMM));
+
+ std::unique_ptr<SdrModel> pModel(
+ new SdrModel(nullptr, nullptr, true));
+ pModel->GetItemPool().FreezeIdRanges();
+ rtl::Reference<SdrPage> pPage = new SdrPage( *pModel, false );
+ pPage->SetSize(Size(1000,1000));
+ pModel->InsertPage( pPage.get(), 0 );
+ {
+ SdrView aView( *pModel, pVDev );
+ aView.hideMarkHandles();
+ aView.ShowSdrPage(pPage.get());
+ size_t nSymTmp = static_cast<size_t>(nSymType);
+ if(m_pSymbolList)
+ {
+ if(m_pSymbolList->GetObjCount())
+ {
+ nSymTmp %= m_pSymbolList->GetObjCount(); // Treat list as cyclic!
+ rtl::Reference<SdrObject> pObj=m_pSymbolList->GetObj(nSymTmp);
+ if(pObj)
+ {
+ // directly clone to target SdrModel
+ pObj = pObj->CloneSdrObject(*pModel);
+
+ if(m_xSymbolAttr)
+ {
+ pObj->SetMergedItemSet(*m_xSymbolAttr);
+ }
+ else
+ {
+ pObj->SetMergedItemSet(m_rOutAttrs);
+ }
+
+ pPage->NbcInsertObject(pObj.get());
+
+ // Generate invisible square to give all symbol types a
+ // bitmap size, which is independent from specific glyph
+ rtl::Reference<SdrObject> pInvisibleSquare(m_pSymbolList->GetObj(0));
+
+ // directly clone to target SdrModel
+ pInvisibleSquare = pInvisibleSquare->CloneSdrObject(*pModel);
+
+ pPage->NbcInsertObject(pInvisibleSquare.get());
+ pInvisibleSquare->SetMergedItem(XFillTransparenceItem(100));
+ pInvisibleSquare->SetMergedItem(XLineTransparenceItem(100));
+
+ aView.MarkAll();
+ GDIMetaFile aMeta(aView.GetMarkedObjMetaFile());
+
+ m_aSymbolGraphic=Graphic(aMeta);
+ m_aSymbolSize=pObj->GetSnapRect().GetSize();
+ m_aSymbolGraphic.SetPrefSize(pInvisibleSquare->GetSnapRect().GetSize());
+ m_aSymbolGraphic.SetPrefMapMode(MapMode(MapUnit::Map100thMM));
+ bPrevSym=true;
+ bEnable=true;
+ bIgnoreGraphic=true;
+
+ aView.UnmarkAll();
+ pPage->RemoveObject(1);
+ pInvisibleSquare.clear();
+ pPage->RemoveObject(0);
+ pObj.clear();
+ }
+ }
+ }
+ }
+ }
+ if(const SvxBrushItem* pBrushItem = rAttrs->GetItemIfSet(rAttrs->GetPool()->GetWhich(SID_ATTR_BRUSH)))
+ {
+ const Graphic* pGraphic = pBrushItem->GetGraphic();
+ if( pGraphic )
+ {
+ if(!bIgnoreGraphic)
+ {
+ m_aSymbolGraphic=*pGraphic;
+ }
+ if(!bIgnoreSize)
+ {
+ m_aSymbolSize=OutputDevice::LogicToLogic( pGraphic->GetPrefSize(),
+ pGraphic->GetPrefMapMode(),
+ MapMode(MapUnit::Map100thMM));
+ }
+ bPrevSym=true;
+ }
+ }
+
+ if(const SvxSizeItem* pSymbolSizeItem = rAttrs->GetItemIfSet(rAttrs->GetPool()->GetWhich(SID_ATTR_SYMBOLSIZE)))
+ {
+ m_aSymbolSize = pSymbolSizeItem->GetSize();
+ }
+
+ m_xGridIconSize->set_sensitive(bEnable);
+
+ if(bPrevSym)
+ {
+ SetMetricValue(*m_xSymbolWidthMF, m_aSymbolSize.Width(), m_ePoolUnit);
+ SetMetricValue(*m_xSymbolHeightMF, m_aSymbolSize.Height(),m_ePoolUnit);
+ m_aCtlPreview.SetSymbol(&m_aSymbolGraphic,m_aSymbolSize);
+ m_aSymbolLastSize=m_aSymbolSize;
+ }
+
+ if( rAttrs->GetItemState( XATTR_LINESTYLE ) != SfxItemState::DONTCARE )
+ {
+ eXLS = rAttrs->Get( XATTR_LINESTYLE ).GetValue();
+
+ switch( eXLS )
+ {
+ case drawing::LineStyle_NONE:
+ m_xLbLineStyle->set_active(0);
+ break;
+ case drawing::LineStyle_SOLID:
+ m_xLbLineStyle->set_active(1);
+ break;
+
+ case drawing::LineStyle_DASH:
+ m_xLbLineStyle->set_active(-1);
+ m_xLbLineStyle->set_active_text(rAttrs->Get( XATTR_LINEDASH ).GetName());
+ break;
+
+ default:
+ break;
+ }
+ }
+ else
+ {
+ m_xLbLineStyle->set_active(-1);
+ }
+
+ // Line strength
+ if( rAttrs->GetItemState( XATTR_LINEWIDTH ) != SfxItemState::DONTCARE )
+ {
+ SetMetricValue( *m_xMtrLineWidth, rAttrs->Get( XATTR_LINEWIDTH ).GetValue(), m_ePoolUnit );
+ }
+ else
+ m_xMtrLineWidth->set_text("");
+
+ // Line color
+ m_xLbColor->SetNoSelection();
+
+ if ( rAttrs->GetItemState( XATTR_LINECOLOR ) != SfxItemState::DONTCARE )
+ {
+ Color aCol = rAttrs->Get( XATTR_LINECOLOR ).GetColorValue();
+ m_xLbColor->SelectEntry( aCol );
+ }
+
+ // Line start
+ if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINESTART ) == SfxItemState::DEFAULT )
+ {
+ m_xLbStartStyle->set_sensitive(false);
+ }
+ else if( rAttrs->GetItemState( XATTR_LINESTART ) != SfxItemState::DONTCARE )
+ {
+ // #86265# select entry using list and polygon, not string
+ bool bSelected(false);
+ const basegfx::B2DPolyPolygon& rItemPolygon = rAttrs->Get(XATTR_LINESTART).GetLineStartValue();
+
+ for(tools::Long a(0);!bSelected && a < m_pLineEndList->Count(); a++)
+ {
+ const XLineEndEntry* pEntry = m_pLineEndList->GetLineEnd(a);
+ const basegfx::B2DPolyPolygon& rEntryPolygon = pEntry->GetLineEnd();
+
+ if(rItemPolygon == rEntryPolygon)
+ {
+ // select this entry
+ m_xLbStartStyle->set_active(a + 1);
+ bSelected = true;
+ }
+ }
+
+ if(!bSelected)
+ m_xLbStartStyle->set_active(0);
+ }
+ else
+ {
+ m_xLbStartStyle->set_active(-1);
+ }
+
+ // Line end
+ if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINEEND ) == SfxItemState::DEFAULT )
+ {
+ m_xLbEndStyle->set_sensitive(false);
+ }
+ else if( rAttrs->GetItemState( XATTR_LINEEND ) != SfxItemState::DONTCARE )
+ {
+ // #86265# select entry using list and polygon, not string
+ bool bSelected(false);
+ const basegfx::B2DPolyPolygon& rItemPolygon = rAttrs->Get(XATTR_LINEEND).GetLineEndValue();
+
+ for(tools::Long a(0);!bSelected && a < m_pLineEndList->Count(); a++)
+ {
+ const XLineEndEntry* pEntry = m_pLineEndList->GetLineEnd(a);
+ const basegfx::B2DPolyPolygon& rEntryPolygon = pEntry->GetLineEnd();
+
+ if(rItemPolygon == rEntryPolygon)
+ {
+ // select this entry
+ m_xLbEndStyle->set_active(a + 1);
+ bSelected = true;
+ }
+ }
+
+ if(!bSelected)
+ m_xLbEndStyle->set_active(0);
+ }
+ else
+ {
+ m_xLbEndStyle->set_active(-1);
+ }
+
+ // Line start strength
+ if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINESTARTWIDTH ) == SfxItemState::DEFAULT )
+ {
+ m_xMtrStartWidth->set_sensitive(false);
+ }
+ else if( rAttrs->GetItemState( XATTR_LINESTARTWIDTH ) != SfxItemState::DONTCARE )
+ {
+ SetMetricValue( *m_xMtrStartWidth,
+ rAttrs->Get( XATTR_LINESTARTWIDTH ).GetValue(),
+ m_ePoolUnit );
+ }
+ else
+ m_xMtrStartWidth->set_text( "" );
+
+ // Line end strength
+ if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINEENDWIDTH ) == SfxItemState::DEFAULT )
+ {
+ m_xMtrEndWidth->set_sensitive(false);
+ }
+ else if( rAttrs->GetItemState( XATTR_LINEENDWIDTH ) != SfxItemState::DONTCARE )
+ {
+ SetMetricValue( *m_xMtrEndWidth,
+ rAttrs->Get( XATTR_LINEENDWIDTH ).GetValue(),
+ m_ePoolUnit );
+ }
+ else
+ m_xMtrEndWidth->set_text("");
+
+ // Centered line end (start)
+ if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINESTARTCENTER ) == SfxItemState::DEFAULT )
+ {
+ m_xTsbCenterStart->set_sensitive(false);
+ }
+ else if( rAttrs->GetItemState( XATTR_LINESTARTCENTER ) != SfxItemState::DONTCARE )
+ {
+ if( rAttrs->Get( XATTR_LINESTARTCENTER ).GetValue() )
+ m_xTsbCenterStart->set_state(TRISTATE_TRUE);
+ else
+ m_xTsbCenterStart->set_state(TRISTATE_FALSE);
+ }
+ else
+ {
+ m_xTsbCenterStart->set_state(TRISTATE_INDET);
+ }
+
+ // Centered line end (end)
+ if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINEENDCENTER ) == SfxItemState::DEFAULT )
+ {
+ m_xTsbCenterEnd->set_sensitive(false);
+ }
+ else if( rAttrs->GetItemState( XATTR_LINEENDCENTER ) != SfxItemState::DONTCARE )
+ {
+ if( rAttrs->Get( XATTR_LINEENDCENTER ).GetValue() )
+ m_xTsbCenterEnd->set_state(TRISTATE_TRUE);
+ else
+ m_xTsbCenterEnd->set_state(TRISTATE_FALSE);
+ }
+ else
+ {
+ m_xTsbCenterEnd->set_state(TRISTATE_INDET);
+ }
+
+ // Transparency
+ if( rAttrs->GetItemState( XATTR_LINETRANSPARENCE ) != SfxItemState::DONTCARE )
+ {
+ sal_uInt16 nTransp = rAttrs->Get( XATTR_LINETRANSPARENCE ).GetValue();
+ m_xMtrTransparent->set_value(nTransp, FieldUnit::PERCENT);
+ ChangeTransparentHdl_Impl(*m_xMtrTransparent);
+ }
+ else
+ m_xMtrTransparent->set_text( "" );
+
+ if( !m_xLbStartStyle->get_sensitive() &&
+ !m_xLbEndStyle->get_sensitive() &&
+ !m_xMtrStartWidth->get_sensitive() &&
+ !m_xMtrEndWidth->get_sensitive() &&
+ !m_xTsbCenterStart->get_sensitive()&&
+ !m_xTsbCenterEnd->get_sensitive() )
+ {
+ m_xCbxSynchronize->set_sensitive(false);
+ m_xFlLineEnds->set_sensitive(false);
+ }
+
+ // Synchronize
+ // We get the value from the INI file now
+ OUString aStr = GetUserData();
+ m_xCbxSynchronize->set_active(aStr.toInt32() != 0);
+
+ if(m_bObjSelected && SfxItemState::DEFAULT == rAttrs->GetItemState(XATTR_LINEJOINT))
+ {
+// maFTEdgeStyle.set_sensitive(false);
+ m_xLBEdgeStyle->set_sensitive(false);
+ }
+ else if(SfxItemState::DONTCARE != rAttrs->GetItemState(XATTR_LINEJOINT))
+ {
+ const css::drawing::LineJoint eLineJoint = rAttrs->Get(XATTR_LINEJOINT).GetValue();
+
+ switch(eLineJoint)
+ {
+ case css::drawing::LineJoint::LineJoint_MAKE_FIXED_SIZE: // fallback to round, unused value
+ case css::drawing::LineJoint_ROUND : m_xLBEdgeStyle->set_active(0); break;
+ case css::drawing::LineJoint_NONE : m_xLBEdgeStyle->set_active(1); break;
+ case css::drawing::LineJoint_MIDDLE : // fallback to mitre, unused value
+ case css::drawing::LineJoint_MITER : m_xLBEdgeStyle->set_active(2); break;
+ case css::drawing::LineJoint_BEVEL : m_xLBEdgeStyle->set_active(3); break;
+ }
+ }
+ else
+ {
+ m_xLBEdgeStyle->set_active(-1);
+ }
+
+ // fdo#43209
+ if(m_bObjSelected && SfxItemState::DEFAULT == rAttrs->GetItemState(XATTR_LINECAP))
+ {
+ m_xLBCapStyle->set_sensitive(false);
+ }
+ else if(SfxItemState::DONTCARE != rAttrs->GetItemState(XATTR_LINECAP))
+ {
+ const css::drawing::LineCap eLineCap(rAttrs->Get(XATTR_LINECAP).GetValue());
+
+ switch(eLineCap)
+ {
+ case css::drawing::LineCap_ROUND: m_xLBCapStyle->set_active(1); break;
+ case css::drawing::LineCap_SQUARE : m_xLBCapStyle->set_active(2); break;
+ default /*css::drawing::LineCap_BUTT*/: m_xLBCapStyle->set_active(0); break;
+ }
+ }
+ else
+ {
+ m_xLBCapStyle->set_active(-1);
+ }
+
+ // Save values
+ m_xLbLineStyle->save_value();
+ m_xMtrLineWidth->save_value();
+ m_xLbColor->SaveValue();
+ m_xLbStartStyle->save_value();
+ m_xLbEndStyle->save_value();
+ m_xMtrStartWidth->save_value();
+ m_xMtrEndWidth->save_value();
+ m_xTsbCenterStart->save_state();
+ m_xTsbCenterEnd->save_state();
+ m_xMtrTransparent->save_value();
+
+ m_xLBEdgeStyle->save_value();
+
+ // LineCaps
+ m_xLBCapStyle->save_value();
+
+ ClickInvisibleHdl_Impl();
+
+ ChangePreviewHdl_Impl( nullptr );
+}
+
+std::unique_ptr<SfxTabPage> SvxLineTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrs)
+{
+ return std::make_unique<SvxLineTabPage>(pPage, pController, *rAttrs);
+}
+
+IMPL_LINK_NOARG(SvxLineTabPage, ChangePreviewListBoxHdl_Impl, ColorListBox&, void)
+{
+ ChangePreviewHdl_Impl(nullptr);
+}
+
+IMPL_LINK(SvxLineTabPage, ChangePreviewModifyHdl_Impl, weld::MetricSpinButton&, rEdit, void)
+{
+ ChangePreviewHdl_Impl(&rEdit);
+}
+
+void SvxLineTabPage::ChangePreviewHdl_Impl(const weld::MetricSpinButton* pCntrl)
+{
+ if (pCntrl == m_xMtrLineWidth.get())
+ {
+ // Line width and start end width
+ sal_Int32 nNewLineWidth = GetCoreValue( *m_xMtrLineWidth, m_ePoolUnit );
+ if(m_nActLineWidth == -1)
+ {
+ // Don't initialize yet, get the start value
+ const SfxPoolItem* pOld = GetOldItem( m_rXLSet, XATTR_LINEWIDTH );
+ sal_Int32 nStartLineWidth = 0;
+ if(pOld)
+ nStartLineWidth = static_cast<const XLineWidthItem *>(pOld)->GetValue();
+ m_nActLineWidth = nStartLineWidth;
+ }
+
+ if(m_nActLineWidth != nNewLineWidth)
+ {
+ // Adapt start/end width
+ sal_Int32 nValAct = GetCoreValue( *m_xMtrStartWidth, m_ePoolUnit );
+ sal_Int32 nValNew = nValAct + (((nNewLineWidth - m_nActLineWidth) * 15) / 10);
+ if(nValNew < 0)
+ nValNew = 0;
+ SetMetricValue( *m_xMtrStartWidth, nValNew, m_ePoolUnit );
+
+ nValAct = GetCoreValue( *m_xMtrEndWidth, m_ePoolUnit );
+ nValNew = nValAct + (((nNewLineWidth - m_nActLineWidth) * 15) / 10);
+ if(nValNew < 0)
+ nValNew = 0;
+ SetMetricValue( *m_xMtrEndWidth, nValNew, m_ePoolUnit );
+ }
+
+ // Remember current value
+ m_nActLineWidth = nNewLineWidth;
+ }
+
+ FillXLSet_Impl();
+ m_aCtlPreview.Invalidate();
+
+ // Make transparency accessible accordingly
+ if( m_xLbLineStyle->get_active() == 0 ) // invisible
+ {
+ m_xBoxTransparency->set_sensitive(false);
+ }
+ else
+ {
+ m_xBoxTransparency->set_sensitive(true);
+ }
+
+ const bool bHasLineStyle = m_xLbLineStyle->get_active() !=0;
+ const bool bHasLineStart = m_xLbStartStyle->get_active() != 0;
+
+ m_xBoxStart->set_sensitive(bHasLineStart && bHasLineStyle);
+
+ const bool bHasLineEnd = m_xLbEndStyle->get_active() != 0;
+
+ m_xBoxEnd->set_sensitive(bHasLineEnd && bHasLineStyle);
+}
+
+IMPL_LINK_NOARG(SvxLineTabPage, ChangeStartClickHdl_Impl, weld::Toggleable&, void)
+{
+ if (m_xCbxSynchronize->get_active())
+ m_xTsbCenterEnd->set_state(m_xTsbCenterStart->get_state());
+ ChangePreviewHdl_Impl(nullptr);
+}
+
+IMPL_LINK_NOARG(SvxLineTabPage, ChangeStartListBoxHdl_Impl, weld::ComboBox&, void)
+{
+ if (m_xCbxSynchronize->get_active())
+ m_xLbEndStyle->set_active(m_xLbStartStyle->get_active());
+
+ ChangePreviewHdl_Impl(nullptr);
+}
+
+IMPL_LINK_NOARG(SvxLineTabPage, ChangeStartModifyHdl_Impl, weld::MetricSpinButton&, void)
+{
+ if (m_xCbxSynchronize->get_active())
+ m_xMtrEndWidth->set_value(m_xMtrStartWidth->get_value(FieldUnit::NONE), FieldUnit::NONE);
+
+ ChangePreviewHdl_Impl(nullptr);
+}
+
+IMPL_LINK_NOARG(SvxLineTabPage, ChangeEdgeStyleHdl_Impl, weld::ComboBox&, void)
+{
+ ChangePreviewHdl_Impl( nullptr );
+}
+
+// fdo#43209
+IMPL_LINK_NOARG(SvxLineTabPage, ChangeCapStyleHdl_Impl, weld::ComboBox&, void)
+{
+ ChangePreviewHdl_Impl( nullptr );
+}
+
+IMPL_LINK_NOARG(SvxLineTabPage, ClickInvisibleHdl_Impl, weld::ComboBox&, void)
+{
+ ClickInvisibleHdl_Impl();
+}
+
+void SvxLineTabPage::ClickInvisibleHdl_Impl()
+{
+ if( m_xLbLineStyle->get_active() == 0 ) // invisible
+ {
+ if(!m_bSymbols)
+ m_xBoxColor->set_sensitive(false);
+
+ m_xBoxWidth->set_sensitive(false);
+
+ if( m_xFlLineEnds->get_sensitive() )
+ {
+ m_xBoxStart->set_sensitive(false);
+ m_xBoxArrowStyles->set_sensitive(false);
+ m_xGridEdgeCaps->set_sensitive(false);
+ }
+ }
+ else
+ {
+ // set cap style associated to the line style
+ sal_Int32 nPos = m_xLbLineStyle->get_active();
+ if( nPos > 1 && m_pDashList->Count() > static_cast<tools::Long>( nPos - 2 ) )
+ {
+ css::drawing::DashStyle eStyle =
+ m_pDashList->GetDash( nPos - 2 )->GetDash().GetDashStyle();
+ if ( eStyle == drawing::DashStyle_RECT || eStyle == drawing::DashStyle_RECTRELATIVE)
+ m_xLBCapStyle->set_active(0);
+ else
+ m_xLBCapStyle->set_active(1);
+ }
+
+ m_xBoxColor->set_sensitive(true);
+ m_xBoxWidth->set_sensitive(true);
+
+ if (m_xFlLineEnds->get_sensitive())
+ {
+ m_xBoxArrowStyles->set_sensitive(true);
+ m_xGridEdgeCaps->set_sensitive(true);
+ }
+ }
+ ChangePreviewHdl_Impl( nullptr );
+}
+
+IMPL_LINK_NOARG(SvxLineTabPage, ChangeEndClickHdl_Impl, weld::Toggleable&, void)
+{
+ if (m_xCbxSynchronize->get_active())
+ m_xTsbCenterStart->set_state(m_xTsbCenterEnd->get_state());
+
+ ChangePreviewHdl_Impl(nullptr);
+}
+
+IMPL_LINK_NOARG(SvxLineTabPage, ChangeEndListBoxHdl_Impl, weld::ComboBox&, void)
+{
+ if (m_xCbxSynchronize->get_active())
+ m_xLbStartStyle->set_active(m_xLbEndStyle->get_active());
+
+ ChangePreviewHdl_Impl(nullptr);
+}
+
+IMPL_LINK_NOARG(SvxLineTabPage, ChangeEndModifyHdl_Impl, weld::MetricSpinButton&, void)
+{
+ if (m_xCbxSynchronize->get_active())
+ m_xMtrStartWidth->set_value(m_xMtrEndWidth->get_value(FieldUnit::NONE), FieldUnit::NONE);
+
+ ChangePreviewHdl_Impl(nullptr);
+}
+
+IMPL_LINK_NOARG(SvxLineTabPage, ChangeTransparentHdl_Impl, weld::MetricSpinButton&, void)
+{
+ sal_uInt16 nVal = m_xMtrTransparent->get_value(FieldUnit::PERCENT);
+
+ m_rXLSet.Put(XLineTransparenceItem(nVal));
+
+ FillXLSet_Impl();
+
+ m_aCtlPreview.Invalidate();
+}
+
+void SvxLineTabPage::FillUserData()
+{
+ // Write the synched value to the INI file
+ OUString aStrUserData = OUString::boolean(m_xCbxSynchronize->get_active());
+ SetUserData( aStrUserData );
+}
+
+// #58425# Symbols on a list (e.g. StarChart)
+// Handler for the symbol selection's popup menu (NumMenueButton)
+// The following link originates from SvxNumOptionsTabPage
+IMPL_LINK_NOARG(SvxLineTabPage, MenuCreateHdl_Impl, weld::Toggleable&, void)
+{
+ ScopedVclPtrInstance< VirtualDevice > pVD;
+
+ // Initialize popup
+ if (!m_xGalleryMenu)
+ {
+ m_xGalleryMenu = m_xBuilder->weld_menu("gallerysubmenu");
+ weld::WaitObject aWait(GetFrameWeld());
+ // Get gallery entries
+ GalleryExplorer::FillObjList(GALLERY_THEME_BULLETS, m_aGrfNames);
+
+ sal_uInt32 i = 0;
+ for (auto const& grfName : m_aGrfNames)
+ {
+ const OUString *pUIName = &grfName;
+
+ // Convert URL encodings to UI characters (e.g. %20 for spaces)
+ OUString aPhysicalName;
+ if (osl::FileBase::getSystemPathFromFileURL(grfName, aPhysicalName)
+ == osl::FileBase::E_None)
+ {
+ pUIName = &aPhysicalName;
+ }
+
+ SvxBmpItemInfo* pInfo = new SvxBmpItemInfo;
+ pInfo->pBrushItem.reset(new SvxBrushItem(grfName, "", GPOS_AREA, SID_ATTR_BRUSH));
+ pInfo->sItemId = "gallery" + OUString::number(i);
+ m_aGalleryBrushItems.emplace_back(pInfo);
+ const Graphic* pGraphic = pInfo->pBrushItem->GetGraphic();
+
+ if(pGraphic)
+ {
+ BitmapEx aBitmap(pGraphic->GetBitmapEx());
+ Size aSize(aBitmap.GetSizePixel());
+ if(aSize.Width() > MAX_BMP_WIDTH || aSize.Height() > MAX_BMP_HEIGHT)
+ {
+ bool bWidth = aSize.Width() > aSize.Height();
+ double nScale = bWidth ?
+ double(MAX_BMP_WIDTH) / static_cast<double>(aSize.Width()):
+ double(MAX_BMP_HEIGHT) / static_cast<double>(aSize.Height());
+ aBitmap.Scale(nScale, nScale);
+
+ }
+ pVD->SetOutputSizePixel(aBitmap.GetSizePixel());
+ pVD->DrawBitmapEx(Point(), aBitmap);
+ m_xGalleryMenu->append(pInfo->sItemId, *pUIName, *pVD);
+ }
+ else
+ {
+ m_xGalleryMenu->append(pInfo->sItemId, *pUIName);
+ }
+ ++i;
+ }
+
+ if (m_aGrfNames.empty())
+ m_xSymbolMB->set_item_sensitive("gallery", false);
+ }
+
+ if (m_xSymbolsMenu || !m_pSymbolList)
+ return;
+
+ m_xSymbolsMenu = m_xBuilder->weld_menu("symbolssubmenu");
+ ScopedVclPtrInstance< VirtualDevice > pVDev;
+ pVDev->SetMapMode(MapMode(MapUnit::Map100thMM));
+ std::unique_ptr<SdrModel> pModel(
+ new SdrModel(nullptr, nullptr, true));
+ pModel->GetItemPool().FreezeIdRanges();
+ // Page
+ rtl::Reference<SdrPage> pPage = new SdrPage( *pModel, false );
+ pPage->SetSize(Size(1000,1000));
+ pModel->InsertPage( pPage.get(), 0 );
+ {
+ // 3D View
+ SdrView aView( *pModel, pVDev );
+ aView.hideMarkHandles();
+ aView.ShowSdrPage(pPage.get());
+
+ // Generate invisible square to give all symbols a
+ // bitmap size, which is independent from specific glyph
+ rtl::Reference<SdrObject> pInvisibleSquare=m_pSymbolList->GetObj(0);
+
+ // directly clone to target SdrModel
+ pInvisibleSquare = pInvisibleSquare->CloneSdrObject(*pModel);
+
+ pPage->NbcInsertObject(pInvisibleSquare.get());
+ pInvisibleSquare->SetMergedItem(XFillTransparenceItem(100));
+ pInvisibleSquare->SetMergedItem(XLineTransparenceItem(100));
+
+ for(size_t i=0; i < m_pSymbolList->GetObjCount(); ++i)
+ {
+ rtl::Reference<SdrObject> pObj=m_pSymbolList->GetObj(i);
+ assert(pObj);
+
+ // directly clone to target SdrModel
+ pObj = pObj->CloneSdrObject(*pModel);
+
+ m_aGrfNames.emplace_back("");
+ pPage->NbcInsertObject(pObj.get());
+ if(m_xSymbolAttr)
+ {
+ pObj->SetMergedItemSet(*m_xSymbolAttr);
+ }
+ else
+ {
+ pObj->SetMergedItemSet(m_rOutAttrs);
+ }
+ aView.MarkAll();
+ BitmapEx aBitmapEx(aView.GetMarkedObjBitmapEx());
+ GDIMetaFile aMeta(aView.GetMarkedObjMetaFile());
+ aView.UnmarkAll();
+ pPage->RemoveObject(1);
+ pObj.clear();
+
+ SvxBmpItemInfo* pInfo = new SvxBmpItemInfo;
+ pInfo->pBrushItem.reset(new SvxBrushItem(Graphic(aMeta), GPOS_AREA, SID_ATTR_BRUSH));
+ pInfo->sItemId = "symbol" + OUString::number(i);
+ m_aSymbolBrushItems.emplace_back(pInfo);
+
+ Size aSize(aBitmapEx.GetSizePixel());
+ if(aSize.Width() > MAX_BMP_WIDTH || aSize.Height() > MAX_BMP_HEIGHT)
+ {
+ bool bWidth = aSize.Width() > aSize.Height();
+ double nScale = bWidth ?
+ double(MAX_BMP_WIDTH) / static_cast<double>(aSize.Width()):
+ double(MAX_BMP_HEIGHT) / static_cast<double>(aSize.Height());
+ aBitmapEx.Scale(nScale, nScale);
+ }
+ pVD->SetOutputSizePixel(aBitmapEx.GetSizePixel());
+ pVD->DrawBitmapEx(Point(), aBitmapEx);
+ m_xSymbolsMenu->append(pInfo->sItemId, "", *pVD);
+ }
+ pPage->RemoveObject(0);
+ pInvisibleSquare.clear();
+
+ if (m_aGrfNames.empty())
+ m_xSymbolMB->set_item_sensitive("symbols", false);
+ }
+}
+
+// #58425# Symbols on a list (e.g. StarChart)
+// Handler for menu button
+IMPL_LINK(SvxLineTabPage, GraphicHdl_Impl, const OUString&, rIdent, void)
+{
+ const Graphic* pGraphic = nullptr;
+ Graphic aGraphic;
+ bool bResetSize = false;
+ bool bEnable = true;
+ tools::Long nPreviousSymbolType = m_nSymbolType;
+
+ OUString sNumber;
+ if (rIdent.startsWith("gallery", &sNumber))
+ {
+ SvxBmpItemInfo* pInfo = m_aGalleryBrushItems[sNumber.toUInt32()].get();
+ pGraphic = pInfo->pBrushItem->GetGraphic();
+ m_nSymbolType = SVX_SYMBOLTYPE_BRUSHITEM;
+ }
+ else if (rIdent.startsWith("symbol", &sNumber))
+ {
+ m_nSymbolType = sNumber.toUInt32();
+ SvxBmpItemInfo* pInfo = m_aSymbolBrushItems[m_nSymbolType].get();
+ pGraphic = pInfo->pBrushItem->GetGraphic();
+ }
+ else if (rIdent == "automatic")
+ {
+ pGraphic=&m_aAutoSymbolGraphic;
+ m_aAutoSymbolGraphic.SetPrefSize( Size(253,253) );
+ m_nSymbolType=SVX_SYMBOLTYPE_AUTO;
+ }
+ else if (rIdent == "none")
+ {
+ m_nSymbolType=SVX_SYMBOLTYPE_NONE;
+ pGraphic=nullptr;
+ bEnable = false;
+ }
+ else if (rIdent == "file")
+ {
+ SvxOpenGraphicDialog aGrfDlg(CuiResId(RID_CUISTR_EDIT_GRAPHIC), GetFrameWeld());
+ aGrfDlg.EnableLink(false);
+ aGrfDlg.AsLink(false);
+ if( !aGrfDlg.Execute() )
+ {
+ // Remember selected filters
+ if( !aGrfDlg.GetGraphic(aGraphic) )
+ {
+ m_nSymbolType=SVX_SYMBOLTYPE_BRUSHITEM;
+ pGraphic = &aGraphic;
+ bResetSize = true;
+ }
+ }
+ if( !pGraphic )
+ return;
+ }
+
+ if (pGraphic)
+ {
+ Size aSize = SvxNumberFormat::GetGraphicSizeMM100(pGraphic);
+ aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(m_ePoolUnit));
+ m_aSymbolGraphic=*pGraphic;
+ if( bResetSize )
+ {
+ m_aSymbolSize=aSize;
+ }
+ else if( nPreviousSymbolType == SVX_SYMBOLTYPE_BRUSHITEM )
+ { //#i31097# Data Point Symbol size changes when a different symbol is chosen(maoyg)
+ if( m_aSymbolSize.Width() != m_aSymbolSize.Height() )
+ {
+ aSize.setWidth( static_cast<tools::Long>( m_aSymbolSize.Width() + m_aSymbolSize.Height() )/2 );
+ aSize.setHeight( static_cast<tools::Long>( m_aSymbolSize.Width() + m_aSymbolSize.Height() )/2 );
+ m_aSymbolSize = aSize;
+ }
+ }
+ m_aCtlPreview.SetSymbol(&m_aSymbolGraphic,m_aSymbolSize);
+ }
+ else
+ {
+ m_aSymbolGraphic=Graphic();
+ m_aCtlPreview.SetSymbol(nullptr,m_aSymbolSize);
+ bEnable = false;
+ }
+ m_aSymbolLastSize=m_aSymbolSize;
+ SetMetricValue(*m_xSymbolWidthMF, m_aSymbolSize.Width(), m_ePoolUnit);
+ SetMetricValue(*m_xSymbolHeightMF, m_aSymbolSize.Height(), m_ePoolUnit);
+
+ m_xGridIconSize->set_sensitive(bEnable);
+ m_aCtlPreview.Invalidate();
+}
+
+IMPL_LINK( SvxLineTabPage, SizeHdl_Impl, weld::MetricSpinButton&, rField, void)
+{
+ m_bNewSize = true;
+ bool bWidth = &rField == m_xSymbolWidthMF.get();
+ m_bLastWidthModified = bWidth;
+ bool bRatio = m_xSymbolRatioCB->get_active();
+ tools::Long nWidthVal = static_cast<tools::Long>(m_xSymbolWidthMF->denormalize(m_xSymbolWidthMF->get_value(FieldUnit::MM_100TH)));
+ tools::Long nHeightVal= static_cast<tools::Long>(m_xSymbolHeightMF->denormalize(m_xSymbolHeightMF->get_value(FieldUnit::MM_100TH)));
+ nWidthVal = OutputDevice::LogicToLogic(nWidthVal,MapUnit::Map100thMM, m_ePoolUnit );
+ nHeightVal = OutputDevice::LogicToLogic(nHeightVal,MapUnit::Map100thMM, m_ePoolUnit);
+ m_aSymbolSize = Size(nWidthVal,nHeightVal);
+ double fSizeRatio = double(1);
+
+ if(bRatio)
+ {
+ if (m_aSymbolLastSize.Height() && m_aSymbolLastSize.Width())
+ fSizeRatio = static_cast<double>(m_aSymbolLastSize.Width()) / m_aSymbolLastSize.Height();
+ }
+
+ if (bWidth)
+ {
+ tools::Long nDelta = nWidthVal - m_aSymbolLastSize.Width();
+ m_aSymbolSize.setWidth( nWidthVal );
+ if (bRatio)
+ {
+ m_aSymbolSize.setHeight( m_aSymbolLastSize.Height() + static_cast<tools::Long>(static_cast<double>(nDelta) / fSizeRatio) );
+ m_aSymbolSize.setHeight( OutputDevice::LogicToLogic( m_aSymbolSize.Height(), m_ePoolUnit, MapUnit::Map100thMM ) );
+//TODO m_xSymbolHeightMF->SetUserValue(m_xSymbolHeightMF->normalize(m_aSymbolSize.Height()), FieldUnit::MM_100TH);
+ m_xSymbolHeightMF->set_value(m_xSymbolHeightMF->normalize(m_aSymbolSize.Height()), FieldUnit::MM_100TH);
+ }
+ }
+ else
+ {
+ tools::Long nDelta = nHeightVal - m_aSymbolLastSize.Height();
+ m_aSymbolSize.setHeight( nHeightVal );
+ if (bRatio)
+ {
+ m_aSymbolSize.setWidth( m_aSymbolLastSize.Width() + static_cast<tools::Long>(static_cast<double>(nDelta) * fSizeRatio) );
+ m_aSymbolSize.setWidth( OutputDevice::LogicToLogic( m_aSymbolSize.Width(), m_ePoolUnit, MapUnit::Map100thMM ) );
+//TODO m_xSymbolWidthMF->SetUserValue(m_xSymbolWidthMF->normalize(m_aSymbolSize.Width()), FieldUnit::MM_100TH);
+ m_xSymbolWidthMF->set_value(m_xSymbolWidthMF->normalize(m_aSymbolSize.Width()), FieldUnit::MM_100TH);
+ }
+ }
+ m_aCtlPreview.ResizeSymbol(m_aSymbolSize);
+ m_aSymbolLastSize=m_aSymbolSize;
+}
+
+IMPL_LINK(SvxLineTabPage, RatioHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ if (rBox.get_active())
+ {
+ if (m_bLastWidthModified)
+ SizeHdl_Impl(*m_xSymbolWidthMF);
+ else
+ SizeHdl_Impl(*m_xSymbolHeightMF);
+ }
+}
+
+void SvxLineTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SvxDashListItem* pDashListItem = aSet.GetItem<SvxDashListItem>(SID_DASH_LIST, false);
+ const SvxLineEndListItem* pLineEndListItem = aSet.GetItem<SvxLineEndListItem>(SID_LINEEND_LIST, false);
+ const SfxUInt16Item* pPageTypeItem = aSet.GetItem<SfxUInt16Item>(SID_PAGE_TYPE, false);
+ const SfxUInt16Item* pDlgTypeItem = aSet.GetItem<SfxUInt16Item>(SID_DLG_TYPE, false);
+ const OfaPtrItem* pSdrObjListItem = aSet.GetItem<OfaPtrItem>(SID_OBJECT_LIST, false);
+ const SfxTabDialogItem* pSymbolAttrItem = aSet.GetItem<SfxTabDialogItem>(SID_ATTR_SET, false);
+ const SvxGraphicItem* pGraphicItem = aSet.GetItem<SvxGraphicItem>(SID_GRAPHIC, false);
+
+ if (pDashListItem)
+ SetDashList(pDashListItem->GetDashList());
+ if (pLineEndListItem)
+ SetLineEndList(pLineEndListItem->GetLineEndList());
+ if (pPageTypeItem)
+ SetPageType(static_cast<PageType>(pPageTypeItem->GetValue()));
+ if (pDlgTypeItem)
+ SetDlgType(pDlgTypeItem->GetValue());
+ Construct();
+
+ if(pSdrObjListItem) //symbols
+ {
+ ShowSymbolControls(true);
+ m_pSymbolList = static_cast<SdrObjList*>(pSdrObjListItem->GetValue());
+ if (pSymbolAttrItem)
+ m_xSymbolAttr.reset(new SfxItemSet(pSymbolAttrItem->GetItemSet()));
+ if(pGraphicItem)
+ m_aAutoSymbolGraphic = pGraphicItem->GetGraphic();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tplnedef.cxx b/cui/source/tabpages/tplnedef.cxx
new file mode 100644
index 0000000000..66fea1aba4
--- /dev/null
+++ b/cui/source/tabpages/tplnedef.cxx
@@ -0,0 +1,840 @@
+/* -*- 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 <tools/urlobj.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <unotools/pathoptions.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+
+#include <strings.hrc>
+
+#include <svx/xlineit0.hxx>
+#include <svx/xlnwtit.hxx>
+#include <svx/xlndsit.hxx>
+#include <svx/xlnclit.hxx>
+#include <svx/xtable.hxx>
+
+#include <svx/dlgctrl.hxx>
+#include <cuitabline.hxx>
+#include <defdlgname.hxx>
+#include <svx/svxdlg.hxx>
+#include <dialmgr.hxx>
+#include <svx/dlgutil.hxx>
+#include <svx/dialmgr.hxx>
+#include <svx/strings.hrc>
+#include <svx/svxids.hrc>
+#include <cuitabarea.hxx>
+#include <svtools/unitconv.hxx>
+#include <osl/diagnose.h>
+
+#define XOUT_WIDTH 150
+
+using namespace com::sun::star;
+
+
+SvxLineDefTabPage::SvxLineDefTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/linestyletabpage.ui", "LineStylePage", &rInAttrs)
+ , rOutAttrs(rInAttrs)
+ , aXLineAttr(rInAttrs.GetPool())
+ , rXLSet(aXLineAttr.GetItemSet())
+ , pnDashListState(nullptr)
+ , pPageType(nullptr)
+ , nDlgType(0)
+ , pPosDashLb(nullptr)
+ , m_xLbLineStyles(new SvxLineLB(m_xBuilder->weld_combo_box("LB_LINESTYLES")))
+ , m_xLbType1(m_xBuilder->weld_combo_box("LB_TYPE_1"))
+ , m_xLbType2(m_xBuilder->weld_combo_box("LB_TYPE_2"))
+ , m_xNumFldNumber1(m_xBuilder->weld_spin_button("NUM_FLD_1"))
+ , m_xNumFldNumber2(m_xBuilder->weld_spin_button("NUM_FLD_2"))
+ , m_xMtrLength1(m_xBuilder->weld_metric_spin_button("MTR_FLD_LENGTH_1", FieldUnit::CM))
+ , m_xMtrLength2(m_xBuilder->weld_metric_spin_button("MTR_FLD_LENGTH_2", FieldUnit::CM))
+ , m_xMtrDistance(m_xBuilder->weld_metric_spin_button("MTR_FLD_DISTANCE", FieldUnit::CM))
+ , m_xCbxSynchronize(m_xBuilder->weld_check_button("CBX_SYNCHRONIZE"))
+ , m_xBtnAdd(m_xBuilder->weld_button("BTN_ADD"))
+ , m_xBtnModify(m_xBuilder->weld_button("BTN_MODIFY"))
+ , m_xBtnDelete(m_xBuilder->weld_button("BTN_DELETE"))
+ , m_xBtnLoad(m_xBuilder->weld_button("BTN_LOAD"))
+ , m_xBtnSave(m_xBuilder->weld_button("BTN_SAVE"))
+ , m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, "CTL_PREVIEW", m_aCtlPreview))
+{
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ // adjust metric
+ eFUnit = GetModuleFieldUnit( rInAttrs );
+
+ switch ( eFUnit )
+ {
+ case FieldUnit::M:
+ case FieldUnit::KM:
+ eFUnit = FieldUnit::MM;
+ break;
+ default: ; //prevent warning
+ }
+ SetFieldUnit(*m_xMtrDistance, eFUnit);
+ SetFieldUnit(*m_xMtrLength1, eFUnit);
+ SetFieldUnit(*m_xMtrLength2, eFUnit);
+
+ // determine PoolUnit
+ SfxItemPool* pPool = rOutAttrs.GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ ePoolUnit = pPool->GetMetric( SID_ATTR_LINE_WIDTH );
+
+ rXLSet.Put( XLineStyleItem(drawing::LineStyle_DASH) );
+ rXLSet.Put( XLineWidthItem(XOUT_WIDTH) );
+ rXLSet.Put( XLineDashItem( OUString(), XDash( css::drawing::DashStyle_RECT, 3, 7, 2, 40, 15 ) ) );
+ rXLSet.Put( XLineColorItem(OUString(), COL_BLACK) );
+
+ // #i34740#
+ m_aCtlPreview.SetLineAttributes(aXLineAttr.GetItemSet());
+
+ m_xBtnAdd->connect_clicked(LINK(this, SvxLineDefTabPage, ClickAddHdl_Impl));
+ m_xBtnModify->connect_clicked(LINK(this, SvxLineDefTabPage, ClickModifyHdl_Impl));
+ m_xBtnDelete->connect_clicked(LINK(this, SvxLineDefTabPage, ClickDeleteHdl_Impl));
+ m_xBtnLoad->connect_clicked(LINK(this, SvxLineDefTabPage, ClickLoadHdl_Impl));
+ m_xBtnSave->connect_clicked(LINK(this, SvxLineDefTabPage, ClickSaveHdl_Impl));
+
+ m_xNumFldNumber1->connect_value_changed(LINK(this, SvxLineDefTabPage, ChangeNumber1Hdl_Impl));
+ m_xNumFldNumber2->connect_value_changed(LINK(this, SvxLineDefTabPage, ChangeNumber2Hdl_Impl));
+ m_xLbLineStyles->connect_changed(LINK(this, SvxLineDefTabPage, SelectLinestyleListBoxHdl_Impl));
+
+ // #i122042# switch off default adding of 'none' and 'solid' entries
+ // for this ListBox; we want to select only editable/dashed styles
+ m_xLbLineStyles->setAddStandardFields(false);
+
+ // absolute (in mm) or relative (in %)
+ m_xCbxSynchronize->connect_toggled(LINK(this, SvxLineDefTabPage, ChangeMetricHdl_Impl));
+
+ // preview must be updated when there's something changed
+ Link<weld::ComboBox&, void> aLink = LINK(this, SvxLineDefTabPage, SelectTypeListBoxHdl_Impl);
+ m_xLbType1->connect_changed(aLink);
+ m_xLbType2->connect_changed(aLink);
+ Link<weld::MetricSpinButton&,void> aLink2 = LINK( this, SvxLineDefTabPage, ChangePreviewHdl_Impl );
+ m_xMtrLength1->connect_value_changed(aLink2);
+ m_xMtrLength2->connect_value_changed(aLink2);
+ m_xMtrDistance->connect_value_changed(aLink2);
+
+ pDashList = nullptr;
+}
+
+SvxLineDefTabPage::~SvxLineDefTabPage()
+{
+ m_xCtlPreview.reset();
+ m_xLbLineStyles.reset();
+}
+
+void SvxLineDefTabPage::Construct()
+{
+ // Line style fill; do *not* add default fields here
+ m_xLbLineStyles->Fill( pDashList );
+}
+
+void SvxLineDefTabPage::ActivatePage( const SfxItemSet& )
+{
+ if( nDlgType != 0 ) // area dialog
+ return;
+
+ // ActivatePage() is called before the dialog receives PageCreated() !!!
+ if( !pDashList.is() )
+ return;
+
+ if (*pPageType == PageType::Gradient &&
+ *pPosDashLb != -1)
+ {
+ m_xLbLineStyles->set_active(*pPosDashLb);
+ }
+ // so that a possibly existing line style is discarded
+ SelectLinestyleHdl_Impl( nullptr );
+
+ // determining (and possibly cutting) the name
+ // and displaying it in the GroupBox
+// OUString aString( CuiResId( RID_CUISTR_TABLE ) );
+// aString += ": ";
+ INetURLObject aURL( pDashList->GetPath() );
+
+ aURL.Append( pDashList->GetName() );
+ DBG_ASSERT( aURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
+
+ *pPageType = PageType::Area; // 2
+ *pPosDashLb = -1;
+}
+
+
+DeactivateRC SvxLineDefTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ CheckChanges_Impl();
+
+ if( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+void SvxLineDefTabPage::CheckChanges_Impl()
+{
+ // is here used to NOT lose changes
+ //css::drawing::DashStyle eXDS;
+
+ if( m_xNumFldNumber1->get_value_changed_from_saved() ||
+ m_xMtrLength1->get_value_changed_from_saved() ||
+ m_xLbType1->get_value_changed_from_saved() ||
+ m_xNumFldNumber2->get_value_changed_from_saved() ||
+ m_xMtrLength2->get_value_changed_from_saved() ||
+ m_xLbType2->get_value_changed_from_saved() ||
+ m_xMtrDistance->get_value_changed_from_saved() )
+ {
+ std::unique_ptr<weld::MessageDialog> xMessDlg(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Warning, VclButtonsType::Cancel,
+ CuiResId(RID_CUISTR_ASK_CHANGE_LINESTYLE)));
+ xMessDlg->set_title(SvxResId(RID_SVXSTR_LINESTYLE));
+ xMessDlg->add_button(CuiResId(RID_CUISTR_CHANGE), RET_BTN_1);
+ xMessDlg->add_button(CuiResId(RID_CUISTR_ADD), RET_BTN_2);
+
+ short nRet = xMessDlg->run();
+
+ switch( nRet )
+ {
+ case RET_BTN_1:
+ {
+ ClickModifyHdl_Impl(*m_xBtnModify);
+ }
+ break;
+
+ case RET_BTN_2:
+ {
+ ClickAddHdl_Impl(*m_xBtnAdd);
+ }
+ break;
+
+ case RET_CANCEL:
+ break;
+ }
+ }
+
+ int nPos = m_xLbLineStyles->get_active();
+ if (nPos != -1)
+ {
+ *pPosDashLb = nPos;
+ }
+}
+
+
+bool SvxLineDefTabPage::FillItemSet( SfxItemSet* rAttrs )
+{
+ if( nDlgType == 0 ) // line dialog
+ {
+ if( *pPageType == PageType::Hatch )
+ {
+ FillDash_Impl();
+
+ OUString aString(m_xLbLineStyles->get_active_text());
+ rAttrs->Put( XLineStyleItem( drawing::LineStyle_DASH ) );
+ rAttrs->Put( XLineDashItem( aString, aDash ) );
+ }
+ }
+ return true;
+}
+
+
+void SvxLineDefTabPage::Reset( const SfxItemSet* rAttrs )
+{
+ if( rAttrs->GetItemState( GetWhich( XATTR_LINESTYLE ) ) != SfxItemState::DONTCARE )
+ {
+ drawing::LineStyle eXLS = rAttrs->Get( GetWhich( XATTR_LINESTYLE ) ).GetValue();
+
+ switch( eXLS )
+ {
+ case drawing::LineStyle_NONE:
+ case drawing::LineStyle_SOLID:
+ m_xLbLineStyles->set_active(0);
+ break;
+ case drawing::LineStyle_DASH:
+ {
+ const XLineDashItem& rDashItem = rAttrs->Get( XATTR_LINEDASH );
+ aDash = rDashItem.GetDashValue();
+
+ m_xLbLineStyles->set_active(-1);
+ m_xLbLineStyles->set_active_text(rDashItem.GetName());
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ SelectLinestyleHdl_Impl( nullptr );
+
+ // determine button state
+ if( pDashList->Count() )
+ {
+ m_xBtnModify->set_sensitive(true);
+ m_xBtnDelete->set_sensitive(true);
+ m_xBtnSave->set_sensitive(true);
+ }
+ else
+ {
+ m_xBtnModify->set_sensitive(false);
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnSave->set_sensitive(false);
+ }
+}
+
+std::unique_ptr<SfxTabPage> SvxLineDefTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rOutAttrs )
+{
+ return std::make_unique<SvxLineDefTabPage>(pPage, pController, *rOutAttrs);
+}
+
+IMPL_LINK(SvxLineDefTabPage, SelectLinestyleListBoxHdl_Impl, weld::ComboBox&, rListBox, void)
+{
+ SelectLinestyleHdl_Impl(&rListBox);
+}
+
+void SvxLineDefTabPage::SelectLinestyleHdl_Impl(const weld::ComboBox* p)
+{
+ if(!pDashList->Count())
+ return;
+
+ int nTmp = m_xLbLineStyles->get_active();
+ if (nTmp == -1)
+ {
+ OSL_ENSURE(false, "OOps, non-existent LineDash selected (!)");
+ nTmp = 1;
+ }
+
+ aDash = pDashList->GetDash( nTmp )->GetDash();
+
+ FillDialog_Impl();
+
+ rXLSet.Put( XLineDashItem( OUString(), aDash ) );
+
+ // #i34740#
+ m_aCtlPreview.SetLineAttributes(aXLineAttr.GetItemSet());
+ m_aCtlPreview.Invalidate();
+
+ // Is not set before, in order to take the new style
+ // only if there was an entry selected in the ListBox.
+ // If it was called via Reset(), then p is == NULL
+ if( p )
+ *pPageType = PageType::Hatch;
+}
+
+IMPL_LINK_NOARG(SvxLineDefTabPage, ChangePreviewHdl_Impl, weld::MetricSpinButton&, void)
+{
+ FillDash_Impl();
+ m_aCtlPreview.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxLineDefTabPage, ChangeNumber1Hdl_Impl, weld::SpinButton&, void)
+{
+ if (m_xNumFldNumber1->get_value() == 0)
+ {
+ m_xNumFldNumber2->set_min(1);
+ }
+ else
+ {
+ m_xNumFldNumber2->set_min(0);
+ }
+
+ ChangePreviewHdl_Impl(*m_xMtrLength1);
+}
+
+IMPL_LINK_NOARG(SvxLineDefTabPage, ChangeNumber2Hdl_Impl, weld::SpinButton&, void)
+{
+ if (m_xNumFldNumber2->get_value() == 0)
+ {
+ m_xNumFldNumber1->set_min(1);
+ }
+ else
+ {
+ m_xNumFldNumber1->set_min(0);
+ }
+
+ ChangePreviewHdl_Impl(*m_xMtrLength1);
+}
+
+IMPL_LINK( SvxLineDefTabPage, ChangeMetricHdl_Impl, weld::Toggleable&, r, void)
+{
+ ChangeMetricHdl_Impl(&r);
+}
+
+void SvxLineDefTabPage::ChangeMetricHdl_Impl(const weld::Toggleable* p)
+{
+ if( !m_xCbxSynchronize->get_active() && m_xMtrLength1->get_unit() != eFUnit )
+ {
+ tools::Long nTmp1, nTmp2, nTmp3;
+
+ // was changed with Control
+ if( p )
+ {
+ nTmp1 = GetCoreValue( *m_xMtrLength1, ePoolUnit ) * XOUT_WIDTH / 100;
+ nTmp2 = GetCoreValue( *m_xMtrLength2, ePoolUnit ) * XOUT_WIDTH / 100;
+ nTmp3 = GetCoreValue( *m_xMtrDistance, ePoolUnit ) * XOUT_WIDTH / 100;
+ }
+ else
+ {
+ nTmp1 = GetCoreValue( *m_xMtrLength1, ePoolUnit );
+ nTmp2 = GetCoreValue( *m_xMtrLength2, ePoolUnit );
+ nTmp3 = GetCoreValue( *m_xMtrDistance, ePoolUnit );
+ }
+ m_xMtrLength1->set_digits(2);
+ m_xMtrLength2->set_digits(2);
+ m_xMtrDistance->set_digits(2);
+
+ // adjust metric
+ m_xMtrLength1->set_unit(eFUnit);
+ m_xMtrLength2->set_unit(eFUnit);
+ m_xMtrDistance->set_unit(eFUnit);
+
+ // tdf#126736 max 5cm
+ m_xMtrLength1->set_range(0, 500, FieldUnit::CM);
+ m_xMtrLength2->set_range(0, 500, FieldUnit::CM);
+ m_xMtrDistance->set_range(0, 500, FieldUnit::CM);
+
+ SetMetricValue( *m_xMtrLength1, nTmp1, ePoolUnit );
+ SetMetricValue( *m_xMtrLength2, nTmp2, ePoolUnit );
+ SetMetricValue( *m_xMtrDistance, nTmp3, ePoolUnit );
+ }
+ else if( m_xCbxSynchronize->get_active() && m_xMtrLength1->get_unit() != FieldUnit::PERCENT )
+ {
+ tools::Long nTmp1, nTmp2, nTmp3;
+
+ // was changed with Control
+ if( p )
+ {
+ nTmp1 = GetCoreValue( *m_xMtrLength1, ePoolUnit ) * 100 / XOUT_WIDTH;
+ nTmp2 = GetCoreValue( *m_xMtrLength2, ePoolUnit ) * 100 / XOUT_WIDTH;
+ nTmp3 = GetCoreValue( *m_xMtrDistance, ePoolUnit ) * 100 / XOUT_WIDTH;
+ }
+ else
+ {
+ nTmp1 = GetCoreValue( *m_xMtrLength1, ePoolUnit );
+ nTmp2 = GetCoreValue( *m_xMtrLength2, ePoolUnit );
+ nTmp3 = GetCoreValue( *m_xMtrDistance, ePoolUnit );
+ }
+
+ m_xMtrLength1->set_digits(0);
+ m_xMtrLength2->set_digits(0);
+ m_xMtrDistance->set_digits(0);
+
+ m_xMtrLength1->set_unit(FieldUnit::PERCENT);
+ m_xMtrLength2->set_unit(FieldUnit::PERCENT);
+ m_xMtrDistance->set_unit(FieldUnit::PERCENT);
+
+ // tdf#126736 800%
+ m_xMtrLength1->set_range(0, 800, FieldUnit::PERCENT);
+ m_xMtrLength2->set_range(0, 800, FieldUnit::PERCENT);
+ m_xMtrDistance->set_range(0, 800, FieldUnit::PERCENT);
+
+ m_xMtrLength1->set_value(nTmp1, FieldUnit::PERCENT);
+ m_xMtrLength2->set_value(nTmp2, FieldUnit::PERCENT);
+ m_xMtrDistance->set_value(nTmp3, FieldUnit::PERCENT);
+ }
+ SelectTypeHdl_Impl( nullptr );
+}
+
+IMPL_LINK( SvxLineDefTabPage, SelectTypeListBoxHdl_Impl, weld::ComboBox&, rListBox, void )
+{
+ SelectTypeHdl_Impl(&rListBox);
+}
+
+void SvxLineDefTabPage::SelectTypeHdl_Impl(const weld::ComboBox* p)
+{
+ if (p == m_xLbType1.get() || !p)
+ {
+ if (m_xLbType1->get_active() == 0)
+ {
+ m_xMtrLength1->set_sensitive(false);
+ m_xMtrLength1->set_text("");
+ }
+ else if (!m_xMtrLength1->get_sensitive())
+ {
+ m_xMtrLength1->set_sensitive(true);
+ m_xMtrLength1->reformat();
+ }
+ }
+
+ if (p == m_xLbType2.get() || !p)
+ {
+ if (m_xLbType2->get_active() == 0)
+ {
+ m_xMtrLength2->set_sensitive(false);
+ m_xMtrLength2->set_text("");
+ }
+ else if (!m_xMtrLength2->get_sensitive())
+ {
+ m_xMtrLength2->set_sensitive(true);
+ m_xMtrLength2->reformat();
+ }
+ }
+ ChangePreviewHdl_Impl(*m_xMtrLength1);
+}
+
+IMPL_LINK_NOARG(SvxLineDefTabPage, ClickAddHdl_Impl, weld::Button&, void)
+{
+ OUString aNewName(SvxResId(RID_SVXSTR_LINESTYLE));
+ OUString aDesc(CuiResId(RID_CUISTR_DESC_LINESTYLE));
+ OUString aName;
+
+ tools::Long nCount = pDashList->Count();
+ tools::Long j = 1;
+ bool bDifferent = false;
+
+ while ( !bDifferent )
+ {
+ aName = aNewName + " " + OUString::number( j++ );
+ bDifferent = true;
+
+ for ( tools::Long i = 0; i < nCount && bDifferent; i++ )
+ if ( aName == pDashList->GetDash( i )->GetName() )
+ bDifferent = false;
+ }
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+ bool bLoop = true;
+
+ while ( bLoop && pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+ bDifferent = true;
+
+ for( tools::Long i = 0; i < nCount && bDifferent; i++ )
+ {
+ if( aName == pDashList->GetDash( i )->GetName() )
+ bDifferent = false;
+ }
+
+ if( bDifferent )
+ {
+ bLoop = false;
+ FillDash_Impl();
+
+ tools::Long nDashCount = pDashList->Count();
+ pDashList->Insert( std::make_unique<XDashEntry>(aDash, aName), nDashCount );
+ m_xLbLineStyles->Append( *pDashList->GetDash(nDashCount), pDashList->GetUiBitmap(nDashCount) );
+
+ m_xLbLineStyles->set_active(m_xLbLineStyles->get_count() - 1);
+
+ *pnDashListState |= ChangeType::MODIFIED;
+
+ *pPageType = PageType::Hatch;
+
+ // save values for changes recognition (-> method)
+ m_xNumFldNumber1->save_value();
+ m_xMtrLength1->save_value();
+ m_xLbType1->save_value();
+ m_xNumFldNumber2->save_value();
+ m_xMtrLength2->save_value();
+ m_xLbType2->save_value();
+ m_xMtrDistance->save_value();
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ xBox->run();
+ }
+ }
+ pDlg.disposeAndClear();
+
+ // determine button state
+ if ( pDashList->Count() )
+ {
+ m_xBtnModify->set_sensitive(true);
+ m_xBtnDelete->set_sensitive(true);
+ m_xBtnSave->set_sensitive(true);
+ }
+}
+
+IMPL_LINK_NOARG(SvxLineDefTabPage, ClickModifyHdl_Impl, weld::Button&, void)
+{
+ int nPos = m_xLbLineStyles->get_active();
+ if (nPos == -1)
+ return;
+
+ OUString aDesc(CuiResId(RID_CUISTR_DESC_LINESTYLE));
+ OUString aName( pDashList->GetDash( nPos )->GetName() );
+ OUString aOldName = aName;
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+
+ tools::Long nCount = pDashList->Count();
+ bool bLoop = true;
+
+ while ( bLoop && pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+ bool bDifferent = true;
+
+ for( tools::Long i = 0; i < nCount && bDifferent; i++ )
+ {
+ if( aName == pDashList->GetDash( i )->GetName() &&
+ aName != aOldName )
+ bDifferent = false;
+ }
+
+ if ( bDifferent )
+ {
+ bLoop = false;
+ FillDash_Impl();
+
+ pDashList->Replace(std::make_unique<XDashEntry>(aDash, aName), nPos);
+ m_xLbLineStyles->Modify(*pDashList->GetDash(nPos), nPos, pDashList->GetUiBitmap(nPos));
+
+ m_xLbLineStyles->set_active(nPos);
+
+ *pnDashListState |= ChangeType::MODIFIED;
+
+ *pPageType = PageType::Hatch;
+
+ // save values for changes recognition (-> method)
+ m_xNumFldNumber1->save_value();
+ m_xMtrLength1->save_value();
+ m_xLbType1->save_value();
+ m_xNumFldNumber2->save_value();
+ m_xMtrLength2->save_value();
+ m_xLbType2->save_value();
+ m_xMtrDistance->save_value();
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ xBox->run();
+ }
+ }
+}
+
+IMPL_LINK_NOARG(SvxLineDefTabPage, ClickDeleteHdl_Impl, weld::Button&, void)
+{
+ int nPos = m_xLbLineStyles->get_active();
+ if (nPos != -1)
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querydeletelinestyledialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("AskDelLineStyleDialog"));
+ if (xQueryBox->run() == RET_YES)
+ {
+ pDashList->Remove(nPos);
+ m_xLbLineStyles->remove(nPos);
+ m_xLbLineStyles->set_active(0);
+
+ SelectLinestyleHdl_Impl( nullptr );
+ *pPageType = PageType::Area; // style should not be taken
+
+ *pnDashListState |= ChangeType::MODIFIED;
+
+ ChangePreviewHdl_Impl( *m_xMtrLength1 );
+ }
+ }
+
+ // determine button state
+ if ( !pDashList->Count() )
+ {
+ m_xBtnModify->set_sensitive(false);
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnSave->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(SvxLineDefTabPage, ClickLoadHdl_Impl, weld::Button&, void)
+{
+ sal_uInt16 nReturn = RET_YES;
+
+ if ( *pnDashListState & ChangeType::MODIFIED )
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querysavelistdialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("AskSaveList"));
+
+ nReturn = xBox->run();
+
+ if ( nReturn == RET_YES )
+ pDashList->Save();
+ }
+
+ if ( nReturn != RET_CANCEL )
+ {
+ ::sfx2::FileDialogHelper aDlg(css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE,
+ FileDialogFlags::NONE, GetFrameWeld());
+ OUString aStrFilterType( "*.sod" );
+ aDlg.AddFilter( aStrFilterType, aStrFilterType );
+ OUString aPalettePath(SvtPathOptions().GetPalettePath());
+ OUString aLastDir;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ aLastDir = aPalettePath.getToken(0, ';', nIndex);
+ }
+ while (nIndex >= 0);
+
+ INetURLObject aFile(aLastDir);
+ aDlg.SetDisplayDirectory( aFile.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+
+ if( aDlg.Execute() == ERRCODE_NONE )
+ {
+ INetURLObject aURL( aDlg.GetPath() );
+ INetURLObject aPathURL( aURL );
+
+ aPathURL.removeSegment();
+ aPathURL.removeFinalSlash();
+
+ XDashListRef pDshLst = XPropertyList::AsDashList(XPropertyList::CreatePropertyList( XPropertyListType::Dash, aPathURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), "" ));
+ pDshLst->SetName( aURL.getName() );
+
+ if( pDshLst->Load() )
+ {
+ pDashList = pDshLst;
+ static_cast<SvxLineTabDialog*>(GetDialogController())->SetNewDashList( pDashList );
+
+ m_xLbLineStyles->clear();
+ m_xLbLineStyles->Fill( pDashList );
+ Reset( &rOutAttrs );
+
+ pDashList->SetName( aURL.getName() );
+
+ *pnDashListState |= ChangeType::CHANGED;
+ *pnDashListState &= ~ChangeType::MODIFIED;
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querynoloadedfiledialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("NoLoadedFileDialog"));
+ xBox->run();
+ }
+ }
+ }
+
+ // determine button state
+ if ( pDashList->Count() )
+ {
+ m_xBtnModify->set_sensitive(true);
+ m_xBtnDelete->set_sensitive(true);
+ m_xBtnSave->set_sensitive(true);
+ }
+ else
+ {
+ m_xBtnModify->set_sensitive(false);
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnSave->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(SvxLineDefTabPage, ClickSaveHdl_Impl, weld::Button&, void)
+{
+ ::sfx2::FileDialogHelper aDlg(css::ui::dialogs::TemplateDescription::FILESAVE_SIMPLE, FileDialogFlags::NONE, GetFrameWeld());
+ OUString aStrFilterType( "*.sod" );
+ aDlg.AddFilter( aStrFilterType, aStrFilterType );
+
+ OUString aPalettePath(SvtPathOptions().GetPalettePath());
+ OUString aLastDir;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ aLastDir = aPalettePath.getToken(0, ';', nIndex);
+ }
+ while (nIndex >= 0);
+
+ INetURLObject aFile(aLastDir);
+ DBG_ASSERT( aFile.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
+
+ if( !pDashList->GetName().isEmpty() )
+ {
+ aFile.Append( pDashList->GetName() );
+
+ if( aFile.getExtension().isEmpty() )
+ aFile.SetExtension( u"sod" );
+ }
+
+ aDlg.SetDisplayDirectory( aFile.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+ if ( aDlg.Execute() != ERRCODE_NONE )
+ return;
+
+ INetURLObject aURL( aDlg.GetPath() );
+ INetURLObject aPathURL( aURL );
+
+ aPathURL.removeSegment();
+ aPathURL.removeFinalSlash();
+
+ pDashList->SetName( aURL.getName() );
+ pDashList->SetPath( aPathURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+
+ if( pDashList->Save() )
+ {
+ *pnDashListState &= ~ChangeType::MODIFIED;
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querynosavefiledialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("NoSaveFileDialog"));
+ xBox->run();
+ }
+}
+
+void SvxLineDefTabPage::FillDash_Impl()
+{
+ css::drawing::DashStyle eXDS;
+
+ if (m_xCbxSynchronize->get_active())
+ eXDS = css::drawing::DashStyle_RECTRELATIVE;
+ else
+ eXDS = css::drawing::DashStyle_RECT;
+
+ aDash.SetDashStyle( eXDS );
+ aDash.SetDots( static_cast<sal_uInt8>(m_xNumFldNumber1->get_value()) );
+ aDash.SetDotLen( m_xLbType1->get_active() == 0 ? 0 : GetCoreValue( *m_xMtrLength1, ePoolUnit ) );
+ aDash.SetDashes( static_cast<sal_uInt8>(m_xNumFldNumber2->get_value()) );
+ aDash.SetDashLen( m_xLbType2->get_active() == 0 ? 0 : GetCoreValue( *m_xMtrLength2, ePoolUnit ) );
+ aDash.SetDistance( GetCoreValue( *m_xMtrDistance, ePoolUnit ) );
+
+ rXLSet.Put( XLineDashItem( OUString(), aDash ) );
+
+ // #i34740#
+ m_aCtlPreview.SetLineAttributes(aXLineAttr.GetItemSet());
+}
+
+void SvxLineDefTabPage::FillDialog_Impl()
+{
+ css::drawing::DashStyle eXDS = aDash.GetDashStyle(); // css::drawing::DashStyle_RECT, css::drawing::DashStyle_ROUND
+ if( eXDS == css::drawing::DashStyle_RECTRELATIVE )
+ m_xCbxSynchronize->set_active(true);
+ else
+ m_xCbxSynchronize->set_active(false);
+
+ m_xNumFldNumber1->set_value(aDash.GetDots());
+ SetMetricValue( *m_xMtrLength1, aDash.GetDotLen(), ePoolUnit );
+ m_xLbType1->set_active(aDash.GetDotLen() == 0 ? 0 : 1);
+ m_xNumFldNumber2->set_value(aDash.GetDashes());
+ SetMetricValue( *m_xMtrLength2, aDash.GetDashLen(), ePoolUnit );
+ m_xLbType2->set_active(aDash.GetDashLen() == 0 ? 0 : 1);
+ SetMetricValue( *m_xMtrDistance, aDash.GetDistance(), ePoolUnit );
+
+ ChangeMetricHdl_Impl(nullptr);
+
+ // save values for changes recognition (-> method)
+ m_xNumFldNumber1->save_value();
+ m_xMtrLength1->save_value();
+ m_xLbType1->save_value();
+ m_xNumFldNumber2->save_value();
+ m_xMtrLength2->save_value();
+ m_xLbType2->save_value();
+ m_xMtrDistance->save_value();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tplneend.cxx b/cui/source/tabpages/tplneend.cxx
new file mode 100644
index 0000000000..fe7bc13158
--- /dev/null
+++ b/cui/source/tabpages/tplneend.cxx
@@ -0,0 +1,610 @@
+/* -*- 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 <tools/urlobj.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <unotools/pathoptions.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+
+#include <strings.hrc>
+#include <svx/dialmgr.hxx>
+#include <svx/dlgctrl.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdopath.hxx>
+#include <svx/xtable.hxx>
+#include <svx/xlineit0.hxx>
+#include <svx/xlnwtit.hxx>
+#include <svx/xlnclit.hxx>
+#include <svx/xlnstwit.hxx>
+#include <svx/xlnedwit.hxx>
+#include <svx/xlnstit.hxx>
+#include <svx/xlnedit.hxx>
+#include <cuitabline.hxx>
+#include <cuitabarea.hxx>
+#include <svx/svxdlg.hxx>
+#include <dialmgr.hxx>
+#include <basegfx/range/b2drange.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <svx/strings.hrc>
+#include <osl/diagnose.h>
+
+#define XOUT_WIDTH 150
+
+SvxLineEndDefTabPage::SvxLineEndDefTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/lineendstabpage.ui", "LineEndPage", &rInAttrs)
+ , rOutAttrs(rInAttrs)
+ , pPolyObj(nullptr)
+ , aXLineAttr(rInAttrs.GetPool())
+ , rXLSet(aXLineAttr.GetItemSet())
+ , pnLineEndListState(nullptr)
+ , pPageType(nullptr)
+ , nDlgType(0)
+ , pPosLineEndLb(nullptr)
+ , m_xEdtName(m_xBuilder->weld_entry("EDT_NAME"))
+ , m_xLbLineEnds(new SvxLineEndLB(m_xBuilder->weld_combo_box("LB_LINEENDS")))
+ , m_xBtnAdd(m_xBuilder->weld_button("BTN_ADD"))
+ , m_xBtnModify(m_xBuilder->weld_button("BTN_MODIFY"))
+ , m_xBtnDelete(m_xBuilder->weld_button("BTN_DELETE"))
+ , m_xBtnLoad(m_xBuilder->weld_button("BTN_LOAD"))
+ , m_xBtnSave(m_xBuilder->weld_button("BTN_SAVE"))
+ , m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, "CTL_PREVIEW", m_aCtlPreview))
+{
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ rXLSet.Put( XLineStyleItem(css::drawing::LineStyle_SOLID) );
+ rXLSet.Put( XLineWidthItem(XOUT_WIDTH) );
+ rXLSet.Put( XLineColorItem( OUString(), COL_BLACK ) );
+ rXLSet.Put( XLineStartWidthItem( m_aCtlPreview.GetOutputSize().Height() / 2 ) );
+ rXLSet.Put( XLineEndWidthItem( m_aCtlPreview.GetOutputSize().Height() / 2 ) );
+
+ // #i34740#
+ m_aCtlPreview.SetLineAttributes(aXLineAttr.GetItemSet());
+
+ m_xBtnAdd->connect_clicked(LINK(this, SvxLineEndDefTabPage, ClickAddHdl_Impl));
+ m_xBtnModify->connect_clicked(LINK( this, SvxLineEndDefTabPage, ClickModifyHdl_Impl));
+ m_xBtnDelete->connect_clicked(LINK( this, SvxLineEndDefTabPage, ClickDeleteHdl_Impl));
+ m_xBtnLoad->connect_clicked(LINK( this, SvxLineEndDefTabPage, ClickLoadHdl_Impl));
+ m_xBtnSave->connect_clicked(LINK( this, SvxLineEndDefTabPage, ClickSaveHdl_Impl));
+
+ m_xLbLineEnds->connect_changed(LINK(this, SvxLineEndDefTabPage, SelectLineEndHdl_Impl));
+}
+
+SvxLineEndDefTabPage::~SvxLineEndDefTabPage()
+{
+ m_xCtlPreview.reset();
+ m_xLbLineEnds.reset();
+}
+
+void SvxLineEndDefTabPage::Construct()
+{
+ m_xLbLineEnds->Fill( pLineEndList );
+
+ bool bCreateArrowPossible = true;
+
+ if( !pPolyObj )
+ {
+ bCreateArrowPossible = false;
+ }
+ else if( nullptr == dynamic_cast<const SdrPathObj*>( pPolyObj) )
+ {
+ SdrObjTransformInfoRec aInfoRec;
+ pPolyObj->TakeObjInfo( aInfoRec );
+ rtl::Reference<SdrObject> pNewObj;
+ if( aInfoRec.bCanConvToPath )
+ pNewObj = pPolyObj->ConvertToPolyObj( true, false );
+
+ bCreateArrowPossible = nullptr != dynamic_cast<const SdrPathObj*>( pNewObj.get());
+ }
+
+ if( !bCreateArrowPossible )
+ m_xBtnAdd->set_sensitive(false);
+}
+
+void SvxLineEndDefTabPage::ActivatePage( const SfxItemSet& )
+{
+ if( nDlgType != 0 ) // area dialog
+ return;
+
+ // ActivatePage() is called before the dialog receives PageCreated() !!!
+ if( !pLineEndList.is() )
+ return;
+
+ if( *pPosLineEndLb != -1)
+ {
+ m_xLbLineEnds->set_active(*pPosLineEndLb);
+ SelectLineEndHdl_Impl();
+ }
+ INetURLObject aURL( pLineEndList->GetPath() );
+
+ aURL.Append( pLineEndList->GetName() );
+ DBG_ASSERT( aURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
+ *pPageType = PageType::Area; // 3
+ *pPosLineEndLb = -1;
+}
+
+
+DeactivateRC SvxLineEndDefTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ CheckChanges_Impl();
+
+ if( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+
+void SvxLineEndDefTabPage::CheckChanges_Impl()
+{
+ int nPos = m_xLbLineEnds->get_active();
+
+ if (nPos != -1)
+ {
+ OUString aString = m_xEdtName->get_text();
+
+ if( aString != m_xLbLineEnds->get_active_text() )
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querychangelineenddialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("AskChangeLineEndDialog"));
+ if (xQueryBox->run() == RET_YES)
+ ClickModifyHdl_Impl(*m_xBtnModify);
+ }
+ }
+ nPos = m_xLbLineEnds->get_active();
+
+ if (nPos != -1)
+ *pPosLineEndLb = nPos;
+}
+
+
+bool SvxLineEndDefTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ if( nDlgType == 0 ) // line dialog
+ {
+ if( *pPageType == PageType::Bitmap )
+ {
+ CheckChanges_Impl();
+
+ int nPos = m_xLbLineEnds->get_active();
+ const XLineEndEntry* pEntry = pLineEndList->GetLineEnd(nPos);
+
+ rSet->Put( XLineStartItem( pEntry->GetName(), pEntry->GetLineEnd() ) );
+ rSet->Put( XLineEndItem( pEntry->GetName(), pEntry->GetLineEnd() ) );
+ }
+ }
+ return true;
+}
+
+void SvxLineEndDefTabPage::Reset( const SfxItemSet* )
+{
+ m_xLbLineEnds->set_active(0);
+
+ // Update lineend
+ if( pLineEndList->Count() > 0 )
+ {
+ int nPos = m_xLbLineEnds->get_active();
+
+ const XLineEndEntry* pEntry = pLineEndList->GetLineEnd(nPos);
+
+ m_xEdtName->set_text(m_xLbLineEnds->get_active_text());
+
+ rXLSet.Put( XLineStartItem( OUString(), pEntry->GetLineEnd() ) );
+ rXLSet.Put( XLineEndItem( OUString(), pEntry->GetLineEnd() ) );
+
+ // #i34740#
+ m_aCtlPreview.SetLineAttributes(aXLineAttr.GetItemSet());
+ m_aCtlPreview.Invalidate();
+ }
+
+ // determine button state
+ if( pLineEndList->Count() )
+ {
+ m_xBtnModify->set_sensitive(true);
+ m_xBtnDelete->set_sensitive(true);
+ m_xBtnSave->set_sensitive(true);
+ }
+ else
+ {
+ m_xBtnModify->set_sensitive(false);
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnSave->set_sensitive(false);
+ }
+}
+
+std::unique_ptr<SfxTabPage> SvxLineEndDefTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxLineEndDefTabPage>(pPage, pController, *rSet );
+}
+
+void SvxLineEndDefTabPage::SelectLineEndHdl_Impl()
+{
+ if( pLineEndList->Count() <= 0 )
+ return;
+
+ int nPos = m_xLbLineEnds->get_active();
+
+ const XLineEndEntry* pEntry = pLineEndList->GetLineEnd(nPos);
+
+ m_xEdtName->set_text(m_xLbLineEnds->get_active_text());
+
+ rXLSet.Put( XLineStartItem( OUString(), pEntry->GetLineEnd() ) );
+ rXLSet.Put( XLineEndItem( OUString(), pEntry->GetLineEnd() ) );
+
+ // #i34740#
+ m_aCtlPreview.SetLineAttributes(aXLineAttr.GetItemSet());
+ m_aCtlPreview.Invalidate();
+
+ // Is not set before, in order to only take the new style,
+ // if there is an entry selected in the ListBox
+ *pPageType = PageType::Bitmap;
+}
+
+IMPL_LINK_NOARG(SvxLineEndDefTabPage, SelectLineEndHdl_Impl, weld::ComboBox&, void)
+{
+ SelectLineEndHdl_Impl();
+}
+
+IMPL_LINK_NOARG(SvxLineEndDefTabPage, ClickModifyHdl_Impl, weld::Button&, void)
+{
+ int nPos = m_xLbLineEnds->get_active();
+ if (nPos == -1)
+ return;
+
+ OUString aDesc(CuiResId(RID_CUISTR_DESC_LINEEND));
+ OUString aName(m_xEdtName->get_text());
+ tools::Long nCount = pLineEndList->Count();
+ bool bDifferent = true;
+
+ // check whether the name is existing already
+ for ( tools::Long i = 0; i < nCount && bDifferent; i++ )
+ if ( aName == pLineEndList->GetLineEnd( i )->GetName() )
+ bDifferent = false;
+
+ // if yes, repeat and demand a new name
+ if ( !bDifferent )
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xWarningBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ xWarningBox->run();
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+ bool bLoop = true;
+
+ while( !bDifferent && bLoop && pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+ bDifferent = true;
+
+ for( tools::Long i = 0; i < nCount && bDifferent; i++ )
+ {
+ if( aName == pLineEndList->GetLineEnd( i )->GetName() )
+ bDifferent = false;
+ }
+
+ if( bDifferent )
+ bLoop = false;
+ else
+ xWarningBox->run();
+ }
+ }
+
+ // if not existing, enter the entry
+ if( !bDifferent )
+ return;
+
+ const XLineEndEntry* pOldEntry = pLineEndList->GetLineEnd(nPos);
+
+ if(pOldEntry)
+ {
+ // #123497# Need to replace the existing entry with a new one
+ pLineEndList->Replace(std::make_unique<XLineEndEntry>(pOldEntry->GetLineEnd(), aName), nPos);
+
+ m_xEdtName->set_text(aName);
+
+ m_xLbLineEnds->Modify(*pLineEndList->GetLineEnd(nPos), nPos, pLineEndList->GetUiBitmap(nPos));
+ m_xLbLineEnds->set_active(nPos);
+
+ // set flag for modified
+ *pnLineEndListState |= ChangeType::MODIFIED;
+
+ *pPageType = PageType::Bitmap;
+ }
+ else
+ {
+ OSL_ENSURE(false, "LineEnd to be modified not existing (!)");
+ }
+}
+
+IMPL_LINK_NOARG(SvxLineEndDefTabPage, ClickAddHdl_Impl, weld::Button&, void)
+{
+ if( pPolyObj )
+ {
+ const SdrObject* pNewObj;
+ rtl::Reference<SdrObject> pConvPolyObj;
+
+ if( nullptr != dynamic_cast<const SdrPathObj*>( pPolyObj) )
+ {
+ pNewObj = pPolyObj;
+ }
+ else
+ {
+ SdrObjTransformInfoRec aInfoRec;
+ pPolyObj->TakeObjInfo( aInfoRec );
+
+ if( aInfoRec.bCanConvToPath )
+ {
+ pConvPolyObj = pPolyObj->ConvertToPolyObj( true, false );
+ pNewObj = pConvPolyObj.get();
+
+ if( !pNewObj || nullptr == dynamic_cast<const SdrPathObj*>( pNewObj) )
+ return; // cancel, additional safety, which
+ // has no use for group objects though.
+ }
+ else return; // cancel
+ }
+
+ basegfx::B2DPolyPolygon aNewPolyPolygon(static_cast<const SdrPathObj*>(pNewObj)->GetPathPoly());
+ basegfx::B2DRange aNewRange(basegfx::utils::getRange(aNewPolyPolygon));
+
+ // normalize
+ aNewPolyPolygon.transform(basegfx::utils::createTranslateB2DHomMatrix( -aNewRange.getMinX(), -aNewRange.getMinY()));
+
+ pConvPolyObj.clear();
+
+ OUString aNewName(SvxResId(RID_SVXSTR_LINEEND));
+ OUString aDesc(CuiResId(RID_CUISTR_DESC_LINEEND));
+ OUString aName;
+
+ tools::Long nCount = pLineEndList->Count();
+ tools::Long j = 1;
+ bool bDifferent = false;
+
+ while ( !bDifferent )
+ {
+ aName = aNewName + " " + OUString::number( j++ );
+ bDifferent = true;
+
+ for( tools::Long i = 0; i < nCount && bDifferent; i++ )
+ if ( aName == pLineEndList->GetLineEnd( i )->GetName() )
+ bDifferent = false;
+ }
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc ));
+ bool bLoop = true;
+
+ while ( bLoop && pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+ bDifferent = true;
+
+ for( tools::Long i = 0; i < nCount && bDifferent; i++ )
+ {
+ if( aName == pLineEndList->GetLineEnd( i )->GetName() )
+ bDifferent = false;
+ }
+
+ if( bDifferent )
+ {
+ bLoop = false;
+
+ auto nLineEndCount = pLineEndList->Count();
+ pLineEndList->Insert(std::make_unique<XLineEndEntry>(aNewPolyPolygon, aName), nLineEndCount);
+
+ // add to the ListBox
+ m_xLbLineEnds->Append(*pLineEndList->GetLineEnd(nLineEndCount), pLineEndList->GetUiBitmap(nLineEndCount));
+ m_xLbLineEnds->set_active(m_xLbLineEnds->get_count() - 1);
+
+ *pnLineEndListState |= ChangeType::MODIFIED;
+
+ SelectLineEndHdl_Impl();
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xWarningBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ xWarningBox->run();
+ }
+ }
+ }
+ else
+ m_xBtnAdd->set_sensitive(false);
+
+ // determine button state
+ if ( pLineEndList->Count() )
+ {
+ m_xBtnModify->set_sensitive(true);
+ m_xBtnDelete->set_sensitive(true);
+ m_xBtnSave->set_sensitive(true);
+ }
+}
+
+IMPL_LINK_NOARG(SvxLineEndDefTabPage, ClickDeleteHdl_Impl, weld::Button&, void)
+{
+ int nPos = m_xLbLineEnds->get_active();
+
+ if (nPos != -1)
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querydeletelineenddialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("AskDelLineEndDialog"));
+
+ if (xQueryBox->run() == RET_YES)
+ {
+ pLineEndList->Remove(nPos);
+ m_xLbLineEnds->remove(nPos);
+ m_xLbLineEnds->set_active(0);
+
+ SelectLineEndHdl_Impl();
+ *pPageType = PageType::Area; // LineEnd shall not be taken over
+
+ *pnLineEndListState |= ChangeType::MODIFIED;
+
+ m_aCtlPreview.Invalidate();
+ }
+ }
+ // determine button state
+ if( !pLineEndList->Count() )
+ {
+ m_xBtnModify->set_sensitive(false);
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnSave->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(SvxLineEndDefTabPage, ClickLoadHdl_Impl, weld::Button&, void)
+{
+ sal_uInt16 nReturn = RET_YES;
+
+ if ( *pnLineEndListState & ChangeType::MODIFIED )
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querysavelistdialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("AskSaveList"));
+
+ nReturn = xBox->run();
+
+ if ( nReturn == RET_YES )
+ pLineEndList->Save();
+ }
+
+ if ( nReturn != RET_CANCEL )
+ {
+ ::sfx2::FileDialogHelper aDlg(css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE,
+ FileDialogFlags::NONE, GetFrameWeld());
+ OUString aStrFilterType( "*.soe" );
+ aDlg.AddFilter( aStrFilterType, aStrFilterType );
+
+ OUString aPalettePath(SvtPathOptions().GetPalettePath());
+ OUString aLastDir;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ aLastDir = aPalettePath.getToken(0, ';', nIndex);
+ }
+ while (nIndex >= 0);
+
+ INetURLObject aFile(aLastDir);
+ aDlg.SetDisplayDirectory( aFile.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+
+ if( aDlg.Execute() == ERRCODE_NONE )
+ {
+ INetURLObject aURL( aDlg.GetPath() );
+ INetURLObject aPathURL( aURL );
+
+ aPathURL.removeSegment();
+ aPathURL.removeFinalSlash();
+
+ XLineEndListRef pLeList = XPropertyList::AsLineEndList(
+ XPropertyList::CreatePropertyList(
+ XPropertyListType::LineEnd,
+ aPathURL.GetMainURL(INetURLObject::DecodeMechanism::NONE), ""));
+ pLeList->SetName( aURL.getName() );
+ if( pLeList->Load() )
+ {
+ pLineEndList = pLeList;
+ static_cast<SvxLineTabDialog*>(GetDialogController())->SetNewLineEndList( pLineEndList );
+ m_xLbLineEnds->clear();
+ m_xLbLineEnds->Fill( pLineEndList );
+ Reset( &rOutAttrs );
+
+ pLineEndList->SetName( aURL.getName() );
+
+ *pnLineEndListState |= ChangeType::CHANGED;
+ *pnLineEndListState &= ~ChangeType::MODIFIED;
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querynoloadedfiledialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("NoLoadedFileDialog"));
+ xBox->run();
+ }
+ }
+ }
+
+ // determine button state
+ if ( pLineEndList->Count() )
+ {
+ m_xBtnModify->set_sensitive(true);
+ m_xBtnDelete->set_sensitive(true);
+ m_xBtnSave->set_sensitive(true);
+ }
+ else
+ {
+ m_xBtnModify->set_sensitive(false);
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnSave->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(SvxLineEndDefTabPage, ClickSaveHdl_Impl, weld::Button&, void)
+{
+ ::sfx2::FileDialogHelper aDlg(css::ui::dialogs::TemplateDescription::FILESAVE_SIMPLE, FileDialogFlags::NONE, GetFrameWeld());
+ OUString aStrFilterType( "*.soe" );
+ aDlg.AddFilter( aStrFilterType, aStrFilterType );
+
+ OUString aPalettePath(SvtPathOptions().GetPalettePath());
+ OUString aLastDir;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ aLastDir = aPalettePath.getToken(0, ';', nIndex);
+ }
+ while (nIndex >= 0);
+
+ INetURLObject aFile(aLastDir);
+ DBG_ASSERT( aFile.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
+
+ if( !pLineEndList->GetName().isEmpty() )
+ {
+ aFile.Append( pLineEndList->GetName() );
+
+ if( aFile.getExtension().isEmpty() )
+ aFile.SetExtension( u"soe" );
+ }
+
+ aDlg.SetDisplayDirectory( aFile.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+ if ( aDlg.Execute() != ERRCODE_NONE )
+ return;
+
+ INetURLObject aURL( aDlg.GetPath() );
+ INetURLObject aPathURL( aURL );
+
+ aPathURL.removeSegment();
+ aPathURL.removeFinalSlash();
+
+ pLineEndList->SetName( aURL.getName() );
+ pLineEndList->SetPath( aPathURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+
+ if( pLineEndList->Save() )
+ {
+ *pnLineEndListState &= ~ChangeType::MODIFIED;
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querynosavefiledialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("NoSaveFileDialog"));
+ xBox->run();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tppattern.cxx b/cui/source/tabpages/tppattern.cxx
new file mode 100644
index 0000000000..4976a0a0ed
--- /dev/null
+++ b/cui/source/tabpages/tppattern.cxx
@@ -0,0 +1,553 @@
+/* -*- 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 <memory>
+#include <tools/urlobj.hxx>
+#include <sfx2/dialoghelper.hxx>
+#include <svx/colorbox.hxx>
+#include <svx/dialmgr.hxx>
+#include <vcl/BitmapTools.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <svx/strings.hrc>
+
+#include <strings.hrc>
+#include <svx/xfillit0.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/xtable.hxx>
+#include <svx/xflbmtit.hxx>
+#include <cuitabarea.hxx>
+#include <svx/svxdlg.hxx>
+#include <dialmgr.hxx>
+#include <sal/log.hxx>
+
+using namespace com::sun::star;
+
+/*************************************************************************
+|* Preview control for the display of bitmaps
+\************************************************************************/
+
+class SvxBitmapCtl
+{
+private:
+ Color aPixelColor, aBackgroundColor;
+ std::array<sal_uInt8,64> const * pBmpArray;
+
+public:
+ // Constructor: BitmapCtl for SvxPixelCtl
+ SvxBitmapCtl()
+ : pBmpArray(nullptr)
+ {
+ }
+
+ // BitmapCtl: Returns the Bitmap
+ BitmapEx GetBitmapEx() const
+ {
+ if (!pBmpArray)
+ return BitmapEx();
+ return vcl::bitmap::createHistorical8x8FromArray(*pBmpArray, aPixelColor, aBackgroundColor);
+ }
+
+ void SetBmpArray( std::array<sal_uInt8,64> const & pPixel ) { pBmpArray = &pPixel; }
+ void SetPixelColor( Color aColor ) { aPixelColor = aColor; }
+ void SetBackgroundColor( Color aColor ) { aBackgroundColor = aColor; }
+};
+
+SvxPatternTabPage::SvxPatternTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SvxTabPage(pPage, pController, "cui/ui/patterntabpage.ui", "PatternTabPage", rInAttrs)
+ , m_rOutAttrs(rInAttrs)
+ , m_pnPatternListState(nullptr)
+ , m_pnColorListState(nullptr)
+ , m_aXFillAttr(rInAttrs.GetPool())
+ , m_rXFSet(m_aXFillAttr.GetItemSet())
+ , m_xCtlPixel(new SvxPixelCtl(this))
+ , m_xLbColor(new ColorListBox(m_xBuilder->weld_menu_button("LB_COLOR"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xLbBackgroundColor(new ColorListBox(m_xBuilder->weld_menu_button("LB_BACKGROUND_COLOR"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xPatternLB(new SvxPresetListBox(m_xBuilder->weld_scrolled_window("patternpresetlistwin", true)))
+ , m_xBtnAdd(m_xBuilder->weld_button("BTN_ADD"))
+ , m_xBtnModify(m_xBuilder->weld_button("BTN_MODIFY"))
+ , m_xCtlPixelWin(new weld::CustomWeld(*m_xBuilder, "CTL_PIXEL", *m_xCtlPixel))
+ , m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, "CTL_PREVIEW", m_aCtlPreview))
+ , m_xPatternLBWin(new weld::CustomWeld(*m_xBuilder, "patternpresetlist", *m_xPatternLB))
+{
+ // size of the bitmap display
+ Size aSize = getDrawPreviewOptimalSize(m_aCtlPreview.GetDrawingArea()->get_ref_device());
+ m_xPatternLB->set_size_request(aSize.Width(), aSize.Height());
+ m_xCtlPreview->set_size_request(aSize.Width(), aSize.Height());
+
+ m_xBitmapCtl.reset(new SvxBitmapCtl);
+
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ // setting the output device
+ m_rXFSet.Put( XFillStyleItem(drawing::FillStyle_BITMAP) );
+ m_rXFSet.Put( XFillBitmapItem(OUString(), Graphic()) );
+
+ m_xBtnAdd->connect_clicked( LINK( this, SvxPatternTabPage, ClickAddHdl_Impl ) );
+ m_xBtnModify->connect_clicked( LINK( this, SvxPatternTabPage, ClickModifyHdl_Impl ) );
+
+ m_xPatternLB->SetSelectHdl( LINK( this, SvxPatternTabPage, ChangePatternHdl_Impl ) );
+ m_xPatternLB->SetRenameHdl( LINK( this, SvxPatternTabPage, ClickRenameHdl_Impl ) );
+ m_xPatternLB->SetDeleteHdl( LINK( this, SvxPatternTabPage, ClickDeleteHdl_Impl ) );
+ m_xLbColor->SetSelectHdl( LINK( this, SvxPatternTabPage, ChangeColorHdl_Impl ) );
+ m_xLbBackgroundColor->SetSelectHdl( LINK( this, SvxPatternTabPage, ChangeColorHdl_Impl ) );
+
+ m_xPatternLB->SetStyle(WB_FLATVALUESET | WB_NO_DIRECTSELECT | WB_TABSTOP);
+}
+
+SvxPatternTabPage::~SvxPatternTabPage()
+{
+ m_xPatternLBWin.reset();
+ m_xCtlPreview.reset();
+ m_xCtlPixelWin.reset();
+ m_xPatternLB.reset();
+ m_xLbBackgroundColor.reset();
+ m_xLbColor.reset();
+ m_xCtlPixel.reset();
+}
+
+void SvxPatternTabPage::Construct()
+{
+ m_xPatternLB->FillPresetListBox( *m_pPatternList );
+}
+
+void SvxPatternTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ if( !m_pColorList.is() )
+ return;
+
+ // ColorList
+ if( *m_pnColorListState & ChangeType::CHANGED ||
+ *m_pnColorListState & ChangeType::MODIFIED )
+ {
+ SvxAreaTabDialog* pArea = (*m_pnColorListState & ChangeType::CHANGED) ?
+ dynamic_cast<SvxAreaTabDialog*>(GetDialogController()) : nullptr;
+ if (pArea)
+ m_pColorList = pArea->GetNewColorList();
+ }
+
+ // determining (possibly cutting) the name and
+ // displaying it in the GroupBox
+ OUString aString = CuiResId( RID_CUISTR_TABLE ) + ": ";
+ INetURLObject aURL( m_pPatternList->GetPath() );
+
+ aURL.Append( m_pPatternList->GetName() );
+ SAL_WARN_IF( aURL.GetProtocol() == INetProtocol::NotValid, "cui.tabpages", "invalid URL" );
+
+ if( aURL.getBase().getLength() > 18 )
+ {
+ aString += OUString::Concat(aURL.getBase().subView( 0, 15 )) + "...";
+ }
+ else
+ aString += aURL.getBase();
+
+ XFillBitmapItem aItem( rSet.Get( XATTR_FILLBITMAP ) );
+
+ if ( aItem.isPattern() )
+ {
+ sal_Int32 nPos = SearchPatternList( aItem.GetName() );
+ if ( nPos != -1)
+ {
+ sal_uInt16 nId = m_xPatternLB->GetItemId( static_cast<size_t>( nPos ) );
+ m_xPatternLB->SelectItem( nId );
+ }
+ }
+ else
+ m_xPatternLB->SelectItem( m_xPatternLB->GetItemId( static_cast<size_t>( 0 ) ) );
+}
+
+
+DeactivateRC SvxPatternTabPage::DeactivatePage( SfxItemSet* _pSet)
+{
+ if( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+
+bool SvxPatternTabPage::FillItemSet( SfxItemSet* _rOutAttrs )
+{
+ _rOutAttrs->Put(XFillStyleItem(drawing::FillStyle_BITMAP));
+ size_t nPos = m_xPatternLB->IsNoSelection() ? VALUESET_ITEM_NOTFOUND : m_xPatternLB->GetSelectItemPos();
+ if(VALUESET_ITEM_NOTFOUND != nPos)
+ {
+ const XBitmapEntry* pXBitmapEntry = m_pPatternList->GetBitmap( static_cast<sal_uInt16>(nPos) );
+ const OUString aString( m_xPatternLB->GetItemText( m_xPatternLB->GetSelectedItemId() ) );
+
+ _rOutAttrs->Put(XFillBitmapItem(aString, pXBitmapEntry->GetGraphicObject()));
+ }
+ else
+ {
+ const BitmapEx aBitmapEx(m_xBitmapCtl->GetBitmapEx());
+
+ _rOutAttrs->Put(XFillBitmapItem(OUString(), Graphic(aBitmapEx)));
+ }
+ _rOutAttrs->Put(XFillBmpTileItem(true));
+ return true;
+}
+
+
+void SvxPatternTabPage::Reset( const SfxItemSet* )
+{
+ m_xBitmapCtl->SetPixelColor( m_xLbColor->GetSelectEntryColor() );
+ m_xBitmapCtl->SetBackgroundColor( m_xLbBackgroundColor->GetSelectEntryColor() );
+ m_xBitmapCtl->SetBmpArray( m_xCtlPixel->GetBitmapPixelPtr() );
+
+ // get bitmap and display it
+ const XFillBitmapItem aBmpItem(OUString(), Graphic(m_xBitmapCtl->GetBitmapEx()));
+ if(aBmpItem.isPattern())
+ {
+ m_rXFSet.Put( aBmpItem );
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlPreview.Invalidate();
+ }
+
+ ChangePatternHdl_Impl(m_xPatternLB.get());
+
+ // determine button state
+ if( m_pPatternList.is() && m_pPatternList->Count() )
+ {
+ m_xBtnAdd->set_sensitive(true);
+ m_xBtnModify->set_sensitive(true);
+ }
+ else
+ {
+ m_xBtnModify->set_sensitive(false);
+ }
+}
+
+std::unique_ptr<SfxTabPage> SvxPatternTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rSet )
+{
+ return std::make_unique<SvxPatternTabPage>(pPage, pController, *rSet);
+}
+
+IMPL_LINK_NOARG(SvxPatternTabPage, ChangePatternHdl_Impl, ValueSet*, void)
+{
+ std::unique_ptr<GraphicObject> pGraphicObject;
+ size_t nPos = m_xPatternLB->GetSelectItemPos();
+
+ if(VALUESET_ITEM_NOTFOUND != nPos)
+ {
+ pGraphicObject.reset(new GraphicObject(m_pPatternList->GetBitmap( static_cast<sal_uInt16>(nPos) )->GetGraphicObject()));
+ }
+ else
+ {
+ if(const XFillStyleItem* pFillStyleItem = m_rOutAttrs.GetItemIfSet(GetWhich(XATTR_FILLSTYLE)))
+ {
+ const drawing::FillStyle eXFS(pFillStyleItem->GetValue());
+
+ const XFillBitmapItem* pBitmapItem;
+ if((drawing::FillStyle_BITMAP == eXFS) && (pBitmapItem = m_rOutAttrs.GetItemIfSet(GetWhich(XATTR_FILLBITMAP))))
+ {
+ pGraphicObject.reset(new GraphicObject(pBitmapItem->GetGraphicObject()));
+ }
+ }
+
+ if(!pGraphicObject)
+ {
+ sal_uInt16 nPosition = m_xPatternLB->GetItemId( 0 );
+ m_xPatternLB->SelectItem( nPosition );
+ if( nPosition != 0 )
+ {
+ pGraphicObject.reset(new GraphicObject(m_pPatternList->GetBitmap(0)->GetGraphicObject()));
+ }
+ }
+ }
+
+ if(!pGraphicObject)
+ return;
+
+ Color aBackColor;
+ Color aPixelColor;
+ bool bIs8x8(vcl::bitmap::isHistorical8x8(pGraphicObject->GetGraphic().GetBitmapEx(), aBackColor, aPixelColor));
+
+ m_xLbColor->SetNoSelection();
+ m_xLbBackgroundColor->SetNoSelection();
+
+ if(bIs8x8)
+ {
+ m_xCtlPixel->SetPaintable( true );
+ m_xBtnModify->set_sensitive(true);
+ m_xBtnAdd->set_sensitive(true);
+
+ // setting the pixel control
+
+ m_xCtlPixel->SetXBitmap(pGraphicObject->GetGraphic().GetBitmapEx());
+
+ m_xLbColor->SelectEntry( aPixelColor );
+ m_xLbBackgroundColor->SelectEntry( aBackColor );
+
+ // update m_xBitmapCtl, rXFSet and m_aCtlPreview
+ m_xBitmapCtl->SetPixelColor( aPixelColor );
+ m_xBitmapCtl->SetBackgroundColor( aBackColor );
+ m_rXFSet.ClearItem();
+ m_rXFSet.Put(XFillStyleItem(drawing::FillStyle_BITMAP));
+ m_rXFSet.Put(XFillBitmapItem(OUString(), Graphic(m_xBitmapCtl->GetBitmapEx())));
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlPreview.Invalidate();
+ }
+ else
+ {
+ m_xCtlPixel->Reset();
+ m_xCtlPixel->SetPaintable( false );
+ m_xBtnModify->set_sensitive(false);
+ m_xBtnAdd->set_sensitive(false);
+ }
+
+ m_xCtlPixel->Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxPatternTabPage, ClickAddHdl_Impl, weld::Button&, void)
+{
+
+ OUString aNewName( SvxResId( RID_SVXSTR_PATTERN_UNTITLED ) );
+ OUString aDesc( CuiResId( RID_CUISTR_DESC_NEW_PATTERN ) );
+ OUString aName;
+
+ tools::Long nCount = m_pPatternList->Count();
+ tools::Long j = 1;
+ bool bValidPatternName = false;
+
+ while( !bValidPatternName )
+ {
+ aName = aNewName + " " + OUString::number( j++ );
+ bValidPatternName = (SearchPatternList(aName) == -1);
+ }
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+ sal_uInt16 nError(1);
+
+ while( pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+
+ bValidPatternName = (SearchPatternList(aName) == -1);
+
+ if( bValidPatternName ) {
+ nError = 0;
+ break;
+ }
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xWarnBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ if (xWarnBox->run() != RET_OK)
+ break;
+ }
+
+ pDlg.disposeAndClear();
+
+ if( !nError )
+ {
+ std::unique_ptr<XBitmapEntry> pEntry;
+ if( m_xCtlPixel->IsEnabled() )
+ {
+ const BitmapEx aBitmapEx(m_xBitmapCtl->GetBitmapEx());
+
+ pEntry.reset(new XBitmapEntry(Graphic(aBitmapEx), aName));
+ }
+ else // it must be a not existing imported bitmap
+ {
+ if(const XFillBitmapItem* pFillBmpItem = m_rOutAttrs.GetItemIfSet(XATTR_FILLBITMAP))
+ {
+ pEntry.reset(new XBitmapEntry(pFillBmpItem->GetGraphicObject(), aName));
+ }
+ else
+ assert(!"SvxPatternTabPage::ClickAddHdl_Impl(), XBitmapEntry* pEntry == nullptr ?");
+ }
+
+ if( pEntry )
+ {
+ m_pPatternList->Insert(std::move(pEntry), nCount);
+ sal_Int32 nId = m_xPatternLB->GetItemId( nCount - 1 );
+ BitmapEx aBitmap = m_pPatternList->GetBitmapForPreview( nCount, m_xPatternLB->GetIconSize() );
+ m_xPatternLB->InsertItem( nId + 1, Image(aBitmap), aName );
+ m_xPatternLB->SelectItem( nId + 1 );
+ m_xPatternLB->Resize();
+
+ *m_pnPatternListState |= ChangeType::MODIFIED;
+
+ ChangePatternHdl_Impl(m_xPatternLB.get());
+ }
+ }
+
+ // determine button state
+ if( m_pPatternList->Count() )
+ {
+ m_xBtnModify->set_sensitive(true);
+ }
+}
+
+IMPL_LINK_NOARG(SvxPatternTabPage, ClickModifyHdl_Impl, weld::Button&, void)
+{
+ sal_uInt16 nId = m_xPatternLB->GetSelectedItemId();
+ size_t nPos = m_xPatternLB->GetSelectItemPos();
+
+ if ( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ OUString aName( m_pPatternList->GetBitmap( static_cast<sal_uInt16>(nPos) )->GetName() );
+
+ const BitmapEx aBitmapEx(m_xBitmapCtl->GetBitmapEx());
+
+ // #i123497# Need to replace the existing entry with a new one (old returned needs to be deleted)
+ m_pPatternList->Replace(std::make_unique<XBitmapEntry>(Graphic(aBitmapEx), aName), nPos);
+
+ BitmapEx aBitmap = m_pPatternList->GetBitmapForPreview( static_cast<sal_uInt16>( nPos ), m_xPatternLB->GetIconSize() );
+ m_xPatternLB->RemoveItem(nId);
+ m_xPatternLB->InsertItem( nId, Image(aBitmap), aName, static_cast<sal_uInt16>(nPos) );
+ m_xPatternLB->SelectItem( nId );
+
+ *m_pnPatternListState |= ChangeType::MODIFIED;
+}
+
+
+IMPL_LINK_NOARG(SvxPatternTabPage, ClickRenameHdl_Impl, SvxPresetListBox*, void)
+{
+ size_t nPos = m_xPatternLB->GetSelectItemPos();
+ sal_Int32 nId = m_xPatternLB->GetSelectedItemId();
+
+ if ( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ OUString aDesc(CuiResId(RID_CUISTR_DESC_NEW_PATTERN));
+ OUString aName(m_pPatternList->GetBitmap(nPos)->GetName());
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+
+ bool bLoop = true;
+
+ while( bLoop && pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+ sal_Int32 nPatternPos = SearchPatternList(aName);
+ bool bValidPatternName = (nPatternPos == static_cast<sal_Int32>(nPos) ) || (nPatternPos == -1);
+
+ if( bValidPatternName )
+ {
+ bLoop = false;
+
+ m_pPatternList->GetBitmap(nPos)->SetName(aName);
+
+ m_xPatternLB->SetItemText( nId, aName );
+ m_xPatternLB->SelectItem( nId );
+
+ *m_pnPatternListState |= ChangeType::MODIFIED;
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xWarnBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ xWarnBox->run();
+ }
+ }
+}
+
+IMPL_LINK_NOARG(SvxPatternTabPage, ClickDeleteHdl_Impl, SvxPresetListBox*, void)
+{
+ sal_uInt16 nId = m_xPatternLB->GetSelectedItemId();
+ size_t nPos = m_xPatternLB->GetSelectItemPos();
+
+ if( nPos != VALUESET_ITEM_NOTFOUND )
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querydeletebitmapdialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("AskDelBitmapDialog"));
+ if (xQueryBox->run() == RET_YES)
+ {
+ m_pPatternList->Remove(nPos);
+ m_xPatternLB->RemoveItem( nId );
+ nId = m_xPatternLB->GetItemId(0);
+ m_xPatternLB->SelectItem( nId );
+ m_xPatternLB->Resize();
+
+ m_aCtlPreview.Invalidate();
+ m_xCtlPixel->Invalidate();
+
+ ChangePatternHdl_Impl(m_xPatternLB.get());
+
+ *m_pnPatternListState |= ChangeType::MODIFIED;
+ }
+ }
+ // determine button state
+ if( !m_pPatternList->Count() )
+ {
+ m_xBtnModify->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(SvxPatternTabPage, ChangeColorHdl_Impl, ColorListBox&, void)
+{
+ ChangeColor_Impl();
+ m_xPatternLB->SetNoSelection();
+}
+
+void SvxPatternTabPage::ChangeColor_Impl()
+{
+ m_xCtlPixel->SetPixelColor( m_xLbColor->GetSelectEntryColor() );
+ m_xCtlPixel->SetBackgroundColor( m_xLbBackgroundColor->GetSelectEntryColor() );
+ m_xCtlPixel->Invalidate();
+
+ m_xBitmapCtl->SetPixelColor( m_xLbColor->GetSelectEntryColor() );
+ m_xBitmapCtl->SetBackgroundColor( m_xLbBackgroundColor->GetSelectEntryColor() );
+
+ // get bitmap and display it
+ m_rXFSet.Put(XFillBitmapItem(OUString(), Graphic(m_xBitmapCtl->GetBitmapEx())));
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlPreview.Invalidate();
+}
+
+void SvxPatternTabPage::PointChanged(weld::DrawingArea* pDrawingArea, RectPoint)
+{
+ if (pDrawingArea == m_xCtlPixel->GetDrawingArea())
+ {
+ m_xBitmapCtl->SetBmpArray(m_xCtlPixel->GetBitmapPixelPtr());
+
+ // get bitmap and display it
+ m_rXFSet.Put(XFillBitmapItem(OUString(), Graphic(m_xBitmapCtl->GetBitmapEx())));
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlPreview.Invalidate();
+ }
+
+ m_xPatternLB->SetNoSelection();
+}
+
+sal_Int32 SvxPatternTabPage::SearchPatternList(std::u16string_view rPatternName)
+{
+ tools::Long nCount = m_pPatternList->Count();
+ bool bValidPatternName = true;
+ sal_Int32 nPos = -1;
+
+ for(tools::Long i = 0;i < nCount && bValidPatternName;i++)
+ {
+ if(rPatternName == m_pPatternList->GetBitmap( i )->GetName())
+ {
+ nPos = i;
+ bValidPatternName = false;
+ }
+ }
+ return nPos;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tpshadow.cxx b/cui/source/tabpages/tpshadow.cxx
new file mode 100644
index 0000000000..795a57f13d
--- /dev/null
+++ b/cui/source/tabpages/tpshadow.cxx
@@ -0,0 +1,515 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svx/colorbox.hxx>
+#include <svx/svxids.hrc>
+#include <svtools/unitconv.hxx>
+
+#include <svx/xfillit0.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xflgrit.hxx>
+#include <svx/xflhtit.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/sdmetitm.hxx>
+#include <svx/sdooitm.hxx>
+#include <svx/sdprcitm.hxx>
+#include <svx/sdshcitm.hxx>
+#include <svx/sdshitm.hxx>
+#include <svx/sdshtitm.hxx>
+#include <svx/sdsxyitm.hxx>
+#include <svx/drawitem.hxx>
+#include <svx/xfltrit.hxx>
+#include <cuitabarea.hxx>
+#include <svx/dlgutil.hxx>
+#include <cuitabline.hxx>
+
+using namespace com::sun::star;
+
+const WhichRangesContainer SvxShadowTabPage::pShadowRanges(svl::Items<
+ SDRATTR_SHADOWCOLOR, SDRATTR_SHADOWTRANSPARENCE,
+ SDRATTR_SHADOWBLUR, SDRATTR_SHADOWBLUR,
+ SID_ATTR_FILL_SHADOW, SID_ATTR_FILL_SHADOW,
+ SID_ATTR_SHADOW_BLUR, SID_ATTR_SHADOW_BLUR,
+ SID_ATTR_SHADOW_TRANSPARENCE, SID_ATTR_SHADOW_YDISTANCE
+>);
+
+SvxShadowTabPage::SvxShadowTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SvxTabPage(pPage, pController, "cui/ui/shadowtabpage.ui", "ShadowTabPage", rInAttrs)
+ , m_rOutAttrs(rInAttrs)
+ , m_pnColorListState(nullptr)
+ , m_nPageType(PageType::Area)
+ , m_nDlgType(0)
+ , m_aXFillAttr(rInAttrs.GetPool())
+ , m_rXFSet(m_aXFillAttr.GetItemSet())
+ , m_aCtlPosition(this)
+ , m_xTsbShowShadow(m_xBuilder->weld_check_button("TSB_SHOW_SHADOW"))
+ , m_xGridShadow(m_xBuilder->weld_widget("gridSHADOW"))
+ , m_xMtrDistance(m_xBuilder->weld_metric_spin_button("MTR_FLD_DISTANCE", FieldUnit::CM))
+ , m_xLbShadowColor(new ColorListBox(m_xBuilder->weld_menu_button("LB_SHADOW_COLOR"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xMtrTransparent(m_xBuilder->weld_metric_spin_button("MTR_SHADOW_TRANSPARENT", FieldUnit::PERCENT))
+ , m_xLbShadowBlurMetric(m_xBuilder->weld_metric_spin_button("LB_SHADOW_BLUR", FieldUnit::POINT))
+ , m_xCtlPosition(new weld::CustomWeld(*m_xBuilder, "CTL_POSITION", m_aCtlPosition))
+ , m_xCtlXRectPreview(new weld::CustomWeld(*m_xBuilder, "CTL_COLOR_PREVIEW", m_aCtlXRectPreview))
+{
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ // adjust metric
+ FieldUnit eFUnit = GetModuleFieldUnit( rInAttrs );
+
+ switch ( eFUnit )
+ {
+ case FieldUnit::M:
+ case FieldUnit::KM:
+ eFUnit = FieldUnit::MM;
+ break;
+ default: ;//prevent warning
+ }
+ SetFieldUnit( *m_xMtrDistance, eFUnit );
+
+ // determine PoolUnit
+ SfxItemPool* pPool = m_rOutAttrs.GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ m_ePoolUnit = pPool->GetMetric( SDRATTR_SHADOWXDIST );
+
+ // setting the output device
+ drawing::FillStyle eXFS = drawing::FillStyle_SOLID;
+ if( m_rOutAttrs.GetItemState( XATTR_FILLSTYLE ) != SfxItemState::DONTCARE )
+ {
+ eXFS = m_rOutAttrs.Get( GetWhich( XATTR_FILLSTYLE ) ).GetValue();
+ switch( eXFS )
+ {
+ case drawing::FillStyle_SOLID:
+ if( SfxItemState::DONTCARE != m_rOutAttrs.GetItemState( XATTR_FILLCOLOR ) )
+ {
+ m_rXFSet.Put( m_rOutAttrs.Get( XATTR_FILLCOLOR ) );
+ }
+ break;
+
+ case drawing::FillStyle_GRADIENT:
+ if( SfxItemState::DONTCARE != m_rOutAttrs.GetItemState( XATTR_FILLGRADIENT ) )
+ {
+ m_rXFSet.Put( m_rOutAttrs.Get( XATTR_FILLGRADIENT ) );
+ }
+ break;
+
+ case drawing::FillStyle_HATCH:
+ if( SfxItemState::DONTCARE != m_rOutAttrs.GetItemState( XATTR_FILLHATCH ) )
+ {
+ m_rXFSet.Put( m_rOutAttrs.Get( XATTR_FILLHATCH ) );
+ }
+ break;
+
+ case drawing::FillStyle_BITMAP:
+ {
+ if( SfxItemState::DONTCARE != m_rOutAttrs.GetItemState( XATTR_FILLBITMAP ) )
+ {
+ m_rXFSet.Put( m_rOutAttrs.Get( XATTR_FILLBITMAP ) );
+ }
+ }
+ break;
+ case drawing::FillStyle_NONE : break;
+ default: break;
+ }
+ }
+ else
+ {
+ m_rXFSet.Put( XFillColorItem( OUString(), COL_LIGHTRED ) );
+ }
+
+ if(drawing::FillStyle_NONE == eXFS)
+ {
+ // #i96350#
+ // fallback to solid fillmode when no fill mode is provided to have
+ // a reasonable shadow preview. The used color will be a set one or
+ // the default (currently blue8)
+ eXFS = drawing::FillStyle_SOLID;
+ }
+
+ m_rXFSet.Put( XFillStyleItem( eXFS ) );
+ m_aCtlXRectPreview.SetRectangleAttributes(m_aXFillAttr.GetItemSet());
+
+ m_xTsbShowShadow->connect_toggled(LINK( this, SvxShadowTabPage, ClickShadowHdl_Impl));
+ m_xLbShadowColor->SetSelectHdl( LINK( this, SvxShadowTabPage, SelectShadowHdl_Impl ) );
+ Link<weld::MetricSpinButton&,void> aLink = LINK( this, SvxShadowTabPage, ModifyShadowHdl_Impl );
+ m_xLbShadowBlurMetric->connect_value_changed(aLink);
+ m_xMtrTransparent->connect_value_changed(aLink);
+ m_xMtrDistance->connect_value_changed(aLink);
+}
+
+SvxShadowTabPage::~SvxShadowTabPage()
+{
+ m_xCtlXRectPreview.reset();
+ m_xLbShadowColor.reset();
+ m_xCtlPosition.reset();
+ m_xLbShadowBlurMetric.reset();
+}
+
+void SvxShadowTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ const SfxUInt16Item* pPageTypeItem = rSet.GetItem<SfxUInt16Item>(SID_PAGE_TYPE, false);
+ if (pPageTypeItem)
+ SetPageType(static_cast<PageType>(pPageTypeItem->GetValue()));
+
+ if( m_nDlgType != 0 )
+ return;
+
+ if( !m_pColorList.is() )
+ return;
+
+ // ColorList
+ if( *m_pnColorListState & ChangeType::CHANGED ||
+ *m_pnColorListState & ChangeType::MODIFIED )
+ {
+ if( *m_pnColorListState & ChangeType::CHANGED )
+ {
+ SvxAreaTabDialog* pArea = dynamic_cast<SvxAreaTabDialog*>(GetDialogController());
+ if( pArea )
+ {
+ m_pColorList = pArea->GetNewColorList();
+ }
+ else
+ {
+ SvxLineTabDialog* pLine = dynamic_cast<SvxLineTabDialog*>(GetDialogController());
+ if( pLine )
+ m_pColorList = pLine->GetNewColorList();
+ }
+ }
+
+ SfxItemSet rAttribs( rSet );
+ // rSet contains shadow attributes too, but we want
+ // to use it for updating rectangle attributes only,
+ // so set the shadow to none here
+ SdrOnOffItem aItem( makeSdrShadowItem( false ));
+ rAttribs.Put( aItem );
+
+ m_aCtlXRectPreview.SetRectangleAttributes( rAttribs );
+ ModifyShadowHdl_Impl( *m_xMtrTransparent );
+ }
+ m_nPageType = PageType::Shadow;
+}
+
+
+DeactivateRC SvxShadowTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+
+bool SvxShadowTabPage::FillItemSet( SfxItemSet* rAttrs )
+{
+ bool bModified = false;
+
+ const SfxPoolItem* pOld = nullptr;
+
+ if (m_xTsbShowShadow->get_state_changed_from_saved())
+ {
+ TriState eState = m_xTsbShowShadow->get_state();
+ assert(eState != TRISTATE_INDET);
+ // given how m_xTsbShowShadow is set up and saved in Reset(),
+ // eState == TRISTATE_INDET would imply
+ // !IsValueChangedFromSaved()
+ SdrOnOffItem aItem( makeSdrShadowItem(eState == TRISTATE_TRUE) );
+ pOld = GetOldItem( *rAttrs, SDRATTR_SHADOW );
+ if ( !pOld || !( *static_cast<const SdrOnOffItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+
+ // shadow removal
+ // a bit intricate inquiry whether there was something changed,
+ // as the items can't be displayed directly on controls
+ sal_Int32 nX = 0, nY = 0;
+ sal_Int32 nXY = GetCoreValue( *m_xMtrDistance, m_ePoolUnit );
+
+ switch (m_aCtlPosition.GetActualRP())
+ {
+ case RectPoint::LT: nX = nY = -nXY; break;
+ case RectPoint::MT: nY = -nXY; break;
+ case RectPoint::RT: nX = nXY; nY = -nXY; break;
+ case RectPoint::LM: nX = -nXY; break;
+ case RectPoint::RM: nX = nXY; break;
+ case RectPoint::LB: nX = -nXY; nY = nXY; break;
+ case RectPoint::MB: nY = nXY; break;
+ case RectPoint::RB: nX = nY = nXY; break;
+ case RectPoint::MM: break;
+ }
+
+ // If the values of the shadow distances==SfxItemState::DONTCARE and the displayed
+ // string in the respective MetricField=="", then the comparison of the old
+ // and the new distance values would return a wrong result because in such a
+ // case the new distance values would match the default values of the MetricField !!!!
+ if ( !m_xMtrDistance->get_text().isEmpty() ||
+ m_rOutAttrs.GetItemState( SDRATTR_SHADOWXDIST ) != SfxItemState::DONTCARE ||
+ m_rOutAttrs.GetItemState( SDRATTR_SHADOWYDIST ) != SfxItemState::DONTCARE )
+ {
+ sal_Int32 nOldX = 9876543; // impossible value, so DontCare
+ sal_Int32 nOldY = 9876543;
+ if( m_rOutAttrs.GetItemState( SDRATTR_SHADOWXDIST ) != SfxItemState::DONTCARE &&
+ m_rOutAttrs.GetItemState( SDRATTR_SHADOWYDIST ) != SfxItemState::DONTCARE )
+ {
+ nOldX = m_rOutAttrs.Get( SDRATTR_SHADOWXDIST ).GetValue();
+ nOldY = m_rOutAttrs.Get( SDRATTR_SHADOWYDIST ).GetValue();
+ }
+ SdrMetricItem aXItem( makeSdrShadowXDistItem(nX) );
+ pOld = GetOldItem( *rAttrs, SDRATTR_SHADOWXDIST );
+ if ( nX != nOldX &&
+ ( !pOld || !( *static_cast<const SdrMetricItem*>(pOld) == aXItem ) ) )
+ {
+ rAttrs->Put( aXItem );
+ bModified = true;
+ }
+ SdrMetricItem aYItem( makeSdrShadowYDistItem(nY) );
+ pOld = GetOldItem( *rAttrs, SDRATTR_SHADOWYDIST );
+ if ( nY != nOldY &&
+ ( !pOld || !( *static_cast<const SdrMetricItem*>(pOld) == aYItem ) ) )
+ {
+ rAttrs->Put( aYItem );
+ bModified = true;
+ }
+ }
+
+ // ShadowColor
+ {
+ XColorItem aItem(makeSdrShadowColorItem(m_xLbShadowColor->GetSelectEntryColor()));
+ pOld = GetOldItem( *rAttrs, SDRATTR_SHADOWCOLOR );
+ if ( !pOld || !( *static_cast<const XColorItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+
+ // transparency
+ sal_uInt16 nVal = static_cast<sal_uInt16>(m_xMtrTransparent->get_value(FieldUnit::PERCENT));
+ if (m_xMtrTransparent->get_value_changed_from_saved())
+ {
+ SdrPercentItem aItem( makeSdrShadowTransparenceItem(nVal) );
+ pOld = GetOldItem( *rAttrs, SDRATTR_SHADOWTRANSPARENCE );
+ if ( !pOld || !( *static_cast<const SdrPercentItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+
+ if (m_xLbShadowBlurMetric->get_value_changed_from_saved())
+ {
+ SdrMetricItem aItem(SDRATTR_SHADOWBLUR, m_xLbShadowBlurMetric->get_value(FieldUnit::MM_100TH));
+ pOld = GetOldItem( *rAttrs, SDRATTR_SHADOWBLUR );
+ if ( !pOld || !( *static_cast<const SdrMetricItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+
+ rAttrs->Put (CntUInt16Item(SID_PAGE_TYPE, static_cast<sal_uInt16>(m_nPageType)));
+
+ return bModified;
+}
+
+
+void SvxShadowTabPage::Reset( const SfxItemSet* rAttrs )
+{
+ // all objects can have a shadow
+ // at the moment there are only 8 possible positions where a shadow can be set
+
+ // has a shadow been set?
+ if( rAttrs->GetItemState( SDRATTR_SHADOW ) != SfxItemState::DONTCARE )
+ {
+ if( rAttrs->Get( SDRATTR_SHADOW ).GetValue() )
+ m_xTsbShowShadow->set_state(TRISTATE_TRUE);
+ else
+ {
+ m_xTsbShowShadow->set_state(TRISTATE_FALSE);
+ }
+ }
+ else
+ m_xTsbShowShadow->set_state(TRISTATE_INDET);
+
+ // distance (only 8 possible positions),
+ // so there is only one item evaluated
+
+ if( rAttrs->GetItemState( SDRATTR_SHADOWXDIST ) != SfxItemState::DONTCARE &&
+ rAttrs->GetItemState( SDRATTR_SHADOWYDIST ) != SfxItemState::DONTCARE )
+ {
+ sal_Int32 nX = rAttrs->Get( SDRATTR_SHADOWXDIST ).GetValue();
+ sal_Int32 nY = rAttrs->Get( SDRATTR_SHADOWYDIST ).GetValue();
+
+ if( nX != 0 )
+ SetMetricValue( *m_xMtrDistance, nX < 0 ? -nX : nX, m_ePoolUnit );
+ else
+ SetMetricValue( *m_xMtrDistance, nY < 0 ? -nY : nY, m_ePoolUnit );
+
+ // setting the shadow control
+ if ( nX < 0 && nY < 0 ) m_aCtlPosition.SetActualRP( RectPoint::LT );
+ else if( nX == 0 && nY < 0 ) m_aCtlPosition.SetActualRP( RectPoint::MT );
+ else if( nX > 0 && nY < 0 ) m_aCtlPosition.SetActualRP( RectPoint::RT );
+ else if( nX < 0 && nY == 0 ) m_aCtlPosition.SetActualRP( RectPoint::LM );
+ // there's no center point anymore
+ else if( nX == 0 && nY == 0 ) m_aCtlPosition.SetActualRP( RectPoint::RB );
+ else if( nX > 0 && nY == 0 ) m_aCtlPosition.SetActualRP( RectPoint::RM );
+ else if( nX < 0 && nY > 0 ) m_aCtlPosition.SetActualRP( RectPoint::LB );
+ else if( nX == 0 && nY > 0 ) m_aCtlPosition.SetActualRP( RectPoint::MB );
+ else if( nX > 0 && nY > 0 ) m_aCtlPosition.SetActualRP( RectPoint::RB );
+ }
+ else
+ {
+ // determine default-distance
+ SfxItemPool* pPool = m_rOutAttrs.GetPool();
+ {
+ sal_Int32 n = pPool->GetDefaultItem(SDRATTR_SHADOWXDIST).GetValue();
+ if (n == 0)
+ n = pPool->GetDefaultItem(SDRATTR_SHADOWYDIST).GetValue();
+ SetMetricValue(*m_xMtrDistance, std::abs(n), m_ePoolUnit);
+ }
+
+ // Tristate, e. g. multiple objects have been marked of which some have a shadow and some don't.
+ // The text (which shall be displayed) of the MetricFields is set to "" and serves as an
+ // identification in the method FillItemSet for the fact that the distance value was NOT changed !!!!
+ m_xMtrDistance->set_text( "" );
+ m_aCtlPosition.SetActualRP( RectPoint::MM );
+ }
+
+ if( rAttrs->GetItemState( SDRATTR_SHADOWCOLOR ) != SfxItemState::DONTCARE )
+ {
+ m_xLbShadowColor->SelectEntry( rAttrs->Get( SDRATTR_SHADOWCOLOR ).GetColorValue() );
+ }
+ else
+ m_xLbShadowColor->SetNoSelection();
+
+ if( rAttrs->GetItemState( SDRATTR_SHADOWTRANSPARENCE ) != SfxItemState::DONTCARE )
+ {
+ sal_uInt16 nTransp = rAttrs->Get( SDRATTR_SHADOWTRANSPARENCE ).GetValue();
+ m_xMtrTransparent->set_value(nTransp, FieldUnit::PERCENT);
+ }
+ else
+ m_xMtrTransparent->set_text("");
+
+ if( rAttrs->GetItemState( SDRATTR_SHADOWBLUR ) != SfxItemState::DONTCARE )
+ {
+ sal_uInt16 nBlur = rAttrs->Get( SDRATTR_SHADOWBLUR ).GetValue();
+ m_xLbShadowBlurMetric->set_value(nBlur, FieldUnit::MM_100TH);
+ }
+ else
+ m_xLbShadowBlurMetric->set_text("");
+
+ //aCtlPosition
+ m_xMtrDistance->save_value();
+ m_xLbShadowColor->SaveValue();
+ m_xTsbShowShadow->save_state();
+ m_xLbShadowBlurMetric->save_value();
+
+ // #66832# This field was not saved, but used to determine changes.
+ // Why? Seems to be the error.
+ // It IS the error.
+ m_xMtrTransparent->save_value();
+
+ ClickShadowHdl_Impl(*m_xTsbShowShadow);
+ ModifyShadowHdl_Impl(*m_xMtrTransparent);
+}
+
+std::unique_ptr<SfxTabPage> SvxShadowTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrs )
+{
+ return std::make_unique<SvxShadowTabPage>(pPage, pController, *rAttrs);
+}
+
+IMPL_LINK_NOARG(SvxShadowTabPage, ClickShadowHdl_Impl, weld::Toggleable&, void)
+{
+ if (m_xTsbShowShadow->get_state() == TRISTATE_FALSE)
+ {
+ m_xGridShadow->set_sensitive(false);
+ m_xCtlPosition->set_sensitive(false);
+ }
+ else
+ {
+ m_xGridShadow->set_sensitive(true);
+ m_xCtlPosition->set_sensitive(true);
+ }
+ m_aCtlPosition.Invalidate();
+ ModifyShadowHdl_Impl(*m_xMtrTransparent);
+}
+
+IMPL_LINK_NOARG(SvxShadowTabPage, SelectShadowHdl_Impl, ColorListBox&, void)
+{
+ ModifyShadowHdl_Impl(*m_xMtrTransparent);
+}
+
+IMPL_LINK_NOARG(SvxShadowTabPage, ModifyShadowHdl_Impl, weld::MetricSpinButton&, void)
+{
+ if (m_xTsbShowShadow->get_state() == TRISTATE_TRUE)
+ m_rXFSet.Put( XFillStyleItem( drawing::FillStyle_SOLID ) );
+ else
+ m_rXFSet.Put( XFillStyleItem( drawing::FillStyle_NONE ) );
+
+ m_rXFSet.Put( XFillColorItem( OUString(), m_xLbShadowColor->GetSelectEntryColor() ) );
+ sal_uInt16 nVal = static_cast<sal_uInt16>(m_xMtrTransparent->get_value(FieldUnit::PERCENT));
+ m_rXFSet.Put( XFillTransparenceItem( nVal ) );
+
+ // shadow removal
+ sal_Int32 nX = 0, nY = 0;
+ sal_Int32 nXY = GetCoreValue( *m_xMtrDistance, m_ePoolUnit );
+ switch( m_aCtlPosition.GetActualRP() )
+ {
+ case RectPoint::LT: nX = nY = -nXY; break;
+ case RectPoint::MT: nY = -nXY; break;
+ case RectPoint::RT: nX = nXY; nY = -nXY; break;
+ case RectPoint::LM: nX = -nXY; break;
+ case RectPoint::RM: nX = nXY; break;
+ case RectPoint::LB: nX = -nXY; nY = nXY; break;
+ case RectPoint::MB: nY = nXY; break;
+ case RectPoint::RB: nX = nY = nXY; break;
+ case RectPoint::MM: break;
+ }
+
+ m_aCtlXRectPreview.SetShadowPosition(Point(nX, nY));
+
+ m_aCtlXRectPreview.SetShadowAttributes(m_aXFillAttr.GetItemSet());
+ m_aCtlXRectPreview.Invalidate();
+}
+
+void SvxShadowTabPage::PointChanged( weld::DrawingArea*, RectPoint )
+{
+ // repaint shadow
+ ModifyShadowHdl_Impl( *m_xMtrTransparent );
+}
+
+void SvxShadowTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SvxColorListItem* pColorListItem = aSet.GetItem<SvxColorListItem>(SID_COLOR_TABLE, false);
+ const SfxUInt16Item* pPageTypeItem = aSet.GetItem<SfxUInt16Item>(SID_PAGE_TYPE, false);
+ const SfxUInt16Item* pDlgTypeItem = aSet.GetItem<SfxUInt16Item>(SID_DLG_TYPE, false);
+
+ if (pColorListItem)
+ SetColorList(pColorListItem->GetColorList());
+ if (pPageTypeItem)
+ SetPageType(static_cast<PageType>(pPageTypeItem->GetValue()));
+ if (pDlgTypeItem)
+ SetDlgType(pDlgTypeItem->GetValue());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tptrans.cxx b/cui/source/tabpages/tptrans.cxx
new file mode 100644
index 0000000000..04cbdfb6b2
--- /dev/null
+++ b/cui/source/tabpages/tptrans.cxx
@@ -0,0 +1,546 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svx/svxids.hrc>
+
+#include <svx/xfillit0.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xflftrit.hxx>
+#include <svx/xflgrit.hxx>
+#include <svx/xflhtit.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/xflbckit.hxx>
+#include <svx/sdshtitm.hxx>
+#include <svx/xfltrit.hxx>
+#include <cuitabarea.hxx>
+#include <svl/intitem.hxx>
+
+using namespace com::sun::star;
+
+const WhichRangesContainer SvxTransparenceTabPage::pTransparenceRanges(svl::Items<
+ XATTR_FILLTRANSPARENCE, XATTR_FILLTRANSPARENCE,
+ XATTR_FILLFLOATTRANSPARENCE, XATTR_FILLFLOATTRANSPARENCE,
+ SDRATTR_SHADOWTRANSPARENCE, SDRATTR_SHADOWTRANSPARENCE
+>);
+
+/*************************************************************************
+|*
+|* Dialog for transparence
+|*
+\************************************************************************/
+
+IMPL_LINK_NOARG(SvxTransparenceTabPage, ClickTransOffHdl_Impl, weld::Toggleable&, void)
+{
+ // disable all other controls
+ ActivateLinear(false);
+ ActivateGradient(false);
+
+ // Preview
+ rXFSet.ClearItem(XATTR_FILLTRANSPARENCE);
+ rXFSet.ClearItem(XATTR_FILLFLOATTRANSPARENCE);
+ m_aCtlXRectPreview.SetAttributes( aXFillAttr.GetItemSet() );
+ m_aCtlBitmapPreview.SetAttributes( aXFillAttr.GetItemSet() );
+
+ InvalidatePreview(false);
+}
+
+IMPL_LINK_NOARG(SvxTransparenceTabPage, ClickTransLinearHdl_Impl, weld::Toggleable&, void)
+{
+ // enable linear, disable other
+ ActivateLinear(true);
+ ActivateGradient(false);
+
+ // preview
+ rXFSet.ClearItem (XATTR_FILLFLOATTRANSPARENCE);
+ ModifyTransparentHdl_Impl(*m_xMtrTransparent);
+}
+
+IMPL_LINK_NOARG(SvxTransparenceTabPage, ClickTransGradientHdl_Impl, weld::Toggleable&, void)
+{
+ // enable gradient, disable other
+ ActivateLinear(false);
+ ActivateGradient(true);
+
+ // preview
+ rXFSet.ClearItem (XATTR_FILLTRANSPARENCE);
+ ModifiedTrgrHdl_Impl(nullptr);
+}
+
+SvxTransparenceTabPage::~SvxTransparenceTabPage()
+{
+}
+
+void SvxTransparenceTabPage::ActivateLinear(bool bActivate)
+{
+ m_xMtrTransparent->set_sensitive(bActivate);
+}
+
+IMPL_LINK_NOARG(SvxTransparenceTabPage, ModifyTransparentHdl_Impl, weld::MetricSpinButton&, void)
+{
+ sal_uInt16 nPos = m_xMtrTransparent->get_value(FieldUnit::PERCENT);
+ rXFSet.Put(XFillTransparenceItem(nPos));
+
+ // preview
+ InvalidatePreview();
+}
+
+IMPL_LINK(SvxTransparenceTabPage, ModifiedTrgrListBoxHdl_Impl, weld::ComboBox&, rListBox, void)
+{
+ ModifiedTrgrHdl_Impl(&rListBox);
+}
+
+IMPL_LINK_NOARG(SvxTransparenceTabPage, ModifiedTrgrEditHdl_Impl, weld::MetricSpinButton&, void)
+{
+ ModifiedTrgrHdl_Impl(nullptr);
+}
+
+void SvxTransparenceTabPage::ModifiedTrgrHdl_Impl(const weld::ComboBox* pControl)
+{
+ if (pControl == m_xLbTrgrGradientType.get())
+ {
+ css::awt::GradientStyle eXGS = static_cast<css::awt::GradientStyle>(m_xLbTrgrGradientType->get_active());
+ SetControlState_Impl( eXGS );
+ }
+
+ // preview
+ basegfx::BGradient aTmpGradient(
+ createColorStops(),
+ static_cast<css::awt::GradientStyle>(m_xLbTrgrGradientType->get_active()),
+ Degree10(static_cast<sal_Int16>(m_xMtrTrgrAngle->get_value(FieldUnit::DEGREE)) * 10),
+ static_cast<sal_uInt16>(m_xMtrTrgrCenterX->get_value(FieldUnit::PERCENT)),
+ static_cast<sal_uInt16>(m_xMtrTrgrCenterY->get_value(FieldUnit::PERCENT)),
+ static_cast<sal_uInt16>(m_xMtrTrgrBorder->get_value(FieldUnit::PERCENT)),
+ 100, 100);
+
+ XFillFloatTransparenceItem aItem( aTmpGradient);
+ rXFSet.Put ( aItem );
+
+ InvalidatePreview();
+}
+
+void SvxTransparenceTabPage::ActivateGradient(bool bActivate)
+{
+ m_xGridGradient->set_sensitive(bActivate);
+
+ if (bActivate)
+ {
+ css::awt::GradientStyle eXGS = static_cast<css::awt::GradientStyle>(m_xLbTrgrGradientType->get_active());
+ SetControlState_Impl( eXGS );
+ }
+}
+
+void SvxTransparenceTabPage::SetControlState_Impl(css::awt::GradientStyle eXGS)
+{
+ switch(eXGS)
+ {
+ case css::awt::GradientStyle_LINEAR:
+ case css::awt::GradientStyle_AXIAL:
+ m_xFtTrgrCenterX->set_sensitive(false);
+ m_xMtrTrgrCenterX->set_sensitive(false);
+ m_xFtTrgrCenterY->set_sensitive(false);
+ m_xMtrTrgrCenterY->set_sensitive(false);
+ m_xFtTrgrAngle->set_sensitive(true);
+ m_xMtrTrgrAngle->set_sensitive(true);
+ break;
+
+ case css::awt::GradientStyle_RADIAL:
+ m_xFtTrgrCenterX->set_sensitive(true);
+ m_xMtrTrgrCenterX->set_sensitive(true);
+ m_xFtTrgrCenterY->set_sensitive(true);
+ m_xMtrTrgrCenterY->set_sensitive(true);
+ m_xFtTrgrAngle->set_sensitive(false);
+ m_xMtrTrgrAngle->set_sensitive(false);
+ break;
+
+ case css::awt::GradientStyle_ELLIPTICAL:
+ case css::awt::GradientStyle_SQUARE:
+ case css::awt::GradientStyle_RECT:
+ m_xFtTrgrCenterX->set_sensitive(true);
+ m_xMtrTrgrCenterX->set_sensitive(true);
+ m_xFtTrgrCenterY->set_sensitive(true);
+ m_xMtrTrgrCenterY->set_sensitive(true);
+ m_xFtTrgrAngle->set_sensitive(true);
+ m_xMtrTrgrAngle->set_sensitive(true);
+ break;
+ default:
+ break;
+ }
+}
+
+SvxTransparenceTabPage::SvxTransparenceTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/transparencytabpage.ui", "TransparencyTabPage", &rInAttrs)
+ , rOutAttrs(rInAttrs)
+ , nPageType(PageType::Area)
+ , nDlgType(0)
+ , bBitmap(false)
+ , aXFillAttr(rInAttrs.GetPool())
+ , rXFSet(aXFillAttr.GetItemSet())
+ , m_xRbtTransOff(m_xBuilder->weld_radio_button("RBT_TRANS_OFF"))
+ , m_xRbtTransLinear(m_xBuilder->weld_radio_button("RBT_TRANS_LINEAR"))
+ , m_xRbtTransGradient(m_xBuilder->weld_radio_button("RBT_TRANS_GRADIENT"))
+ , m_xMtrTransparent(m_xBuilder->weld_metric_spin_button("MTR_TRANSPARENT", FieldUnit::PERCENT))
+ , m_xGridGradient(m_xBuilder->weld_widget("gridGradient"))
+ , m_xLbTrgrGradientType(m_xBuilder->weld_combo_box("LB_TRGR_GRADIENT_TYPES"))
+ , m_xFtTrgrCenterX(m_xBuilder->weld_label("FT_TRGR_CENTER_X"))
+ , m_xMtrTrgrCenterX(m_xBuilder->weld_metric_spin_button("MTR_TRGR_CENTER_X", FieldUnit::PERCENT))
+ , m_xFtTrgrCenterY(m_xBuilder->weld_label("FT_TRGR_CENTER_Y"))
+ , m_xMtrTrgrCenterY(m_xBuilder->weld_metric_spin_button("MTR_TRGR_CENTER_Y", FieldUnit::PERCENT))
+ , m_xFtTrgrAngle(m_xBuilder->weld_label("FT_TRGR_ANGLE"))
+ , m_xMtrTrgrAngle(m_xBuilder->weld_metric_spin_button("MTR_TRGR_ANGLE", FieldUnit::DEGREE))
+ , m_xMtrTrgrBorder(m_xBuilder->weld_metric_spin_button("MTR_TRGR_BORDER", FieldUnit::PERCENT))
+ , m_xMtrTrgrStartValue(m_xBuilder->weld_metric_spin_button("MTR_TRGR_START_VALUE", FieldUnit::PERCENT))
+ , m_xMtrTrgrEndValue(m_xBuilder->weld_metric_spin_button("MTR_TRGR_END_VALUE", FieldUnit::PERCENT))
+ , m_xCtlBitmapBorder(m_xBuilder->weld_widget("bitmap_border"))
+ , m_xCtlXRectBorder(m_xBuilder->weld_widget("trans_border"))
+ , m_xCtlBitmapPreview(new weld::CustomWeld(*m_xBuilder, "CTL_IMAGE_PREVIEW", m_aCtlBitmapPreview))
+ , m_xCtlXRectPreview(new weld::CustomWeld(*m_xBuilder, "CTL_TRANS_PREVIEW", m_aCtlXRectPreview))
+{
+ // main selection
+ m_xRbtTransOff->connect_toggled(LINK(this, SvxTransparenceTabPage, ClickTransOffHdl_Impl));
+ m_xRbtTransLinear->connect_toggled(LINK(this, SvxTransparenceTabPage, ClickTransLinearHdl_Impl));
+ m_xRbtTransGradient->connect_toggled(LINK(this, SvxTransparenceTabPage, ClickTransGradientHdl_Impl));
+
+ // linear transparency
+ m_xMtrTransparent->set_value(50, FieldUnit::PERCENT);
+ m_xMtrTransparent->connect_value_changed(LINK(this, SvxTransparenceTabPage, ModifyTransparentHdl_Impl));
+
+ // gradient transparency
+ m_xMtrTrgrEndValue->set_value(100, FieldUnit::PERCENT);
+ m_xMtrTrgrStartValue->set_value(0, FieldUnit::PERCENT);
+ Link<weld::MetricSpinButton&,void> aLink = LINK( this, SvxTransparenceTabPage, ModifiedTrgrEditHdl_Impl);
+ m_xLbTrgrGradientType->connect_changed(LINK(this, SvxTransparenceTabPage, ModifiedTrgrListBoxHdl_Impl));
+ m_xMtrTrgrCenterX->connect_value_changed( aLink );
+ m_xMtrTrgrCenterY->connect_value_changed( aLink );
+ m_xMtrTrgrAngle->connect_value_changed( aLink );
+ m_xMtrTrgrBorder->connect_value_changed( aLink );
+ m_xMtrTrgrStartValue->connect_value_changed( aLink );
+ m_xMtrTrgrEndValue->connect_value_changed( aLink );
+
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+}
+
+std::unique_ptr<SfxTabPage> SvxTransparenceTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrs)
+{
+ return std::make_unique<SvxTransparenceTabPage>(pPage, pController, *rAttrs);
+}
+
+bool SvxTransparenceTabPage::FillItemSet(SfxItemSet* rAttrs)
+{
+ const SfxPoolItem* pGradientItem = nullptr;
+ const SfxPoolItem* pLinearItem = nullptr;
+ SfxItemState eStateGradient(rOutAttrs.GetItemState(XATTR_FILLFLOATTRANSPARENCE, true, &pGradientItem));
+ SfxItemState eStateLinear(rOutAttrs.GetItemState(XATTR_FILLTRANSPARENCE, true, &pLinearItem));
+ bool bGradActive = (eStateGradient == SfxItemState::SET && static_cast<const XFillFloatTransparenceItem*>(pGradientItem)->IsEnabled());
+ bool bLinearActive = (eStateLinear == SfxItemState::SET && static_cast<const XFillTransparenceItem*>(pLinearItem)->GetValue() != 0);
+
+ bool bGradUsed = (eStateGradient == SfxItemState::DONTCARE);
+ bool bLinearUsed = (eStateLinear == SfxItemState::DONTCARE);
+
+ bool bModified(false);
+ bool bSwitchOffLinear(false);
+ bool bSwitchOffGradient(false);
+
+ if (m_xMtrTransparent->get_sensitive())
+ {
+ // linear transparence
+ sal_uInt16 nPos = m_xMtrTransparent->get_value(FieldUnit::PERCENT);
+ if (m_xMtrTransparent->get_value_changed_from_saved() || !bLinearActive)
+ {
+ XFillTransparenceItem aItem(nPos);
+ SdrPercentItem aShadowItem(makeSdrShadowTransparenceItem(nPos));
+ const SfxPoolItem* pOld = GetOldItem(*rAttrs, XATTR_FILLTRANSPARENCE);
+ if(!pOld || !(*static_cast<const XFillTransparenceItem*>(pOld) == aItem) || !bLinearActive)
+ {
+ rAttrs->Put(aItem);
+ rAttrs->Put(aShadowItem);
+ bModified = true;
+ bSwitchOffGradient = true;
+ }
+ }
+ }
+ else if (m_xGridGradient->get_sensitive())
+ {
+ // transparence gradient, fill ItemSet from values
+ if (!bGradActive
+ || m_xLbTrgrGradientType->get_value_changed_from_saved()
+ || m_xMtrTrgrAngle->get_value_changed_from_saved()
+ || m_xMtrTrgrCenterX->get_value_changed_from_saved()
+ || m_xMtrTrgrCenterY->get_value_changed_from_saved()
+ || m_xMtrTrgrBorder->get_value_changed_from_saved()
+ || m_xMtrTrgrStartValue->get_value_changed_from_saved()
+ || m_xMtrTrgrEndValue->get_value_changed_from_saved())
+ {
+ basegfx::BGradient aTmpGradient(
+ createColorStops(),
+ static_cast<css::awt::GradientStyle>(m_xLbTrgrGradientType->get_active()),
+ Degree10(static_cast<sal_Int16>(m_xMtrTrgrAngle->get_value(FieldUnit::DEGREE)) * 10),
+ static_cast<sal_uInt16>(m_xMtrTrgrCenterX->get_value(FieldUnit::PERCENT)),
+ static_cast<sal_uInt16>(m_xMtrTrgrCenterY->get_value(FieldUnit::PERCENT)),
+ static_cast<sal_uInt16>(m_xMtrTrgrBorder->get_value(FieldUnit::PERCENT)),
+ 100, 100);
+
+ XFillFloatTransparenceItem aItem(aTmpGradient);
+ const SfxPoolItem* pOld = GetOldItem(*rAttrs, XATTR_FILLFLOATTRANSPARENCE);
+
+ if(!pOld || !(*static_cast<const XFillFloatTransparenceItem*>(pOld) == aItem) || !bGradActive)
+ {
+ rAttrs->Put(aItem);
+ bModified = true;
+ bSwitchOffLinear = true;
+ }
+ }
+ }
+ else
+ {
+ // no transparence
+ bSwitchOffGradient = true;
+ bSwitchOffLinear = true;
+ }
+
+ // disable unused XFillFloatTransparenceItem
+ if(bSwitchOffGradient && (bGradActive || bGradUsed))
+ {
+ // basegfx::BGradient() default already creates [COL_BLACK, COL_WHITE] with same defaults
+ // basegfx::BGradient() default also sets the Start/EndIntensity to 100 already
+ basegfx::BGradient aGrad;
+
+ XFillFloatTransparenceItem aItem(aGrad);
+ aItem.SetEnabled(false);
+ rAttrs->Put(aItem);
+ bModified = true;
+ }
+
+ // disable unused XFillFloatTransparenceItem
+ if(bSwitchOffLinear && (bLinearActive || bLinearUsed))
+ {
+ XFillTransparenceItem aItem(0);
+ SdrPercentItem aShadowItem(makeSdrShadowTransparenceItem(0));
+ rAttrs->Put(aItem);
+ rAttrs->Put(aShadowItem);
+ bModified = true;
+ }
+ rAttrs->Put(CntUInt16Item(SID_PAGE_TYPE, static_cast<sal_uInt16>(nPageType)));
+ return bModified;
+}
+
+void SvxTransparenceTabPage::Reset(const SfxItemSet* rAttrs)
+{
+ const XFillFloatTransparenceItem* pGradientItem =
+ rAttrs->GetItemIfSet(XATTR_FILLFLOATTRANSPARENCE);
+ bool bGradActive = (pGradientItem && pGradientItem->IsEnabled());
+ if(!pGradientItem)
+ pGradientItem = &rAttrs->Get(XATTR_FILLFLOATTRANSPARENCE);
+
+ const XFillTransparenceItem* pLinearItem =
+ rAttrs->GetItemIfSet(XATTR_FILLTRANSPARENCE);
+ bool bLinearActive = (pLinearItem && pLinearItem->GetValue() != 0);
+ if(!pLinearItem)
+ pLinearItem = &rAttrs->Get(XATTR_FILLTRANSPARENCE);
+
+ // transparence gradient
+ const basegfx::BGradient& rGradient = pGradientItem->GetGradientValue();
+ css::awt::GradientStyle eXGS(rGradient.GetGradientStyle());
+ m_xLbTrgrGradientType->set_active(sal::static_int_cast< sal_Int32 >(eXGS));
+ m_xMtrTrgrAngle->set_value(rGradient.GetAngle().get() / 10, FieldUnit::DEGREE);
+ m_xMtrTrgrBorder->set_value(rGradient.GetBorder(), FieldUnit::PERCENT);
+ m_xMtrTrgrCenterX->set_value(rGradient.GetXOffset(), FieldUnit::PERCENT);
+ m_xMtrTrgrCenterY->set_value(rGradient.GetYOffset(), FieldUnit::PERCENT);
+ const Color aStart(rGradient.GetColorStops().front().getStopColor());
+ const Color aEnd(rGradient.GetColorStops().back().getStopColor());
+ m_xMtrTrgrStartValue->set_value(static_cast<sal_uInt16>(((static_cast<sal_uInt16>(aStart.GetRed()) + 1) * 100) / 255), FieldUnit::PERCENT);
+ m_xMtrTrgrEndValue->set_value(static_cast<sal_uInt16>(((static_cast<sal_uInt16>(aEnd.GetRed()) + 1) * 100) / 255), FieldUnit::PERCENT);
+
+ // MCGR: preserve ColorStops if given
+ // tdf#155901 We need offset of first and last stop, so include them.
+ if (rGradient.GetColorStops().size() >= 2)
+ maColorStops = rGradient.GetColorStops();
+ else
+ maColorStops.clear();
+
+ // linear transparence
+ sal_uInt16 nTransp = pLinearItem->GetValue();
+ m_xMtrTransparent->set_value(bLinearActive ? nTransp : 50, FieldUnit::PERCENT);
+ ModifyTransparentHdl_Impl(*m_xMtrTransparent);
+
+ // select the correct radio button
+ if(bGradActive)
+ {
+ // transparence gradient, set controls appropriate to item
+ m_xRbtTransGradient->set_active(true);
+ ClickTransGradientHdl_Impl(*m_xRbtTransGradient);
+ }
+ else if(bLinearActive)
+ {
+ // linear transparence
+ m_xRbtTransLinear->set_active(true);
+ ClickTransLinearHdl_Impl(*m_xRbtTransLinear);
+ }
+ else
+ {
+ // no transparence
+ m_xRbtTransOff->set_active(true);
+ ClickTransOffHdl_Impl(*m_xRbtTransOff);
+ ModifiedTrgrHdl_Impl(nullptr);
+ }
+
+ // save values
+ ChangesApplied();
+ bool bActive = InitPreview ( *rAttrs );
+ InvalidatePreview ( bActive );
+}
+
+void SvxTransparenceTabPage::ChangesApplied()
+{
+ m_xMtrTransparent->save_value();
+ m_xLbTrgrGradientType->save_value();
+ m_xMtrTrgrCenterX->save_value();
+ m_xMtrTrgrCenterY->save_value();
+ m_xMtrTrgrAngle->save_value();
+ m_xMtrTrgrBorder->save_value();
+ m_xMtrTrgrStartValue->save_value();
+ m_xMtrTrgrEndValue->save_value();
+}
+
+void SvxTransparenceTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ const CntUInt16Item* pPageTypeItem = rSet.GetItem<SfxUInt16Item>(SID_PAGE_TYPE, false);
+ if (pPageTypeItem)
+ SetPageType(static_cast<PageType>(pPageTypeItem->GetValue()));
+
+ if(nDlgType == 0) // area dialog
+ nPageType = PageType::Transparence;
+
+ InitPreview ( rSet );
+}
+
+DeactivateRC SvxTransparenceTabPage::DeactivatePage(SfxItemSet* _pSet)
+{
+ if( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+// Preview-Methods
+
+bool SvxTransparenceTabPage::InitPreview(const SfxItemSet& rSet)
+{
+ // set transparencetype for preview
+ if (m_xRbtTransOff->get_active())
+ {
+ ClickTransOffHdl_Impl(*m_xRbtTransOff);
+ }
+ else if (m_xRbtTransLinear->get_active())
+ {
+ ClickTransLinearHdl_Impl(*m_xRbtTransLinear);
+ }
+ else if (m_xRbtTransGradient->get_active())
+ {
+ ClickTransGradientHdl_Impl(*m_xRbtTransGradient);
+ }
+
+ // Get fillstyle for preview
+ rXFSet.Put ( rSet.Get(XATTR_FILLSTYLE) );
+ rXFSet.Put ( rSet.Get(XATTR_FILLCOLOR) );
+ rXFSet.Put ( rSet.Get(XATTR_FILLGRADIENT) );
+ rXFSet.Put ( rSet.Get(XATTR_FILLHATCH) );
+ rXFSet.Put ( rSet.Get(XATTR_FILLBACKGROUND) );
+ rXFSet.Put ( rSet.Get(XATTR_FILLBITMAP) );
+
+ m_aCtlXRectPreview.SetAttributes( aXFillAttr.GetItemSet() );
+ m_aCtlBitmapPreview.SetAttributes( aXFillAttr.GetItemSet() );
+
+ bBitmap = rSet.Get(XATTR_FILLSTYLE).GetValue() == drawing::FillStyle_BITMAP;
+
+ // show the right preview window
+ if ( bBitmap )
+ {
+ m_xCtlBitmapBorder->show();
+ m_xCtlXRectBorder->hide();
+ }
+ else
+ {
+ m_xCtlBitmapBorder->hide();
+ m_xCtlXRectBorder->show();
+ }
+
+ return !m_xRbtTransOff->get_active();
+}
+
+void SvxTransparenceTabPage::InvalidatePreview (bool bEnable)
+{
+ if ( bBitmap )
+ {
+ if ( bEnable )
+ {
+ m_xCtlBitmapPreview->set_sensitive(true);
+ m_aCtlBitmapPreview.SetAttributes( aXFillAttr.GetItemSet() );
+ }
+ else
+ m_xCtlBitmapPreview->set_sensitive(false);
+ m_xCtlBitmapPreview->queue_draw();
+ }
+ else
+ {
+ if ( bEnable )
+ {
+ m_xCtlXRectPreview->set_sensitive(true);
+ m_aCtlXRectPreview.SetAttributes( aXFillAttr.GetItemSet() );
+ }
+ else
+ m_xCtlXRectPreview->set_sensitive(false);
+ m_xCtlXRectPreview->queue_draw();
+ }
+}
+
+basegfx::BColorStops SvxTransparenceTabPage::createColorStops()
+{
+ basegfx::BColorStops aColorStops;
+ basegfx::BColor aStartBColor(m_xMtrTrgrStartValue->get_value(FieldUnit::PERCENT) / 100.0);
+ aStartBColor.clamp();
+ basegfx::BColor aEndBColor(m_xMtrTrgrEndValue->get_value(FieldUnit::PERCENT) / 100.0);
+ aEndBColor.clamp();
+
+ if(maColorStops.size() >= 2)
+ {
+ aColorStops = maColorStops;
+ aColorStops.front() = basegfx::BColorStop(maColorStops.front().getStopOffset(), aStartBColor);
+ aColorStops.back() = basegfx::BColorStop(maColorStops.back().getStopOffset(), aEndBColor);
+ }
+ else
+ {
+ aColorStops.emplace_back(0.0, aStartBColor);
+ aColorStops.emplace_back(1.0, aEndBColor);
+ }
+
+ return aColorStops;
+}
+
+void SvxTransparenceTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxUInt16Item* pPageTypeItem = aSet.GetItem<SfxUInt16Item>(SID_PAGE_TYPE, false);
+ const SfxUInt16Item* pDlgTypeItem = aSet.GetItem<SfxUInt16Item>(SID_DLG_TYPE, false);
+
+ if (pPageTypeItem)
+ SetPageType(static_cast<PageType>(pPageTypeItem->GetValue()));
+ if (pDlgTypeItem)
+ SetDlgType(pDlgTypeItem->GetValue());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/transfrm.cxx b/cui/source/tabpages/transfrm.cxx
new file mode 100644
index 0000000000..05fd9e5670
--- /dev/null
+++ b/cui/source/tabpages/transfrm.cxx
@@ -0,0 +1,1562 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <algorithm>
+
+#include <svx/EnhancedCustomShape2d.hxx>
+#include <svx/sdangitm.hxx>
+#include <svx/svdundo.hxx>
+#include <svx/svdview.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdoashp.hxx>
+#include <svx/sderitm.hxx>
+#include <svx/svxids.hrc>
+#include <svx/transfrmhelper.hxx>
+#include <svtools/unitconv.hxx>
+
+#include <transfrm.hxx>
+#include <svx/dlgutil.hxx>
+#include <svx/anchorid.hxx>
+#include <svl/rectitem.hxx>
+#include <swpossizetabpage.hxx>
+#include <vcl/canvastools.hxx>
+#include <vcl/fieldvalues.hxx>
+
+// static ----------------------------------------------------------------
+
+const WhichRangesContainer SvxPositionSizeTabPage::pPosSizeRanges(svl::Items<
+ SID_ATTR_TRANSFORM_POS_X, SID_ATTR_TRANSFORM_POS_Y,
+ SID_ATTR_TRANSFORM_WIDTH, SID_ATTR_TRANSFORM_SIZE_POINT,
+ SID_ATTR_TRANSFORM_PROTECT_POS, SID_ATTR_TRANSFORM_INTERN,
+ SID_ATTR_TRANSFORM_AUTOWIDTH, SID_ATTR_TRANSFORM_AUTOHEIGHT,
+ SID_ATTR_TRANSFORM_ANCHOR, SID_ATTR_TRANSFORM_VERT_ORIENT
+>);
+
+const WhichRangesContainer SvxAngleTabPage::pAngleRanges(svl::Items<
+ SID_ATTR_TRANSFORM_ROT_X, SID_ATTR_TRANSFORM_ANGLE,
+ SID_ATTR_TRANSFORM_INTERN, SID_ATTR_TRANSFORM_INTERN
+>);
+
+const WhichRangesContainer SvxSlantTabPage::pSlantRanges(svl::Items<
+ SDRATTR_CORNER_RADIUS, SDRATTR_CORNER_RADIUS,
+ SID_ATTR_TRANSFORM_INTERN, SID_ATTR_TRANSFORM_INTERN,
+ SID_ATTR_TRANSFORM_SHEAR, SID_ATTR_TRANSFORM_SHEAR_VERTICAL
+>);
+
+/*************************************************************************
+|*
+|* constructor of the tab dialog: adds the pages to the dialog
+|*
+\************************************************************************/
+
+SvxTransformTabDialog::SvxTransformTabDialog(weld::Window* pParent, const SfxItemSet* pAttr,
+ const SdrView* pSdrView, SvxAnchorIds nAnchorTypes)
+ : SfxTabDialogController(pParent, "cui/ui/positionsizedialog.ui", "PositionAndSizeDialog", pAttr)
+ , pView(pSdrView)
+ , nAnchorCtrls(nAnchorTypes)
+{
+ DBG_ASSERT(pView, "no valid view (!)");
+
+ //different positioning page in Writer
+ if(nAnchorCtrls & (SvxAnchorIds::Paragraph | SvxAnchorIds::Character | SvxAnchorIds::Page | SvxAnchorIds::Fly))
+ {
+ AddTabPage("RID_SVXPAGE_SWPOSSIZE", SvxSwPosSizeTabPage::Create, SvxSwPosSizeTabPage::GetRanges);
+ RemoveTabPage("RID_SVXPAGE_POSITION_SIZE");
+ }
+ else
+ {
+ AddTabPage("RID_SVXPAGE_POSITION_SIZE", SvxPositionSizeTabPage::Create, SvxPositionSizeTabPage::GetRanges);
+ RemoveTabPage("RID_SVXPAGE_SWPOSSIZE");
+ }
+
+ AddTabPage("RID_SVXPAGE_ANGLE", SvxAngleTabPage::Create, SvxAngleTabPage::GetRanges);
+ AddTabPage("RID_SVXPAGE_SLANT", SvxSlantTabPage::Create, SvxSlantTabPage::GetRanges);
+}
+
+
+void SvxTransformTabDialog::PageCreated(const OUString& rId, SfxTabPage &rPage)
+{
+ if (rId == "RID_SVXPAGE_POSITION_SIZE")
+ {
+ SvxPositionSizeTabPage& rSvxPos = static_cast<SvxPositionSizeTabPage&>(rPage);
+ rSvxPos.SetView(pView);
+ rSvxPos.Construct();
+
+ if(nAnchorCtrls & SvxAnchorIds::NoResize)
+ {
+ rSvxPos.DisableResize();
+ }
+
+ if(nAnchorCtrls & SvxAnchorIds::NoProtect)
+ {
+ rSvxPos.DisableProtect();
+ rSvxPos.UpdateControlStates();
+ }
+ }
+ else if (rId == "RID_SVXPAGE_SWPOSSIZE")
+ {
+ SvxSwPosSizeTabPage& rSwPos = static_cast<SvxSwPosSizeTabPage&>(rPage);
+
+ rSwPos.EnableAnchorTypes(nAnchorCtrls);
+ rSwPos.SetValidateFramePosLink(aValidateLink);
+ rSwPos.SetView(pView);
+ }
+ else if (rId == "RID_SVXPAGE_ANGLE")
+ {
+ SvxAngleTabPage& rSvxAng = static_cast<SvxAngleTabPage&>(rPage);
+
+ rSvxAng.SetView( pView );
+ rSvxAng.Construct();
+ }
+ else if (rId == "RID_SVXPAGE_SLANT")
+ {
+ SvxSlantTabPage& rSvxSlnt = static_cast<SvxSlantTabPage&>(rPage);
+
+ rSvxSlnt.SetView( pView );
+ rSvxSlnt.Construct();
+ }
+}
+
+void SvxTransformTabDialog::SetValidateFramePosLink(const Link<SvxSwFrameValidation&,void>& rLink)
+{
+ aValidateLink = rLink;
+}
+
+/*************************************************************************
+|*
+|* dialog for changing the positions of the rotation
+|* angle and the rotation angle of the graphic objects
+|*
+\************************************************************************/
+SvxAngleTabPage::SvxAngleTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SvxTabPage(pPage, pController, "cui/ui/rotationtabpage.ui", "Rotation", rInAttrs)
+ , pView(nullptr)
+ , eDlgUnit(FieldUnit::NONE)
+ , m_aCtlRect(this)
+ , m_xFlPosition(m_xBuilder->weld_widget("FL_POSITION"))
+ , m_xMtrPosX(m_xBuilder->weld_metric_spin_button("MTR_FLD_POS_X", FieldUnit::CM))
+ , m_xMtrPosY(m_xBuilder->weld_metric_spin_button("MTR_FLD_POS_Y", FieldUnit::CM))
+ , m_xCtlRect(new weld::CustomWeld(*m_xBuilder, "CTL_RECT", m_aCtlRect))
+ , m_xFlAngle(m_xBuilder->weld_widget("FL_ANGLE"))
+ , m_xNfAngle(m_xBuilder->weld_metric_spin_button("NF_ANGLE", FieldUnit::DEGREE))
+ , m_xCtlAngle(new svx::DialControl)
+ , m_xCtlAngleWin(new weld::CustomWeld(*m_xBuilder, "CTL_ANGLE", *m_xCtlAngle))
+{
+ // calculate PoolUnit
+ SfxItemPool* pPool = rInAttrs.GetPool();
+ DBG_ASSERT( pPool, "no pool (!)" );
+ ePoolUnit = pPool->GetMetric(SID_ATTR_TRANSFORM_POS_X);
+
+ m_xCtlAngle->SetLinkedField(m_xNfAngle.get(), 2);
+}
+
+SvxAngleTabPage::~SvxAngleTabPage()
+{
+}
+
+void SvxAngleTabPage::Construct()
+{
+ DBG_ASSERT(pView, "No valid view (!)");
+ eDlgUnit = GetModuleFieldUnit(GetItemSet());
+ SetFieldUnit(*m_xMtrPosX, eDlgUnit, true);
+ SetFieldUnit(*m_xMtrPosY, eDlgUnit, true);
+
+ if (FieldUnit::MILE == eDlgUnit || FieldUnit::KM == eDlgUnit)
+ {
+ m_xMtrPosX->set_digits(3);
+ m_xMtrPosY->set_digits(3);
+ }
+
+ { // #i75273#
+ ::tools::Rectangle aTempRect(pView->GetAllMarkedRect());
+ pView->GetSdrPageView()->LogicToPagePos(aTempRect);
+ maRange = vcl::unotools::b2DRectangleFromRectangle(aTempRect);
+ }
+
+ // Take anchor into account (Writer)
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+
+ if(rMarkList.GetMarkCount())
+ {
+ const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ maAnchor = basegfx::B2DPoint(pObj->GetAnchorPos().X(), pObj->GetAnchorPos().Y());
+
+ if(!maAnchor.equalZero()) // -> Writer
+ {
+ maRange = basegfx::B2DRange(maRange.getMinimum() - maAnchor, maRange.getMaximum() - maAnchor);
+ }
+ }
+
+ // take scale into account
+ const Fraction aUIScale(pView->GetModel().GetUIScale());
+ TransfrmHelper::ScaleRect(maRange, aUIScale);
+
+ // take UI units into account
+ sal_uInt16 nDigits(m_xMtrPosX->get_digits());
+ TransfrmHelper::ConvertRect(maRange, nDigits, ePoolUnit, eDlgUnit);
+
+ if(!pView->IsRotateAllowed())
+ {
+ m_xFlPosition->set_sensitive(false);
+ m_xFlAngle->set_sensitive(false);
+ }
+}
+
+bool SvxAngleTabPage::FillItemSet(SfxItemSet* rSet)
+{
+ bool bModified = false;
+
+ if (m_xCtlAngle->IsValueModified() || m_xMtrPosX->get_value_changed_from_saved() || m_xMtrPosY->get_value_changed_from_saved())
+ {
+ const double fUIScale(double(pView->GetModel().GetUIScale()));
+ const double fTmpX((GetCoreValue(*m_xMtrPosX, ePoolUnit) + maAnchor.getX()) * fUIScale);
+ const double fTmpY((GetCoreValue(*m_xMtrPosY, ePoolUnit) + maAnchor.getY()) * fUIScale);
+
+ rSet->Put(SdrAngleItem(SID_ATTR_TRANSFORM_ANGLE, m_xCtlAngle->GetRotation()));
+ rSet->Put(SfxInt32Item(SID_ATTR_TRANSFORM_ROT_X, basegfx::fround(fTmpX)));
+ rSet->Put(SfxInt32Item(SID_ATTR_TRANSFORM_ROT_Y, basegfx::fround(fTmpY)));
+
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+
+void SvxAngleTabPage::Reset(const SfxItemSet* rAttrs)
+{
+ const double fUIScale(double(pView->GetModel().GetUIScale()));
+
+ const SfxPoolItem* pItem = GetItem( *rAttrs, SID_ATTR_TRANSFORM_ROT_X );
+ if(pItem)
+ {
+ const double fTmp((static_cast<double>(static_cast<const SfxInt32Item*>(pItem)->GetValue()) - maAnchor.getX()) / fUIScale);
+ SetMetricValue(*m_xMtrPosX, basegfx::fround(fTmp), ePoolUnit);
+ }
+ else
+ {
+ m_xMtrPosX->set_text(OUString());
+ }
+
+ pItem = GetItem(*rAttrs, SID_ATTR_TRANSFORM_ROT_Y);
+ if(pItem)
+ {
+ const double fTmp((static_cast<double>(static_cast<const SfxInt32Item*>(pItem)->GetValue()) - maAnchor.getY()) / fUIScale);
+ SetMetricValue(*m_xMtrPosY, basegfx::fround(fTmp), ePoolUnit);
+ }
+ else
+ {
+ m_xMtrPosY->set_text(OUString());
+ }
+
+ pItem = GetItem( *rAttrs, SID_ATTR_TRANSFORM_ANGLE );
+ if(pItem)
+ {
+ m_xCtlAngle->SetRotation(static_cast<const SdrAngleItem*>(pItem)->GetValue());
+ }
+ else
+ {
+ m_xCtlAngle->SetRotation(0_deg100);
+ }
+ m_xCtlAngle->SaveValue();
+ m_xMtrPosX->save_value();
+ m_xMtrPosY->save_value();
+}
+
+std::unique_ptr<SfxTabPage> SvxAngleTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxAngleTabPage>(pPage, pController, *rSet);
+}
+
+void SvxAngleTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ if(SfxBoolItem const * bPosProtect = rSet.GetItemIfSet( SID_ATTR_TRANSFORM_PROTECT_POS, false ))
+ {
+ m_xFlPosition->set_sensitive(!bPosProtect->GetValue());
+ m_xFlAngle->set_sensitive(!bPosProtect->GetValue());
+ }
+}
+
+DeactivateRC SvxAngleTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if(_pSet)
+ {
+ FillItemSet(_pSet);
+ }
+
+ return DeactivateRC::LeavePage;
+}
+
+void SvxAngleTabPage::PointChanged(weld::DrawingArea* pDrawingArea, RectPoint eRP)
+{
+ if (pDrawingArea != m_aCtlRect.GetDrawingArea())
+ return;
+
+ switch(eRP)
+ {
+ case RectPoint::LT:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMinX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMinY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::MT:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getCenter().getX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMinY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::RT:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMaxX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMinY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::LM:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMinX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getCenter().getY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::MM:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getCenter().getX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getCenter().getY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::RM:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMaxX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getCenter().getY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::LB:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMinX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMaxY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::MB:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getCenter().getX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMaxY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::RB:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMaxX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMaxY()), FieldUnit::NONE );
+ break;
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* dialog for changing slant and corner radius
+|*
+\************************************************************************/
+SvxSlantTabPage::SvxSlantTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/slantcornertabpage.ui", "SlantAndCornerRadius", &rInAttrs)
+ , pView(nullptr)
+ , eDlgUnit(FieldUnit::NONE)
+ , m_xFlRadius(m_xBuilder->weld_widget("FL_RADIUS"))
+ , m_xMtrRadius(m_xBuilder->weld_metric_spin_button("MTR_FLD_RADIUS", FieldUnit::CM))
+ , m_xFlAngle(m_xBuilder->weld_widget("FL_SLANT"))
+ , m_xMtrAngle(m_xBuilder->weld_metric_spin_button("MTR_FLD_ANGLE", FieldUnit::DEGREE))
+{
+ for (int i = 0; i < 2; ++i)
+ {
+ m_aControlGroups[i] = m_xBuilder->weld_widget("controlgroups" + OUString::number(i+1));
+ m_aControlGroupX[i] = m_xBuilder->weld_widget("controlgroupx" + OUString::number(i+1));
+ m_aControlX[i] = m_xBuilder->weld_metric_spin_button("controlx" + OUString::number(i+1), FieldUnit::CM);
+ m_aControlGroupY[i] = m_xBuilder->weld_widget("controlgroupy" + OUString::number(i+1));
+ m_aControlY[i] = m_xBuilder->weld_metric_spin_button("controly" + OUString::number(i+1), FieldUnit::CM);
+ }
+
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ // evaluate PoolUnit
+ SfxItemPool* pPool = rInAttrs.GetPool();
+ assert(pPool && "no pool (!)");
+ ePoolUnit = pPool->GetMetric( SID_ATTR_TRANSFORM_POS_X );
+}
+
+SvxSlantTabPage::~SvxSlantTabPage()
+{
+}
+
+void SvxSlantTabPage::Construct()
+{
+ // get the range
+ DBG_ASSERT(pView, "no valid view (!)");
+ eDlgUnit = GetModuleFieldUnit(GetItemSet());
+ SetFieldUnit(*m_xMtrRadius, eDlgUnit, true);
+ for (int i = 0; i < 2; ++i)
+ {
+ SetFieldUnit(*m_aControlX[i], eDlgUnit, true);
+ SetFieldUnit(*m_aControlY[i], eDlgUnit, true);
+ }
+
+ { // #i75273#
+ ::tools::Rectangle aTempRect(pView->GetAllMarkedRect());
+ pView->GetSdrPageView()->LogicToPagePos(aTempRect);
+ }
+}
+
+bool SvxSlantTabPage::FillItemSet(SfxItemSet* rAttrs)
+{
+ bool bModified = false;
+
+ if (m_xMtrRadius->get_value_changed_from_saved())
+ {
+ Fraction aUIScale = pView->GetModel().GetUIScale();
+ tools::Long nTmp = tools::Long(GetCoreValue(*m_xMtrRadius, ePoolUnit) * aUIScale);
+
+ rAttrs->Put( makeSdrEckenradiusItem( nTmp ) );
+ bModified = true;
+ }
+
+ if (m_xMtrAngle->get_value_changed_from_saved())
+ {
+ sal_Int32 nValue = static_cast<sal_Int32>(m_xMtrAngle->get_value(FieldUnit::NONE));
+ rAttrs->Put( SdrAngleItem( SID_ATTR_TRANSFORM_SHEAR, Degree100(nValue) ) );
+ bModified = true;
+ }
+
+ if( bModified )
+ {
+ // set reference points
+ ::tools::Rectangle aObjectRect(pView->GetAllMarkedRect());
+ pView->GetSdrPageView()->LogicToPagePos(aObjectRect);
+ Point aPt = aObjectRect.Center();
+
+ rAttrs->Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR_X, aPt.X()));
+ rAttrs->Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR_Y, aPt.Y()));
+ rAttrs->Put( SfxBoolItem( SID_ATTR_TRANSFORM_SHEAR_VERTICAL, false ) );
+ }
+
+ bool bControlPointsChanged = false;
+ for (int i = 0; i < 2; ++i)
+ {
+ bControlPointsChanged |= (m_aControlX[i]->get_value_changed_from_saved() ||
+ m_aControlY[i]->get_value_changed_from_saved());
+ }
+
+ if (!bControlPointsChanged)
+ return bModified;
+
+ bool bSelectionIsSdrObjCustomShape(false);
+
+ while(true)
+ {
+ if(nullptr == pView)
+ {
+ break;
+ }
+
+ if(0 == pView->GetMarkedObjectList().GetMarkCount())
+ {
+ break;
+ }
+
+ SdrObject* pCandidate(pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj());
+
+ if(nullptr == pCandidate)
+ {
+ break;
+ }
+
+ if(nullptr == dynamic_cast< SdrObjCustomShape* >(pCandidate))
+ {
+ break;
+ }
+
+ bSelectionIsSdrObjCustomShape = true;
+ break;
+ }
+
+ if(bSelectionIsSdrObjCustomShape)
+ {
+ SdrObjCustomShape& rSdrObjCustomShape(
+ static_cast< SdrObjCustomShape& >(
+ *pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj()));
+ SdrModel& rModel(rSdrObjCustomShape.getSdrModelFromSdrObject());
+ std::unique_ptr<SdrUndoAction> pUndo;
+ if (rModel.IsUndoEnabled())
+ pUndo = rModel.GetSdrUndoFactory().CreateUndoAttrObject(rSdrObjCustomShape);
+
+ if(pUndo)
+ {
+ rModel.BegUndo(pUndo->GetComment());
+ }
+
+ EnhancedCustomShape2d aShape(rSdrObjCustomShape);
+ ::tools::Rectangle aLogicRect = aShape.GetLogicRect();
+
+ for (int i = 0; i < 2; ++i)
+ {
+ if (m_aControlX[i]->get_value_changed_from_saved() || m_aControlY[i]->get_value_changed_from_saved())
+ {
+ Point aNewPosition(GetCoreValue(*m_aControlX[i], ePoolUnit),
+ GetCoreValue(*m_aControlY[i], ePoolUnit));
+ aNewPosition.Move(aLogicRect.Left(), aLogicRect.Top());
+
+ css::awt::Point aPosition;
+ aPosition.X = aNewPosition.X();
+ aPosition.Y = aNewPosition.Y();
+
+ aShape.SetHandleControllerPosition(i, aPosition);
+ }
+ }
+
+ rSdrObjCustomShape.SetChanged();
+ rSdrObjCustomShape.BroadcastObjectChange();
+ bModified = true;
+
+ if (pUndo)
+ {
+ rModel.AddUndo(std::move(pUndo));
+ rModel.EndUndo();
+ }
+ }
+
+ return bModified;
+}
+
+void SvxSlantTabPage::Reset(const SfxItemSet* rAttrs)
+{
+ // if the view has selected objects, items with SfxItemState::DEFAULT need to be disabled
+ const SfxPoolItem* pItem;
+
+ // corner radius
+ if(!pView->IsEdgeRadiusAllowed())
+ {
+ m_xMtrRadius->set_text("");
+ m_xFlRadius->set_sensitive(false);
+ }
+ else
+ {
+ pItem = GetItem( *rAttrs, SDRATTR_CORNER_RADIUS );
+
+ if( pItem )
+ {
+ const double fUIScale(double(pView->GetModel().GetUIScale()));
+ const double fTmp(static_cast<double>(static_cast<const SdrMetricItem*>(pItem)->GetValue()) / fUIScale);
+ SetMetricValue(*m_xMtrRadius, basegfx::fround(fTmp), ePoolUnit);
+ }
+ else
+ {
+ m_xMtrRadius->set_text("");
+ }
+ }
+
+ m_xMtrRadius->save_value();
+
+ // slant: angle
+ if( !pView->IsShearAllowed() )
+ {
+ m_xMtrAngle->set_text( "" );
+ m_xFlAngle->set_sensitive(false);
+ }
+ else
+ {
+ pItem = GetItem( *rAttrs, SID_ATTR_TRANSFORM_SHEAR );
+
+ if( pItem )
+ {
+ m_xMtrAngle->set_value(static_cast<const SdrAngleItem*>(pItem)->GetValue().get(), FieldUnit::NONE);
+ }
+ else
+ {
+ m_xMtrAngle->set_text("");
+ }
+ }
+
+ m_xMtrAngle->save_value();
+
+ bool bSelectionIsSdrObjCustomShape(false);
+
+ while(true)
+ {
+ if(1 != pView->GetMarkedObjectList().GetMarkCount())
+ {
+ break;
+ }
+
+ SdrObject* pCandidate(pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj());
+
+ if(nullptr == pCandidate)
+ {
+ break;
+ }
+
+ if(nullptr == dynamic_cast< SdrObjCustomShape* >(pCandidate))
+ {
+ break;
+ }
+
+ bSelectionIsSdrObjCustomShape = true;
+ break;
+ }
+
+ if(bSelectionIsSdrObjCustomShape)
+ {
+ SdrObjCustomShape& rSdrObjCustomShape(
+ static_cast< SdrObjCustomShape& >(
+ *pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj()));
+
+ //save geometry
+ const bool bOrigModelChangeState = pView->GetModel().IsChanged();
+ SdrCustomShapeGeometryItem aInitialGeometry(rSdrObjCustomShape.GetMergedItem(SDRATTR_CUSTOMSHAPE_GEOMETRY));
+ EnhancedCustomShape2d aShape(rSdrObjCustomShape);
+
+ for (int i = 0; i < 2; ++i)
+ {
+ Point aInitialPosition;
+ if (!aShape.GetHandlePosition(i, aInitialPosition))
+ break;
+ m_aControlGroups[i]->set_sensitive(true);
+ css::awt::Point aPosition;
+
+ aPosition.X = SAL_MAX_INT32/2;
+ aPosition.Y = SAL_MAX_INT32/2;
+ aShape.SetHandleControllerPosition(i, aPosition);
+ Point aMaxPosition;
+ aShape.GetHandlePosition(i, aMaxPosition);
+
+ aPosition.X = SAL_MIN_INT32/2;
+ aPosition.Y = SAL_MIN_INT32/2;
+ aShape.SetHandleControllerPosition(i, aPosition);
+ Point aMinPosition;
+ aShape.GetHandlePosition(i, aMinPosition);
+
+ ::tools::Rectangle aLogicRect = aShape.GetLogicRect();
+ aInitialPosition.Move(-aLogicRect.Left(), -aLogicRect.Top());
+ aMaxPosition.Move(-aLogicRect.Left(), -aLogicRect.Top());
+ aMinPosition.Move(-aLogicRect.Left(), -aLogicRect.Top());
+
+ SetMetricValue(*m_aControlX[i], aInitialPosition.X(), ePoolUnit);
+ SetMetricValue(*m_aControlY[i], aInitialPosition.Y(), ePoolUnit);
+
+ if (aMaxPosition.X() == aMinPosition.X())
+ m_aControlGroupX[i]->set_sensitive(false);
+ else
+ m_aControlX[i]->set_range(aMinPosition.X(), aMaxPosition.X(), FieldUnit::MM);
+ if (aMaxPosition.Y() == aMinPosition.Y())
+ m_aControlGroupY[i]->set_sensitive(false);
+ else
+ m_aControlY[i]->set_range(aMinPosition.Y(), aMaxPosition.Y(), FieldUnit::MM);
+ }
+
+ //restore geometry
+ rSdrObjCustomShape.SetMergedItem(aInitialGeometry);
+ pView->GetModel().SetChanged(bOrigModelChangeState);
+ }
+
+ for (int i = 0; i < 2; ++i)
+ {
+ m_aControlX[i]->save_value();
+ m_aControlY[i]->save_value();
+ }
+}
+
+std::unique_ptr<SfxTabPage> SvxSlantTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rOutAttrs)
+{
+ return std::make_unique<SvxSlantTabPage>(pPage, pController, *rOutAttrs);
+}
+
+void SvxSlantTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ if(SfxBoolItem const * bPosProtect = rSet.GetItemIfSet( SID_ATTR_TRANSFORM_PROTECT_POS, false ))
+ {
+ m_xFlAngle->set_sensitive(!bPosProtect->GetValue());
+ }
+ if(SfxBoolItem const * bSizeProtect = rSet.GetItemIfSet( SID_ATTR_TRANSFORM_PROTECT_SIZE, false ))
+ {
+ m_xFlAngle->set_sensitive(!bSizeProtect->GetValue());
+ }
+
+}
+
+DeactivateRC SvxSlantTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if(_pSet)
+ {
+ FillItemSet(_pSet);
+ }
+
+ return DeactivateRC::LeavePage;
+}
+
+
+/*************************************************************************
+|*
+|* Dialog for changing position and size of graphic objects
+|*
+\************************************************************************/
+SvxPositionSizeTabPage::SvxPositionSizeTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SvxTabPage(pPage, pController, "cui/ui/possizetabpage.ui", "PositionAndSize", rInAttrs)
+ , mrOutAttrs(rInAttrs)
+ , mpView(nullptr)
+ , meDlgUnit(FieldUnit::NONE)
+ , mnProtectSizeState(TRISTATE_FALSE)
+ , mbPageDisabled(false)
+ , mbProtectDisabled(false)
+ , mbSizeDisabled(false)
+ , mbAdjustDisabled(true)
+ , mbIgnoreAutoGrowWidth(true)
+ , mbIgnoreAutoGrowHeight(true)
+ , mfOldWidth(0.0)
+ , mfOldHeight(0.0)
+ , m_aCtlPos(this)
+ , m_aCtlSize(this)
+ , m_xFlPosition(m_xBuilder->weld_widget("FL_POSITION"))
+ , m_xMtrPosX(m_xBuilder->weld_metric_spin_button("MTR_FLD_POS_X", FieldUnit::CM))
+ , m_xMtrPosY(m_xBuilder->weld_metric_spin_button("MTR_FLD_POS_Y", FieldUnit::CM))
+ , m_xCtlPos(new weld::CustomWeld(*m_xBuilder, "CTL_POSRECT", m_aCtlPos))
+ , m_xFlSize(m_xBuilder->weld_widget("FL_SIZE"))
+ , m_xFtWidth(m_xBuilder->weld_label("FT_WIDTH"))
+ , m_xMtrWidth(m_xBuilder->weld_metric_spin_button("MTR_FLD_WIDTH", FieldUnit::CM))
+ , m_xFtHeight(m_xBuilder->weld_label("FT_HEIGHT"))
+ , m_xMtrHeight(m_xBuilder->weld_metric_spin_button("MTR_FLD_HEIGHT", FieldUnit::CM))
+ , m_xCbxScale(m_xBuilder->weld_check_button("CBX_SCALE"))
+ , m_xCtlSize(new weld::CustomWeld(*m_xBuilder, "CTL_SIZERECT", m_aCtlSize))
+ , m_xFlProtect(m_xBuilder->weld_widget("FL_PROTECT"))
+ , m_xTsbPosProtect(m_xBuilder->weld_check_button("TSB_POSPROTECT"))
+ , m_xTsbSizeProtect(m_xBuilder->weld_check_button("TSB_SIZEPROTECT"))
+ , m_xFlAdjust(m_xBuilder->weld_widget("FL_ADJUST"))
+ , m_xTsbAutoGrowWidth(m_xBuilder->weld_check_button("TSB_AUTOGROW_WIDTH"))
+ , m_xTsbAutoGrowHeight(m_xBuilder->weld_check_button("TSB_AUTOGROW_HEIGHT"))
+{
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ // evaluate PoolUnit
+ SfxItemPool* pPool = mrOutAttrs.GetPool();
+ DBG_ASSERT( pPool, "no pool (!)" );
+ mePoolUnit = pPool->GetMetric( SID_ATTR_TRANSFORM_POS_X );
+
+ m_aCtlPos.SetActualRP(RectPoint::LT);
+ m_aCtlSize.SetActualRP(RectPoint::LT);
+ meRP = RectPoint::LT; // see above
+
+ m_xMtrWidth->connect_value_changed( LINK( this, SvxPositionSizeTabPage, ChangeWidthHdl ) );
+ m_xMtrHeight->connect_value_changed( LINK( this, SvxPositionSizeTabPage, ChangeHeightHdl ) );
+ m_xCbxScale->connect_toggled( LINK( this, SvxPositionSizeTabPage, ClickAutoHdl ) );
+
+ m_xFlAdjust->set_sensitive(false);
+
+ // #i2379# disable controls when protected
+ m_xTsbPosProtect->connect_toggled( LINK( this, SvxPositionSizeTabPage, ChangePosProtectHdl ) );
+ m_xTsbSizeProtect->connect_toggled( LINK( this, SvxPositionSizeTabPage, ChangeSizeProtectHdl ) );
+}
+
+SvxPositionSizeTabPage::~SvxPositionSizeTabPage()
+{
+}
+
+void SvxPositionSizeTabPage::Construct()
+{
+ // get range and work area
+ DBG_ASSERT( mpView, "no valid view (!)" );
+ meDlgUnit = GetModuleFieldUnit( GetItemSet() );
+ SetFieldUnit( *m_xMtrPosX, meDlgUnit, true );
+ SetFieldUnit( *m_xMtrPosY, meDlgUnit, true );
+ SetFieldUnit( *m_xMtrWidth, meDlgUnit, true );
+ SetFieldUnit( *m_xMtrHeight, meDlgUnit, true );
+
+ if(FieldUnit::MILE == meDlgUnit || FieldUnit::KM == meDlgUnit)
+ {
+ m_xMtrPosX->set_digits( 3 );
+ m_xMtrPosY->set_digits( 3 );
+ m_xMtrWidth->set_digits( 3 );
+ m_xMtrHeight->set_digits( 3 );
+ }
+
+ { // #i75273#
+ ::tools::Rectangle aTempRect(mpView->GetAllMarkedRect());
+ mpView->GetSdrPageView()->LogicToPagePos(aTempRect);
+ maRange = vcl::unotools::b2DRectangleFromRectangle(aTempRect);
+ }
+
+ { // #i75273#
+ ::tools::Rectangle aTempRect(mpView->GetWorkArea());
+ mpView->GetSdrPageView()->LogicToPagePos(aTempRect);
+ maWorkRange = vcl::unotools::b2DRectangleFromRectangle(aTempRect);
+ }
+
+ // take anchor into account (Writer)
+ const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
+
+ if(rMarkList.GetMarkCount())
+ {
+ const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ maAnchor = basegfx::B2DPoint(pObj->GetAnchorPos().X(), pObj->GetAnchorPos().Y());
+
+ if(!maAnchor.equalZero()) // -> Writer
+ {
+ for(size_t i = 1; i < rMarkList.GetMarkCount(); ++i)
+ {
+ pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
+
+ if(maAnchor != basegfx::B2DPoint(pObj->GetAnchorPos().X(), pObj->GetAnchorPos().Y()))
+ {
+ // different anchor positions
+ m_xMtrPosX->set_text("");
+ m_xMtrPosY->set_text("");
+ mbPageDisabled = true;
+ return;
+ }
+ }
+
+ // translate ranges about anchor
+ maRange = basegfx::B2DRange(maRange.getMinimum() - maAnchor, maRange.getMaximum() - maAnchor);
+ maWorkRange = basegfx::B2DRange(maWorkRange.getMinimum() - maAnchor, maWorkRange.getMaximum() - maAnchor);
+ }
+ }
+
+ // this should happen via SID_ATTR_TRANSFORM_AUTOSIZE
+ if(1 == rMarkList.GetMarkCount())
+ {
+ const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ const SdrObjKind eKind(pObj->GetObjIdentifier());
+
+ if((pObj->GetObjInventor() == SdrInventor::Default) &&
+ (SdrObjKind::Text == eKind || SdrObjKind::TitleText == eKind || SdrObjKind::OutlineText == eKind) &&
+ pObj->HasText())
+ {
+ mbAdjustDisabled = false;
+
+ m_xFlAdjust->set_sensitive(true);
+
+ m_xTsbAutoGrowWidth->connect_toggled( LINK( this, SvxPositionSizeTabPage, ClickSizeProtectHdl ) );
+ m_xTsbAutoGrowHeight->connect_toggled( LINK( this, SvxPositionSizeTabPage, ClickSizeProtectHdl ) );
+
+ // is used as flag to evaluate if it's selectable
+ mbIgnoreAutoGrowWidth = false;
+ mbIgnoreAutoGrowHeight = false;
+ }
+ }
+
+ // take scale into account
+ const Fraction aUIScale(mpView->GetModel().GetUIScale());
+ TransfrmHelper::ScaleRect( maWorkRange, aUIScale );
+ TransfrmHelper::ScaleRect( maRange, aUIScale );
+
+ // take UI units into account
+ const sal_uInt16 nDigits(m_xMtrPosX->get_digits());
+ TransfrmHelper::ConvertRect( maWorkRange, nDigits, mePoolUnit, meDlgUnit );
+ TransfrmHelper::ConvertRect( maRange, nDigits, mePoolUnit, meDlgUnit );
+
+ SetMinMaxPosition();
+}
+
+
+bool SvxPositionSizeTabPage::FillItemSet( SfxItemSet* rOutAttrs )
+{
+ bool bModified(false);
+
+ if ( m_xMtrWidth->has_focus() )
+ {
+ ChangeWidthHdl( *m_xMtrWidth );
+ }
+
+ if ( m_xMtrHeight->has_focus() )
+ {
+ ChangeHeightHdl( *m_xMtrHeight );
+ }
+
+ if( !mbPageDisabled )
+ {
+ if (m_xMtrPosX->get_value_changed_from_saved() || m_xMtrPosY->get_value_changed_from_saved())
+ {
+ const double fUIScale(double(mpView->GetModel().GetUIScale()));
+ double fX((GetCoreValue( *m_xMtrPosX, mePoolUnit ) + maAnchor.getX()) * fUIScale);
+ double fY((GetCoreValue( *m_xMtrPosY, mePoolUnit ) + maAnchor.getY()) * fUIScale);
+
+ { // #i75273#
+ ::tools::Rectangle aTempRect(mpView->GetAllMarkedRect());
+ mpView->GetSdrPageView()->LogicToPagePos(aTempRect);
+ maRange = vcl::unotools::b2DRectangleFromRectangle(aTempRect);
+ }
+
+ // #101581# GetTopLeftPosition(...) needs coordinates after UI scaling, in real PagePositions
+ GetTopLeftPosition(fX, fY, maRange);
+
+ rOutAttrs->Put(SfxInt32Item(SID_ATTR_TRANSFORM_POS_X, basegfx::fround(fX)));
+ rOutAttrs->Put(SfxInt32Item(SID_ATTR_TRANSFORM_POS_Y, basegfx::fround(fY)));
+
+ bModified = true;
+ }
+
+ if (m_xTsbPosProtect->get_state_changed_from_saved())
+ {
+ if( m_xTsbPosProtect->get_inconsistent() )
+ {
+ rOutAttrs->InvalidateItem( SID_ATTR_TRANSFORM_PROTECT_POS );
+ }
+ else
+ {
+ rOutAttrs->Put(
+ SfxBoolItem( SID_ATTR_TRANSFORM_PROTECT_POS,
+ m_xTsbPosProtect->get_active() ) );
+ }
+
+ bModified = true;
+ }
+ }
+
+ if (m_xMtrWidth->get_value_changed_from_saved() || m_xMtrHeight->get_value_changed_from_saved())
+ {
+ Fraction aUIScale = mpView->GetModel().GetUIScale();
+
+ // get Width
+ double nWidth = static_cast<double>(m_xMtrWidth->get_value(FieldUnit::MM_100TH));
+ tools::Long lWidth = tools::Long(nWidth * static_cast<double>(aUIScale));
+ lWidth = OutputDevice::LogicToLogic( lWidth, MapUnit::Map100thMM, mePoolUnit );
+ lWidth = static_cast<tools::Long>(m_xMtrWidth->denormalize( lWidth ));
+
+ // get Height
+ double nHeight = static_cast<double>(m_xMtrHeight->get_value(FieldUnit::MM_100TH));
+ tools::Long lHeight = tools::Long(nHeight * static_cast<double>(aUIScale));
+ lHeight = OutputDevice::LogicToLogic( lHeight, MapUnit::Map100thMM, mePoolUnit );
+ lHeight = static_cast<tools::Long>(m_xMtrHeight->denormalize( lHeight ));
+
+ // put Width & Height to itemset
+ rOutAttrs->Put( SfxUInt32Item( SID_ATTR_TRANSFORM_WIDTH, static_cast<sal_uInt32>(lWidth) ) );
+ rOutAttrs->Put( SfxUInt32Item( SID_ATTR_TRANSFORM_HEIGHT, static_cast<sal_uInt32>(lHeight) ) );
+ rOutAttrs->Put( SfxUInt16Item( SID_ATTR_TRANSFORM_SIZE_POINT, sal::static_int_cast< sal_uInt16 >( meRP ) ) );
+ bModified = true;
+ }
+
+ if (m_xTsbSizeProtect->get_state_changed_from_saved())
+ {
+ if ( m_xTsbSizeProtect->get_inconsistent() )
+ rOutAttrs->InvalidateItem( SID_ATTR_TRANSFORM_PROTECT_SIZE );
+ else
+ rOutAttrs->Put(
+ SfxBoolItem( SID_ATTR_TRANSFORM_PROTECT_SIZE,
+ m_xTsbSizeProtect->get_active() ) );
+ bModified = true;
+ }
+
+ if (m_xTsbAutoGrowWidth->get_state_changed_from_saved())
+ {
+ if (!mbIgnoreAutoGrowWidth)
+ {
+ if( m_xTsbAutoGrowWidth->get_inconsistent() )
+ rOutAttrs->InvalidateItem( SID_ATTR_TRANSFORM_AUTOWIDTH );
+ else
+ rOutAttrs->Put(
+ SfxBoolItem( SID_ATTR_TRANSFORM_AUTOWIDTH,
+ m_xTsbAutoGrowWidth->get_active() ) );
+ }
+ bModified = true;
+ }
+
+ if (m_xTsbAutoGrowHeight->get_state_changed_from_saved())
+ {
+ if (!mbIgnoreAutoGrowHeight)
+ {
+ if (m_xTsbAutoGrowHeight->get_inconsistent())
+ {
+ rOutAttrs->InvalidateItem( SID_ATTR_TRANSFORM_AUTOHEIGHT );
+ }
+ else
+ {
+ rOutAttrs->Put(
+ SfxBoolItem( SID_ATTR_TRANSFORM_AUTOHEIGHT,
+ m_xTsbAutoGrowHeight->get_active() ) );
+ }
+ }
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+void SvxPositionSizeTabPage::Reset( const SfxItemSet* )
+{
+ const SfxPoolItem* pItem;
+ const double fUIScale(double(mpView->GetModel().GetUIScale()));
+
+ if ( !mbPageDisabled )
+ {
+ pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_POS_X );
+ if ( pItem )
+ {
+ const double fTmp((static_cast<const SfxInt32Item*>(pItem)->GetValue() - maAnchor.getX()) / fUIScale);
+ SetMetricValue(*m_xMtrPosX, basegfx::fround(fTmp), mePoolUnit);
+ }
+
+ pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_POS_Y );
+ if ( pItem )
+ {
+ const double fTmp((static_cast<const SfxInt32Item*>(pItem)->GetValue() - maAnchor.getY()) / fUIScale);
+ SetMetricValue(*m_xMtrPosY, basegfx::fround(fTmp), mePoolUnit);
+ }
+
+ pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_PROTECT_POS );
+ if ( pItem )
+ {
+ bool bProtected = static_cast<const SfxBoolItem*>( pItem )->GetValue();
+ m_xTsbPosProtect->set_active(bProtected);
+ }
+ else
+ {
+ m_xTsbPosProtect->set_inconsistent(true);
+ }
+
+ m_xTsbPosProtect->save_state();
+ m_aCtlPos.Reset();
+
+ // #i2379# Disable controls for protected objects
+ ChangePosProtectHdl(*m_xTsbPosProtect);
+ }
+
+ { // #i75273# set width
+ pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_WIDTH );
+ mfOldWidth = std::max( pItem ? static_cast<double>(static_cast<const SfxUInt32Item*>(pItem)->GetValue()) : 0.0, 1.0 );
+ double fTmpWidth((OutputDevice::LogicToLogic(static_cast<sal_Int32>(mfOldWidth), mePoolUnit, MapUnit::Map100thMM)) / fUIScale);
+ if (m_xMtrWidth->get_digits())
+ fTmpWidth *= pow(10.0, m_xMtrWidth->get_digits());
+ m_xMtrWidth->set_value(fTmpWidth, FieldUnit::MM_100TH);
+ }
+
+ { // #i75273# set height
+ pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_HEIGHT );
+ mfOldHeight = std::max( pItem ? static_cast<double>(static_cast<const SfxUInt32Item*>(pItem)->GetValue()) : 0.0, 1.0 );
+ double fTmpHeight((OutputDevice::LogicToLogic(static_cast<sal_Int32>(mfOldHeight), mePoolUnit, MapUnit::Map100thMM)) / fUIScale);
+ if (m_xMtrHeight->get_digits())
+ fTmpHeight *= pow(10.0, m_xMtrHeight->get_digits());
+ m_xMtrHeight->set_value(fTmpHeight, FieldUnit::MM_100TH);
+ }
+
+ pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_PROTECT_SIZE );
+ if ( pItem )
+ {
+ m_xTsbSizeProtect->set_active(static_cast<const SfxBoolItem*>(pItem)->GetValue());
+ }
+ else
+ m_xTsbSizeProtect->set_inconsistent(true);
+
+ pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_AUTOWIDTH );
+ if ( pItem )
+ {
+ m_xTsbAutoGrowWidth->set_active(static_cast<const SfxBoolItem*>( pItem )->GetValue());
+ }
+ else
+ m_xTsbAutoGrowWidth->set_inconsistent(true);
+
+ pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_AUTOHEIGHT );
+ if ( pItem )
+ {
+ m_xTsbAutoGrowHeight->set_active(static_cast<const SfxBoolItem*>( pItem )->GetValue());
+ }
+ else
+ m_xTsbAutoGrowHeight->set_inconsistent(true);
+
+ // Is matching set?
+ OUString aStr = GetUserData();
+ m_xCbxScale->set_active(aStr.toInt32() != 0);
+
+ m_xMtrPosX->save_value();
+ m_xMtrPosY->save_value();
+ m_xMtrWidth->save_value();
+ m_xMtrHeight->save_value();
+
+ m_xTsbSizeProtect->save_state();
+ m_xTsbAutoGrowWidth->save_state();
+ m_xTsbAutoGrowHeight->save_state();
+ ClickSizeProtectHdl(*m_xTsbAutoGrowHeight);
+
+ // #i2379# Disable controls for protected objects
+ ChangeSizeProtectHdl(*m_xTsbSizeProtect);
+}
+
+std::unique_ptr<SfxTabPage> SvxPositionSizeTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rOutAttrs)
+{
+ return std::make_unique<SvxPositionSizeTabPage>(pPage, pController, *rOutAttrs);
+}
+
+void SvxPositionSizeTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ if( SfxRectangleItem const * pRectItem = rSet.GetItemIfSet( SID_ATTR_TRANSFORM_INTERN, false ) )
+ {
+ { // #i75273#
+ const ::tools::Rectangle aTempRect(pRectItem->GetValue());
+ maRange = vcl::unotools::b2DRectangleFromRectangle(aTempRect);
+ }
+
+ SetMinMaxPosition();
+ }
+}
+
+
+DeactivateRC SvxPositionSizeTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if( _pSet )
+ {
+ double fX(static_cast<double>(m_xMtrPosX->get_value(FieldUnit::NONE)));
+ double fY(static_cast<double>(m_xMtrPosY->get_value(FieldUnit::NONE)));
+
+ GetTopLeftPosition(fX, fY, maRange);
+ const ::tools::Rectangle aOutRectangle(
+ basegfx::fround(fX), basegfx::fround(fY),
+ basegfx::fround(fX + maRange.getWidth()), basegfx::fround(fY + maRange.getHeight()));
+ _pSet->Put(SfxRectangleItem(SID_ATTR_TRANSFORM_INTERN, aOutRectangle));
+ _pSet->Put(SfxBoolItem( SID_ATTR_TRANSFORM_PROTECT_POS,
+ m_xTsbPosProtect->get_state() == TRISTATE_TRUE ));
+ _pSet->Put(SfxBoolItem( SID_ATTR_TRANSFORM_PROTECT_SIZE,
+ m_xTsbSizeProtect->get_state() == TRISTATE_TRUE ));
+ FillItemSet(_pSet);
+ }
+
+ return DeactivateRC::LeavePage;
+}
+
+
+IMPL_LINK_NOARG(SvxPositionSizeTabPage, ChangePosProtectHdl, weld::Toggleable&, void)
+{
+ // #106572# Remember user's last choice
+ m_xTsbSizeProtect->set_state(m_xTsbPosProtect->get_state() == TRISTATE_TRUE ? TRISTATE_TRUE : mnProtectSizeState);
+ UpdateControlStates();
+}
+
+
+void SvxPositionSizeTabPage::UpdateControlStates()
+{
+ const bool bPosProtect = m_xTsbPosProtect->get_state() == TRISTATE_TRUE;
+ const bool bSizeProtect = m_xTsbSizeProtect->get_state() == TRISTATE_TRUE;
+ const bool bHeightChecked = !mbIgnoreAutoGrowHeight && (m_xTsbAutoGrowHeight->get_active());
+ const bool bWidthChecked = !mbIgnoreAutoGrowWidth && (m_xTsbAutoGrowWidth->get_active());
+
+ m_xFlPosition->set_sensitive(!bPosProtect && !mbPageDisabled);
+
+ m_xTsbPosProtect->set_sensitive( !mbProtectDisabled && !mbPageDisabled );
+
+ m_xFlSize->set_sensitive( !mbSizeDisabled && !bSizeProtect );
+
+ m_xFtWidth->set_sensitive( !mbSizeDisabled && !bSizeProtect && !bWidthChecked );
+ m_xMtrWidth->set_sensitive( !mbSizeDisabled && !bSizeProtect && !bWidthChecked );
+
+ m_xFtHeight->set_sensitive( !mbSizeDisabled && !bSizeProtect && !bHeightChecked );
+ m_xMtrHeight->set_sensitive( !mbSizeDisabled && !bSizeProtect && !bHeightChecked );
+
+ m_xCbxScale->set_sensitive( !mbSizeDisabled && !bSizeProtect && !bHeightChecked && !bWidthChecked );
+ m_xCtlSize->set_sensitive( !mbSizeDisabled && !bSizeProtect && (!bHeightChecked || !bWidthChecked) );
+
+ m_xFlProtect->set_sensitive( !mbProtectDisabled );
+ m_xTsbSizeProtect->set_sensitive( !mbProtectDisabled && !bPosProtect );
+
+ m_xFlAdjust->set_sensitive( !mbSizeDisabled && !bSizeProtect && !mbAdjustDisabled );
+
+ m_aCtlSize.Invalidate();
+ m_aCtlPos.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxPositionSizeTabPage, ChangeSizeProtectHdl, weld::Toggleable&, void)
+{
+ if (m_xTsbSizeProtect->get_sensitive())
+ {
+ // #106572# Remember user's last choice
+
+ // Note: this works only as long as the dialog is open. When
+ // the user closes the dialog, there is no way to remember
+ // whether size was enabled or disabled before pos protect was
+ // clicked. Thus, if pos protect is selected, the dialog is
+ // closed and reopened again, unchecking pos protect will
+ // always uncheck size protect, too. That's life.
+ mnProtectSizeState = m_xTsbSizeProtect->get_state();
+ }
+
+ UpdateControlStates();
+}
+
+void SvxPositionSizeTabPage::SetMinMaxPosition()
+{
+ // position
+ double fLeft(maWorkRange.getMinX());
+ double fTop(maWorkRange.getMinY());
+ double fRight(maWorkRange.getMaxX());
+ double fBottom(maWorkRange.getMaxY());
+
+ switch (m_aCtlPos.GetActualRP())
+ {
+ case RectPoint::LT:
+ {
+ fRight -= maRange.getWidth();
+ fBottom -= maRange.getHeight();
+ break;
+ }
+ case RectPoint::MT:
+ {
+ fLeft += maRange.getWidth() / 2.0;
+ fRight -= maRange.getWidth() / 2.0;
+ fBottom -= maRange.getHeight();
+ break;
+ }
+ case RectPoint::RT:
+ {
+ fLeft += maRange.getWidth();
+ fBottom -= maRange.getHeight();
+ break;
+ }
+ case RectPoint::LM:
+ {
+ fRight -= maRange.getWidth();
+ fTop += maRange.getHeight() / 2.0;
+ fBottom -= maRange.getHeight() / 2.0;
+ break;
+ }
+ case RectPoint::MM:
+ {
+ fLeft += maRange.getWidth() / 2.0;
+ fRight -= maRange.getWidth() / 2.0;
+ fTop += maRange.getHeight() / 2.0;
+ fBottom -= maRange.getHeight() / 2.0;
+ break;
+ }
+ case RectPoint::RM:
+ {
+ fLeft += maRange.getWidth();
+ fTop += maRange.getHeight() / 2.0;
+ fBottom -= maRange.getHeight() / 2.0;
+ break;
+ }
+ case RectPoint::LB:
+ {
+ fRight -= maRange.getWidth();
+ fTop += maRange.getHeight();
+ break;
+ }
+ case RectPoint::MB:
+ {
+ fLeft += maRange.getWidth() / 2.0;
+ fRight -= maRange.getWidth() / 2.0;
+ fTop += maRange.getHeight();
+ break;
+ }
+ case RectPoint::RB:
+ {
+ fLeft += maRange.getWidth();
+ fTop += maRange.getHeight();
+ break;
+ }
+ }
+
+ const double fMaxLong(vcl::ConvertValue(std::numeric_limits<sal_Int64>::max(), 0, MapUnit::Map100thMM, meDlgUnit) - 1);
+ fLeft = std::clamp(fLeft, -fMaxLong, fMaxLong);
+ fRight = std::clamp(fRight, -fMaxLong, fMaxLong);
+ fTop = std::clamp(fTop, - fMaxLong, fMaxLong);
+ fBottom = std::clamp(fBottom, -fMaxLong, fMaxLong);
+
+ // #i75273# normalizing when setting the min/max values was wrong, removed
+ m_xMtrPosX->set_range(basegfx::fround64(fLeft), basegfx::fround64(fRight), FieldUnit::NONE);
+ m_xMtrPosY->set_range(basegfx::fround64(fTop), basegfx::fround64(fBottom), FieldUnit::NONE);
+
+ // size
+ fLeft = maWorkRange.getMinX();
+ fTop = maWorkRange.getMinY();
+ fRight = maWorkRange.getMaxX();
+ fBottom = maWorkRange.getMaxY();
+ double fNewX(0);
+ double fNewY(0);
+
+ switch (m_aCtlSize.GetActualRP())
+ {
+ case RectPoint::LT:
+ {
+ fNewX = maWorkRange.getWidth() - ( maRange.getMinX() - fLeft );
+ fNewY = maWorkRange.getHeight() - ( maRange.getMinY() - fTop );
+ break;
+ }
+ case RectPoint::MT:
+ {
+ fNewX = std::min( maRange.getCenter().getX() - fLeft, fRight - maRange.getCenter().getX() ) * 2.0;
+ fNewY = maWorkRange.getHeight() - ( maRange.getMinY() - fTop );
+ break;
+ }
+ case RectPoint::RT:
+ {
+ fNewX = maWorkRange.getWidth() - ( fRight - maRange.getMaxX() );
+ fNewY = maWorkRange.getHeight() - ( maRange.getMinY() - fTop );
+ break;
+ }
+ case RectPoint::LM:
+ {
+ fNewX = maWorkRange.getWidth() - ( maRange.getMinX() - fLeft );
+ fNewY = std::min( maRange.getCenter().getY() - fTop, fBottom - maRange.getCenter().getY() ) * 2.0;
+ break;
+ }
+ case RectPoint::MM:
+ {
+ const double f1(maRange.getCenter().getX() - fLeft);
+ const double f2(fRight - maRange.getCenter().getX());
+ const double f3(std::min(f1, f2));
+ const double f4(maRange.getCenter().getY() - fTop);
+ const double f5(fBottom - maRange.getCenter().getY());
+ const double f6(std::min(f4, f5));
+
+ fNewX = f3 * 2.0;
+ fNewY = f6 * 3.0;
+
+ break;
+ }
+ case RectPoint::RM:
+ {
+ fNewX = maWorkRange.getWidth() - ( fRight - maRange.getMaxX() );
+ fNewY = std::min( maRange.getCenter().getY() - fTop, fBottom - maRange.getCenter().getY() ) * 2.0;
+ break;
+ }
+ case RectPoint::LB:
+ {
+ fNewX = maWorkRange.getWidth() - ( maRange.getMinX() - fLeft );
+ fNewY = maWorkRange.getHeight() - ( fBottom - maRange.getMaxY() );
+ break;
+ }
+ case RectPoint::MB:
+ {
+ fNewX = std::min( maRange.getCenter().getX() - fLeft, fRight - maRange.getCenter().getX() ) * 2.0;
+ fNewY = maWorkRange.getHeight() - ( maRange.getMaxY() - fBottom );
+ break;
+ }
+ case RectPoint::RB:
+ {
+ fNewX = maWorkRange.getWidth() - ( fRight - maRange.getMaxX() );
+ fNewY = maWorkRange.getHeight() - ( fBottom - maRange.getMaxY() );
+ break;
+ }
+ }
+
+ // #i75273# normalizing when setting the min/max values was wrong, removed
+ m_xMtrWidth->set_max(basegfx::fround64(fNewX), FieldUnit::NONE);
+ m_xMtrHeight->set_max(basegfx::fround64(fNewY), FieldUnit::NONE);
+}
+
+void SvxPositionSizeTabPage::GetTopLeftPosition(double& rfX, double& rfY, const basegfx::B2DRange& rRange)
+{
+ switch (m_aCtlPos.GetActualRP())
+ {
+ case RectPoint::LT:
+ {
+ break;
+ }
+ case RectPoint::MT:
+ {
+ rfX -= rRange.getCenter().getX() - rRange.getMinX();
+ break;
+ }
+ case RectPoint::RT:
+ {
+ rfX -= rRange.getWidth();
+ break;
+ }
+ case RectPoint::LM:
+ {
+ rfY -= rRange.getCenter().getY() - rRange.getMinY();
+ break;
+ }
+ case RectPoint::MM:
+ {
+ rfX -= rRange.getCenter().getX() - rRange.getMinX();
+ rfY -= rRange.getCenter().getY() - rRange.getMinY();
+ break;
+ }
+ case RectPoint::RM:
+ {
+ rfX -= rRange.getWidth();
+ rfY -= rRange.getCenter().getY() - rRange.getMinY();
+ break;
+ }
+ case RectPoint::LB:
+ {
+ rfY -= rRange.getHeight();
+ break;
+ }
+ case RectPoint::MB:
+ {
+ rfX -= rRange.getCenter().getX() - rRange.getMinX();
+ rfY -= rRange.getHeight();
+ break;
+ }
+ case RectPoint::RB:
+ {
+ rfX -= rRange.getWidth();
+ rfY -= rRange.getHeight();
+ break;
+ }
+ }
+}
+
+void SvxPositionSizeTabPage::PointChanged(weld::DrawingArea* pDrawingArea, RectPoint eRP)
+{
+ if (pDrawingArea == m_aCtlPos.GetDrawingArea())
+ {
+ SetMinMaxPosition();
+ switch( eRP )
+ {
+ case RectPoint::LT:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMinX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMinY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::MT:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getCenter().getX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMinY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::RT:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMaxX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMinY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::LM:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMinX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getCenter().getY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::MM:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getCenter().getX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getCenter().getY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::RM:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMaxX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getCenter().getY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::LB:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMinX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMaxY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::MB:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getCenter().getX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMaxY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::RB:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMaxX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMaxY()), FieldUnit::NONE );
+ break;
+ }
+ }
+ }
+ else
+ {
+ meRP = eRP;
+ SetMinMaxPosition();
+ }
+}
+
+void SvxPositionSizeTabPage::DisableResize()
+{
+ mbSizeDisabled = true;
+}
+
+
+void SvxPositionSizeTabPage::DisableProtect()
+{
+ mbProtectDisabled = true;
+}
+
+
+IMPL_LINK_NOARG(SvxPositionSizeTabPage, ChangeWidthHdl, weld::MetricSpinButton&, void)
+{
+ if( !(m_xCbxScale->get_active() && m_xCbxScale->get_sensitive()) )
+ return;
+
+ sal_Int64 nHeight(basegfx::fround64((mfOldHeight * static_cast<double>(m_xMtrWidth->get_value(FieldUnit::NONE))) / mfOldWidth));
+ sal_Int64 nMin, nMax;
+ m_xMtrHeight->get_range(nMin, nMax, FieldUnit::NONE);
+
+ if (nHeight <= nMax)
+ {
+ m_xMtrHeight->set_value(nHeight, FieldUnit::NONE);
+ }
+ else
+ {
+ nHeight = nMax;
+ m_xMtrHeight->set_value(nHeight, FieldUnit::NONE);
+
+ const sal_Int64 nWidth(basegfx::fround64((mfOldWidth * static_cast<double>(nHeight)) / mfOldHeight));
+ m_xMtrWidth->set_value(nWidth, FieldUnit::NONE);
+ }
+}
+
+IMPL_LINK_NOARG(SvxPositionSizeTabPage, ChangeHeightHdl, weld::MetricSpinButton&, void)
+{
+ if( !(m_xCbxScale->get_active() && m_xCbxScale->get_sensitive()) )
+ return;
+
+ sal_Int64 nWidth(basegfx::fround64((mfOldWidth * static_cast<double>(m_xMtrHeight->get_value(FieldUnit::NONE))) / mfOldHeight));
+ sal_Int64 nMin, nMax;
+ m_xMtrWidth->get_range(nMin, nMax, FieldUnit::NONE);
+
+ if (nWidth <= nMax)
+ {
+ m_xMtrWidth->set_value(nWidth, FieldUnit::NONE);
+ }
+ else
+ {
+ nWidth = nMax;
+ m_xMtrWidth->set_value(nWidth, FieldUnit::NONE);
+
+ const sal_Int64 nHeight(basegfx::fround64((mfOldHeight * static_cast<double>(nWidth)) / mfOldWidth));
+ m_xMtrHeight->set_value(nHeight, FieldUnit::NONE);
+ }
+}
+
+IMPL_LINK_NOARG(SvxPositionSizeTabPage, ClickSizeProtectHdl, weld::Toggleable&, void)
+{
+ UpdateControlStates();
+}
+
+IMPL_LINK_NOARG(SvxPositionSizeTabPage, ClickAutoHdl, weld::Toggleable&, void)
+{
+ if (m_xCbxScale->get_active())
+ {
+ mfOldWidth = std::max( static_cast<double>(GetCoreValue( *m_xMtrWidth, mePoolUnit )), 1.0 );
+ mfOldHeight = std::max( static_cast<double>(GetCoreValue( *m_xMtrHeight, mePoolUnit )), 1.0 );
+ }
+}
+
+void SvxPositionSizeTabPage::FillUserData()
+{
+ // matching is saved in the Ini-file
+ OUString aStr = m_xCbxScale->get_active() ? OUString("1") : OUString("0");
+ SetUserData( aStr );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */