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