xref: /trunk/main/sw/source/ui/chrdlg/drpcps.cxx (revision efeef26f)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 #ifdef SW_DLLIMPLEMENTATION
27 #undef SW_DLLIMPLEMENTATION
28 #endif
29 
30 
31 
32 #include <hintids.hxx>
33 #define _SVSTDARR_STRINGSDTOR
34 #define _SVSTDARR_STRINGSISORTDTOR
35 #include <svl/svstdarr.hxx>
36 
37 #include "cmdid.h"
38 #include "swmodule.hxx"
39 #include "view.hxx"
40 #include "wrtsh.hxx"
41 #include "globals.hrc"
42 
43 
44 #ifndef _METRIC_HXX //autogen
45 #include <vcl/metric.hxx>
46 #endif
47 #include <svl/stritem.hxx>
48 #include <editeng/fontitem.hxx>
49 #include <svx/htmlmode.hxx>
50 #include <sfx2/objsh.hxx>
51 #include <editeng/svxfont.hxx>
52 #include <vcl/print.hxx>
53 #include <sfx2/printer.hxx>
54 #ifndef _COM_SUN_STAR_I18N_SCRIPTTYPE_HDL_
55 #include <com/sun/star/i18n/ScriptType.hdl>
56 #endif
57 #include <editeng/scripttypeitem.hxx>
58 #include <com/sun/star/i18n/XBreakIterator.hpp>
59 #include <comphelper/processfactory.hxx>
60 
61 #define _SVSTDARR_XUB_STRLEN
62 #define _SVSTDARR_USHORTS
63 #define _SVSTDARR_ULONGS
64 #include <svl/svstdarr.hxx>
65 
66 #include "charatr.hxx"
67 #include "viewopt.hxx"
68 #include "drpcps.hxx"
69 #include "paratr.hxx"
70 #include "uitool.hxx"
71 #include "charfmt.hxx"
72 
73 #include "chrdlg.hrc"
74 #include "drpcps.hrc"
75 
76 
77 using namespace ::com::sun::star;
78 using namespace ::com::sun::star::uno;
79 using namespace ::com::sun::star::lang;
80 //using namespace i18n; !using this namespace leads to mysterious conflicts with ScriptType::...!
81 //												so don't use this instead of the following defines!
82 
83 #define I18N                ::com::sun::star::i18n
84 #define I18N_SCRIPTTYPE     ::com::sun::star::i18n::ScriptType
85 
86 // Globals ******************************************************************
87 
88 static sal_uInt16 __FAR_DATA aPageRg[] = {
89 	RES_PARATR_DROP, RES_PARATR_DROP,
90 	0
91 };
92 
93 
94 
95 // class SwDropCapsPict *****************************************************
96 
97 class SwDropCapsPict : public Control
98 {
99 	String			maText;
100 	String			maScriptText;
101 	Color			maBackColor;
102 	Color			maTextLineColor;
103 	sal_uInt8			mnLines;
104 	long			mnTotLineH;
105 	long			mnLineH;
106 	long			mnTextH;
107 	sal_uInt16			mnDistance;
108     sal_Int32       mnLeading;
109 	Printer*		mpPrinter;
110 	sal_Bool			mbDelPrinter;
111 	SvULongs		maTextWidth;
112 	SvXub_StrLens	maScriptChg;
113 	SvUShorts		maScriptType;
114 	SvxFont			maFont;
115 	SvxFont			maCJKFont;
116 	SvxFont			maCTLFont;
117 	Size			maTextSize;
118 	Reference< I18N::XBreakIterator >	xBreak;
119 
120 	virtual void	Paint(const Rectangle &rRect);
121 	void			CheckScript( void );
122 	Size			CalcTextSize( void );
123 	inline void		InitPrinter( void );
124 	void			_InitPrinter( void );
125 	void			GetFontSettings( const SwDropCapsPage& _rPage, Font& _rFont, sal_uInt16 _nWhich );
126 public:
127 
SwDropCapsPict(Window * pParent,const ResId & rResId)128 	 SwDropCapsPict(Window *pParent, const ResId &rResId) :
129 			Control(pParent, rResId), mpPrinter( NULL ), mbDelPrinter( sal_False ) {}
130 	~SwDropCapsPict();
131 
132 	void UpdatePaintSettings( void );		// also invalidates control!
133 
134 	inline void SetText( const String& rT );
135 	inline void SetLines( sal_uInt8 nL );
136 	inline void SetDistance( sal_uInt16 nD );
137 	inline void SetValues( const String& rText, sal_uInt8 nLines, sal_uInt16 nDistance );
138 
139     void        DrawPrev( const Point& rPt );
140 };
141 
SetText(const String & rT)142 inline void SwDropCapsPict::SetText( const String& rT )
143 {
144 	maText = rT;
145 	UpdatePaintSettings();
146 }
147 
SetLines(sal_uInt8 nL)148 inline void SwDropCapsPict::SetLines( sal_uInt8 nL )
149 {
150 	mnLines = nL;
151 	UpdatePaintSettings();
152 }
153 
SetDistance(sal_uInt16 nD)154 inline void SwDropCapsPict::SetDistance( sal_uInt16 nD )
155 {
156 	mnDistance = nD;
157 	UpdatePaintSettings();
158 }
159 
SetValues(const String & rText,sal_uInt8 nLines,sal_uInt16 nDistance)160 inline void SwDropCapsPict::SetValues( const String& rText, sal_uInt8 nLines, sal_uInt16 nDistance )
161 {
162 	maText = rText;
163 	mnLines = nLines;
164 	mnDistance = nDistance;
165 
166 	UpdatePaintSettings();
167 }
168 
InitPrinter(void)169 inline void SwDropCapsPict::InitPrinter( void )
170 {
171 	if( !mpPrinter )
172 		_InitPrinter();
173 }
174 
175 /****************************************************************************
176 Default-String aus Zeichenanzahl erzeugen (A, AB, ABC, ...)
177 ****************************************************************************/
178 
179 
GetDefaultString(sal_uInt16 nChars)180 String GetDefaultString(sal_uInt16 nChars)
181 {
182 	String aStr;
183 	for (sal_uInt16 i = 0; i < nChars; i++)
184 		aStr += String((char) (i + 65));
185 	return aStr;
186 }
187 
calcFontHeightAnyAscent(OutputDevice * _pWin,Font & _rFont,long & _nHeight,long & _nAscent)188 static void calcFontHeightAnyAscent( OutputDevice* _pWin, Font& _rFont, long& _nHeight, long& _nAscent )
189 {
190     if ( !_nHeight )
191     {
192         _pWin->SetFont( _rFont );
193         FontMetric aMetric( _pWin->GetFontMetric() );
194         _nHeight = aMetric.GetLineHeight();
195         _nAscent = aMetric.GetAscent();
196     }
197 }
198 
199 /****************************************************************************
200 Pict: Dtor
201 ****************************************************************************/
202 
203 
~SwDropCapsPict()204  SwDropCapsPict::~SwDropCapsPict()
205 {
206 	 if( mbDelPrinter )
207 		 delete mpPrinter;
208 }
209 
210 /****************************************************************************
211 Pict: Update Font
212 ****************************************************************************/
213 
214 #define LINES  10
215 #define BORDER  2
216 
GetFontSettings(const SwDropCapsPage & _rPage,Font & _rFont,sal_uInt16 _nWhich)217 void SwDropCapsPict::GetFontSettings( const SwDropCapsPage& _rPage, Font& _rFont, sal_uInt16 _nWhich )
218 {
219 	SfxItemSet aSet( _rPage.rSh.GetAttrPool(), _nWhich, _nWhich);
220     _rPage.rSh.GetCurAttr(aSet);
221 	SvxFontItem aFmtFont((SvxFontItem &) aSet.Get(_nWhich));
222 
223 	_rFont.SetFamily (aFmtFont.GetFamily());
224 	_rFont.SetName   (aFmtFont.GetFamilyName());
225 	_rFont.SetPitch  (aFmtFont.GetPitch());
226 	_rFont.SetCharSet(aFmtFont.GetCharSet());
227 }
228 
UpdatePaintSettings(void)229 void SwDropCapsPict::UpdatePaintSettings( void )
230 {
231 	maBackColor = GetSettings().GetStyleSettings().GetWindowColor();
232 	maTextLineColor = Color( COL_LIGHTGRAY );
233 
234 	// gray lines
235 	mnTotLineH = (GetOutputSizePixel().Height() - 2 * BORDER) / LINES;
236 	mnLineH = mnTotLineH - 2;
237     mnLeading = GetFontMetric().GetIntLeading();
238 
239 	Font aFont;
240 	{
241 		SwDropCapsPage* pPage = ( SwDropCapsPage* ) GetParent();
242 		if (!pPage->aTemplateBox.GetSelectEntryPos())
243 		{
244 			// Font an Absatzanfang erfragen
245 			pPage->rSh.SttCrsrMove();
246 			pPage->rSh.Push();
247 			pPage->rSh.ClearMark();
248             SwWhichPara pSwuifnParaCurr = GetfnParaCurr();
249             SwPosPara pSwuifnParaStart = GetfnParaStart();
250 			pPage->rSh.MovePara(pSwuifnParaCurr,pSwuifnParaStart);
251 			// normal
252 			GetFontSettings( *pPage, aFont, RES_CHRATR_FONT );
253 
254 			// CJK
255 			GetFontSettings( *pPage, maCJKFont, RES_CHRATR_CJK_FONT );
256 
257 			// CTL
258 			GetFontSettings( *pPage, maCTLFont, RES_CHRATR_CTL_FONT );
259 
260 			pPage->rSh.Pop(sal_False);
261 			pPage->rSh.EndCrsrMove();
262 		}
263 		else
264 		{
265 			// Font an Zeichenvorlage erfragen
266 			SwCharFmt *pFmt = pPage->rSh.GetCharStyle(
267 									pPage->aTemplateBox.GetSelectEntry(),
268 									SwWrtShell::GETSTYLE_CREATEANY );
269 			ASSERT(pFmt, "Zeichenvorlage existiert nicht!");
270 			const SvxFontItem &rFmtFont = pFmt->GetFont();
271 
272 			aFont.SetFamily (rFmtFont.GetFamily());
273 			aFont.SetName   (rFmtFont.GetFamilyName());
274 			aFont.SetPitch  (rFmtFont.GetPitch());
275 			aFont.SetCharSet(rFmtFont.GetCharSet());
276         }
277 	}
278 
279 	mnTextH = mnLines * mnTotLineH;
280 	aFont.SetSize(Size(0, mnTextH));
281 	maCJKFont.SetSize(Size(0, mnTextH));
282 	maCTLFont.SetSize(Size(0, mnTextH));
283 
284 	aFont.SetTransparent(sal_True);
285 	maCJKFont.SetTransparent(sal_True);
286 	maCTLFont.SetTransparent(sal_True);
287 
288     aFont.SetColor( SwViewOption::GetFontColor() );
289     maCJKFont.SetColor( SwViewOption::GetFontColor() );
290     maCTLFont.SetColor( SwViewOption::GetFontColor() );
291 
292 	aFont.SetFillColor(GetSettings().GetStyleSettings().GetWindowColor());
293 	maCJKFont.SetFillColor(GetSettings().GetStyleSettings().GetWindowColor());
294 	maCTLFont.SetFillColor(GetSettings().GetStyleSettings().GetWindowColor());
295 
296 	maCJKFont.SetSize(Size(0, maCJKFont.GetSize().Height() + mnLeading));
297 	maCTLFont.SetSize(Size(0, maCTLFont.GetSize().Height() + mnLeading));
298 
299 	SetFont(aFont);
300 	aFont.SetSize(Size(0, aFont.GetSize().Height() + mnLeading));
301 	SetFont(aFont);
302 	maFont = aFont;
303 
304 	CheckScript();
305 
306 	maTextSize = CalcTextSize();
307 
308 	Invalidate();
309 }
310 
311 /****************************************************************************
312 Pict: Paint-Overload
313 ****************************************************************************/
314 
Paint(const Rectangle &)315 void  SwDropCapsPict::Paint(const Rectangle &/*rRect*/)
316 {
317 	if (!IsVisible())
318 		return;
319 
320 	SetMapMode(MapMode(MAP_PIXEL));
321 	SetLineColor();
322 
323 	SetFillColor( maBackColor );
324 
325 	Size aOutputSizePixel( GetOutputSizePixel() );
326 
327 	DrawRect(Rectangle(Point(0, 0), aOutputSizePixel ));
328 	SetClipRegion(Region(Rectangle(
329 		Point(BORDER, BORDER),
330 		Size (aOutputSizePixel.Width () - 2 * BORDER,
331 			  aOutputSizePixel.Height() - 2 * BORDER))));
332 
333 	ASSERT(mnLineH > 0, "So klein lassen wir uns nicht machen");
334 	long nY0 = (aOutputSizePixel.Height() - (LINES * mnTotLineH)) / 2;
335 	SetFillColor( maTextLineColor );
336 	for (sal_uInt16 i = 0; i < LINES; ++i)
337 		DrawRect(Rectangle(Point(BORDER, nY0 + i * mnTotLineH), Size(aOutputSizePixel.Width() - 2 * BORDER, mnLineH)));
338 
339 	// Texthintergrund mit Abstand (240 twips ~ 1 Zeilenhoehe)
340 	sal_uLong lDistance = mnDistance;
341 	sal_uInt16 nDistW = (sal_uInt16) (sal_uLong) (((lDistance * 100) / 240) * mnTotLineH) / 100;
342 	SetFillColor( maBackColor );
343 	if(((SwDropCapsPage*)GetParent())->aDropCapsBox.IsChecked())
344 	{
345 		Size	aTextSize( maTextSize );
346 		aTextSize.Width() += nDistW;
347 		DrawRect( Rectangle( Point( BORDER, nY0 ), aTextSize ) );
348 
349 		// Text zeichnen
350 		DrawPrev( Point( BORDER, nY0 - mnLeading ) );
351 	}
352 
353 	SetClipRegion();
354 }
355 
DrawPrev(const Point & rPt)356 void SwDropCapsPict::DrawPrev( const Point& rPt )
357 {
358     Point aPt(rPt);
359     InitPrinter();
360 
361     Font		aOldFont = mpPrinter->GetFont();
362     sal_uInt16		nScript;
363     size_t		nIdx = 0;
364     xub_StrLen	nStart = 0;
365     xub_StrLen	nEnd;
366     size_t		nCnt = maScriptChg.size();
367 
368     if( nCnt )
369     {
370         nEnd = maScriptChg[ nIdx ];
371         nScript = maScriptType[ nIdx ];
372     }
373     else
374     {
375         nEnd = maText.Len();
376         nScript = I18N_SCRIPTTYPE::LATIN;
377     }
378     do
379     {
380         SvxFont&	rFnt = (nScript==I18N_SCRIPTTYPE::ASIAN) ? maCJKFont : ((nScript==I18N_SCRIPTTYPE::COMPLEX) ? maCTLFont : maFont);
381         mpPrinter->SetFont( rFnt );
382 
383         rFnt.DrawPrev( this, mpPrinter, aPt, maText, nStart, nEnd - nStart );
384 
385         aPt.X() += maTextWidth[ nIdx++ ];
386         if( nEnd < maText.Len() && nIdx < nCnt )
387         {
388             nStart = nEnd;
389             nEnd = maScriptChg[ nIdx ];
390             nScript = maScriptType[ nIdx ];
391         }
392         else
393             break;
394     }
395     while( sal_True );
396 	mpPrinter->SetFont( aOldFont );
397 }
398 
CheckScript(void)399 void SwDropCapsPict::CheckScript( void )
400 {
401 	if( maScriptText == maText )
402 		return;
403 
404     maScriptText = maText;
405     size_t nCnt = maScriptChg.size();
406     if( nCnt )
407     {
408         maScriptChg.clear();
409         maScriptType.Remove( 0, nCnt );
410         maTextWidth.Remove( 0, nCnt );
411         nCnt = 0;
412     }
413     if( !xBreak.is() )
414     {
415         Reference< XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory();
416         xBreak = Reference< I18N::XBreakIterator >(xMSF->createInstance(
417 				::rtl::OUString::createFromAscii( "com.sun.star.i18n.BreakIterator" ) ),UNO_QUERY);
418     }
419     if( xBreak.is() )
420     {
421         sal_uInt16 nScript = xBreak->getScriptType( maText, 0 );
422         sal_uInt16 nChg = 0;
423         if( I18N_SCRIPTTYPE::WEAK == nScript )
424         {
425             nChg = (xub_StrLen)xBreak->endOfScript( maText, nChg, nScript );
426             if( nChg < maText.Len() )
427                 nScript = xBreak->getScriptType( maText, nChg );
428             else
429                 nScript = I18N_SCRIPTTYPE::LATIN;
430         }
431 
432         do
433         {
434             nChg = (xub_StrLen)xBreak->endOfScript( maText, nChg, nScript );
435             maScriptChg.push_back( nChg );
436             maScriptType.Insert( nScript, nCnt );
437             maTextWidth.Insert( sal_uLong(0), nCnt++ );
438 
439             if( nChg < maText.Len() )
440                 nScript = xBreak->getScriptType( maText, nChg );
441             else
442                 break;
443         } while( sal_True );
444     }
445 }
446 
CalcTextSize(void)447 Size SwDropCapsPict::CalcTextSize( void )
448 {
449 	InitPrinter();
450 
451     sal_uInt16		nScript;
452     size_t		nIdx = 0;
453     xub_StrLen	nStart = 0;
454     xub_StrLen	nEnd;
455     size_t		nCnt = maScriptChg.size();
456     if( nCnt )
457     {
458         nEnd = maScriptChg[ nIdx ];
459         nScript = maScriptType[ nIdx ];
460     }
461     else
462     {
463         nEnd = maText.Len();
464         nScript = I18N_SCRIPTTYPE::LATIN;
465     }
466     long		nTxtWidth = 0;
467     long		nCJKHeight = 0;
468 	long		nCTLHeight = 0;
469     long		nHeight = 0;
470     long		nAscent = 0;
471     long		nCJKAscent = 0;
472 	long		nCTLAscent = 0;
473     do
474     {
475         SvxFont&	rFnt = ( nScript == I18N_SCRIPTTYPE::ASIAN )? maCJKFont :
476 								( ( nScript == I18N_SCRIPTTYPE::COMPLEX )? maCTLFont : maFont );
477         sal_uLong		nWidth = rFnt.GetTxtSize( mpPrinter, maText, nStart, nEnd-nStart ).Width();
478 
479 		if( nIdx < maTextWidth.Count() )
480 			maTextWidth[ nIdx++ ] = nWidth;
481         nTxtWidth += nWidth;
482 		switch(nScript)
483 		{
484 			case I18N_SCRIPTTYPE::ASIAN:
485 				calcFontHeightAnyAscent( this, maCJKFont, nCJKHeight, nCJKAscent );
486 				break;
487 			case I18N_SCRIPTTYPE::COMPLEX:
488 				calcFontHeightAnyAscent( this, maCTLFont, nCTLHeight, nCTLAscent );
489 				break;
490 			default:
491 				calcFontHeightAnyAscent( this, maFont, nHeight, nAscent );
492 		}
493 
494         if( nEnd < maText.Len() && nIdx < nCnt )
495         {
496             nStart = nEnd;
497             nEnd = maScriptChg[ nIdx ];
498             nScript = maScriptType[ nIdx ];
499         }
500         else
501             break;
502     }
503     while( sal_True );
504     nHeight -= nAscent;
505     nCJKHeight -= nCJKAscent;
506 	nCTLHeight -= nCTLAscent;
507     if( nHeight < nCJKHeight )
508         nHeight = nCJKHeight;
509     if( nAscent < nCJKAscent )
510         nAscent = nCJKAscent;
511 	if( nHeight < nCTLHeight )
512         nHeight = nCTLHeight;
513     if( nAscent < nCTLAscent )
514         nAscent = nCTLAscent;
515     nHeight += nAscent;
516 
517     Size aTxtSize( nTxtWidth, nHeight );
518     return aTxtSize;
519 }
520 
_InitPrinter()521 void SwDropCapsPict::_InitPrinter()
522 {
523 	SfxViewShell*	pSh = SfxViewShell::Current();
524 
525 	if ( pSh )
526 		mpPrinter = pSh->GetPrinter();
527 
528 	if ( !mpPrinter )
529 	{
530 		mpPrinter = new Printer;
531 		mbDelPrinter = sal_True;
532 	}
533 }
534 
535 /****************************************************************************
536 Dlg: Ctor
537 ****************************************************************************/
538 
539 
SwDropCapsDlg(Window * pParent,const SfxItemSet & rSet)540 SwDropCapsDlg::SwDropCapsDlg(Window *pParent, const SfxItemSet &rSet ) :
541 
542 	SfxSingleTabDialog(pParent, rSet, 0)
543 
544 {
545     SwDropCapsPage* pNewPage = (SwDropCapsPage*) SwDropCapsPage::Create(this, rSet);
546     pNewPage->SetFormat(sal_False);
547     SetTabPage(pNewPage);
548 }
549 
550 /****************************************************************************
551 Dlg: Dtor
552 ****************************************************************************/
553 
554 
~SwDropCapsDlg()555  SwDropCapsDlg::~SwDropCapsDlg()
556 {
557 }
558 
559 /****************************************************************************
560 Page: Ctor
561 ****************************************************************************/
562 
563 
SwDropCapsPage(Window * pParent,const SfxItemSet & rSet)564 SwDropCapsPage::SwDropCapsPage(Window *pParent, const SfxItemSet &rSet) :
565 
566 	SfxTabPage(pParent, SW_RES(TP_DROPCAPS), rSet),
567 
568     aSettingsFL   (this, SW_RES(FL_SETTINGS)),
569 	aDropCapsBox  (this, SW_RES(CB_SWITCH   )),
570 	aWholeWordCB  (this, SW_RES(CB_WORD		)),
571 	aSwitchText   (this, SW_RES(FT_DROPCAPS )),
572 	aDropCapsField(this, SW_RES(FLD_DROPCAPS)),
573 	aLinesText    (this, SW_RES(TXT_LINES   )),
574 	aLinesField   (this, SW_RES(FLD_LINES   )),
575 	aDistanceText (this, SW_RES(TXT_DISTANCE)),
576 	aDistanceField(this, SW_RES(FLD_DISTANCE)),
577 
578     aContentFL    (this, SW_RES(FL_CONTENT )),
579     aTextText     (this, SW_RES(TXT_TEXT    )),
580 	aTextEdit     (this, SW_RES(EDT_TEXT    )),
581 	aTemplateText (this, SW_RES(TXT_TEMPLATE)),
582 	aTemplateBox  (this, SW_RES(BOX_TEMPLATE)),
583 
584     pPict         (new SwDropCapsPict(this, SW_RES(CNT_PICT))),
585 
586     bModified(sal_False),
587 	bFormat(sal_True),
588 	rSh(::GetActiveView()->GetWrtShell())
589 {
590 	FreeResource();
591 	SetExchangeSupport();
592 
593 	sal_uInt16 nHtmlMode = ::GetHtmlMode((const SwDocShell*)SfxObjectShell::Current());
594 	bHtmlMode = nHtmlMode & HTMLMODE_ON ? sal_True : sal_False;
595 
596 	//Im Vorlagendialog kann der Text nicht beeinflusst werden
597 	aTextText.Enable( !bFormat );
598 	aTextEdit.Enable( !bFormat );
599 
600 	// Metriken
601 	SetMetric( aDistanceField, GetDfltMetric(bHtmlMode) );
602 
603     pPict->SetBorderStyle( WINDOW_BORDER_MONO );
604 
605 	// Handler installieren
606 	Link aLk = LINK(this, SwDropCapsPage, ModifyHdl);
607 	aDropCapsField.SetModifyHdl( aLk );
608 	aLinesField   .SetModifyHdl( aLk );
609 	aDistanceField.SetModifyHdl( aLk );
610 	aTextEdit     .SetModifyHdl( aLk );
611 	aDropCapsBox  .SetClickHdl (LINK(this, SwDropCapsPage, ClickHdl ));
612 	aTemplateBox  .SetSelectHdl(LINK(this, SwDropCapsPage, SelectHdl));
613 	aWholeWordCB  .SetClickHdl (LINK(this, SwDropCapsPage, WholeWordHdl ));
614 }
615 
616 /****************************************************************************
617 Page: Dtor
618 ****************************************************************************/
619 
620 
~SwDropCapsPage()621  SwDropCapsPage::~SwDropCapsPage()
622 {
623 	delete pPict;
624 }
625 
626 
DeactivatePage(SfxItemSet * _pSet)627 int  SwDropCapsPage::DeactivatePage(SfxItemSet * _pSet)
628 {
629     if ( _pSet )
630         FillSet( *_pSet );
631 
632 	return LEAVE_PAGE;
633 }
634 
635 /****************************************************************************
636 Page: Factory
637 ****************************************************************************/
638 
639 
Create(Window * pParent,const SfxItemSet & rSet)640 SfxTabPage*  SwDropCapsPage::Create(Window *pParent,
641 	const SfxItemSet &rSet)
642 {
643 	return new SwDropCapsPage(pParent, rSet);
644 }
645 
646 /****************************************************************************
647 Page: FillItemSet-Overload
648 ****************************************************************************/
649 
650 
FillItemSet(SfxItemSet & rSet)651 sal_Bool  SwDropCapsPage::FillItemSet(SfxItemSet &rSet)
652 {
653 	if(bModified)
654 		FillSet(rSet);
655 	return bModified;
656 }
657 
658 /****************************************************************************
659 Page: Reset-Overload
660 ****************************************************************************/
661 
662 
Reset(const SfxItemSet & rSet)663 void  SwDropCapsPage::Reset(const SfxItemSet &rSet)
664 {
665 	// Zeichen, Zeilen, Abstand und Text
666 	SwFmtDrop aFmtDrop((SwFmtDrop &) rSet.Get(RES_PARATR_DROP));
667 	if (aFmtDrop.GetLines() > 1)
668 	{
669 		aDropCapsField.SetValue(aFmtDrop.GetChars());
670 		aLinesField   .SetValue(aFmtDrop.GetLines());
671 		aDistanceField.SetValue(aDistanceField.Normalize(aFmtDrop.GetDistance()), FUNIT_TWIP);
672 		aWholeWordCB  .Check   (aFmtDrop.GetWholeWord());
673 	}
674 	else
675 	{
676 		aDropCapsField.SetValue(1);
677 		aLinesField   .SetValue(3);
678 		aDistanceField.SetValue(0);
679 	}
680 
681 	::FillCharStyleListBox(aTemplateBox, rSh.GetView().GetDocShell(), sal_True);
682 
683 	aTemplateBox.InsertEntry(SW_RESSTR(SW_STR_NONE), 0);
684 	// Vorlage defaulten
685 	aTemplateBox.SelectEntryPos(0);
686 	if (aFmtDrop.GetCharFmt())
687 		aTemplateBox.SelectEntry(aFmtDrop.GetCharFmt()->GetName());
688 
689 	// Controls enablen
690 	aDropCapsBox.Check(aFmtDrop.GetLines() > 1);
691 	const sal_uInt16 nVal = sal_uInt16(aDropCapsField.GetValue());
692 	if (bFormat)
693 		aTextEdit.SetText(GetDefaultString(nVal));
694 	else
695 	{
696 		aTextEdit.SetText(rSh.GetDropTxt(nVal));
697 		aTextEdit.Enable();
698 		aTextText.Enable();
699 	}
700 
701 	// Preview
702 	pPict->SetValues(	aTextEdit.GetText(),
703 						sal_uInt8( aLinesField.GetValue() ),
704 						sal_uInt16( aDistanceField.Denormalize( aDistanceField.GetValue( FUNIT_TWIP ) ) ) );
705 
706 	ClickHdl(&aDropCapsBox);
707 	bModified = sal_False;
708 }
709 
710 /****************************************************************************
711 Page: Click-Handler der CheckBox
712 ****************************************************************************/
713 
714 
IMPL_LINK(SwDropCapsPage,ClickHdl,Button *,EMPTYARG)715 IMPL_LINK( SwDropCapsPage, ClickHdl, Button *, EMPTYARG )
716 {
717 	sal_Bool bChecked = aDropCapsBox.IsChecked();
718 
719 	aWholeWordCB  .Enable( bChecked && !bHtmlMode );
720 
721 	aSwitchText.Enable( bChecked && !aWholeWordCB.IsChecked() );
722 	aDropCapsField.Enable( bChecked && !aWholeWordCB.IsChecked() );
723 	aLinesText   .Enable( bChecked );
724 	aLinesField   .Enable( bChecked );
725 	aDistanceText.Enable( bChecked );
726 	aDistanceField.Enable( bChecked );
727 	aTemplateText .Enable( bChecked );
728 	aTemplateBox  .Enable( bChecked );
729 	aTextEdit	  .Enable( bChecked && !bFormat );
730 	aTextText	  .Enable( bChecked && !bFormat );
731 
732 	if ( bChecked )
733 	{
734 		ModifyHdl(&aDropCapsField);
735 		aDropCapsField.GrabFocus();
736 	}
737 	else
738 		pPict->SetText(aEmptyStr);
739 
740 	bModified = sal_True;
741 
742 	return 0;
743 }
744 
745 /****************************************************************************
746 Page: Click-Handler der CheckBox
747 ****************************************************************************/
748 
749 
IMPL_LINK(SwDropCapsPage,WholeWordHdl,CheckBox *,EMPTYARG)750 IMPL_LINK( SwDropCapsPage, WholeWordHdl, CheckBox *, EMPTYARG )
751 {
752 	aDropCapsField.Enable( !aWholeWordCB.IsChecked() );
753 
754 	ModifyHdl(&aDropCapsField);
755 
756 	bModified = sal_True;
757 
758 	return 0;
759 }
760 
761 /****************************************************************************
762 Page: Modify-Handler der SpinFields
763 ****************************************************************************/
764 
765 
IMPL_LINK(SwDropCapsPage,ModifyHdl,Edit *,pEdit)766 IMPL_LINK( SwDropCapsPage, ModifyHdl, Edit *, pEdit )
767 {
768 	String sPreview;
769 
770 	// Ggf. Text setzen
771 	if (pEdit == &aDropCapsField)
772 	{
773 		sal_uInt16 nVal;
774 		sal_Bool bSetText = sal_False;
775 
776 		if (!aWholeWordCB.IsChecked())
777 			nVal = (sal_uInt16)aDropCapsField.GetValue();
778 		else
779             nVal = 0;
780 
781 		if (bFormat || !rSh.GetDropTxt(1).Len())
782 			sPreview = GetDefaultString(nVal);
783 		else
784 		{
785 			bSetText = sal_True;
786 			sPreview = rSh.GetDropTxt(nVal);
787 		}
788 
789 		String sEdit(aTextEdit.GetText());
790 
791 		if (sEdit.Len() && sPreview.CompareTo(sEdit, sEdit.Len()) != COMPARE_EQUAL)
792 		{
793 			sPreview = sEdit.Copy(0, sPreview.Len());
794 			bSetText = sal_False;
795 		}
796 
797 		if (bSetText)
798 			aTextEdit.SetText(sPreview);
799 	}
800 	else if (pEdit == &aTextEdit)	// Ggf. Anzahl setzen
801 	{
802 		sal_uInt16 nTmp = aTextEdit.GetText().Len();
803 		aDropCapsField.SetValue(Max((sal_uInt16)1, nTmp));
804 
805 		sPreview = aTextEdit.GetText().Copy(0, nTmp);
806 	}
807 
808 	// Bild anpassen
809 	if (pEdit == &aDropCapsField || pEdit == &aTextEdit)
810 		pPict->SetText (sPreview);
811 	else if (pEdit == &aLinesField)
812 		pPict->SetLines((sal_uInt8)aLinesField.GetValue());
813 	else
814 		pPict->SetDistance((sal_uInt16)aDistanceField.Denormalize(aDistanceField.GetValue(FUNIT_TWIP)));
815 
816 	bModified = sal_True;
817 
818 	return 0;
819 }
820 
821 /****************************************************************************
822 Page: Select-Handler der Template-Box.
823 *****************************************************************************/
824 
825 
IMPL_LINK_INLINE_START(SwDropCapsPage,SelectHdl,ListBox *,EMPTYARG)826 IMPL_LINK_INLINE_START( SwDropCapsPage, SelectHdl, ListBox *, EMPTYARG )
827 {
828 	pPict->UpdatePaintSettings();
829 	bModified = sal_True;
830 	return 0;
831 }
IMPL_LINK_INLINE_END(SwDropCapsPage,SelectHdl,ListBox *,EMPTYARG)832 IMPL_LINK_INLINE_END( SwDropCapsPage, SelectHdl, ListBox *, EMPTYARG )
833 
834 
835 sal_uInt16*  SwDropCapsPage::GetRanges()
836 {
837 	return aPageRg;
838 }
839 
840 
FillSet(SfxItemSet & rSet)841 void SwDropCapsPage::FillSet( SfxItemSet &rSet )
842 {
843 	if(bModified)
844 	{
845 		SwFmtDrop aFmt;
846 
847 		sal_Bool bOn = aDropCapsBox.IsChecked();
848 		if(bOn)
849 		{
850 			// Anzahl, Zeilen, Abstand
851 			aFmt.GetChars()     = (sal_uInt8) aDropCapsField.GetValue();
852 			aFmt.GetLines()     = (sal_uInt8) aLinesField.GetValue();
853 			aFmt.GetDistance()  = (sal_uInt16) aDistanceField.Denormalize(aDistanceField.GetValue(FUNIT_TWIP));
854 			aFmt.GetWholeWord() = aWholeWordCB.IsChecked();
855 
856 			// Vorlage
857 			if (aTemplateBox.GetSelectEntryPos())
858 				aFmt.SetCharFmt(rSh.GetCharStyle(aTemplateBox.GetSelectEntry()));
859 		}
860 		else
861 		{
862 			aFmt.GetChars()    = 1;
863 			aFmt.GetLines()    = 1;
864 			aFmt.GetDistance() = 0;
865 		}
866 
867 		// Attribute setzen
868 		const SfxPoolItem* pOldItem;
869 		if(0 == (pOldItem = GetOldItem( rSet, FN_FORMAT_DROPCAPS )) ||
870 					aFmt != *pOldItem )
871 			rSet.Put(aFmt);
872 
873 		// Harte Textformatierung
874 		// Bug 24974: In Gestalter/Vorlagenkatoplog macht das keinen Sinn!!
875 		if( !bFormat && aDropCapsBox.IsChecked() )
876 		{
877             String sText(aTextEdit.GetText());
878 
879 			if (!aWholeWordCB.IsChecked())
880                 sText.Erase( static_cast< xub_StrLen >(aDropCapsField.GetValue()));
881 
882 			SfxStringItem aStr(FN_PARAM_1, sText);
883 			rSet.Put( aStr );
884 		}
885 	}
886 }
887 
888 
889 
890 
891