Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <hintids.hxx>
21 :
22 : #include "cmdid.h"
23 : #include <docsh.hxx>
24 : #include "swmodule.hxx"
25 : #include "view.hxx"
26 : #include "wrtsh.hxx"
27 : #include "globals.hrc"
28 :
29 : #include <vcl/metric.hxx>
30 : #include <vcl/settings.hxx>
31 :
32 : #include <svl/stritem.hxx>
33 : #include <editeng/fontitem.hxx>
34 : #include <sfx2/dialoghelper.hxx>
35 : #include <sfx2/htmlmode.hxx>
36 : #include <sfx2/objsh.hxx>
37 : #include <editeng/svxfont.hxx>
38 : #include <vcl/print.hxx>
39 : #include <vcl/builderfactory.hxx>
40 : #include <sfx2/printer.hxx>
41 : #include <com/sun/star/i18n/ScriptType.hpp>
42 : #include <editeng/scripttypeitem.hxx>
43 : #include <com/sun/star/i18n/BreakIterator.hpp>
44 : #include <comphelper/processfactory.hxx>
45 :
46 : #include "charatr.hxx"
47 : #include "viewopt.hxx"
48 : #include "drpcps.hxx"
49 : #include "paratr.hxx"
50 : #include "uitool.hxx"
51 : #include "charfmt.hxx"
52 :
53 : #include "chrdlg.hrc"
54 :
55 : using namespace css;
56 : using namespace css::uno;
57 : using namespace css::lang;
58 :
59 : const sal_uInt16 SwDropCapsPage::aPageRg[] = {
60 : RES_PARATR_DROP, RES_PARATR_DROP,
61 : 0
62 : };
63 :
64 : class SwDropCapsPict : public Control
65 : {
66 : VclPtr<SwDropCapsPage> mpPage;
67 : OUString maText;
68 : OUString maScriptText;
69 : Color maBackColor;
70 : Color maTextLineColor;
71 : sal_uInt8 mnLines;
72 : long mnTotLineH;
73 : long mnLineH;
74 : long mnTextH;
75 : sal_uInt16 mnDistance;
76 : VclPtr<Printer> mpPrinter;
77 : bool mbDelPrinter;
78 : /// The _ScriptInfo structure holds information on where we change from one
79 : /// script to another.
80 : struct _ScriptInfo
81 : {
82 : sal_uLong textWidth; ///< Physical width of this segment.
83 : sal_uInt16 scriptType; ///< Script type (e.g. Latin, Asian, Complex)
84 : sal_Int32 changePos; ///< Character position where the script changes.
85 0 : _ScriptInfo(sal_uLong txtWidth, sal_uInt16 scrptType, sal_Int32 position)
86 0 : : textWidth(txtWidth), scriptType(scrptType), changePos(position) {}
87 : };
88 : std::vector<_ScriptInfo> maScriptChanges;
89 : SvxFont maFont;
90 : SvxFont maCJKFont;
91 : SvxFont maCTLFont;
92 : Size maTextSize;
93 : Reference< css::i18n::XBreakIterator > xBreak;
94 :
95 : virtual void Paint(vcl::RenderContext& /*rRenderContext*/, const Rectangle &rRect) SAL_OVERRIDE;
96 : void CheckScript();
97 : Size CalcTextSize();
98 : inline void InitPrinter();
99 : void _InitPrinter();
100 : static void GetFontSettings( const SwDropCapsPage& _rPage, vcl::Font& _rFont, sal_uInt16 _nWhich );
101 : void GetFirstScriptSegment(sal_Int32 &start, sal_Int32 &end, sal_uInt16 &scriptType);
102 : bool GetNextScriptSegment(size_t &nIdx, sal_Int32 &start, sal_Int32 &end, sal_uInt16 &scriptType);
103 :
104 : public:
105 :
106 0 : SwDropCapsPict(vcl::Window *pParent, WinBits nBits)
107 : : Control(pParent, nBits)
108 : , mpPage(NULL)
109 : , mnLines(0)
110 : , mnTotLineH(0)
111 : , mnLineH(0)
112 : , mnTextH(0)
113 : , mnDistance(0)
114 : , mpPrinter(NULL)
115 0 : , mbDelPrinter(false)
116 0 : {}
117 :
118 0 : void SetDropCapsPage(SwDropCapsPage* pPage) { mpPage = pPage; }
119 :
120 : virtual ~SwDropCapsPict();
121 : virtual void dispose() SAL_OVERRIDE;
122 :
123 : void UpdatePaintSettings(); // also invalidates control!
124 :
125 : virtual void Resize() SAL_OVERRIDE;
126 : virtual Size GetOptimalSize() const SAL_OVERRIDE;
127 :
128 : void SetText( const OUString& rT ) SAL_OVERRIDE;
129 : void SetLines( sal_uInt8 nL );
130 : void SetDistance( sal_uInt16 nD );
131 : void SetValues( const OUString& rText, sal_uInt8 nLines, sal_uInt16 nDistance );
132 :
133 : void DrawPrev(vcl::RenderContext& rRenderContext, const Point& rPt);
134 : };
135 :
136 0 : VCL_BUILDER_FACTORY_ARGS(SwDropCapsPict, WB_BORDER)
137 :
138 0 : void SwDropCapsPict::SetText( const OUString& rT )
139 : {
140 0 : maText = rT;
141 0 : UpdatePaintSettings();
142 0 : }
143 :
144 0 : Size SwDropCapsPict::GetOptimalSize() const
145 : {
146 0 : return getParagraphPreviewOptimalSize(this);
147 : }
148 :
149 0 : void SwDropCapsPict::Resize()
150 : {
151 0 : Control::Resize();
152 0 : UpdatePaintSettings();
153 0 : }
154 :
155 0 : void SwDropCapsPict::SetLines( sal_uInt8 nL )
156 : {
157 0 : mnLines = nL;
158 0 : UpdatePaintSettings();
159 0 : }
160 :
161 0 : void SwDropCapsPict::SetDistance( sal_uInt16 nD )
162 : {
163 0 : mnDistance = nD;
164 0 : UpdatePaintSettings();
165 0 : }
166 :
167 0 : void SwDropCapsPict::SetValues( const OUString& rText, sal_uInt8 nLines, sal_uInt16 nDistance )
168 : {
169 0 : maText = rText;
170 0 : mnLines = nLines;
171 0 : mnDistance = nDistance;
172 :
173 0 : UpdatePaintSettings();
174 0 : }
175 :
176 0 : void SwDropCapsPict::InitPrinter()
177 : {
178 0 : if( !mpPrinter )
179 0 : _InitPrinter();
180 0 : }
181 :
182 : // Create Default-String from character-count (A, AB, ABC, ...)
183 0 : OUString GetDefaultString(sal_Int32 nChars)
184 : {
185 0 : OUString aStr;
186 0 : for (sal_Int32 i = 0; i < nChars; i++)
187 0 : aStr += OUString((char) (i + 65));
188 0 : return aStr;
189 : }
190 :
191 0 : static void calcFontHeightAnyAscent( vcl::RenderContext* _pWin, vcl::Font& _rFont, long& _nHeight, long& _nAscent )
192 : {
193 0 : if ( !_nHeight )
194 : {
195 0 : _pWin->SetFont( _rFont );
196 0 : FontMetric aMetric( _pWin->GetFontMetric() );
197 0 : _nHeight = aMetric.GetLineHeight();
198 0 : _nAscent = aMetric.GetAscent();
199 : }
200 0 : }
201 :
202 0 : SwDropCapsPict::~SwDropCapsPict()
203 : {
204 0 : disposeOnce();
205 0 : }
206 :
207 0 : void SwDropCapsPict::dispose()
208 : {
209 0 : if( mbDelPrinter )
210 0 : mpPrinter.disposeAndClear();
211 0 : mpPage.clear();
212 0 : Control::dispose();
213 0 : }
214 :
215 : /// Get the details of the first script change.
216 : /// @param[out] start The character position of the start of the segment.
217 : /// @param[out] end The character position of the end of the segment.
218 : /// @param[out] scriptType The script type (Latin, Asian, Complex etc.)
219 0 : void SwDropCapsPict::GetFirstScriptSegment(sal_Int32 &start, sal_Int32 &end, sal_uInt16 &scriptType)
220 : {
221 0 : start = 0;
222 0 : if( maScriptChanges.empty() )
223 : {
224 0 : end = maText.getLength();
225 0 : scriptType = css::i18n::ScriptType::LATIN;
226 : }
227 : else
228 : {
229 0 : end = maScriptChanges[ 0 ].changePos;
230 0 : scriptType = maScriptChanges[ 0 ].scriptType;
231 : }
232 0 : }
233 :
234 : /// Get the details of the first script change.
235 : /// @param[in,out] nIdx Index of the current script change.
236 : /// @param[out] start The character position of the start of the segment.
237 : /// @param[in,out] end The character position of the end of the segment.
238 : /// @param[out] scriptType The script type (Latin, Asian, Complex etc.)
239 : /// @returns True if there was a next segment, false if not.
240 0 : bool SwDropCapsPict::GetNextScriptSegment(size_t &nIdx, sal_Int32 &start, sal_Int32 &end, sal_uInt16 &scriptType)
241 : {
242 0 : if (maScriptChanges.empty() || nIdx >= maScriptChanges.size() - 1 || end >= maText.getLength())
243 0 : return false;
244 0 : start = maScriptChanges[nIdx++].changePos;
245 0 : end = maScriptChanges[ nIdx ].changePos;
246 0 : scriptType = maScriptChanges[ nIdx ].scriptType;
247 0 : return true;
248 : }
249 :
250 : #define LINES 10
251 : #define BORDER 2
252 :
253 0 : void SwDropCapsPict::GetFontSettings( const SwDropCapsPage& _rPage, vcl::Font& _rFont, sal_uInt16 _nWhich )
254 : {
255 0 : SfxItemSet aSet( _rPage.rSh.GetAttrPool(), _nWhich, _nWhich);
256 0 : _rPage.rSh.GetCurAttr(aSet);
257 0 : SvxFontItem aFormatFont(static_cast<const SvxFontItem &>( aSet.Get(_nWhich)));
258 :
259 0 : _rFont.SetFamily (aFormatFont.GetFamily());
260 0 : _rFont.SetName (aFormatFont.GetFamilyName());
261 0 : _rFont.SetPitch (aFormatFont.GetPitch());
262 0 : _rFont.SetCharSet(aFormatFont.GetCharSet());
263 0 : }
264 :
265 0 : void SwDropCapsPict::UpdatePaintSettings()
266 : {
267 0 : maBackColor = GetSettings().GetStyleSettings().GetWindowColor();
268 0 : maTextLineColor = Color( COL_LIGHTGRAY );
269 :
270 : // gray lines
271 0 : mnTotLineH = (GetOutputSizePixel().Height() - 2 * BORDER) / LINES;
272 0 : mnLineH = mnTotLineH - 2;
273 :
274 0 : vcl::Font aFont;
275 0 : if (mpPage)
276 : {
277 0 : if (!mpPage->m_pTemplateBox->GetSelectEntryPos())
278 : {
279 : // query the Font at paragraph's beginning
280 0 : mpPage->rSh.Push();
281 0 : mpPage->rSh.SttCrsrMove();
282 0 : mpPage->rSh.ClearMark();
283 0 : SwWhichPara pSwuifnParaCurr = GetfnParaCurr();
284 0 : SwPosPara pSwuifnParaStart = GetfnParaStart();
285 0 : mpPage->rSh.MovePara(pSwuifnParaCurr,pSwuifnParaStart);
286 : // normal
287 0 : GetFontSettings( *mpPage, aFont, RES_CHRATR_FONT );
288 :
289 : // CJK
290 0 : GetFontSettings( *mpPage, maCJKFont, RES_CHRATR_CJK_FONT );
291 :
292 : // CTL
293 0 : GetFontSettings( *mpPage, maCTLFont, RES_CHRATR_CTL_FONT );
294 :
295 0 : mpPage->rSh.EndCrsrMove();
296 0 : mpPage->rSh.Pop(false);
297 : }
298 : else
299 : {
300 : // query Font at character template
301 0 : SwCharFormat *pFormat = mpPage->rSh.GetCharStyle(
302 0 : mpPage->m_pTemplateBox->GetSelectEntry(),
303 0 : SwWrtShell::GETSTYLE_CREATEANY );
304 : OSL_ENSURE(pFormat, "character style doesn't exist!");
305 0 : const SvxFontItem &rFormatFont = pFormat->GetFont();
306 :
307 0 : aFont.SetFamily (rFormatFont.GetFamily());
308 0 : aFont.SetName (rFormatFont.GetFamilyName());
309 0 : aFont.SetPitch (rFormatFont.GetPitch());
310 0 : aFont.SetCharSet(rFormatFont.GetCharSet());
311 : }
312 : }
313 :
314 0 : mnTextH = mnLines * mnTotLineH;
315 0 : aFont.SetSize(Size(0, mnTextH));
316 0 : maCJKFont.SetSize(Size(0, mnTextH));
317 0 : maCTLFont.SetSize(Size(0, mnTextH));
318 :
319 0 : aFont.SetTransparent(true);
320 0 : maCJKFont.SetTransparent(true);
321 0 : maCTLFont.SetTransparent(true);
322 :
323 0 : aFont.SetColor( SwViewOption::GetFontColor() );
324 0 : maCJKFont.SetColor( SwViewOption::GetFontColor() );
325 0 : maCTLFont.SetColor( SwViewOption::GetFontColor() );
326 :
327 0 : aFont.SetFillColor(GetSettings().GetStyleSettings().GetWindowColor());
328 0 : maCJKFont.SetFillColor(GetSettings().GetStyleSettings().GetWindowColor());
329 0 : maCTLFont.SetFillColor(GetSettings().GetStyleSettings().GetWindowColor());
330 :
331 0 : maCJKFont.SetSize(Size(0, maCJKFont.GetSize().Height()));
332 0 : maCTLFont.SetSize(Size(0, maCTLFont.GetSize().Height()));
333 :
334 0 : SetFont(aFont);
335 0 : aFont.SetSize(Size(0, aFont.GetSize().Height()));
336 0 : SetFont(aFont);
337 0 : maFont = aFont;
338 :
339 0 : CheckScript();
340 :
341 0 : maTextSize = CalcTextSize();
342 :
343 0 : Invalidate();
344 0 : }
345 :
346 0 : void SwDropCapsPict::Paint(vcl::RenderContext& rRenderContext, const Rectangle& /*rRect*/)
347 : {
348 0 : if (!IsVisible())
349 0 : return;
350 :
351 0 : rRenderContext.SetMapMode(MapMode(MAP_PIXEL));
352 0 : rRenderContext.SetLineColor();
353 :
354 0 : rRenderContext.SetFillColor(maBackColor);
355 :
356 0 : Size aOutputSizePixel(rRenderContext.GetOutputSizePixel());
357 :
358 0 : DrawRect(Rectangle(Point(0, 0), aOutputSizePixel));
359 : rRenderContext.SetClipRegion(vcl::Region(Rectangle(Point(BORDER, BORDER),
360 0 : Size(aOutputSizePixel.Width () - 2 * BORDER,
361 0 : aOutputSizePixel.Height() - 2 * BORDER))));
362 :
363 : OSL_ENSURE(mnLineH > 0, "We cannot make it that small");
364 0 : long nY0 = (aOutputSizePixel.Height() - (LINES * mnTotLineH)) / 2;
365 :
366 0 : rRenderContext.SetFillColor(maTextLineColor);
367 :
368 0 : for (int i = 0; i < LINES; ++i)
369 : {
370 0 : rRenderContext.DrawRect(Rectangle(Point(BORDER, nY0 + i * mnTotLineH),
371 0 : Size(aOutputSizePixel.Width() - 2 * BORDER, mnLineH)));
372 : }
373 :
374 : // Text background with gap (240 twips ~ 1 line height)
375 0 : const long nDistW = (((static_cast<long>(mnDistance) * 100) / 240) * mnTotLineH) / 100;
376 0 : rRenderContext.SetFillColor(maBackColor);
377 0 : if (mpPage && mpPage->m_pDropCapsBox->IsChecked())
378 : {
379 0 : const Size aTextSize(maTextSize.Width() + nDistW, maTextSize.Height());
380 0 : rRenderContext.DrawRect(Rectangle(Point(BORDER, nY0), aTextSize));
381 :
382 : // draw Text
383 0 : DrawPrev(rRenderContext, Point(BORDER, nY0));
384 : }
385 0 : rRenderContext.SetClipRegion();
386 : }
387 :
388 0 : void SwDropCapsPict::DrawPrev(vcl::RenderContext& rRenderContext, const Point& rPt)
389 : {
390 0 : Point aPt(rPt);
391 0 : InitPrinter();
392 :
393 0 : vcl::Font aOldFont = mpPrinter->GetFont();
394 : sal_uInt16 nScript;
395 0 : size_t nIdx = 0;
396 : sal_Int32 nStart;
397 : sal_Int32 nEnd;
398 :
399 0 : GetFirstScriptSegment(nStart, nEnd, nScript);
400 :
401 : do
402 : {
403 0 : SvxFont& rFnt = (nScript == css::i18n::ScriptType::ASIAN)
404 : ? maCJKFont
405 0 : : ((nScript == css::i18n::ScriptType::COMPLEX)
406 : ? maCTLFont
407 0 : : maFont);
408 0 : mpPrinter->SetFont(rFnt);
409 :
410 0 : rFnt.DrawPrev(&rRenderContext, mpPrinter, aPt, maText, nStart, nEnd - nStart);
411 :
412 0 : if (!maScriptChanges.empty())
413 0 : aPt.X() += maScriptChanges[nIdx].textWidth;
414 :
415 0 : if (!GetNextScriptSegment(nIdx, nStart, nEnd, nScript))
416 0 : break;
417 : }
418 : while(true);
419 :
420 0 : mpPrinter->SetFont(aOldFont);
421 0 : }
422 :
423 0 : void SwDropCapsPict::CheckScript()
424 : {
425 0 : if( maScriptText == maText )
426 0 : return;
427 :
428 0 : maScriptText = maText;
429 0 : maScriptChanges.clear();
430 0 : if( !xBreak.is() )
431 : {
432 0 : Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
433 0 : xBreak = css::i18n::BreakIterator::create(xContext);
434 : }
435 0 : sal_Int16 nScript = xBreak->getScriptType( maText, 0 );
436 0 : sal_Int32 nChg = 0;
437 0 : if( css::i18n::ScriptType::WEAK == nScript )
438 : {
439 0 : nChg = xBreak->endOfScript( maText, nChg, nScript );
440 0 : if( nChg < maText.getLength() )
441 0 : nScript = xBreak->getScriptType( maText, nChg );
442 : else
443 0 : nScript = css::i18n::ScriptType::LATIN;
444 : }
445 :
446 : for(;;)
447 : {
448 0 : nChg = xBreak->endOfScript( maText, nChg, nScript );
449 0 : maScriptChanges.push_back( _ScriptInfo(0, nScript, nChg) );
450 0 : if( nChg >= maText.getLength() || nChg < 0 )
451 0 : break;
452 0 : nScript = xBreak->getScriptType( maText, nChg );
453 0 : }
454 : }
455 :
456 0 : Size SwDropCapsPict::CalcTextSize()
457 : {
458 0 : InitPrinter();
459 :
460 : sal_uInt16 nScript;
461 0 : size_t nIdx = 0;
462 : sal_Int32 nStart;
463 : sal_Int32 nEnd;
464 0 : GetFirstScriptSegment(nStart, nEnd, nScript);
465 0 : long nTextWidth = 0;
466 0 : long nCJKHeight = 0;
467 0 : long nCTLHeight = 0;
468 0 : long nHeight = 0;
469 0 : long nAscent = 0;
470 0 : long nCJKAscent = 0;
471 0 : long nCTLAscent = 0;
472 : do
473 : {
474 0 : SvxFont& rFnt = (nScript == css::i18n::ScriptType::ASIAN)
475 : ? maCJKFont
476 0 : : ((nScript == css::i18n::ScriptType::COMPLEX)
477 : ? maCTLFont
478 0 : : maFont);
479 :
480 0 : sal_uLong nWidth = rFnt.GetTextSize(mpPrinter, maText, nStart, nEnd-nStart ).Width();
481 :
482 0 : if (nIdx < maScriptChanges.size())
483 0 : maScriptChanges[nIdx].textWidth = nWidth;
484 0 : nTextWidth += nWidth;
485 0 : switch(nScript)
486 : {
487 : case css::i18n::ScriptType::ASIAN:
488 0 : calcFontHeightAnyAscent(this, maCJKFont, nCJKHeight, nCJKAscent);
489 0 : break;
490 : case css::i18n::ScriptType::COMPLEX:
491 0 : calcFontHeightAnyAscent(this, maCTLFont, nCTLHeight, nCTLAscent);
492 0 : break;
493 : default:
494 0 : calcFontHeightAnyAscent(this, maFont, nHeight, nAscent);
495 : }
496 :
497 0 : if (!GetNextScriptSegment(nIdx, nStart, nEnd, nScript))
498 0 : break;
499 : }
500 : while(true);
501 :
502 0 : nHeight -= nAscent;
503 0 : nCJKHeight -= nCJKAscent;
504 0 : nCTLHeight -= nCTLAscent;
505 0 : if (nHeight < nCJKHeight)
506 0 : nHeight = nCJKHeight;
507 0 : if (nAscent < nCJKAscent)
508 0 : nAscent = nCJKAscent;
509 0 : if (nHeight < nCTLHeight)
510 0 : nHeight = nCTLHeight;
511 0 : if (nAscent < nCTLAscent)
512 0 : nAscent = nCTLAscent;
513 0 : nHeight += nAscent;
514 :
515 0 : Size aTextSize(nTextWidth, nHeight);
516 0 : return aTextSize;
517 : }
518 :
519 0 : void SwDropCapsPict::_InitPrinter()
520 : {
521 0 : SfxViewShell* pSh = SfxViewShell::Current();
522 :
523 0 : if (pSh)
524 0 : mpPrinter = pSh->GetPrinter();
525 :
526 0 : if (!mpPrinter)
527 : {
528 0 : mpPrinter = VclPtr<Printer>::Create();
529 0 : mbDelPrinter = true;
530 : }
531 0 : }
532 :
533 0 : SwDropCapsDlg::SwDropCapsDlg(vcl::Window *pParent, const SfxItemSet &rSet )
534 0 : : SfxSingleTabDialog(pParent, rSet)
535 : {
536 0 : VclPtr<SwDropCapsPage> pNewPage( static_cast<SwDropCapsPage*>( SwDropCapsPage::Create(get_content_area(), &rSet).get() ) );
537 0 : pNewPage->SetFormat(false);
538 0 : SetTabPage(pNewPage);
539 0 : }
540 :
541 0 : SwDropCapsPage::SwDropCapsPage(vcl::Window *pParent, const SfxItemSet &rSet)
542 : : SfxTabPage(pParent, "DropCapPage","modules/swriter/ui/dropcapspage.ui", &rSet)
543 : , bModified(false)
544 : , bFormat(true)
545 0 : , rSh(::GetActiveView()->GetWrtShell())
546 : {
547 0 : get(m_pDropCapsBox,"checkCB_SWITCH");
548 0 : get(m_pWholeWordCB,"checkCB_WORD");
549 0 : get(m_pDropCapsField,"spinFLD_DROPCAPS");
550 0 : get(m_pLinesField,"spinFLD_LINES");
551 0 : get(m_pDistanceField,"spinFLD_DISTANCE");
552 0 : get(m_pSwitchText,"labelFT_DROPCAPS");
553 0 : get(m_pLinesText,"labelTXT_LINES");
554 0 : get(m_pDistanceText,"labelTXT_DISTANCE");
555 0 : get(m_pTemplateText,"labelTXT_TEMPLATE");
556 0 : get(m_pTextText,"labelTXT_TEXT");
557 0 : get(m_pTextEdit,"entryEDT_TEXT");
558 0 : get(m_pTemplateBox,"comboBOX_TEMPLATE");
559 0 : get(m_pPict,"drawingareaWN_EXAMPLE");
560 :
561 0 : m_pPict->SetDropCapsPage(this);
562 :
563 0 : SetExchangeSupport();
564 :
565 0 : const sal_uInt16 nHtmlMode = ::GetHtmlMode(static_cast<const SwDocShell*>(SfxObjectShell::Current()));
566 0 : bHtmlMode = (nHtmlMode & HTMLMODE_ON) != 0;
567 :
568 : // In the template dialog the text is not influenceable
569 0 : m_pTextText->Enable( !bFormat );
570 0 : m_pTextEdit->Enable( !bFormat );
571 :
572 : // Metrics
573 0 : SetMetric( *m_pDistanceField, GetDfltMetric(bHtmlMode) );
574 :
575 0 : m_pPict->SetBorderStyle( WindowBorderStyle::MONO );
576 :
577 : // Install handler
578 0 : Link<> aLk = LINK(this, SwDropCapsPage, ModifyHdl);
579 0 : m_pDropCapsField->SetModifyHdl( aLk );
580 0 : m_pLinesField->SetModifyHdl( aLk );
581 0 : m_pDistanceField->SetModifyHdl( aLk );
582 0 : m_pTextEdit->SetModifyHdl( aLk );
583 0 : m_pDropCapsBox->SetClickHdl (LINK(this, SwDropCapsPage, ClickHdl ));
584 0 : m_pTemplateBox->SetSelectHdl(LINK(this, SwDropCapsPage, SelectHdl));
585 0 : m_pWholeWordCB->SetClickHdl (LINK(this, SwDropCapsPage, WholeWordHdl ));
586 :
587 0 : setPreviewsToSamePlace(pParent, this);
588 0 : }
589 :
590 0 : SwDropCapsPage::~SwDropCapsPage()
591 : {
592 0 : disposeOnce();
593 0 : }
594 :
595 0 : void SwDropCapsPage::dispose()
596 : {
597 0 : m_pDropCapsBox.clear();
598 0 : m_pWholeWordCB.clear();
599 0 : m_pSwitchText.clear();
600 0 : m_pDropCapsField.clear();
601 0 : m_pLinesText.clear();
602 0 : m_pLinesField.clear();
603 0 : m_pDistanceText.clear();
604 0 : m_pDistanceField.clear();
605 0 : m_pTextText.clear();
606 0 : m_pTextEdit.clear();
607 0 : m_pTemplateText.clear();
608 0 : m_pTemplateBox.clear();
609 0 : m_pPict.clear();
610 0 : SfxTabPage::dispose();
611 0 : }
612 :
613 0 : SfxTabPage::sfxpg SwDropCapsPage::DeactivatePage(SfxItemSet * _pSet)
614 : {
615 0 : if (_pSet)
616 0 : FillSet(*_pSet);
617 :
618 0 : return LEAVE_PAGE;
619 : }
620 :
621 0 : VclPtr<SfxTabPage> SwDropCapsPage::Create(vcl::Window *pParent,
622 : const SfxItemSet *rSet)
623 : {
624 0 : return VclPtr<SwDropCapsPage>::Create(pParent, *rSet);
625 : }
626 :
627 0 : bool SwDropCapsPage::FillItemSet(SfxItemSet *rSet)
628 : {
629 0 : if (bModified)
630 0 : FillSet(*rSet);
631 0 : return bModified;
632 : }
633 :
634 0 : void SwDropCapsPage::Reset(const SfxItemSet *rSet)
635 : {
636 : // Characters, lines, gap and text
637 0 : SwFormatDrop aFormatDrop(static_cast<const SwFormatDrop &>( rSet->Get(RES_PARATR_DROP)));
638 0 : if (aFormatDrop.GetLines() > 1)
639 : {
640 0 : m_pDropCapsField->SetValue(aFormatDrop.GetChars());
641 0 : m_pLinesField->SetValue(aFormatDrop.GetLines());
642 0 : m_pDistanceField->SetValue(m_pDistanceField->Normalize(aFormatDrop.GetDistance()), FUNIT_TWIP);
643 0 : m_pWholeWordCB->Check(aFormatDrop.GetWholeWord());
644 : }
645 : else
646 : {
647 0 : m_pDropCapsField->SetValue(1);
648 0 : m_pLinesField->SetValue(3);
649 0 : m_pDistanceField->SetValue(0);
650 : }
651 :
652 0 : ::FillCharStyleListBox(*m_pTemplateBox, rSh.GetView().GetDocShell(), true);
653 :
654 0 : m_pTemplateBox->InsertEntry(SW_RESSTR(SW_STR_NONE), 0);
655 :
656 : // Reset format
657 0 : m_pTemplateBox->SelectEntryPos(0);
658 0 : if (aFormatDrop.GetCharFormat())
659 0 : m_pTemplateBox->SelectEntry(aFormatDrop.GetCharFormat()->GetName());
660 :
661 : // Enable controls
662 0 : m_pDropCapsBox->Check(aFormatDrop.GetLines() > 1);
663 0 : const sal_Int32 nVal = static_cast<sal_Int32>(m_pDropCapsField->GetValue());
664 0 : if (bFormat)
665 0 : m_pTextEdit->SetText(GetDefaultString(nVal));
666 : else
667 : {
668 0 : m_pTextEdit->SetText(rSh.GetDropText(nVal));
669 0 : m_pTextEdit->Enable();
670 0 : m_pTextText->Enable();
671 : }
672 :
673 : // Preview
674 0 : m_pPict->SetValues(m_pTextEdit->GetText(),
675 0 : sal_uInt8(m_pLinesField->GetValue()),
676 0 : sal_uInt16(m_pDistanceField->Denormalize(m_pDistanceField->GetValue(FUNIT_TWIP))));
677 :
678 0 : ClickHdl(m_pDropCapsBox);
679 0 : bModified = false;
680 0 : }
681 :
682 0 : IMPL_LINK_NOARG(SwDropCapsPage, ClickHdl)
683 : {
684 0 : bool bChecked = m_pDropCapsBox->IsChecked();
685 :
686 0 : m_pWholeWordCB->Enable( bChecked && !bHtmlMode );
687 :
688 0 : m_pSwitchText->Enable( bChecked && !m_pWholeWordCB->IsChecked() );
689 0 : m_pDropCapsField->Enable( bChecked && !m_pWholeWordCB->IsChecked() );
690 0 : m_pLinesText->Enable( bChecked );
691 0 : m_pLinesField->Enable( bChecked );
692 0 : m_pDistanceText->Enable( bChecked );
693 0 : m_pDistanceField->Enable( bChecked );
694 0 : m_pTemplateText->Enable( bChecked );
695 0 : m_pTemplateBox->Enable( bChecked );
696 0 : m_pTextEdit->Enable( bChecked && !bFormat );
697 0 : m_pTextText->Enable( bChecked && !bFormat );
698 :
699 0 : if ( bChecked )
700 : {
701 0 : ModifyHdl(m_pDropCapsField);
702 0 : m_pDropCapsField->GrabFocus();
703 : }
704 : else
705 0 : m_pPict->SetText("");
706 :
707 0 : bModified = true;
708 :
709 0 : return 0;
710 : }
711 :
712 0 : IMPL_LINK_NOARG(SwDropCapsPage, WholeWordHdl)
713 : {
714 0 : m_pDropCapsField->Enable( !m_pWholeWordCB->IsChecked() );
715 0 : m_pSwitchText->Enable(!m_pWholeWordCB->IsChecked());
716 :
717 0 : ModifyHdl(m_pDropCapsField);
718 :
719 0 : bModified = true;
720 :
721 0 : return 0;
722 : }
723 :
724 0 : IMPL_LINK( SwDropCapsPage, ModifyHdl, Edit *, pEdit )
725 : {
726 0 : OUString sPreview;
727 :
728 : // set text if applicable
729 0 : if (pEdit == m_pDropCapsField)
730 : {
731 0 : const sal_Int32 nVal = !m_pWholeWordCB->IsChecked()
732 0 : ? static_cast<sal_Int32>(m_pDropCapsField->GetValue())
733 0 : : 0;
734 0 : bool bSetText = false;
735 :
736 0 : if (bFormat || rSh.GetDropText(1).isEmpty())
737 0 : sPreview = GetDefaultString(nVal);
738 : else
739 : {
740 0 : bSetText = true;
741 0 : sPreview = rSh.GetDropText(nVal);
742 : }
743 :
744 0 : OUString sEdit(m_pTextEdit->GetText());
745 :
746 0 : if (!sEdit.isEmpty() && !sPreview.startsWith(sEdit))
747 : {
748 0 : sPreview = sEdit.copy(0, std::min(sEdit.getLength(), sPreview.getLength()));
749 0 : bSetText = false;
750 : }
751 :
752 0 : if (bSetText)
753 0 : m_pTextEdit->SetText(sPreview);
754 : }
755 0 : else if (pEdit == m_pTextEdit) // set quantity if applicable
756 : {
757 0 : const sal_Int32 nTmp = m_pTextEdit->GetText().getLength();
758 0 : m_pDropCapsField->SetValue(std::max<sal_Int32>(1, nTmp));
759 0 : sPreview = m_pTextEdit->GetText();
760 : }
761 :
762 : // adjust image
763 0 : if (pEdit == m_pDropCapsField || pEdit == m_pTextEdit)
764 0 : m_pPict->SetText (sPreview);
765 0 : else if (pEdit == m_pLinesField)
766 0 : m_pPict->SetLines((sal_uInt8)m_pLinesField->GetValue());
767 : else
768 0 : m_pPict->SetDistance((sal_uInt16)m_pDistanceField->Denormalize(m_pDistanceField->GetValue(FUNIT_TWIP)));
769 :
770 0 : bModified = true;
771 :
772 0 : return 0;
773 : }
774 :
775 0 : IMPL_LINK_NOARG(SwDropCapsPage, SelectHdl)
776 : {
777 0 : m_pPict->UpdatePaintSettings();
778 0 : bModified = true;
779 0 : return 0;
780 : }
781 :
782 0 : void SwDropCapsPage::FillSet( SfxItemSet &rSet )
783 : {
784 0 : if(bModified)
785 : {
786 0 : SwFormatDrop aFormat;
787 :
788 0 : bool bOn = m_pDropCapsBox->IsChecked();
789 0 : if(bOn)
790 : {
791 : // quantity, lines, gap
792 0 : aFormat.GetChars() = (sal_uInt8) m_pDropCapsField->GetValue();
793 0 : aFormat.GetLines() = (sal_uInt8) m_pLinesField->GetValue();
794 0 : aFormat.GetDistance() = (sal_uInt16) m_pDistanceField->Denormalize(m_pDistanceField->GetValue(FUNIT_TWIP));
795 0 : aFormat.GetWholeWord() = m_pWholeWordCB->IsChecked();
796 :
797 : // template
798 0 : if (m_pTemplateBox->GetSelectEntryPos())
799 0 : aFormat.SetCharFormat(rSh.GetCharStyle(m_pTemplateBox->GetSelectEntry()));
800 : }
801 : else
802 : {
803 0 : aFormat.GetChars() = 1;
804 0 : aFormat.GetLines() = 1;
805 0 : aFormat.GetDistance() = 0;
806 : }
807 :
808 : // set attributes
809 : const SfxPoolItem* pOldItem;
810 0 : if (0 == (pOldItem = GetOldItem(rSet, FN_FORMAT_DROPCAPS)) || aFormat != *pOldItem)
811 0 : rSet.Put(aFormat);
812 :
813 : // hard text formatting
814 : // Bug 24974: in designer/template catalog this doesn't make sense!!
815 0 : if (!bFormat && m_pDropCapsBox->IsChecked())
816 : {
817 0 : OUString sText(m_pTextEdit->GetText());
818 :
819 0 : if (!m_pWholeWordCB->IsChecked())
820 : {
821 0 : sText = sText.copy(0, std::min<sal_Int32>(sText.getLength(), m_pDropCapsField->GetValue()));
822 : }
823 :
824 0 : SfxStringItem aStr(FN_PARAM_1, sText);
825 0 : rSet.Put(aStr);
826 0 : }
827 : }
828 0 : }
829 :
830 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|