summaryrefslogtreecommitdiffstats
path: root/sw/source/ui/chrdlg/drpcps.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/ui/chrdlg/drpcps.cxx')
-rw-r--r--sw/source/ui/chrdlg/drpcps.cxx759
1 files changed, 759 insertions, 0 deletions
diff --git a/sw/source/ui/chrdlg/drpcps.cxx b/sw/source/ui/chrdlg/drpcps.cxx
new file mode 100644
index 000000000..32509c501
--- /dev/null
+++ b/sw/source/ui/chrdlg/drpcps.cxx
@@ -0,0 +1,759 @@
+/* -*- 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 <hintids.hxx>
+
+#include <cmdid.h>
+#include <docsh.hxx>
+#include <swmodule.hxx>
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include <strings.hrc>
+
+#include <vcl/metric.hxx>
+#include <vcl/settings.hxx>
+
+#include <rtl/ustrbuf.hxx>
+#include <svl/stritem.hxx>
+#include <editeng/fontitem.hxx>
+#include <sfx2/dialoghelper.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/printer.hxx>
+#include <svtools/unitconv.hxx>
+#include <vcl/print.hxx>
+#include <vcl/svapp.hxx>
+#include <com/sun/star/i18n/BreakIterator.hpp>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <comphelper/processfactory.hxx>
+#include <osl/diagnose.h>
+
+#include <charatr.hxx>
+#include <viewopt.hxx>
+#include <drpcps.hxx>
+#include <paratr.hxx>
+#include <uitool.hxx>
+#include <charfmt.hxx>
+
+using namespace css;
+using namespace css::uno;
+using namespace css::lang;
+
+const WhichRangesContainer SwDropCapsPage::aPageRg(svl::Items<RES_PARATR_DROP, RES_PARATR_DROP>);
+
+void SwDropCapsPict::SetText( const OUString& rT )
+{
+ maText = rT;
+ UpdatePaintSettings();
+}
+
+void SwDropCapsPict::SetDrawingArea(weld::DrawingArea* pDrawingArea)
+{
+ CustomWidgetController::SetDrawingArea(pDrawingArea);
+ Size aPrefSize(getParagraphPreviewOptimalSize(pDrawingArea->get_ref_device()));
+ pDrawingArea->set_size_request(aPrefSize.Width(), aPrefSize.Height());
+}
+
+void SwDropCapsPict::Resize()
+{
+ CustomWidgetController::Resize();
+ UpdatePaintSettings();
+}
+
+void SwDropCapsPict::SetLines( sal_uInt8 nL )
+{
+ mnLines = nL;
+ UpdatePaintSettings();
+}
+
+void SwDropCapsPict::SetDistance( sal_uInt16 nD )
+{
+ mnDistance = nD;
+ UpdatePaintSettings();
+}
+
+void SwDropCapsPict::SetValues( const OUString& rText, sal_uInt8 nLines, sal_uInt16 nDistance )
+{
+ maText = rText;
+ mnLines = nLines;
+ mnDistance = nDistance;
+
+ UpdatePaintSettings();
+}
+
+void SwDropCapsPict::InitPrinter()
+{
+ if( !mpPrinter )
+ InitPrinter_();
+}
+
+// Create Default-String from character-count (A, AB, ABC, ...)
+static OUString GetDefaultString(sal_Int32 nChars)
+{
+ OUStringBuffer aStr(nChars);
+ for (sal_Int32 i = 0; i < nChars; i++)
+ aStr.append(static_cast<sal_Unicode>(i + 65));
+ return aStr.makeStringAndClear();
+}
+
+static void calcFontHeightAnyAscent(vcl::RenderContext& rWin, vcl::Font const & _rFont, tools::Long& _nHeight, tools::Long& _nAscent)
+{
+ if ( !_nHeight )
+ {
+ rWin.Push(vcl::PushFlags::FONT);
+ rWin.SetFont(_rFont);
+ FontMetric aMetric(rWin.GetFontMetric());
+ _nHeight = aMetric.GetLineHeight();
+ _nAscent = aMetric.GetAscent();
+ rWin.Pop();
+ }
+}
+
+SwDropCapsPict::~SwDropCapsPict()
+{
+ if (mbDelPrinter)
+ mpPrinter.disposeAndClear();
+}
+
+/// Get the details of the first script change.
+/// @param[out] start The character position of the start of the segment.
+/// @param[out] end The character position of the end of the segment.
+/// @param[out] scriptType The script type (Latin, Asian, Complex etc.)
+void SwDropCapsPict::GetFirstScriptSegment(sal_Int32 &start, sal_Int32 &end, sal_uInt16 &scriptType)
+{
+ start = 0;
+ if( maScriptChanges.empty() )
+ {
+ end = maText.getLength();
+ scriptType = css::i18n::ScriptType::LATIN;
+ }
+ else
+ {
+ end = maScriptChanges[ 0 ].changePos;
+ scriptType = maScriptChanges[ 0 ].scriptType;
+ }
+}
+
+/// Get the details of the first script change.
+/// @param[in,out] nIdx Index of the current script change.
+/// @param[out] start The character position of the start of the segment.
+/// @param[in,out] end The character position of the end of the segment.
+/// @param[out] scriptType The script type (Latin, Asian, Complex etc.)
+/// @returns True if there was a next segment, false if not.
+bool SwDropCapsPict::GetNextScriptSegment(size_t &nIdx, sal_Int32 &start, sal_Int32 &end, sal_uInt16 &scriptType)
+{
+ if (maScriptChanges.empty() || nIdx >= maScriptChanges.size() - 1 || end >= maText.getLength())
+ return false;
+ start = maScriptChanges[nIdx++].changePos;
+ end = maScriptChanges[ nIdx ].changePos;
+ scriptType = maScriptChanges[ nIdx ].scriptType;
+ return true;
+}
+
+#define LINES 10
+#define BORDER 2
+
+void SwDropCapsPict::GetFontSettings( vcl::Font& _rFont, sal_uInt16 _nWhich )
+{
+ SwView* pView = GetActiveView();
+ if (!pView)
+ return;
+ SwWrtShell& rWrtShell = pView->GetWrtShell();
+ SfxItemSet aSet( rWrtShell.GetAttrPool(), _nWhich, _nWhich);
+ rWrtShell.GetCurAttr(aSet);
+
+ SvxFontItem aFormatFont(static_cast<const SvxFontItem &>( aSet.Get(_nWhich)));
+
+ _rFont.SetFamily(aFormatFont.GetFamily());
+ _rFont.SetFamilyName(aFormatFont.GetFamilyName());
+ _rFont.SetPitch(aFormatFont.GetPitch());
+ _rFont.SetCharSet(aFormatFont.GetCharSet());
+}
+
+void SwDropCapsPict::UpdatePaintSettings()
+{
+ SwView* pView = GetActiveView();
+ if (!pView)
+ return;
+ SwWrtShell& rWrtShell = pView->GetWrtShell();
+
+ maBackColor = Application::GetSettings().GetStyleSettings().GetWindowColor();
+ maTextLineColor = COL_LIGHTGRAY;
+
+ // gray lines
+ mnTotLineH = (GetOutputSizePixel().Height() - 2 * BORDER) / LINES;
+ mnLineH = mnTotLineH - 2;
+
+ vcl::Font aFont;
+ if (mpPage)
+ {
+ // tdf#135244: preview generation should not jump document view
+ auto aLock(rWrtShell.GetView().GetDocShell()->LockAllViews());
+
+ if (!mpPage->m_xTemplateBox->get_active())
+ {
+ // query the Font at paragraph's beginning
+ rWrtShell.Push();
+ rWrtShell.SttCursorMove();
+ rWrtShell.ClearMark();
+ SwWhichPara pSwuifnParaCurr = GoCurrPara;
+ SwMoveFnCollection const & pSwuifnParaStart = fnParaStart;
+ rWrtShell.MovePara(pSwuifnParaCurr,pSwuifnParaStart);
+ // normal
+ GetFontSettings( aFont, RES_CHRATR_FONT );
+
+ // CJK
+ GetFontSettings( maCJKFont, RES_CHRATR_CJK_FONT );
+
+ // CTL
+ GetFontSettings( maCTLFont, RES_CHRATR_CTL_FONT );
+
+ rWrtShell.EndCursorMove();
+ rWrtShell.Pop(SwCursorShell::PopMode::DeleteCurrent);
+ }
+ else
+ {
+ // query Font at character template
+ SwCharFormat *pFormat = rWrtShell.GetCharStyle(
+ mpPage->m_xTemplateBox->get_active_text(),
+ SwWrtShell::GETSTYLE_CREATEANY );
+ OSL_ENSURE(pFormat, "character style doesn't exist!");
+ const SvxFontItem &rFormatFont = pFormat->GetFont();
+
+ aFont.SetFamily(rFormatFont.GetFamily());
+ aFont.SetFamilyName(rFormatFont.GetFamilyName());
+ aFont.SetPitch(rFormatFont.GetPitch());
+ aFont.SetCharSet(rFormatFont.GetCharSet());
+ }
+ }
+
+ mnTextH = mnLines * mnTotLineH;
+ aFont.SetFontSize(Size(0, mnTextH));
+ maCJKFont.SetFontSize(Size(0, mnTextH));
+ maCTLFont.SetFontSize(Size(0, mnTextH));
+
+ aFont.SetTransparent(true);
+ maCJKFont.SetTransparent(true);
+ maCTLFont.SetTransparent(true);
+
+ aFont.SetColor( SwViewOption::GetFontColor() );
+ maCJKFont.SetColor( SwViewOption::GetFontColor() );
+ maCTLFont.SetColor( SwViewOption::GetFontColor() );
+
+ aFont.SetFillColor(Application::GetSettings().GetStyleSettings().GetWindowColor());
+ maCJKFont.SetFillColor(Application::GetSettings().GetStyleSettings().GetWindowColor());
+ maCTLFont.SetFillColor(Application::GetSettings().GetStyleSettings().GetWindowColor());
+
+ maCJKFont.SetFontSize(Size(0, maCJKFont.GetFontSize().Height()));
+ maCTLFont.SetFontSize(Size(0, maCTLFont.GetFontSize().Height()));
+
+ aFont.SetFontSize(Size(0, aFont.GetFontSize().Height()));
+ maFont = aFont;
+
+ CheckScript();
+
+ maTextSize = CalcTextSize();
+
+ Invalidate();
+}
+
+void SwDropCapsPict::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& /*rRect*/)
+{
+ if (!IsVisible())
+ return;
+
+ rRenderContext.SetMapMode(MapMode(MapUnit::MapPixel));
+ rRenderContext.SetLineColor();
+
+ rRenderContext.SetFillColor(maBackColor);
+
+ Size aOutputSizePixel(GetOutputSizePixel());
+
+ rRenderContext.DrawRect(tools::Rectangle(Point(0, 0), aOutputSizePixel));
+ rRenderContext.SetClipRegion(vcl::Region(tools::Rectangle(Point(BORDER, BORDER),
+ Size(aOutputSizePixel.Width () - 2 * BORDER,
+ aOutputSizePixel.Height() - 2 * BORDER))));
+
+ OSL_ENSURE(mnLineH > 0, "We cannot make it that small");
+ tools::Long nY0 = (aOutputSizePixel.Height() - (LINES * mnTotLineH)) / 2;
+
+ rRenderContext.SetFillColor(maTextLineColor);
+
+ for (int i = 0; i < LINES; ++i)
+ {
+ rRenderContext.DrawRect(tools::Rectangle(Point(BORDER, nY0 + i * mnTotLineH),
+ Size(aOutputSizePixel.Width() - 2 * BORDER, mnLineH)));
+ }
+
+ // Text background with gap (240 twips ~ 1 line height)
+ const tools::Long nDistW = (((static_cast<tools::Long>(mnDistance) * 100) / 240) * mnTotLineH) / 100;
+ rRenderContext.SetFillColor(maBackColor);
+ if (mpPage && mpPage->m_xDropCapsBox->get_active())
+ {
+ const Size aTextSize(maTextSize.Width() + nDistW, maTextSize.Height());
+ rRenderContext.DrawRect(tools::Rectangle(Point(BORDER, nY0), aTextSize));
+
+ // draw Text
+ DrawPrev(rRenderContext, Point(BORDER, nY0));
+ }
+ rRenderContext.SetClipRegion();
+}
+
+void SwDropCapsPict::DrawPrev(vcl::RenderContext& rRenderContext, const Point& rPt)
+{
+ Point aPt(rPt);
+ InitPrinter();
+
+ vcl::Font aOldFont = mpPrinter->GetFont();
+ sal_uInt16 nScript;
+ size_t nIdx = 0;
+ sal_Int32 nStart;
+ sal_Int32 nEnd;
+
+ GetFirstScriptSegment(nStart, nEnd, nScript);
+
+ do
+ {
+ SvxFont& rFnt = (nScript == css::i18n::ScriptType::ASIAN)
+ ? maCJKFont
+ : ((nScript == css::i18n::ScriptType::COMPLEX)
+ ? maCTLFont
+ : maFont);
+ mpPrinter->SetFont(rFnt);
+
+ rFnt.DrawPrev(&rRenderContext, mpPrinter, aPt, maText, nStart, nEnd - nStart);
+
+ if (!maScriptChanges.empty())
+ aPt.AdjustX(maScriptChanges[nIdx].textWidth );
+
+ if (!GetNextScriptSegment(nIdx, nStart, nEnd, nScript))
+ break;
+ }
+ while(true);
+
+ mpPrinter->SetFont(aOldFont);
+}
+
+void SwDropCapsPict::CheckScript()
+{
+ if( maScriptText == maText )
+ return;
+
+ maScriptText = maText;
+ maScriptChanges.clear();
+ if( !xBreak.is() )
+ {
+ Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
+ xBreak = css::i18n::BreakIterator::create(xContext);
+ }
+ sal_Int16 nScript = xBreak->getScriptType( maText, 0 );
+ sal_Int32 nChg = 0;
+ if( css::i18n::ScriptType::WEAK == nScript )
+ {
+ nChg = xBreak->endOfScript( maText, nChg, nScript );
+ if( nChg < maText.getLength() )
+ nScript = xBreak->getScriptType( maText, nChg );
+ else
+ nScript = css::i18n::ScriptType::LATIN;
+ }
+
+ for(;;)
+ {
+ nChg = xBreak->endOfScript( maText, nChg, nScript );
+ maScriptChanges.emplace_back(nScript, nChg );
+ if( nChg >= maText.getLength() || nChg < 0 )
+ break;
+ nScript = xBreak->getScriptType( maText, nChg );
+ }
+}
+
+Size SwDropCapsPict::CalcTextSize()
+{
+ InitPrinter();
+
+ sal_uInt16 nScript;
+ size_t nIdx = 0;
+ sal_Int32 nStart;
+ sal_Int32 nEnd;
+ GetFirstScriptSegment(nStart, nEnd, nScript);
+ tools::Long nTextWidth = 0;
+ tools::Long nCJKHeight = 0;
+ tools::Long nCTLHeight = 0;
+ tools::Long nHeight = 0;
+ tools::Long nAscent = 0;
+ tools::Long nCJKAscent = 0;
+ tools::Long nCTLAscent = 0;
+ do
+ {
+ SvxFont& rFnt = (nScript == css::i18n::ScriptType::ASIAN)
+ ? maCJKFont
+ : ((nScript == css::i18n::ScriptType::COMPLEX)
+ ? maCTLFont
+ : maFont);
+
+ sal_uLong nWidth = rFnt.GetTextSize(*mpPrinter, maText, nStart, nEnd-nStart ).Width();
+
+ if (nIdx < maScriptChanges.size())
+ maScriptChanges[nIdx].textWidth = nWidth;
+ nTextWidth += nWidth;
+ switch(nScript)
+ {
+ case css::i18n::ScriptType::ASIAN:
+ calcFontHeightAnyAscent(GetDrawingArea()->get_ref_device(), maCJKFont, nCJKHeight, nCJKAscent);
+ break;
+ case css::i18n::ScriptType::COMPLEX:
+ calcFontHeightAnyAscent(GetDrawingArea()->get_ref_device(), maCTLFont, nCTLHeight, nCTLAscent);
+ break;
+ default:
+ calcFontHeightAnyAscent(GetDrawingArea()->get_ref_device(), maFont, nHeight, nAscent);
+ }
+
+ if (!GetNextScriptSegment(nIdx, nStart, nEnd, nScript))
+ break;
+ }
+ while(true);
+
+ nHeight -= nAscent;
+ nCJKHeight -= nCJKAscent;
+ nCTLHeight -= nCTLAscent;
+ if (nHeight < nCJKHeight)
+ nHeight = nCJKHeight;
+ if (nAscent < nCJKAscent)
+ nAscent = nCJKAscent;
+ if (nHeight < nCTLHeight)
+ nHeight = nCTLHeight;
+ if (nAscent < nCTLAscent)
+ nAscent = nCTLAscent;
+ nHeight += nAscent;
+
+ Size aTextSize(nTextWidth, nHeight);
+ return aTextSize;
+}
+
+void SwDropCapsPict::InitPrinter_()
+{
+ SfxViewShell* pSh = SfxViewShell::Current();
+
+ if (pSh)
+ mpPrinter = pSh->GetPrinter();
+
+ if (!mpPrinter)
+ {
+ mpPrinter = VclPtr<Printer>::Create();
+ mbDelPrinter = true;
+ }
+}
+
+SwDropCapsDlg::SwDropCapsDlg(weld::Window *pParent, const SfxItemSet &rSet)
+ : SfxSingleTabDialogController(pParent, &rSet)
+{
+ auto xNewPage(SwDropCapsPage::Create(get_content_area(), this, &rSet));
+ static_cast<SwDropCapsPage*>(xNewPage.get())->SetFormat(false);
+ SetTabPage(std::move(xNewPage));
+}
+
+SwDropCapsPage::SwDropCapsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/dropcapspage.ui", "DropCapPage", &rSet)
+ , bModified(false)
+ , bFormat(true)
+ , m_xDropCapsBox(m_xBuilder->weld_check_button("checkCB_SWITCH"))
+ , m_xWholeWordCB(m_xBuilder->weld_check_button("checkCB_WORD"))
+ , m_xSwitchText(m_xBuilder->weld_label("labelFT_DROPCAPS"))
+ , m_xDropCapsField(m_xBuilder->weld_spin_button("spinFLD_DROPCAPS"))
+ , m_xLinesText(m_xBuilder->weld_label("labelTXT_LINES"))
+ , m_xLinesField(m_xBuilder->weld_spin_button("spinFLD_LINES"))
+ , m_xDistanceText(m_xBuilder->weld_label("labelTXT_DISTANCE"))
+ , m_xDistanceField(m_xBuilder->weld_metric_spin_button("spinFLD_DISTANCE", FieldUnit::CM))
+ , m_xTextText(m_xBuilder->weld_label("labelTXT_TEXT"))
+ , m_xTextEdit(m_xBuilder->weld_entry("entryEDT_TEXT"))
+ , m_xTemplateText(m_xBuilder->weld_label("labelTXT_TEMPLATE"))
+ , m_xTemplateBox(m_xBuilder->weld_combo_box("comboBOX_TEMPLATE"))
+ , m_xPict(new weld::CustomWeld(*m_xBuilder, "drawingareaWN_EXAMPLE", m_aPict))
+{
+ m_aPict.SetDropCapsPage(this);
+
+ SetExchangeSupport();
+
+ const sal_uInt16 nHtmlMode = ::GetHtmlMode(static_cast<const SwDocShell*>(SfxObjectShell::Current()));
+ bHtmlMode = (nHtmlMode & HTMLMODE_ON) != 0;
+
+ // tdf#92154 limit comboBOX_TEMPLATE length
+ const int nMaxWidth(m_xTemplateBox->get_approximate_digit_width() * 50);
+ m_xTemplateBox->set_size_request(nMaxWidth , -1);
+
+ // In the template dialog the text is not influenceable
+ m_xTextText->set_sensitive(!bFormat);
+ m_xTextEdit->set_sensitive(!bFormat);
+
+ // Metrics
+ SetFieldUnit(*m_xDistanceField, GetDfltMetric(bHtmlMode));
+
+ // Install handler
+ Link<weld::SpinButton&,void> aValueChangedLk = LINK(this, SwDropCapsPage, ValueChangedHdl);
+ m_xDropCapsField->connect_value_changed(aValueChangedLk);
+ m_xLinesField->connect_value_changed(aValueChangedLk);
+ Link<weld::MetricSpinButton&,void> aMetricValueChangedLk = LINK(this, SwDropCapsPage, MetricValueChangedHdl);
+ m_xDistanceField->connect_value_changed(aMetricValueChangedLk);
+ m_xTextEdit->connect_changed(LINK(this, SwDropCapsPage, ModifyHdl));
+ m_xDropCapsBox->connect_toggled(LINK(this, SwDropCapsPage, ClickHdl));
+ m_xTemplateBox->connect_changed(LINK(this, SwDropCapsPage, SelectHdl));
+ m_xWholeWordCB->connect_toggled(LINK(this, SwDropCapsPage, WholeWordHdl));
+}
+
+SwDropCapsPage::~SwDropCapsPage()
+{
+}
+
+DeactivateRC SwDropCapsPage::DeactivatePage(SfxItemSet * _pSet)
+{
+ if (_pSet)
+ FillSet(*_pSet);
+
+ return DeactivateRC::LeavePage;
+}
+
+std::unique_ptr<SfxTabPage> SwDropCapsPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rSet)
+{
+ return std::make_unique<SwDropCapsPage>(pPage, pController, *rSet);
+}
+
+bool SwDropCapsPage::FillItemSet(SfxItemSet *rSet)
+{
+ if (bModified)
+ FillSet(*rSet);
+ return bModified;
+}
+
+void SwDropCapsPage::Reset(const SfxItemSet *rSet)
+{
+ // Characters, lines, gap and text
+ SwFormatDrop aFormatDrop( rSet->Get(RES_PARATR_DROP) );
+ if (aFormatDrop.GetLines() > 1)
+ {
+ m_xDropCapsField->set_value(aFormatDrop.GetChars());
+ m_xLinesField->set_value(aFormatDrop.GetLines());
+ m_xDistanceField->set_value(m_xDistanceField->normalize(aFormatDrop.GetDistance()), FieldUnit::TWIP);
+ m_xWholeWordCB->set_active(aFormatDrop.GetWholeWord());
+ }
+ else
+ {
+ m_xDropCapsField->set_value(1);
+ m_xLinesField->set_value(3);
+ m_xDistanceField->set_value(0, FieldUnit::TWIP);
+ }
+
+ SwView* pView = GetActiveView();
+ if (pView)
+ ::FillCharStyleListBox(*m_xTemplateBox, pView->GetWrtShell().GetView().GetDocShell(), true);
+
+ m_xTemplateBox->insert_text(0, SwResId(SW_STR_NONE));
+
+ // Reset format
+ int nSelect = 0;
+ if (aFormatDrop.GetCharFormat())
+ {
+ int nPos = m_xTemplateBox->find_text(aFormatDrop.GetCharFormat()->GetName());
+ if (nPos != -1)
+ nSelect = nPos;
+ }
+ m_xTemplateBox->set_active(nSelect);
+
+ // Enable controls
+ m_xDropCapsBox->set_active(aFormatDrop.GetLines() > 1);
+ const sal_Int32 nVal = m_xDropCapsField->get_value();
+ if (bFormat)
+ m_xTextEdit->set_text(GetDefaultString(nVal));
+ else
+ {
+ if (pView)
+ m_xTextEdit->set_text(pView->GetWrtShell().GetDropText(nVal));
+ m_xTextEdit->set_sensitive(true);
+ m_xTextText->set_sensitive(true);
+ }
+
+ // Preview
+ m_aPict.SetValues(m_xTextEdit->get_text(),
+ sal_uInt8(m_xLinesField->get_value()),
+ sal_uInt16(m_xDistanceField->denormalize(m_xDistanceField->get_value(FieldUnit::TWIP))));
+
+ ClickHdl(*m_xDropCapsBox);
+ bModified = false;
+}
+
+IMPL_LINK_NOARG(SwDropCapsPage, ClickHdl, weld::Toggleable&, void)
+{
+ bool bChecked = m_xDropCapsBox->get_active();
+
+ m_xWholeWordCB->set_sensitive(bChecked && !bHtmlMode);
+
+ m_xSwitchText->set_sensitive(bChecked && !m_xWholeWordCB->get_active());
+ m_xDropCapsField->set_sensitive(bChecked && !m_xWholeWordCB->get_active());
+ m_xLinesText->set_sensitive( bChecked );
+ m_xLinesField->set_sensitive( bChecked );
+ m_xDistanceText->set_sensitive( bChecked );
+ m_xDistanceField->set_sensitive( bChecked );
+ m_xTemplateText->set_sensitive( bChecked );
+ m_xTemplateBox->set_sensitive( bChecked );
+ m_xTextEdit->set_sensitive( bChecked && !bFormat );
+ m_xTextText->set_sensitive( bChecked && !bFormat );
+
+ if ( bChecked )
+ {
+ ValueChangedHdl(*m_xDropCapsField);
+ m_xDropCapsField->grab_focus();
+ }
+ else
+ m_aPict.SetText("");
+
+ bModified = true;
+}
+
+IMPL_LINK_NOARG(SwDropCapsPage, WholeWordHdl, weld::Toggleable&, void)
+{
+ m_xDropCapsField->set_sensitive(!m_xWholeWordCB->get_active());
+ m_xSwitchText->set_sensitive(!m_xWholeWordCB->get_active());
+
+ ValueChangedHdl(*m_xDropCapsField);
+
+ bModified = true;
+}
+
+void SwDropCapsPage::ModifyEntry(const weld::Entry& rEdit)
+{
+ OUString sPreview;
+
+ // set text if applicable
+ if (&rEdit == m_xDropCapsField.get())
+ {
+ const sal_Int32 nVal = !m_xWholeWordCB->get_active()
+ ? static_cast<sal_Int32>(m_xDropCapsField->get_value())
+ : 0;
+ bool bSetText = false;
+
+ if (SwView* pView = GetActiveView())
+ {
+ if (bFormat || pView->GetWrtShell().GetDropText(1).isEmpty())
+ sPreview = GetDefaultString(nVal);
+ else
+ {
+ bSetText = true;
+ sPreview = pView->GetWrtShell().GetDropText(nVal);
+ }
+ }
+
+ OUString sEdit(m_xTextEdit->get_text());
+
+ if (!sEdit.isEmpty() && !sPreview.startsWith(sEdit))
+ {
+ sPreview = sEdit.copy(0, std::min(sEdit.getLength(), sPreview.getLength()));
+ bSetText = false;
+ }
+
+ if (bSetText)
+ m_xTextEdit->set_text(sPreview);
+ }
+ else if (&rEdit == m_xTextEdit.get()) // set quantity if applicable
+ {
+ const sal_Int32 nTmp = m_xTextEdit->get_text().getLength();
+ m_xDropCapsField->set_value(std::max<sal_Int32>(1, nTmp));
+ sPreview = m_xTextEdit->get_text();
+ }
+
+ // adjust image
+ if (&rEdit == m_xDropCapsField.get() || &rEdit == m_xTextEdit.get())
+ m_aPict.SetText(sPreview);
+ else if (&rEdit == m_xLinesField.get())
+ m_aPict.SetLines(static_cast<sal_uInt8>(m_xLinesField->get_value()));
+ else
+ m_aPict.SetDistance(o3tl::narrowing<sal_uInt16>(m_xDistanceField->denormalize(m_xDistanceField->get_value(FieldUnit::TWIP))));
+
+ bModified = true;
+}
+
+IMPL_LINK(SwDropCapsPage, ModifyHdl, weld::Entry&, rEdit, void)
+{
+ ModifyEntry(rEdit);
+}
+
+IMPL_LINK(SwDropCapsPage, ValueChangedHdl, weld::SpinButton&, rEdit, void)
+{
+ ModifyEntry(rEdit);
+}
+
+IMPL_LINK(SwDropCapsPage, MetricValueChangedHdl, weld::MetricSpinButton&, rEdit, void)
+{
+ ModifyEntry(rEdit.get_widget());
+}
+
+IMPL_LINK_NOARG(SwDropCapsPage, SelectHdl, weld::ComboBox&, void)
+{
+ m_aPict.UpdatePaintSettings();
+ bModified = true;
+}
+
+void SwDropCapsPage::FillSet( SfxItemSet &rSet )
+{
+ if(!bModified)
+ return;
+
+ SwFormatDrop aFormat;
+
+ bool bOn = m_xDropCapsBox->get_active();
+ if (bOn)
+ {
+ // quantity, lines, gap
+ aFormat.GetChars() = static_cast<sal_uInt8>(m_xDropCapsField->get_value());
+ aFormat.GetLines() = static_cast<sal_uInt8>(m_xLinesField->get_value());
+ aFormat.GetDistance() = o3tl::narrowing<sal_uInt16>(m_xDistanceField->denormalize(m_xDistanceField->get_value(FieldUnit::TWIP)));
+ aFormat.GetWholeWord() = m_xWholeWordCB->get_active();
+
+ // template
+ if (SwView* pView = GetActiveView())
+ if (m_xTemplateBox->get_active())
+ aFormat.SetCharFormat(pView->GetWrtShell().GetCharStyle(m_xTemplateBox->get_active_text()));
+ }
+ else
+ {
+ aFormat.GetChars() = 1;
+ aFormat.GetLines() = 1;
+ aFormat.GetDistance() = 0;
+ }
+
+ // set attributes
+ const SfxPoolItem* pOldItem;
+ if (nullptr == (pOldItem = GetOldItem(rSet, FN_FORMAT_DROPCAPS)) || aFormat != *pOldItem)
+ rSet.Put(aFormat);
+
+ // hard text formatting
+ // Bug 24974: in designer/template catalog this doesn't make sense!!
+ if (!bFormat && m_xDropCapsBox->get_active())
+ {
+ OUString sText(m_xTextEdit->get_text());
+
+ if (!m_xWholeWordCB->get_active())
+ {
+ sText = sText.copy(0, std::min<sal_Int32>(sText.getLength(), m_xDropCapsField->get_value()));
+ }
+
+ SfxStringItem aStr(FN_PARAM_1, sText);
+ rSet.Put(aStr);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */