Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / source / ui / chrdlg / drpcps.cxx
blob15bdd270a0efe335e09457b4cb94bec330b7a3f0
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <hintids.hxx>
22 #include <cmdid.h>
23 #include <docsh.hxx>
24 #include <swmodule.hxx>
25 #include <view.hxx>
26 #include <wrtsh.hxx>
27 #include <strings.hrc>
29 #include <vcl/metric.hxx>
30 #include <vcl/settings.hxx>
32 #include <rtl/ustrbuf.hxx>
33 #include <svl/stritem.hxx>
34 #include <editeng/fontitem.hxx>
35 #include <sfx2/dialoghelper.hxx>
36 #include <sfx2/htmlmode.hxx>
37 #include <sfx2/objsh.hxx>
38 #include <sfx2/printer.hxx>
39 #include <svtools/unitconv.hxx>
40 #include <vcl/print.hxx>
41 #include <vcl/svapp.hxx>
42 #include <com/sun/star/i18n/BreakIterator.hpp>
43 #include <com/sun/star/i18n/ScriptType.hpp>
44 #include <comphelper/processfactory.hxx>
45 #include <osl/diagnose.h>
47 #include <charatr.hxx>
48 #include <viewopt.hxx>
49 #include <drpcps.hxx>
50 #include <paratr.hxx>
51 #include <uitool.hxx>
52 #include <charfmt.hxx>
54 using namespace css;
55 using namespace css::uno;
56 using namespace css::lang;
58 const WhichRangesContainer SwDropCapsPage::s_aPageRg(svl::Items<RES_PARATR_DROP, RES_PARATR_DROP>);
60 void SwDropCapsPict::SetText( const OUString& rT )
62 maText = rT;
63 UpdatePaintSettings();
66 void SwDropCapsPict::SetDrawingArea(weld::DrawingArea* pDrawingArea)
68 CustomWidgetController::SetDrawingArea(pDrawingArea);
69 Size aPrefSize(getParagraphPreviewOptimalSize(pDrawingArea->get_ref_device()));
70 pDrawingArea->set_size_request(aPrefSize.Width(), aPrefSize.Height());
73 void SwDropCapsPict::Resize()
75 CustomWidgetController::Resize();
76 UpdatePaintSettings();
79 void SwDropCapsPict::SetLines( sal_uInt8 nL )
81 mnLines = nL;
82 UpdatePaintSettings();
85 void SwDropCapsPict::SetDistance( sal_uInt16 nD )
87 mnDistance = nD;
88 UpdatePaintSettings();
91 void SwDropCapsPict::SetValues( const OUString& rText, sal_uInt8 nLines, sal_uInt16 nDistance )
93 maText = rText;
94 mnLines = nLines;
95 mnDistance = nDistance;
97 UpdatePaintSettings();
100 void SwDropCapsPict::InitPrinter()
102 if( !mpPrinter )
103 InitPrinter_();
106 // Create Default-String from character-count (A, AB, ABC, ...)
107 static OUString GetDefaultString(sal_Int32 nChars)
109 OUStringBuffer aStr(nChars);
110 for (sal_Int32 i = 0; i < nChars; i++)
111 aStr.append(static_cast<sal_Unicode>(i + 65));
112 return aStr.makeStringAndClear();
115 static void calcFontHeightAnyAscent(vcl::RenderContext& rWin, vcl::Font const & _rFont, tools::Long& _nHeight, tools::Long& _nAscent)
117 if ( !_nHeight )
119 rWin.Push(vcl::PushFlags::FONT);
120 rWin.SetFont(_rFont);
121 FontMetric aMetric(rWin.GetFontMetric());
122 _nHeight = aMetric.GetLineHeight();
123 _nAscent = aMetric.GetAscent();
124 rWin.Pop();
128 SwDropCapsPict::~SwDropCapsPict()
130 if (mbDelPrinter)
131 mpPrinter.disposeAndClear();
134 /// Get the details of the first script change.
135 /// @param[out] start The character position of the start of the segment.
136 /// @param[out] end The character position of the end of the segment.
137 /// @param[out] scriptType The script type (Latin, Asian, Complex etc.)
138 void SwDropCapsPict::GetFirstScriptSegment(sal_Int32 &start, sal_Int32 &end, sal_uInt16 &scriptType)
140 start = 0;
141 if( maScriptChanges.empty() )
143 end = maText.getLength();
144 scriptType = css::i18n::ScriptType::LATIN;
146 else
148 end = maScriptChanges[ 0 ].changePos;
149 scriptType = maScriptChanges[ 0 ].scriptType;
153 /// Get the details of the first script change.
154 /// @param[in,out] nIdx Index of the current script change.
155 /// @param[out] start The character position of the start of the segment.
156 /// @param[in,out] end The character position of the end of the segment.
157 /// @param[out] scriptType The script type (Latin, Asian, Complex etc.)
158 /// @returns True if there was a next segment, false if not.
159 bool SwDropCapsPict::GetNextScriptSegment(size_t &nIdx, sal_Int32 &start, sal_Int32 &end, sal_uInt16 &scriptType)
161 if (maScriptChanges.empty() || nIdx >= maScriptChanges.size() - 1 || end >= maText.getLength())
162 return false;
163 start = maScriptChanges[nIdx++].changePos;
164 end = maScriptChanges[ nIdx ].changePos;
165 scriptType = maScriptChanges[ nIdx ].scriptType;
166 return true;
169 #define LINES 10
170 #define BORDER 2
172 void SwDropCapsPict::GetFontSettings( vcl::Font& _rFont, sal_uInt16 _nWhich )
174 SwView* pView = GetActiveView();
175 if (!pView)
176 return;
177 SwWrtShell& rWrtShell = pView->GetWrtShell();
179 SfxItemSet aSet( rWrtShell.GetAttrPool(), _nWhich, _nWhich);
180 rWrtShell.GetCurAttr(aSet);
181 SvxFontItem aFormatFont(static_cast<const SvxFontItem &>( aSet.Get(_nWhich)));
183 _rFont.SetFamily(aFormatFont.GetFamily());
184 _rFont.SetFamilyName(aFormatFont.GetFamilyName());
185 _rFont.SetPitch(aFormatFont.GetPitch());
186 _rFont.SetCharSet(aFormatFont.GetCharSet());
189 void SwDropCapsPict::UpdatePaintSettings()
191 SwView* pView = GetActiveView();
192 if (!pView)
193 return;
194 SwWrtShell& rWrtShell = pView->GetWrtShell();
196 maBackColor = Application::GetSettings().GetStyleSettings().GetWindowColor();
197 maTextLineColor = COL_LIGHTGRAY;
199 // gray lines
200 mnTotLineH = (GetOutputSizePixel().Height() - 2 * BORDER) / LINES;
201 mnLineH = mnTotLineH - 2;
203 vcl::Font aFont;
204 if (mpPage)
206 // tdf#135244: preview generation should not jump document view
207 auto aLock(rWrtShell.GetView().GetDocShell()->LockAllViews());
209 if (!mpPage->m_xTemplateBox->get_active())
211 // query the Font at paragraph's beginning
212 rWrtShell.Push();
213 rWrtShell.SttCursorMove();
214 rWrtShell.ClearMark();
215 SwWhichPara pSwuifnParaCurr = GoCurrPara;
216 SwMoveFnCollection const & pSwuifnParaStart = fnParaStart;
217 rWrtShell.MovePara(pSwuifnParaCurr,pSwuifnParaStart);
218 // normal
219 GetFontSettings( aFont, RES_CHRATR_FONT );
221 // CJK
222 GetFontSettings( maCJKFont, RES_CHRATR_CJK_FONT );
224 // CTL
225 GetFontSettings( maCTLFont, RES_CHRATR_CTL_FONT );
227 rWrtShell.EndCursorMove();
228 rWrtShell.Pop(SwCursorShell::PopMode::DeleteCurrent);
230 else
232 // query Font at character template
233 SwCharFormat *pFormat = rWrtShell.GetCharStyle(
234 mpPage->m_xTemplateBox->get_active_text(),
235 SwWrtShell::GETSTYLE_CREATEANY );
236 OSL_ENSURE(pFormat, "character style doesn't exist!");
237 const SvxFontItem &rFormatFont = pFormat->GetFont();
239 aFont.SetFamily(rFormatFont.GetFamily());
240 aFont.SetFamilyName(rFormatFont.GetFamilyName());
241 aFont.SetPitch(rFormatFont.GetPitch());
242 aFont.SetCharSet(rFormatFont.GetCharSet());
245 const Color& rFontColor = rWrtShell.GetViewOptions()->GetFontColor();
246 aFont.SetColor( rFontColor );
247 maCJKFont.SetColor( rFontColor );
248 maCTLFont.SetColor( rFontColor );
251 mnTextH = mnLines * mnTotLineH;
252 aFont.SetFontSize(Size(0, mnTextH));
253 maCJKFont.SetFontSize(Size(0, mnTextH));
254 maCTLFont.SetFontSize(Size(0, mnTextH));
256 aFont.SetTransparent(true);
257 maCJKFont.SetTransparent(true);
258 maCTLFont.SetTransparent(true);
260 aFont.SetFillColor(Application::GetSettings().GetStyleSettings().GetWindowColor());
261 maCJKFont.SetFillColor(Application::GetSettings().GetStyleSettings().GetWindowColor());
262 maCTLFont.SetFillColor(Application::GetSettings().GetStyleSettings().GetWindowColor());
264 maCJKFont.SetFontSize(Size(0, maCJKFont.GetFontSize().Height()));
265 maCTLFont.SetFontSize(Size(0, maCTLFont.GetFontSize().Height()));
267 aFont.SetFontSize(Size(0, aFont.GetFontSize().Height()));
268 maFont = aFont;
270 CheckScript();
272 maTextSize = CalcTextSize();
274 Invalidate();
277 void SwDropCapsPict::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& /*rRect*/)
279 if (!IsVisible())
280 return;
282 rRenderContext.SetMapMode(MapMode(MapUnit::MapPixel));
283 rRenderContext.SetLineColor();
285 rRenderContext.SetFillColor(maBackColor);
287 Size aOutputSizePixel(GetOutputSizePixel());
289 rRenderContext.DrawRect(tools::Rectangle(Point(0, 0), aOutputSizePixel));
290 rRenderContext.SetClipRegion(vcl::Region(tools::Rectangle(Point(BORDER, BORDER),
291 Size(aOutputSizePixel.Width () - 2 * BORDER,
292 aOutputSizePixel.Height() - 2 * BORDER))));
294 OSL_ENSURE(mnLineH > 0, "We cannot make it that small");
295 tools::Long nY0 = (aOutputSizePixel.Height() - (LINES * mnTotLineH)) / 2;
297 rRenderContext.SetFillColor(maTextLineColor);
299 for (int i = 0; i < LINES; ++i)
301 rRenderContext.DrawRect(tools::Rectangle(Point(BORDER, nY0 + i * mnTotLineH),
302 Size(aOutputSizePixel.Width() - 2 * BORDER, mnLineH)));
305 // Text background with gap (240 twips ~ 1 line height)
306 const tools::Long nDistW = (((static_cast<tools::Long>(mnDistance) * 100) / 240) * mnTotLineH) / 100;
307 rRenderContext.SetFillColor(maBackColor);
308 if (mpPage && mpPage->m_xDropCapsBox->get_active())
310 const Size aTextSize(maTextSize.Width() + nDistW, maTextSize.Height());
311 rRenderContext.DrawRect(tools::Rectangle(Point(BORDER, nY0), aTextSize));
313 // draw Text
314 DrawPrev(rRenderContext, Point(BORDER, nY0));
316 rRenderContext.SetClipRegion();
319 void SwDropCapsPict::DrawPrev(vcl::RenderContext& rRenderContext, const Point& rPt)
321 Point aPt(rPt);
322 InitPrinter();
324 vcl::Font aOldFont = mpPrinter->GetFont();
325 sal_uInt16 nScript;
326 size_t nIdx = 0;
327 sal_Int32 nStart;
328 sal_Int32 nEnd;
330 GetFirstScriptSegment(nStart, nEnd, nScript);
334 SvxFont& rFnt = (nScript == css::i18n::ScriptType::ASIAN)
335 ? maCJKFont
336 : ((nScript == css::i18n::ScriptType::COMPLEX)
337 ? maCTLFont
338 : maFont);
339 mpPrinter->SetFont(rFnt);
341 rFnt.DrawPrev(&rRenderContext, mpPrinter, aPt, maText, nStart, nEnd - nStart);
343 if (!maScriptChanges.empty())
344 aPt.AdjustX(maScriptChanges[nIdx].textWidth );
346 if (!GetNextScriptSegment(nIdx, nStart, nEnd, nScript))
347 break;
349 while(true);
351 mpPrinter->SetFont(aOldFont);
354 void SwDropCapsPict::CheckScript()
356 if( maScriptText == maText )
357 return;
359 maScriptText = maText;
360 maScriptChanges.clear();
361 if( !m_xBreak.is() )
363 Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
364 m_xBreak = css::i18n::BreakIterator::create(xContext);
366 sal_Int16 nScript = m_xBreak->getScriptType( maText, 0 );
367 sal_Int32 nChg = 0;
368 if( css::i18n::ScriptType::WEAK == nScript )
370 nChg = m_xBreak->endOfScript( maText, nChg, nScript );
371 if( nChg < maText.getLength() )
372 nScript = m_xBreak->getScriptType( maText, nChg );
373 else
374 nScript = css::i18n::ScriptType::LATIN;
377 for(;;)
379 nChg = m_xBreak->endOfScript( maText, nChg, nScript );
380 maScriptChanges.emplace_back(nScript, nChg );
381 if( nChg >= maText.getLength() || nChg < 0 )
382 break;
383 nScript = m_xBreak->getScriptType( maText, nChg );
387 Size SwDropCapsPict::CalcTextSize()
389 InitPrinter();
391 sal_uInt16 nScript;
392 size_t nIdx = 0;
393 sal_Int32 nStart;
394 sal_Int32 nEnd;
395 GetFirstScriptSegment(nStart, nEnd, nScript);
396 tools::Long nTextWidth = 0;
397 tools::Long nCJKHeight = 0;
398 tools::Long nCTLHeight = 0;
399 tools::Long nHeight = 0;
400 tools::Long nAscent = 0;
401 tools::Long nCJKAscent = 0;
402 tools::Long nCTLAscent = 0;
405 SvxFont& rFnt = (nScript == css::i18n::ScriptType::ASIAN)
406 ? maCJKFont
407 : ((nScript == css::i18n::ScriptType::COMPLEX)
408 ? maCTLFont
409 : maFont);
411 sal_uLong nWidth = rFnt.GetTextSize(*mpPrinter, maText, nStart, nEnd-nStart ).Width();
413 if (nIdx < maScriptChanges.size())
414 maScriptChanges[nIdx].textWidth = nWidth;
415 nTextWidth += nWidth;
416 switch(nScript)
418 case css::i18n::ScriptType::ASIAN:
419 calcFontHeightAnyAscent(GetDrawingArea()->get_ref_device(), maCJKFont, nCJKHeight, nCJKAscent);
420 break;
421 case css::i18n::ScriptType::COMPLEX:
422 calcFontHeightAnyAscent(GetDrawingArea()->get_ref_device(), maCTLFont, nCTLHeight, nCTLAscent);
423 break;
424 default:
425 calcFontHeightAnyAscent(GetDrawingArea()->get_ref_device(), maFont, nHeight, nAscent);
428 if (!GetNextScriptSegment(nIdx, nStart, nEnd, nScript))
429 break;
431 while(true);
433 nHeight -= nAscent;
434 nCJKHeight -= nCJKAscent;
435 nCTLHeight -= nCTLAscent;
436 if (nHeight < nCJKHeight)
437 nHeight = nCJKHeight;
438 if (nAscent < nCJKAscent)
439 nAscent = nCJKAscent;
440 if (nHeight < nCTLHeight)
441 nHeight = nCTLHeight;
442 if (nAscent < nCTLAscent)
443 nAscent = nCTLAscent;
444 nHeight += nAscent;
446 Size aTextSize(nTextWidth, nHeight);
447 return aTextSize;
450 void SwDropCapsPict::InitPrinter_()
452 SfxViewShell* pSh = SfxViewShell::Current();
454 if (pSh)
455 mpPrinter = pSh->GetPrinter();
457 if (!mpPrinter)
459 mpPrinter = VclPtr<Printer>::Create();
460 mbDelPrinter = true;
464 SwDropCapsDlg::SwDropCapsDlg(weld::Window *pParent, const SfxItemSet &rSet)
465 : SfxSingleTabDialogController(pParent, &rSet)
467 auto xNewPage(SwDropCapsPage::Create(get_content_area(), this, &rSet));
468 static_cast<SwDropCapsPage*>(xNewPage.get())->SetFormat(false);
469 SetTabPage(std::move(xNewPage));
472 SwDropCapsPage::SwDropCapsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rSet)
473 : SfxTabPage(pPage, pController, "modules/swriter/ui/dropcapspage.ui", "DropCapPage", &rSet)
474 , m_bModified(false)
475 , m_bFormat(true)
476 , m_xDropCapsBox(m_xBuilder->weld_check_button("checkCB_SWITCH"))
477 , m_xWholeWordCB(m_xBuilder->weld_check_button("checkCB_WORD"))
478 , m_xSwitchText(m_xBuilder->weld_label("labelFT_DROPCAPS"))
479 , m_xDropCapsField(m_xBuilder->weld_spin_button("spinFLD_DROPCAPS"))
480 , m_xLinesText(m_xBuilder->weld_label("labelTXT_LINES"))
481 , m_xLinesField(m_xBuilder->weld_spin_button("spinFLD_LINES"))
482 , m_xDistanceText(m_xBuilder->weld_label("labelTXT_DISTANCE"))
483 , m_xDistanceField(m_xBuilder->weld_metric_spin_button("spinFLD_DISTANCE", FieldUnit::CM))
484 , m_xTextText(m_xBuilder->weld_label("labelTXT_TEXT"))
485 , m_xTextEdit(m_xBuilder->weld_entry("entryEDT_TEXT"))
486 , m_xTemplateText(m_xBuilder->weld_label("labelTXT_TEMPLATE"))
487 , m_xTemplateBox(m_xBuilder->weld_combo_box("comboBOX_TEMPLATE"))
488 , m_xPict(new weld::CustomWeld(*m_xBuilder, "drawingareaWN_EXAMPLE", m_aPict))
490 m_aPict.SetDropCapsPage(this);
492 SetExchangeSupport();
494 const sal_uInt16 nHtmlMode = ::GetHtmlMode(static_cast<const SwDocShell*>(SfxObjectShell::Current()));
495 m_bHtmlMode = (nHtmlMode & HTMLMODE_ON) != 0;
497 // tdf#92154 limit comboBOX_TEMPLATE length
498 const int nMaxWidth(m_xTemplateBox->get_approximate_digit_width() * 50);
499 m_xTemplateBox->set_size_request(nMaxWidth , -1);
501 // In the template dialog the text is not influenceable
502 m_xTextText->set_sensitive(!m_bFormat);
503 m_xTextEdit->set_sensitive(!m_bFormat);
505 // Metrics
506 SetFieldUnit(*m_xDistanceField, GetDfltMetric(m_bHtmlMode));
508 // Install handler
509 Link<weld::SpinButton&,void> aValueChangedLk = LINK(this, SwDropCapsPage, ValueChangedHdl);
510 m_xDropCapsField->connect_value_changed(aValueChangedLk);
511 m_xLinesField->connect_value_changed(aValueChangedLk);
512 Link<weld::MetricSpinButton&,void> aMetricValueChangedLk = LINK(this, SwDropCapsPage, MetricValueChangedHdl);
513 m_xDistanceField->connect_value_changed(aMetricValueChangedLk);
514 m_xTextEdit->connect_changed(LINK(this, SwDropCapsPage, ModifyHdl));
515 m_xDropCapsBox->connect_toggled(LINK(this, SwDropCapsPage, ClickHdl));
516 m_xTemplateBox->connect_changed(LINK(this, SwDropCapsPage, SelectHdl));
517 m_xWholeWordCB->connect_toggled(LINK(this, SwDropCapsPage, WholeWordHdl));
520 SwDropCapsPage::~SwDropCapsPage()
524 DeactivateRC SwDropCapsPage::DeactivatePage(SfxItemSet * _pSet)
526 if (_pSet)
527 FillSet(*_pSet);
529 return DeactivateRC::LeavePage;
532 std::unique_ptr<SfxTabPage> SwDropCapsPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rSet)
534 return std::make_unique<SwDropCapsPage>(pPage, pController, *rSet);
537 bool SwDropCapsPage::FillItemSet(SfxItemSet *rSet)
539 if (m_bModified)
540 FillSet(*rSet);
541 return m_bModified;
544 void SwDropCapsPage::Reset(const SfxItemSet *rSet)
546 // Characters, lines, gap and text
547 SwFormatDrop aFormatDrop( rSet->Get(RES_PARATR_DROP) );
548 if (aFormatDrop.GetLines() > 1)
550 m_xDropCapsField->set_value(aFormatDrop.GetChars());
551 m_xLinesField->set_value(aFormatDrop.GetLines());
552 m_xDistanceField->set_value(m_xDistanceField->normalize(aFormatDrop.GetDistance()), FieldUnit::TWIP);
553 m_xWholeWordCB->set_active(aFormatDrop.GetWholeWord());
555 else
557 m_xDropCapsField->set_value(1);
558 m_xLinesField->set_value(3);
559 m_xDistanceField->set_value(0, FieldUnit::TWIP);
562 SwView* pView = GetActiveView();
563 if (pView)
564 ::FillCharStyleListBox(*m_xTemplateBox, pView->GetWrtShell().GetView().GetDocShell(), true);
566 m_xTemplateBox->insert_text(0, SwResId(SW_STR_NONE));
568 // Reset format
569 int nSelect = 0;
570 if (aFormatDrop.GetCharFormat())
572 int nPos = m_xTemplateBox->find_text(aFormatDrop.GetCharFormat()->GetName());
573 if (nPos != -1)
574 nSelect = nPos;
576 m_xTemplateBox->set_active(nSelect);
578 // Enable controls
579 m_xDropCapsBox->set_active(aFormatDrop.GetLines() > 1);
580 const sal_Int32 nVal = m_xDropCapsField->get_value();
581 if (m_bFormat)
582 m_xTextEdit->set_text(GetDefaultString(nVal));
583 else
585 if (pView)
586 m_xTextEdit->set_text(pView->GetWrtShell().GetDropText(nVal));
587 m_xTextEdit->set_sensitive(true);
588 m_xTextText->set_sensitive(true);
591 // Preview
592 m_aPict.SetValues(m_xTextEdit->get_text(),
593 sal_uInt8(m_xLinesField->get_value()),
594 sal_uInt16(m_xDistanceField->denormalize(m_xDistanceField->get_value(FieldUnit::TWIP))));
596 ClickHdl(*m_xDropCapsBox);
597 m_bModified = false;
600 IMPL_LINK_NOARG(SwDropCapsPage, ClickHdl, weld::Toggleable&, void)
602 bool bChecked = m_xDropCapsBox->get_active();
604 m_xWholeWordCB->set_sensitive(bChecked && !m_bHtmlMode);
606 m_xSwitchText->set_sensitive(bChecked && !m_xWholeWordCB->get_active());
607 m_xDropCapsField->set_sensitive(bChecked && !m_xWholeWordCB->get_active());
608 m_xLinesText->set_sensitive( bChecked );
609 m_xLinesField->set_sensitive( bChecked );
610 m_xDistanceText->set_sensitive( bChecked );
611 m_xDistanceField->set_sensitive( bChecked );
612 m_xTemplateText->set_sensitive( bChecked );
613 m_xTemplateBox->set_sensitive( bChecked );
614 m_xTextEdit->set_sensitive( bChecked && !m_bFormat );
615 m_xTextText->set_sensitive( bChecked && !m_bFormat );
617 if ( bChecked )
619 ValueChangedHdl(*m_xDropCapsField);
620 m_xDropCapsField->grab_focus();
622 else
623 m_aPict.SetText("");
625 m_bModified = true;
628 IMPL_LINK_NOARG(SwDropCapsPage, WholeWordHdl, weld::Toggleable&, void)
630 m_xDropCapsField->set_sensitive(!m_xWholeWordCB->get_active());
631 m_xSwitchText->set_sensitive(!m_xWholeWordCB->get_active());
633 ValueChangedHdl(*m_xDropCapsField);
635 m_bModified = true;
638 void SwDropCapsPage::ModifyEntry(const weld::Entry& rEdit)
640 OUString sPreview;
642 // set text if applicable
643 if (&rEdit == m_xDropCapsField.get())
645 const sal_Int32 nVal = !m_xWholeWordCB->get_active()
646 ? static_cast<sal_Int32>(m_xDropCapsField->get_value())
647 : 0;
648 bool bSetText = false;
650 if (SwView* pView = GetActiveView())
652 if (m_bFormat || pView->GetWrtShell().GetDropText(1).isEmpty())
653 sPreview = GetDefaultString(nVal);
654 else
656 bSetText = true;
657 sPreview = pView->GetWrtShell().GetDropText(nVal);
661 OUString sEdit(m_xTextEdit->get_text());
663 if (!sEdit.isEmpty() && !sPreview.startsWith(sEdit))
665 sPreview = sEdit.copy(0, std::min(sEdit.getLength(), sPreview.getLength()));
666 bSetText = false;
669 if (bSetText)
670 m_xTextEdit->set_text(sPreview);
672 else if (&rEdit == m_xTextEdit.get()) // set quantity if applicable
674 const sal_Int32 nTmp = m_xTextEdit->get_text().getLength();
675 m_xDropCapsField->set_value(std::max<sal_Int32>(1, nTmp));
676 sPreview = m_xTextEdit->get_text();
679 // adjust image
680 if (&rEdit == m_xDropCapsField.get() || &rEdit == m_xTextEdit.get())
681 m_aPict.SetText(sPreview);
682 else if (&rEdit == m_xLinesField.get())
683 m_aPict.SetLines(static_cast<sal_uInt8>(m_xLinesField->get_value()));
684 else
685 m_aPict.SetDistance(o3tl::narrowing<sal_uInt16>(m_xDistanceField->denormalize(m_xDistanceField->get_value(FieldUnit::TWIP))));
687 m_bModified = true;
690 IMPL_LINK(SwDropCapsPage, ModifyHdl, weld::Entry&, rEdit, void)
692 ModifyEntry(rEdit);
695 IMPL_LINK(SwDropCapsPage, ValueChangedHdl, weld::SpinButton&, rEdit, void)
697 ModifyEntry(rEdit);
700 IMPL_LINK(SwDropCapsPage, MetricValueChangedHdl, weld::MetricSpinButton&, rEdit, void)
702 ModifyEntry(rEdit.get_widget());
705 IMPL_LINK_NOARG(SwDropCapsPage, SelectHdl, weld::ComboBox&, void)
707 m_aPict.UpdatePaintSettings();
708 m_bModified = true;
711 void SwDropCapsPage::FillSet( SfxItemSet &rSet )
713 if(!m_bModified)
714 return;
716 SwFormatDrop aFormat;
718 bool bOn = m_xDropCapsBox->get_active();
719 if (bOn)
721 // quantity, lines, gap
722 aFormat.GetChars() = static_cast<sal_uInt8>(m_xDropCapsField->get_value());
723 aFormat.GetLines() = static_cast<sal_uInt8>(m_xLinesField->get_value());
724 aFormat.GetDistance() = o3tl::narrowing<sal_uInt16>(m_xDistanceField->denormalize(m_xDistanceField->get_value(FieldUnit::TWIP)));
725 aFormat.GetWholeWord() = m_xWholeWordCB->get_active();
727 // template
728 if (SwView* pView = GetActiveView())
729 if (m_xTemplateBox->get_active())
730 aFormat.SetCharFormat(pView->GetWrtShell().GetCharStyle(m_xTemplateBox->get_active_text()));
732 else
734 aFormat.GetChars() = 1;
735 aFormat.GetLines() = 1;
736 aFormat.GetDistance() = 0;
739 // set attributes
740 const SfxPoolItem* pOldItem;
741 if (nullptr == (pOldItem = GetOldItem(rSet, FN_FORMAT_DROPCAPS)) || aFormat != *pOldItem)
742 rSet.Put(aFormat);
744 // hard text formatting
745 // Bug 24974: in designer/template catalog this doesn't make sense!!
746 if (!m_bFormat && m_xDropCapsBox->get_active())
748 OUString sText(m_xTextEdit->get_text());
750 if (!m_xWholeWordCB->get_active())
752 sText = sText.copy(0, std::min<sal_Int32>(sText.getLength(), m_xDropCapsField->get_value()));
755 SfxStringItem aStr(FN_PARAM_1, sText);
756 rSet.Put(aStr);
760 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */