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