xref: /trunk/main/sw/source/ui/table/tautofmt.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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 
31 #ifdef SW_DLLIMPLEMENTATION
32 #undef SW_DLLIMPLEMENTATION
33 #endif
34 
35 
36 
37 
38 #ifndef _EDIT_HXX //autogen
39 #include <vcl/edit.hxx>
40 #endif
41 #ifndef _MSGBOX_HXX //autogen
42 #include <vcl/msgbox.hxx>
43 #endif
44 #include <vcl/svapp.hxx>
45 #include <svl/zforlist.hxx>
46 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
47 #include <com/sun/star/i18n/XBreakIterator.hpp>
48 #include <comphelper/processfactory.hxx>
49 #include <svtools/scriptedtext.hxx>
50 #include <svtools/accessibilityoptions.hxx>
51 #include <svx/framelinkarray.hxx>
52 #include "swmodule.hxx"
53 #include "swtypes.hxx"
54 #ifndef _VIEW_HXX
55 #include "view.hxx"
56 #endif
57 #include "wrtsh.hxx"
58 #include "tblafmt.hxx"
59 #ifndef _TAUTOFMT_HXX
60 #include "tautofmt.hxx"
61 #endif
62 #include "shellres.hxx"
63 #ifndef _TAUTOFMT_HRC
64 #include "tautofmt.hrc"
65 #endif
66 
67 using namespace com::sun::star;
68 
69 #define FRAME_OFFSET 4
70 
71 //========================================================================
72 
73 class AutoFmtPreview : public Window
74 {
75 public:
76             AutoFmtPreview( Window* pParent, const ResId& rRes, SwWrtShell* pWrtShell );
77             ~AutoFmtPreview();
78 
79     void NotifyChange( const SwTableAutoFmt& rNewData );
80 
81 protected:
82     virtual void Paint( const Rectangle& rRect );
83 
84 private:
85     SwTableAutoFmt          aCurData;
86     VirtualDevice           aVD;
87     SvtScriptedTextHelper   aScriptedText;
88     svx::frame::Array       maArray;            /// Implementation to draw the frame borders.
89     sal_Bool                    bFitWidth;
90     bool                    mbRTL;
91     Size                    aPrvSize;
92     long                    nLabelColWidth;
93     long                    nDataColWidth1;
94     long                    nDataColWidth2;
95     long                    nRowHeight;
96     const String            aStrJan;
97     const String            aStrFeb;
98     const String            aStrMar;
99     const String            aStrNorth;
100     const String            aStrMid;
101     const String            aStrSouth;
102     const String            aStrSum;
103     SvNumberFormatter*      pNumFmt;
104 
105     uno::Reference< lang::XMultiServiceFactory > m_xMSF;
106     uno::Reference< i18n::XBreakIterator >       m_xBreak;
107 
108     //-------------------------------------------
109     void    Init            ();
110     void    DoPaint         ( const Rectangle& rRect );
111     void    CalcCellArray   ( sal_Bool bFitWidth );
112     void    CalcLineMap     ();
113     void    PaintCells      ();
114 
115     sal_uInt8                GetFormatIndex( size_t nCol, size_t nRow ) const;
116     const SvxBoxItem&   GetBoxItem( size_t nCol, size_t nRow ) const;
117 
118     void                DrawString( size_t nCol, size_t nRow );
119     void                DrawStrings();
120     void                DrawBackground();
121 
122     void    MakeFonts       ( sal_uInt8 nIndex, Font& rFont, Font& rCJKFont, Font& rCTLFont );
123     String  MakeNumberString( String cellString, sal_Bool bAddDec );
124 };
125 
126 //========================================================================
127 
128 class SwStringInputDlg : public ModalDialog
129 {
130 public:
131             SwStringInputDlg(     Window* pParent,
132                             const String& rTitle,
133                             const String& rEditTitle,
134                             const String& rDefault );
135             ~SwStringInputDlg();
136 
137     void GetInputString( String& rString ) const;
138 
139 private:
140     Edit            aEdInput;   // Edit erhaelt so den Focus
141     FixedText       aFtEditTitle;
142     OKButton        aBtnOk;
143     CancelButton    aBtnCancel;
144 };
145 
146 
147 SwStringInputDlg::SwStringInputDlg( Window*         pParent,
148                                     const String&   rTitle,
149                                     const String&   rEditTitle,
150                                     const String&   rDefault    ) :
151     ModalDialog     ( pParent, SW_RES( DLG_SWDLG_STRINPUT ) ),
152     //
153     aEdInput        ( this, SW_RES( ED_INPUT ) ),
154     aFtEditTitle    ( this, SW_RES( FT_LABEL ) ),
155     aBtnOk          ( this, SW_RES( BTN_OK ) ),
156     aBtnCancel      ( this, SW_RES( BTN_CANCEL ) )
157 {
158     SetText( rTitle );
159     aFtEditTitle.SetText( rEditTitle );
160     aEdInput.SetText( rDefault );
161     //-------------
162     FreeResource();
163 }
164 
165 //------------------------------------------------------------------------
166 
167 void SwStringInputDlg::GetInputString( String& rString ) const
168 {
169     rString = aEdInput.GetText();
170 }
171 
172 
173 __EXPORT SwStringInputDlg::~SwStringInputDlg()
174 {
175 }
176 
177 //========================================================================
178 // AutoFormat-Dialog:
179 
180 
181 SwAutoFormatDlg::SwAutoFormatDlg( Window* pParent, SwWrtShell* pWrtShell,
182                     sal_Bool bSetAutoFormat, const SwTableAutoFmt* pSelFmt )
183     : SfxModalDialog( pParent, SW_RES( DLG_AUTOFMT_TABLE ) ),
184     //
185     aFlFormat       ( this, SW_RES( FL_FORMAT ) ),
186     aLbFormat       ( this, SW_RES( LB_FORMAT ) ),
187     aFlFormats       ( this, SW_RES( FL_FORMATS ) ),
188 
189     aBtnNumFormat   ( this, SW_RES( BTN_NUMFORMAT ) ),
190     aBtnBorder      ( this, SW_RES( BTN_BORDER ) ),
191     aBtnFont        ( this, SW_RES( BTN_FONT ) ),
192     aBtnPattern     ( this, SW_RES( BTN_PATTERN ) ),
193     aBtnAlignment   ( this, SW_RES( BTN_ALIGNMENT ) ),
194     aBtnOk          ( this, SW_RES( BTN_OK ) ),
195     aBtnCancel      ( this, SW_RES( BTN_CANCEL ) ),
196     aBtnHelp        ( this, SW_RES( BTN_HELP ) ),
197     aBtnAdd         ( this, SW_RES( BTN_ADD ) ),
198     aBtnRemove      ( this, SW_RES( BTN_REMOVE ) ),
199     aBtnRename      ( this, SW_RES( BTN_RENAME ) ),
200     aBtnMore        ( this, SW_RES( BTN_MORE ) ),
201     aStrTitle       ( SW_RES( STR_ADD_TITLE ) ),
202     aStrLabel       ( SW_RES( STR_ADD_LABEL ) ),
203     aStrClose       ( SW_RES( STR_BTN_CLOSE ) ),
204     aStrDelTitle    ( SW_RES( STR_DEL_TITLE ) ),
205     aStrDelMsg      ( SW_RES( STR_DEL_MSG ) ),
206     aStrRenameTitle ( SW_RES( STR_RENAME_TITLE ) ),
207     aStrInvalidFmt  ( SW_RES( STR_INVALID_AFNAME )),
208     pWndPreview     ( new AutoFmtPreview( this, SW_RES( WND_PREVIEW ), pWrtShell )),
209     //
210     pShell          ( pWrtShell ),
211     nIndex          ( 0 ),
212     nDfltStylePos   ( 0 ),
213     bCoreDataChanged( sal_False ),
214     bSetAutoFmt     ( bSetAutoFormat )
215 {
216     pTableTbl = new SwTableAutoFmtTbl;
217     pTableTbl->Load();
218 
219     Init( pSelFmt );
220     //------------- >
221     FreeResource();
222 }
223 
224 //------------------------------------------------------------------------
225 
226 
227 __EXPORT SwAutoFormatDlg::~SwAutoFormatDlg()
228 {
229     delete pWndPreview;
230 
231     if( bCoreDataChanged )
232         pTableTbl->Save();
233     delete pTableTbl;
234 }
235 
236 //------------------------------------------------------------------------
237 
238 
239 void SwAutoFormatDlg::Init( const SwTableAutoFmt* pSelFmt )
240 {
241     Link aLk( LINK( this, SwAutoFormatDlg, CheckHdl ) );
242     aBtnBorder.SetClickHdl( aLk );
243     aBtnFont.SetClickHdl( aLk );
244     aBtnPattern.SetClickHdl( aLk );
245     aBtnAlignment.SetClickHdl( aLk );
246     aBtnNumFormat.SetClickHdl( aLk );
247 
248     aBtnAdd.SetClickHdl ( LINK( this, SwAutoFormatDlg, AddHdl ) );
249     aBtnRemove.SetClickHdl ( LINK( this, SwAutoFormatDlg, RemoveHdl ) );
250     aBtnRename.SetClickHdl ( LINK( this, SwAutoFormatDlg, RenameHdl ) );
251     aBtnOk.SetClickHdl ( LINK( this, SwAutoFormatDlg, OkHdl ) );
252     aLbFormat.SetSelectHdl( LINK( this, SwAutoFormatDlg, SelFmtHdl ) );
253 
254     aBtnMore.AddWindow( &aBtnNumFormat );
255     aBtnMore.AddWindow( &aBtnBorder );
256     aBtnMore.AddWindow( &aBtnFont );
257     aBtnMore.AddWindow( &aBtnPattern );
258     aBtnMore.AddWindow( &aBtnAlignment );
259     aBtnMore.AddWindow( &aFlFormats );
260     aBtnMore.AddWindow( &aBtnRename );
261 
262     aBtnAdd.Enable( bSetAutoFmt );
263 
264     nIndex = 0;
265     if( !bSetAutoFmt )
266     {
267         // dann muss die Liste um den Eintrag <Keins> erweitert werden.
268         aLbFormat.InsertEntry( ViewShell::GetShellRes()->aStrNone );
269         nDfltStylePos = 1;
270         nIndex = 255;
271     }
272 
273     for( sal_uInt8 i = 0, nCount = (sal_uInt8)pTableTbl->Count(); i < nCount; i++ )
274     {
275         SwTableAutoFmt* pFmt = (*pTableTbl)[ i ];
276         aLbFormat.InsertEntry( pFmt->GetName() );
277         if( pSelFmt && pFmt->GetName() == pSelFmt->GetName() )
278             nIndex = i;
279     }
280 
281     aLbFormat.SelectEntryPos( 255 != nIndex ? (nDfltStylePos + nIndex) : 0 );
282     SelFmtHdl( 0 );
283 }
284 
285 //------------------------------------------------------------------------
286 
287 
288 void SwAutoFormatDlg::UpdateChecks( const SwTableAutoFmt& rFmt, sal_Bool bEnable )
289 {
290     aBtnNumFormat.Enable( bEnable );
291     aBtnNumFormat.Check( rFmt.IsValueFormat() );
292 
293     aBtnBorder.Enable( bEnable );
294     aBtnBorder.Check( rFmt.IsFrame() );
295 
296     aBtnFont.Enable( bEnable );
297     aBtnFont.Check( rFmt.IsFont() );
298 
299     aBtnPattern.Enable( bEnable );
300     aBtnPattern.Check( rFmt.IsBackground() );
301 
302     aBtnAlignment.Enable( bEnable );
303     aBtnAlignment.Check( rFmt.IsJustify() );
304 }
305 
306 void SwAutoFormatDlg::FillAutoFmtOfIndex( SwTableAutoFmt*& rToFill ) const
307 {
308     if( 255 != nIndex )
309     {
310         if( rToFill )
311             *rToFill = *(*pTableTbl)[ nIndex ];
312         else
313             rToFill = new SwTableAutoFmt( *(*pTableTbl)[ nIndex ] );
314     }
315     else if( rToFill )
316         delete rToFill, rToFill = 0;
317 }
318 
319 
320 /*------------------------------------------------------------------------
321   Handler:
322   ---------*/
323 
324 
325 IMPL_LINK( SwAutoFormatDlg, CheckHdl, Button *, pBtn )
326 {
327     SwTableAutoFmtPtr pData  = (*pTableTbl)[nIndex];
328     sal_Bool bCheck = ((CheckBox*)pBtn)->IsChecked(), bDataChgd = sal_True;
329 
330     if( pBtn == &aBtnNumFormat )
331         pData->SetValueFormat( bCheck );
332     else if ( pBtn == &aBtnBorder )
333         pData->SetFrame( bCheck );
334     else if ( pBtn == &aBtnFont )
335         pData->SetFont( bCheck );
336     else if ( pBtn == &aBtnPattern )
337         pData->SetBackground( bCheck );
338     else if ( pBtn == &aBtnAlignment )
339         pData->SetJustify( bCheck );
340 //    else if ( pBtn == &aBtnAdjust )
341 //        pData->SetIncludeWidthHeight( bCheck );
342     else
343         bDataChgd = sal_False;
344 
345     if( bDataChgd )
346     {
347         if( !bCoreDataChanged )
348         {
349             aBtnCancel.SetText( aStrClose );
350             bCoreDataChanged = sal_True;
351         }
352 
353         pWndPreview->NotifyChange( *pData );
354     }
355     return 0;
356 }
357 
358 /*------------------------------------------------------------------------*/
359 
360 
361 IMPL_LINK( SwAutoFormatDlg, AddHdl, void *, EMPTYARG )
362 {
363     sal_Bool bOk = sal_False, bFmtInserted = sal_False;
364     while( !bOk )
365     {
366         SwStringInputDlg*   pDlg = new SwStringInputDlg( this,
367                                                             aStrTitle,
368                                                             aStrLabel,
369                                                             aEmptyStr );
370         if( RET_OK == pDlg->Execute() )
371         {
372             String aFormatName;
373             pDlg->GetInputString( aFormatName );
374 
375             if( aFormatName.Len() > 0 )
376             {
377                 sal_uInt16 n;
378                 for( n = 0; n < pTableTbl->Count(); ++n )
379                     if( (*pTableTbl)[n]->GetName() == aFormatName )
380                         break;
381 
382                 if( n >= pTableTbl->Count() )
383                 {
384                     // Format mit dem Namen noch nicht vorhanden, also
385                     // aufnehmen
386                     SwTableAutoFmtPtr pNewData = new
387                                         SwTableAutoFmt( aFormatName );
388                     pShell->GetTableAutoFmt( *pNewData );
389 
390                     // Sortiert einfuegen!!
391                     for( n = 1; n < pTableTbl->Count(); ++n )
392                         if( (*pTableTbl)[ n ]->GetName() > aFormatName )
393                             break;
394 
395                     pTableTbl->Insert( pNewData, n );
396                     aLbFormat.InsertEntry( aFormatName, nDfltStylePos + n );
397                     aLbFormat.SelectEntryPos( nDfltStylePos + n );
398                     bFmtInserted = sal_True;
399                     aBtnAdd.Enable( sal_False );
400                     if ( !bCoreDataChanged )
401                     {
402                         aBtnCancel.SetText( aStrClose );
403                         bCoreDataChanged = sal_True;
404                     }
405 
406                     SelFmtHdl( 0 );
407                     bOk = sal_True;
408                 }
409             }
410 
411             if( !bFmtInserted )
412             {
413                 bOk = RET_CANCEL == ErrorBox( this,
414                                     WinBits( WB_OK_CANCEL | WB_DEF_OK),
415                                     aStrInvalidFmt
416                                     ).Execute();
417             }
418         }
419         else
420             bOk = sal_True;
421         delete pDlg;
422     }
423     return 0;
424 }
425 
426 //------------------------------------------------------------------------
427 
428 IMPL_LINK( SwAutoFormatDlg, RemoveHdl, void *, EMPTYARG )
429 {
430     String aMessage = aStrDelMsg ;
431     aMessage.AppendAscii("\n\n");
432     aMessage += aLbFormat.GetSelectEntry() ;
433     aMessage += '\n';
434 
435     MessBox* pBox = new MessBox( this, WinBits( WB_OK_CANCEL ),
436                                     aStrDelTitle, aMessage);
437 
438     if ( pBox->Execute() == RET_OK )
439     {
440         aLbFormat.RemoveEntry( nDfltStylePos + nIndex );
441         aLbFormat.SelectEntryPos( nDfltStylePos + nIndex-1 );
442 
443         pTableTbl->DeleteAndDestroy( nIndex );
444         nIndex--;
445 
446         if( !nIndex )
447         {
448             aBtnRemove.Enable(sal_False);
449             aBtnRename.Enable(sal_False);
450         }
451 
452         if( !bCoreDataChanged )
453         {
454             aBtnCancel.SetText( aStrClose );
455             bCoreDataChanged = sal_True;
456         }
457     }
458     delete pBox;
459 
460     SelFmtHdl( 0 );
461 
462     return 0;
463 }
464 
465 IMPL_LINK( SwAutoFormatDlg, RenameHdl, void *, EMPTYARG )
466 {
467     sal_Bool bOk = sal_False;
468     while( !bOk )
469     {
470         SwStringInputDlg* pDlg = new SwStringInputDlg( this,
471                         aStrRenameTitle, aLbFormat.GetSelectEntry(),
472                                                         aEmptyStr );
473         if( pDlg->Execute() == RET_OK )
474         {
475             sal_Bool bFmtRenamed = sal_False;
476             String aFormatName;
477             pDlg->GetInputString( aFormatName );
478 
479             if ( aFormatName.Len() > 0 )
480             {
481                 sal_uInt16 n;
482                 for( n = 0; n < pTableTbl->Count(); ++n )
483                     if ((*pTableTbl)[n]->GetName() == aFormatName)
484                         break;
485 
486                 if( n >= pTableTbl->Count() )
487                 {
488                     // Format mit dem Namen noch nicht vorhanden, also
489                     // umbenennen
490 
491                     aLbFormat.RemoveEntry( nDfltStylePos + nIndex );
492                     SwTableAutoFmtPtr p = (*pTableTbl)[ nIndex ];
493                     pTableTbl->Remove( nIndex );
494 
495                     p->SetName( aFormatName );
496 
497                     // Sortiert einfuegen!!
498                     for( n = 1; n < pTableTbl->Count(); ++n )
499                         if( (*pTableTbl)[ n ]->GetName() > aFormatName )
500                             break;
501 
502                     pTableTbl->Insert( p, n );
503                     aLbFormat.InsertEntry( aFormatName, nDfltStylePos + n );
504                     aLbFormat.SelectEntryPos( nDfltStylePos + n );
505 
506                     if ( !bCoreDataChanged )
507                     {
508                         aBtnCancel.SetText( aStrClose );
509                         bCoreDataChanged = sal_True;
510                     }
511 
512                     SelFmtHdl( 0 );
513                     bOk = sal_True;
514                     bFmtRenamed = sal_True;
515                 }
516             }
517 
518             if( !bFmtRenamed )
519             {
520                 bOk = RET_CANCEL == ErrorBox( this,
521                                     WinBits( WB_OK_CANCEL | WB_DEF_OK),
522                                     aStrInvalidFmt
523                                     ).Execute();
524             }
525         }
526         else
527             bOk = sal_True;
528         delete pDlg;
529     }
530     return 0;
531 }
532 
533 //------------------------------------------------------------------------
534 
535 IMPL_LINK( SwAutoFormatDlg, SelFmtHdl, void *, EMPTYARG )
536 {
537     sal_Bool bBtnEnable = sal_False;
538     sal_uInt8 nSelPos = (sal_uInt8) aLbFormat.GetSelectEntryPos(), nOldIdx = nIndex;
539     if( nSelPos >= nDfltStylePos )
540     {
541         nIndex = nSelPos - nDfltStylePos;
542         pWndPreview->NotifyChange( *(*pTableTbl)[nIndex] );
543         bBtnEnable = 0 != nIndex;
544         UpdateChecks( *(*pTableTbl)[nIndex], sal_True );
545     }
546     else
547     {
548         nIndex = 255;
549 
550         SwTableAutoFmt aTmp( ViewShell::GetShellRes()->aStrNone );
551         aTmp.SetFont( sal_False );
552         aTmp.SetJustify( sal_False );
553         aTmp.SetFrame( sal_False );
554         aTmp.SetBackground( sal_False );
555         aTmp.SetValueFormat( sal_False );
556         aTmp.SetWidthHeight( sal_False );
557 
558         if( nOldIdx != nIndex )
559             pWndPreview->NotifyChange( aTmp );
560         UpdateChecks( aTmp, sal_False );
561     }
562 
563     aBtnRemove.Enable( bBtnEnable );
564     aBtnRename.Enable( bBtnEnable );
565 
566     return 0;
567 }
568 //------------------------------------------------------------------------
569 
570 IMPL_LINK_INLINE_START( SwAutoFormatDlg, OkHdl, Button *, EMPTYARG )
571 {
572     if( bSetAutoFmt )
573         pShell->SetTableAutoFmt( *(*pTableTbl)[ nIndex ] );
574     EndDialog( RET_OK );
575     return sal_True;
576 }
577 IMPL_LINK_INLINE_END( SwAutoFormatDlg, OkHdl, Button *, EMPTYARG )
578 
579 //========================================================================
580 // AutoFmtPreview
581 
582 //------------------------------------------------------------------------
583 
584 AutoFmtPreview::AutoFmtPreview( Window* pParent, const ResId& rRes, SwWrtShell* pWrtShell ) :
585         Window          ( pParent, rRes ),
586 
587         aCurData        ( aEmptyStr ),
588         aVD             ( *this ),
589         aScriptedText   ( aVD ),
590         bFitWidth       ( sal_False ),
591         mbRTL           ( false ),
592         aPrvSize        ( GetSizePixel().Width() - 6, GetSizePixel().Height() - 30 ),
593         nLabelColWidth  ( (aPrvSize.Width() - 4) / 4 - 12 ),
594         nDataColWidth1  ( (aPrvSize.Width() - 4 - 2 * nLabelColWidth) / 3 ),
595         nDataColWidth2  ( (aPrvSize.Width() - 4 - 2 * nLabelColWidth) / 4 ),
596         nRowHeight      ( (aPrvSize.Height() - 4) / 5 ),
597         aStrJan         ( SW_RES( STR_JAN ) ),
598         aStrFeb         ( SW_RES( STR_FEB ) ),
599         aStrMar         ( SW_RES( STR_MAR ) ),
600         aStrNorth       ( SW_RES( STR_NORTH ) ),
601         aStrMid         ( SW_RES( STR_MID ) ),
602         aStrSouth       ( SW_RES( STR_SOUTH ) ),
603         aStrSum         ( SW_RES( STR_SUM ) ),
604         m_xMSF          ( comphelper::getProcessServiceFactory() )
605 {
606     if (!pWrtShell->IsCrsrInTbl()) // We haven't created the table yet
607         mbRTL = Application::GetSettings().GetLayoutRTL();
608     else
609         mbRTL = pWrtShell->IsTableRightToLeft();
610 
611     DBG_ASSERT( m_xMSF.is(), "AutoFmtPreview: no MultiServiceFactory");
612     if ( m_xMSF.is() )
613     {
614         m_xBreak = uno::Reference< i18n::XBreakIterator >(
615             m_xMSF->createInstance (
616                 rtl::OUString::createFromAscii( "com.sun.star.i18n.BreakIterator" ) ),
617             uno::UNO_QUERY);
618     }
619     pNumFmt = new SvNumberFormatter( m_xMSF, LANGUAGE_SYSTEM );
620 
621     Init();
622 }
623 
624 //------------------------------------------------------------------------
625 
626 __EXPORT AutoFmtPreview::~AutoFmtPreview()
627 {
628     delete pNumFmt;
629 }
630 
631 //------------------------------------------------------------------------
632 
633 static void lcl_SetFontProperties(
634         Font& rFont,
635         const SvxFontItem& rFontItem,
636         const SvxWeightItem& rWeightItem,
637         const SvxPostureItem& rPostureItem )
638 {
639     rFont.SetFamily     ( rFontItem.GetFamily() );
640     rFont.SetName       ( rFontItem.GetFamilyName() );
641     rFont.SetStyleName  ( rFontItem.GetStyleName() );
642     rFont.SetCharSet    ( rFontItem.GetCharSet() );
643     rFont.SetPitch      ( rFontItem.GetPitch() );
644     rFont.SetWeight     ( (FontWeight)rWeightItem.GetValue() );
645     rFont.SetItalic     ( (FontItalic)rPostureItem.GetValue() );
646 }
647 
648 #define SETONALLFONTS( MethodName, Value )                  \
649 rFont.MethodName( Value );                                  \
650 rCJKFont.MethodName( Value );                               \
651 rCTLFont.MethodName( Value );
652 
653 void AutoFmtPreview::MakeFonts( sal_uInt8 nIndex, Font& rFont, Font& rCJKFont, Font& rCTLFont )
654 {
655     const SwBoxAutoFmt& rBoxFmt = aCurData.GetBoxFmt( nIndex );
656 
657     rFont = rCJKFont = rCTLFont = GetFont();
658     Size aFontSize( rFont.GetSize().Width(), 10 );
659 
660     lcl_SetFontProperties( rFont, rBoxFmt.GetFont(), rBoxFmt.GetWeight(), rBoxFmt.GetPosture() );
661     lcl_SetFontProperties( rCJKFont, rBoxFmt.GetCJKFont(), rBoxFmt.GetCJKWeight(), rBoxFmt.GetCJKPosture() );
662     lcl_SetFontProperties( rCTLFont, rBoxFmt.GetCTLFont(), rBoxFmt.GetCTLWeight(), rBoxFmt.GetCTLPosture() );
663 
664     SETONALLFONTS( SetUnderline,    (FontUnderline)rBoxFmt.GetUnderline().GetValue() );
665     SETONALLFONTS( SetOverline,     (FontUnderline)rBoxFmt.GetOverline().GetValue() );
666     SETONALLFONTS( SetStrikeout,    (FontStrikeout)rBoxFmt.GetCrossedOut().GetValue() );
667     SETONALLFONTS( SetOutline,      rBoxFmt.GetContour().GetValue() );
668     SETONALLFONTS( SetShadow,       rBoxFmt.GetShadowed().GetValue() );
669     SETONALLFONTS( SetColor,        rBoxFmt.GetColor().GetValue() );
670     SETONALLFONTS( SetSize,         aFontSize );
671     SETONALLFONTS( SetTransparent,  sal_True );
672 }
673 
674 //------------------------------------------------------------------------
675 
676 sal_uInt8 AutoFmtPreview::GetFormatIndex( size_t nCol, size_t nRow ) const
677 {
678     static const sal_uInt8 pnFmtMap[] =
679     {
680         0,  1,  2,  1,  3,
681         4,  5,  6,  5,  7,
682         8,  9,  10, 9,  11,
683         4,  5,  6,  5,  7,
684         12, 13, 14, 13, 15
685     };
686     return pnFmtMap[ maArray.GetCellIndex( nCol, nRow, mbRTL ) ];
687 }
688 
689 const SvxBoxItem& AutoFmtPreview::GetBoxItem( size_t nCol, size_t nRow ) const
690 {
691     return aCurData.GetBoxFmt( GetFormatIndex( nCol, nRow ) ).GetBox();
692 }
693 
694 //------------------------------------------------------------------------
695 
696 void AutoFmtPreview::DrawString( size_t nCol, size_t nRow )
697 {
698     //------------------------
699     // Ausgabe des Zelltextes:
700     //------------------------
701     sal_uLong   nNum;
702     double  nVal;
703     String cellString;
704     sal_uInt8    nIndex = static_cast< sal_uInt8 >( maArray.GetCellIndex( nCol, nRow, mbRTL ) );
705 
706     switch( nIndex )
707     {
708         case  1: cellString = aStrJan;          break;
709         case  2: cellString = aStrFeb;          break;
710         case  3: cellString = aStrMar;          break;
711         case  5: cellString = aStrNorth;        break;
712         case 10: cellString = aStrMid;          break;
713         case 15: cellString = aStrSouth;        break;
714         case  4:
715         case 20: cellString = aStrSum;          break;
716 
717         case  6:
718         case  8:
719         case 16:
720         case 18:    nVal = nIndex;
721                     nNum = 5;
722                     goto MAKENUMSTR;
723         case 17:
724         case  7:    nVal = nIndex;
725                     nNum = 6;
726                     goto MAKENUMSTR;
727         case 11:
728         case 12:
729         case 13:    nVal = nIndex;
730                     nNum = 12 == nIndex ? 10 : 9;
731                     goto MAKENUMSTR;
732 
733         case  9:    nVal = 21; nNum = 7;    goto MAKENUMSTR;
734         case 14:    nVal = 36; nNum = 11;   goto MAKENUMSTR;
735         case 19:    nVal = 51; nNum = 7;    goto MAKENUMSTR;
736         case 21:    nVal = 33; nNum = 13;   goto MAKENUMSTR;
737         case 22:    nVal = 36; nNum = 14;   goto MAKENUMSTR;
738         case 23:    nVal = 39; nNum = 13;   goto MAKENUMSTR;
739         case 24:    nVal = 108; nNum = 15;  goto MAKENUMSTR;
740 MAKENUMSTR:
741             if( aCurData.IsValueFormat() )
742             {
743                 String sFmt; LanguageType eLng, eSys;
744                 aCurData.GetBoxFmt( (sal_uInt8)nNum ).GetValueFormat( sFmt, eLng, eSys );
745 
746                 short nType;
747                 sal_Bool bNew;
748                 xub_StrLen nCheckPos;
749                 sal_uInt32 nKey = pNumFmt->GetIndexPuttingAndConverting( sFmt, eLng,
750                         eSys, nType, bNew, nCheckPos);
751                 Color* pDummy;
752                 pNumFmt->GetOutputString( nVal, nKey, cellString, &pDummy );
753             }
754             else
755                 cellString = String::CreateFromInt32((sal_Int32)nVal);
756             break;
757 
758     }
759 
760     if( cellString.Len() )
761     {
762         Size                aStrSize;
763         sal_uInt8                nFmtIndex       = GetFormatIndex( nCol, nRow );
764         Rectangle           cellRect        = maArray.GetCellRect( nCol, nRow );
765         Point               aPos            = cellRect.TopLeft();
766         sal_uInt16              nRightX         = 0;
767 //            sal_Bool                bJustify        = aCurData.IsJustify();
768 //            ScHorJustifyAttr    aHorJustifyItem;
769 //          CellHorJustify    eJustification;
770 
771         Size theMaxStrSize( cellRect.GetWidth() - FRAME_OFFSET,
772                             cellRect.GetHeight() - FRAME_OFFSET );
773         if( aCurData.IsFont() )
774         {
775             Font aFont, aCJKFont, aCTLFont;
776             MakeFonts( nFmtIndex, aFont, aCJKFont, aCTLFont );
777             aScriptedText.SetFonts( &aFont, &aCJKFont, &aCTLFont );
778         }
779         else
780             aScriptedText.SetDefaultFont();
781 
782         aScriptedText.SetText( cellString, m_xBreak );
783         aStrSize = aScriptedText.GetTextSize();
784 
785         if( aCurData.IsFont() &&
786             theMaxStrSize.Height() < aStrSize.Height() )
787         {
788                 // wenn der String in diesem Font nicht
789                 // in die Zelle passt, wird wieder der
790                 // Standard-Font genommen:
791                 aScriptedText.SetDefaultFont();
792                 aStrSize = aScriptedText.GetTextSize();
793         }
794 
795         while( theMaxStrSize.Width() <= aStrSize.Width() &&
796                 cellString.Len() > 1 )
797         {
798 //                  if( eJustification == SVX_HOR_JUSTIFY_RIGHT )
799 //                          cellString.Erase( 0, 1 );
800 //                  else
801             cellString.Erase( cellString.Len() - 1 );
802             aScriptedText.SetText( cellString, m_xBreak );
803             aStrSize = aScriptedText.GetTextSize();
804         }
805 
806         nRightX  = (sal_uInt16)(  cellRect.GetWidth()
807                                 - aStrSize.Width()
808                                 - FRAME_OFFSET );
809         //-------------
810         // Ausrichtung:
811         //-------------
812         /*   if ( bJustify )
813         {
814             aCurData.GetHorJustify( nFmtIndex, aHorJustifyItem );
815             eJustification = (CellHorJustify)aHorJustifyItem.GetValue();
816         }
817         else
818         {
819             eJustification = SC_HOR_JUSTIFY_STANDARD;
820         }*/
821 
822         //-----------------------------
823         // vertikal (immer zentrieren):
824         //-----------------------------
825         aPos.Y() += (nRowHeight - (sal_uInt16)aStrSize.Height()) / 2;
826 
827         //-----------
828         // horizontal
829         //-----------
830 /*        if ( eJustification != SC_HOR_JUSTIFY_STANDARD )*/
831         if( mbRTL )
832             aPos.X() += nRightX;
833         else if (aCurData.IsJustify())
834         {
835             sal_uInt16 nHorPos = (sal_uInt16)
836                     ((cellRect.GetWidth()-aStrSize.Width())/2);
837             const SvxAdjustItem& rAdj = aCurData.GetBoxFmt(nFmtIndex).GetAdjust();
838             switch ( rAdj.GetAdjust() )
839             {
840                 case SVX_ADJUST_LEFT:
841                     aPos.X() += FRAME_OFFSET;
842                     break;
843                 case SVX_ADJUST_RIGHT:
844                     aPos.X() += nRightX;
845                     break;
846                 default:
847                     aPos.X() += nHorPos;
848                     break;
849             }
850         }
851         else
852         {
853             //---------------------
854             // Standardausrichtung:
855             //---------------------
856             if ( (nCol == 0) || (nIndex == 4) )
857             {
858                 // Text-Label links oder Summe linksbuendig
859                 aPos.X() += FRAME_OFFSET;
860             }
861             else
862             {
863                     // Zahlen/Datum rechtsbuendig
864                 aPos.X() += nRightX;
865             }
866         }
867 
868         //-------------------------------
869         aScriptedText.DrawText( aPos );
870         //-------------------------------
871     }
872 }
873 
874 #undef FRAME_OFFSET
875 
876 //------------------------------------------------------------------------
877 
878 void AutoFmtPreview::DrawStrings()
879 {
880     for( size_t nRow = 0; nRow < 5; ++nRow )
881         for( size_t nCol = 0; nCol < 5; ++nCol )
882             DrawString( nCol, nRow );
883 }
884 
885 //------------------------------------------------------------------------
886 
887 
888 void AutoFmtPreview::DrawBackground()
889 {
890     for( size_t nRow = 0; nRow < 5; ++nRow )
891     {
892         for( size_t nCol = 0; nCol < 5; ++nCol )
893         {
894             SvxBrushItem aBrushItem( aCurData.GetBoxFmt( GetFormatIndex( nCol, nRow ) ).GetBackground() );
895 
896             aVD.Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
897             aVD.SetLineColor();
898             aVD.SetFillColor( aBrushItem.GetColor() );
899             aVD.DrawRect( maArray.GetCellRect( nCol, nRow ) );
900             aVD.Pop();
901         }
902     }
903 }
904 
905 //------------------------------------------------------------------------
906 
907 
908 void AutoFmtPreview::PaintCells()
909 {
910     // 1) background
911     if ( aCurData.IsBackground() )
912         DrawBackground();
913 
914     // 2) values
915     DrawStrings();
916 
917     // 3) border
918     if ( aCurData.IsFrame() )
919         maArray.DrawArray( aVD );
920 }
921 
922 //------------------------------------------------------------------------
923 
924 
925 void __EXPORT AutoFmtPreview::Init()
926 {
927     SetBorderStyle( GetBorderStyle() | WINDOW_BORDER_MONO );
928     maArray.Initialize( 5, 5 );
929     maArray.SetUseDiagDoubleClipping( false );
930     CalcCellArray( sal_False );
931     CalcLineMap();
932 }
933 
934 //------------------------------------------------------------------------
935 
936 
937 void AutoFmtPreview::CalcCellArray( sal_Bool _bFitWidth )
938 {
939     maArray.SetXOffset( 2 );
940     maArray.SetAllColWidths( _bFitWidth ? nDataColWidth2 : nDataColWidth1 );
941     maArray.SetColWidth( 0, nLabelColWidth );
942     maArray.SetColWidth( 4, nLabelColWidth );
943 
944     maArray.SetYOffset( 2 );
945     maArray.SetAllRowHeights( nRowHeight );
946 
947     aPrvSize.Width() = maArray.GetWidth() + 4;
948     aPrvSize.Height() = maArray.GetHeight() + 4;
949 }
950 
951 //------------------------------------------------------------------------
952 
953 inline void lclSetStyleFromBorder( svx::frame::Style& rStyle, const SvxBorderLine* pBorder )
954 {
955     rStyle.Set( pBorder, 0.05, 5 );
956 }
957 
958 void AutoFmtPreview::CalcLineMap()
959 {
960     for( size_t nRow = 0; nRow < 5; ++nRow )
961     {
962         for( size_t nCol = 0; nCol < 5; ++nCol )
963         {
964             svx::frame::Style aStyle;
965 
966             const SvxBoxItem& rItem = GetBoxItem( nCol, nRow );
967             lclSetStyleFromBorder( aStyle, rItem.GetLeft() );
968             maArray.SetCellStyleLeft( nCol, nRow, aStyle );
969             lclSetStyleFromBorder( aStyle, rItem.GetRight() );
970             maArray.SetCellStyleRight( nCol, nRow, aStyle );
971             lclSetStyleFromBorder( aStyle, rItem.GetTop() );
972             maArray.SetCellStyleTop( nCol, nRow, aStyle );
973             lclSetStyleFromBorder( aStyle, rItem.GetBottom() );
974             maArray.SetCellStyleBottom( nCol, nRow, aStyle );
975 
976 // FIXME - uncomment to draw diagonal borders
977 //            lclSetStyleFromBorder( aStyle, GetDiagItem( nCol, nRow, true ).GetLine() );
978 //            maArray.SetCellStyleTLBR( nCol, nRow, aStyle );
979 //            lclSetStyleFromBorder( aStyle, GetDiagItem( nCol, nRow, false ).GetLine() );
980 //            maArray.SetCellStyleBLTR( nCol, nRow, aStyle );
981         }
982     }
983 }
984 
985 //------------------------------------------------------------------------
986 
987 
988 void AutoFmtPreview::NotifyChange( const SwTableAutoFmt& rNewData )
989 {
990     aCurData  = rNewData;
991     bFitWidth = aCurData.IsJustify();//sal_True;  //???
992     CalcCellArray( bFitWidth );
993     CalcLineMap();
994     DoPaint( Rectangle( Point(0,0), GetSizePixel() ) );
995 }
996 
997 //------------------------------------------------------------------------
998 
999 
1000 void AutoFmtPreview::DoPaint( const Rectangle& /*rRect*/ )
1001 {
1002     sal_uInt32 nOldDrawMode = aVD.GetDrawMode();
1003     if( GetSettings().GetStyleSettings().GetHighContrastMode() &&
1004             SW_MOD()->GetAccessibilityOptions().GetIsForBorders() )
1005         aVD.SetDrawMode( DRAWMODE_SETTINGSLINE | DRAWMODE_SETTINGSFILL | DRAWMODE_SETTINGSTEXT | DRAWMODE_SETTINGSGRADIENT );
1006 
1007     Bitmap  thePreview;
1008     Point   aCenterPos;
1009     Size    theWndSize = GetSizePixel();
1010     Size    thePrevSize;
1011     Color   oldColor;
1012     Font    aFont;
1013 
1014     aFont = aVD.GetFont();
1015     aFont.SetTransparent( sal_True );
1016 
1017     aVD.SetFont          ( aFont );
1018     aVD.SetLineColor     ();
1019     const Color& rWinColor = GetSettings().GetStyleSettings().GetWindowColor();
1020     aVD.SetBackground    ( Wallpaper(rWinColor) );
1021     aVD.SetFillColor     ( rWinColor );
1022     aVD.SetOutputSizePixel  ( aPrvSize );
1023 
1024     //--------------------------------
1025     // Zellen auf virtual Device malen
1026     // und Ergebnis sichern
1027     //--------------------------------
1028     PaintCells();
1029     thePreview = aVD.GetBitmap( Point(0,0), aPrvSize );
1030 
1031     //--------------------------------------
1032     // Rahmen malen und Vorschau zentrieren:
1033     // (virtual Device fuer Fensterausgabe)
1034     //--------------------------------------
1035     aVD.SetOutputSizePixel( theWndSize );
1036     oldColor = aVD.GetLineColor();
1037     aVD.SetLineColor();
1038     aVD.DrawRect( Rectangle( Point(0,0), theWndSize ) );
1039     SetLineColor( oldColor );
1040     aCenterPos  = Point( (theWndSize.Width()  - aPrvSize.Width() ) / 2,
1041                          (theWndSize.Height() - aPrvSize.Height()) / 2 );
1042     aVD.DrawBitmap( aCenterPos, thePreview );
1043 
1044     //----------------------------
1045     // Ausgabe im Vorschaufenster:
1046     //----------------------------
1047     DrawBitmap( Point(0,0), aVD.GetBitmap( Point(0,0), theWndSize ) );
1048 
1049     aVD.SetDrawMode( nOldDrawMode );
1050 }
1051 
1052 //------------------------------------------------------------------------
1053 
1054 void __EXPORT AutoFmtPreview::Paint( const Rectangle& rRect )
1055 {
1056     DoPaint( rRect );
1057 }
1058