Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <vcl/edit.hxx>
21 : #include <vcl/layout.hxx>
22 : #include <vcl/msgbox.hxx>
23 : #include <vcl/svapp.hxx>
24 : #include <vcl/settings.hxx>
25 :
26 : #include <svl/zforlist.hxx>
27 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
28 : #include <com/sun/star/i18n/BreakIterator.hpp>
29 : #include <comphelper/processfactory.hxx>
30 : #include <svtools/scriptedtext.hxx>
31 : #include <svtools/accessibilityoptions.hxx>
32 : #include <svx/framelinkarray.hxx>
33 : #include "app.hrc"
34 : #include "swmodule.hxx"
35 : #include "swtypes.hxx"
36 : #include "view.hxx"
37 : #include "wrtsh.hxx"
38 : #include "tblafmt.hxx"
39 : #include "tautofmt.hxx"
40 : #include "shellres.hxx"
41 : #include <boost/scoped_ptr.hpp>
42 :
43 : using namespace com::sun::star;
44 :
45 : #define FRAME_OFFSET 4
46 :
47 : class AutoFmtPreview : public vcl::Window
48 : {
49 : public:
50 : AutoFmtPreview(vcl::Window* pParent);
51 : virtual ~AutoFmtPreview();
52 :
53 : void NotifyChange( const SwTableAutoFmt& rNewData );
54 :
55 : void DetectRTL(SwWrtShell* pWrtShell);
56 :
57 : virtual void Resize() SAL_OVERRIDE;
58 : protected:
59 : virtual void Paint( const Rectangle& rRect ) SAL_OVERRIDE;
60 :
61 : private:
62 : SwTableAutoFmt aCurData;
63 : VirtualDevice aVD;
64 : SvtScriptedTextHelper aScriptedText;
65 : svx::frame::Array maArray; /// Implementation to draw the frame borders.
66 : bool bFitWidth;
67 : bool mbRTL;
68 : Size aPrvSize;
69 : long nLabelColWidth;
70 : long nDataColWidth1;
71 : long nDataColWidth2;
72 : long nRowHeight;
73 : const OUString aStrJan;
74 : const OUString aStrFeb;
75 : const OUString aStrMar;
76 : const OUString aStrNorth;
77 : const OUString aStrMid;
78 : const OUString aStrSouth;
79 : const OUString aStrSum;
80 : SvNumberFormatter* pNumFmt;
81 :
82 : uno::Reference< i18n::XBreakIterator > m_xBreak;
83 :
84 : void Init ();
85 : void DoPaint ( const Rectangle& rRect );
86 : void CalcCellArray ( bool bFitWidth );
87 : void CalcLineMap ();
88 : void PaintCells ();
89 :
90 : sal_uInt8 GetFormatIndex( size_t nCol, size_t nRow ) const;
91 : const SvxBoxItem& GetBoxItem( size_t nCol, size_t nRow ) const;
92 :
93 : void DrawString( size_t nCol, size_t nRow );
94 : void DrawStrings();
95 : void DrawBackground();
96 :
97 : void MakeFonts( sal_uInt8 nIndex, vcl::Font& rFont, vcl::Font& rCJKFont, vcl::Font& rCTLFont );
98 : };
99 :
100 : class SwStringInputDlg : public ModalDialog
101 : {
102 : public:
103 : SwStringInputDlg( vcl::Window* pParent,
104 : const OUString& rTitle,
105 : const OUString& rEditTitle,
106 : const OUString& rDefault );
107 : virtual ~SwStringInputDlg();
108 :
109 : OUString GetInputString() const;
110 :
111 : private:
112 : Edit* m_pEdInput; // Edit obtains the focus.
113 : };
114 :
115 0 : SwStringInputDlg::SwStringInputDlg(vcl::Window* pParent, const OUString& rTitle,
116 : const OUString& rEditTitle, const OUString& rDefault)
117 0 : : ModalDialog(pParent, "StringInputDialog", "modules/swriter/ui/stringinput.ui")
118 : {
119 0 : get<FixedText>("name")->SetText(rEditTitle);
120 0 : get(m_pEdInput, "edit");
121 :
122 0 : SetText(rTitle);
123 0 : m_pEdInput->SetText(rDefault);
124 0 : }
125 :
126 0 : OUString SwStringInputDlg::GetInputString() const
127 : {
128 0 : return m_pEdInput->GetText();
129 : }
130 :
131 0 : SwStringInputDlg::~SwStringInputDlg()
132 : {
133 0 : }
134 :
135 : // AutoFormat-Dialogue:
136 :
137 0 : SwAutoFormatDlg::SwAutoFormatDlg( vcl::Window* pParent, SwWrtShell* pWrtShell,
138 : bool bSetAutoFormat, const SwTableAutoFmt* pSelFmt )
139 : : SfxModalDialog(pParent, "AutoFormatTableDialog", "modules/swriter/ui/autoformattable.ui")
140 : , aStrTitle(SW_RES(STR_ADD_AUTOFORMAT_TITLE))
141 : , aStrLabel(SW_RES(STR_ADD_AUTOFORMAT_LABEL))
142 : , aStrClose(SW_RES(STR_BTN_AUTOFORMAT_CLOSE))
143 : , aStrDelTitle(SW_RES(STR_DEL_AUTOFORMAT_TITLE))
144 : , aStrDelMsg(SW_RES(STR_DEL_AUTOFORMAT_MSG))
145 : , aStrRenameTitle(SW_RES(STR_RENAME_AUTOFORMAT_TITLE))
146 : , aStrInvalidFmt(SW_RES(STR_INVALID_AUTOFORMAT_NAME))
147 : , pShell(pWrtShell)
148 : , nIndex(0)
149 : , nDfltStylePos(0)
150 : , bCoreDataChanged(false)
151 0 : , bSetAutoFmt(bSetAutoFormat)
152 : {
153 0 : get(m_pLbFormat, "formatlb");
154 0 : get(m_pFormatting, "formatting");
155 0 : get(m_pBtnNumFormat, "numformatcb");
156 0 : get(m_pBtnBorder, "bordercb");
157 0 : get(m_pBtnFont, "fontcb");
158 0 : get(m_pBtnPattern, "patterncb");
159 0 : get(m_pBtnAlignment, "alignmentcb");
160 0 : get(m_pBtnOk, "ok");
161 0 : get(m_pBtnCancel, "cancel");
162 0 : get(m_pBtnAdd, "add");
163 0 : get(m_pBtnRemove, "remove");
164 0 : get(m_pBtnRename, "rename");
165 0 : get(m_pWndPreview, "preview");
166 :
167 0 : m_pWndPreview->DetectRTL(pWrtShell);
168 :
169 0 : pTableTbl = new SwTableAutoFmtTbl;
170 0 : pTableTbl->Load();
171 :
172 0 : Init(pSelFmt);
173 0 : }
174 :
175 0 : SwAutoFormatDlg::~SwAutoFormatDlg()
176 : {
177 0 : if (bCoreDataChanged)
178 0 : pTableTbl->Save();
179 0 : delete pTableTbl;
180 0 : }
181 :
182 0 : void SwAutoFormatDlg::Init( const SwTableAutoFmt* pSelFmt )
183 : {
184 0 : Link aLk( LINK( this, SwAutoFormatDlg, CheckHdl ) );
185 0 : m_pBtnBorder->SetClickHdl( aLk );
186 0 : m_pBtnFont->SetClickHdl( aLk );
187 0 : m_pBtnPattern->SetClickHdl( aLk );
188 0 : m_pBtnAlignment->SetClickHdl( aLk );
189 0 : m_pBtnNumFormat->SetClickHdl( aLk );
190 :
191 0 : m_pBtnAdd->SetClickHdl ( LINK( this, SwAutoFormatDlg, AddHdl ) );
192 0 : m_pBtnRemove->SetClickHdl ( LINK( this, SwAutoFormatDlg, RemoveHdl ) );
193 0 : m_pBtnRename->SetClickHdl ( LINK( this, SwAutoFormatDlg, RenameHdl ) );
194 0 : m_pBtnOk->SetClickHdl ( LINK( this, SwAutoFormatDlg, OkHdl ) );
195 0 : m_pLbFormat->SetSelectHdl( LINK( this, SwAutoFormatDlg, SelFmtHdl ) );
196 :
197 0 : m_pBtnAdd->Enable( bSetAutoFmt );
198 :
199 0 : nIndex = 0;
200 0 : if( !bSetAutoFmt )
201 : {
202 : // Then the list to be expanded by the entry "- none -".
203 0 : m_pLbFormat->InsertEntry( SwViewShell::GetShellRes()->aStrNone );
204 0 : nDfltStylePos = 1;
205 0 : nIndex = 255;
206 : }
207 :
208 0 : for (sal_uInt8 i = 0, nCount = static_cast<sal_uInt8>(pTableTbl->size());
209 : i < nCount; i++)
210 : {
211 0 : SwTableAutoFmt const& rFmt = (*pTableTbl)[ i ];
212 0 : m_pLbFormat->InsertEntry(rFmt.GetName());
213 0 : if (pSelFmt && rFmt.GetName() == pSelFmt->GetName())
214 0 : nIndex = i;
215 : }
216 :
217 0 : m_pLbFormat->SelectEntryPos( 255 != nIndex ? (nDfltStylePos + nIndex) : 0 );
218 0 : SelFmtHdl( 0 );
219 0 : }
220 :
221 0 : void SwAutoFormatDlg::UpdateChecks( const SwTableAutoFmt& rFmt, bool bEnable )
222 : {
223 0 : m_pBtnNumFormat->Enable( bEnable );
224 0 : m_pBtnNumFormat->Check( rFmt.IsValueFormat() );
225 :
226 0 : m_pBtnBorder->Enable( bEnable );
227 0 : m_pBtnBorder->Check( rFmt.IsFrame() );
228 :
229 0 : m_pBtnFont->Enable( bEnable );
230 0 : m_pBtnFont->Check( rFmt.IsFont() );
231 :
232 0 : m_pBtnPattern->Enable( bEnable );
233 0 : m_pBtnPattern->Check( rFmt.IsBackground() );
234 :
235 0 : m_pBtnAlignment->Enable( bEnable );
236 0 : m_pBtnAlignment->Check( rFmt.IsJustify() );
237 0 : }
238 :
239 0 : void SwAutoFormatDlg::FillAutoFmtOfIndex( SwTableAutoFmt*& rToFill ) const
240 : {
241 0 : if( 255 != nIndex )
242 : {
243 0 : if( rToFill )
244 0 : *rToFill = (*pTableTbl)[ nIndex ];
245 : else
246 0 : rToFill = new SwTableAutoFmt( (*pTableTbl)[ nIndex ] );
247 : }
248 : else
249 0 : delete rToFill, rToFill = 0;
250 0 : }
251 :
252 : // Handler:
253 :
254 0 : IMPL_LINK( SwAutoFormatDlg, CheckHdl, Button *, pBtn )
255 : {
256 0 : SwTableAutoFmt* pData = &(*pTableTbl)[nIndex];
257 0 : bool bCheck = ((CheckBox*)pBtn)->IsChecked(), bDataChgd = true;
258 :
259 0 : if( pBtn == m_pBtnNumFormat )
260 0 : pData->SetValueFormat( bCheck );
261 0 : else if ( pBtn == m_pBtnBorder )
262 0 : pData->SetFrame( bCheck );
263 0 : else if ( pBtn == m_pBtnFont )
264 0 : pData->SetFont( bCheck );
265 0 : else if ( pBtn == m_pBtnPattern )
266 0 : pData->SetBackground( bCheck );
267 0 : else if ( pBtn == m_pBtnAlignment )
268 0 : pData->SetJustify( bCheck );
269 : else
270 0 : bDataChgd = false;
271 :
272 0 : if( bDataChgd )
273 : {
274 0 : if( !bCoreDataChanged )
275 : {
276 0 : m_pBtnCancel->SetText( aStrClose );
277 0 : bCoreDataChanged = true;
278 : }
279 :
280 0 : m_pWndPreview->NotifyChange( *pData );
281 : }
282 0 : return 0;
283 : }
284 :
285 0 : IMPL_LINK_NOARG(SwAutoFormatDlg, AddHdl)
286 : {
287 0 : bool bOk = false, bFmtInserted = false;
288 0 : while( !bOk )
289 : {
290 : boost::scoped_ptr<SwStringInputDlg> pDlg(new SwStringInputDlg( this,
291 : aStrTitle,
292 : aStrLabel,
293 0 : OUString() ));
294 0 : if( RET_OK == pDlg->Execute() )
295 : {
296 0 : const OUString aFormatName( pDlg->GetInputString() );
297 :
298 0 : if ( !aFormatName.isEmpty() )
299 : {
300 : size_t n;
301 0 : for( n = 0; n < pTableTbl->size(); ++n )
302 0 : if( (*pTableTbl)[n].GetName() == aFormatName )
303 0 : break;
304 :
305 0 : if( n >= pTableTbl->size() )
306 : {
307 : // Format with the name does not already exist, so take up.
308 : SwTableAutoFmt* pNewData = new
309 0 : SwTableAutoFmt( aFormatName );
310 0 : pShell->GetTableAutoFmt( *pNewData );
311 :
312 : // Insert sorted!!
313 0 : for( n = 1; n < pTableTbl->size(); ++n )
314 0 : if( (*pTableTbl)[ n ].GetName() > aFormatName )
315 0 : break;
316 :
317 0 : pTableTbl->InsertAutoFmt(n, pNewData);
318 0 : m_pLbFormat->InsertEntry( aFormatName, nDfltStylePos + n );
319 0 : m_pLbFormat->SelectEntryPos( nDfltStylePos + n );
320 0 : bFmtInserted = true;
321 0 : m_pBtnAdd->Enable( false );
322 0 : if ( !bCoreDataChanged )
323 : {
324 0 : m_pBtnCancel->SetText( aStrClose );
325 0 : bCoreDataChanged = true;
326 : }
327 :
328 0 : SelFmtHdl( 0 );
329 0 : bOk = true;
330 : }
331 : }
332 :
333 0 : if( !bFmtInserted )
334 : {
335 : bOk = RET_CANCEL == MessageDialog(this, aStrInvalidFmt, VCL_MESSAGE_ERROR, VCL_BUTTONS_OK_CANCEL)
336 0 : .Execute();
337 0 : }
338 : }
339 : else
340 0 : bOk = true;
341 0 : }
342 0 : return 0;
343 : }
344 :
345 0 : IMPL_LINK_NOARG(SwAutoFormatDlg, RemoveHdl)
346 : {
347 0 : OUString aMessage = aStrDelMsg;
348 0 : aMessage += "\n\n";
349 0 : aMessage += m_pLbFormat->GetSelectEntry();
350 0 : aMessage += "\n";
351 :
352 : boost::scoped_ptr<MessBox> pBox(new MessBox( this, WinBits( WB_OK_CANCEL ),
353 0 : aStrDelTitle, aMessage));
354 :
355 0 : if ( pBox->Execute() == RET_OK )
356 : {
357 0 : m_pLbFormat->RemoveEntry( nDfltStylePos + nIndex );
358 0 : m_pLbFormat->SelectEntryPos( nDfltStylePos + nIndex-1 );
359 :
360 0 : pTableTbl->EraseAutoFmt(nIndex);
361 0 : nIndex--;
362 :
363 0 : if( !nIndex )
364 : {
365 0 : m_pBtnRemove->Enable(false);
366 0 : m_pBtnRename->Enable(false);
367 : }
368 :
369 0 : if( !bCoreDataChanged )
370 : {
371 0 : m_pBtnCancel->SetText( aStrClose );
372 0 : bCoreDataChanged = true;
373 : }
374 : }
375 0 : pBox.reset();
376 :
377 0 : SelFmtHdl( 0 );
378 :
379 0 : return 0;
380 : }
381 :
382 0 : IMPL_LINK_NOARG(SwAutoFormatDlg, RenameHdl)
383 : {
384 0 : bool bOk = false;
385 0 : while( !bOk )
386 : {
387 : boost::scoped_ptr<SwStringInputDlg> pDlg(new SwStringInputDlg( this,
388 : aStrRenameTitle,
389 : m_pLbFormat->GetSelectEntry(),
390 0 : OUString() ));
391 0 : if( pDlg->Execute() == RET_OK )
392 : {
393 0 : bool bFmtRenamed = false;
394 0 : const OUString aFormatName( pDlg->GetInputString() );
395 :
396 0 : if ( !aFormatName.isEmpty() )
397 : {
398 : size_t n;
399 0 : for( n = 0; n < pTableTbl->size(); ++n )
400 0 : if ((*pTableTbl)[n].GetName() == aFormatName)
401 0 : break;
402 :
403 0 : if( n >= pTableTbl->size() )
404 : {
405 : // no format with this name exists, so rename it
406 0 : m_pLbFormat->RemoveEntry( nDfltStylePos + nIndex );
407 0 : SwTableAutoFmt* p = pTableTbl->ReleaseAutoFmt( nIndex );
408 :
409 0 : p->SetName( aFormatName );
410 :
411 : // keep all arrays sorted!
412 0 : for( n = 1; n < pTableTbl->size(); ++n )
413 0 : if ((*pTableTbl)[n].GetName() > aFormatName)
414 : {
415 0 : break;
416 : }
417 :
418 0 : pTableTbl->InsertAutoFmt( n, p );
419 0 : m_pLbFormat->InsertEntry( aFormatName, nDfltStylePos + n );
420 0 : m_pLbFormat->SelectEntryPos( nDfltStylePos + n );
421 :
422 0 : if ( !bCoreDataChanged )
423 : {
424 0 : m_pBtnCancel->SetText( aStrClose );
425 0 : bCoreDataChanged = true;
426 : }
427 :
428 0 : SelFmtHdl( 0 );
429 0 : bOk = true;
430 0 : bFmtRenamed = true;
431 : }
432 : }
433 :
434 0 : if( !bFmtRenamed )
435 : {
436 : bOk = RET_CANCEL == MessageDialog(this, aStrInvalidFmt, VCL_MESSAGE_ERROR, VCL_BUTTONS_OK_CANCEL)
437 0 : .Execute();
438 0 : }
439 : }
440 : else
441 0 : bOk = true;
442 0 : }
443 0 : return 0;
444 : }
445 :
446 0 : IMPL_LINK_NOARG(SwAutoFormatDlg, SelFmtHdl)
447 : {
448 0 : bool bBtnEnable = false;
449 0 : sal_uInt8 nSelPos = (sal_uInt8) m_pLbFormat->GetSelectEntryPos(), nOldIdx = nIndex;
450 0 : if( nSelPos >= nDfltStylePos )
451 : {
452 0 : nIndex = nSelPos - nDfltStylePos;
453 0 : m_pWndPreview->NotifyChange( (*pTableTbl)[nIndex] );
454 0 : bBtnEnable = 0 != nIndex;
455 0 : UpdateChecks( (*pTableTbl)[nIndex], true );
456 : }
457 : else
458 : {
459 0 : nIndex = 255;
460 :
461 0 : SwTableAutoFmt aTmp( SwViewShell::GetShellRes()->aStrNone );
462 0 : aTmp.SetFont( false );
463 0 : aTmp.SetJustify( false );
464 0 : aTmp.SetFrame( false );
465 0 : aTmp.SetBackground( false );
466 0 : aTmp.SetValueFormat( false );
467 0 : aTmp.SetWidthHeight( false );
468 :
469 0 : if( nOldIdx != nIndex )
470 0 : m_pWndPreview->NotifyChange( aTmp );
471 0 : UpdateChecks( aTmp, false );
472 : }
473 :
474 0 : m_pBtnRemove->Enable( bBtnEnable );
475 0 : m_pBtnRename->Enable( bBtnEnable );
476 :
477 0 : return 0;
478 : }
479 :
480 0 : IMPL_LINK_NOARG_INLINE_START(SwAutoFormatDlg, OkHdl)
481 : {
482 0 : if( bSetAutoFmt )
483 0 : pShell->SetTableAutoFmt( (*pTableTbl)[ nIndex ] );
484 0 : EndDialog( RET_OK );
485 0 : return sal_True;
486 : }
487 0 : IMPL_LINK_NOARG_INLINE_END(SwAutoFormatDlg, OkHdl)
488 :
489 0 : AutoFmtPreview::AutoFmtPreview(vcl::Window* pParent) :
490 : Window ( pParent ),
491 : aCurData ( OUString() ),
492 : aVD ( *this ),
493 : aScriptedText ( aVD ),
494 : bFitWidth ( false ),
495 : mbRTL ( false ),
496 : aStrJan ( SW_RES( STR_JAN ) ),
497 : aStrFeb ( SW_RES( STR_FEB ) ),
498 : aStrMar ( SW_RES( STR_MAR ) ),
499 : aStrNorth ( SW_RES( STR_NORTH ) ),
500 : aStrMid ( SW_RES( STR_MID ) ),
501 : aStrSouth ( SW_RES( STR_SOUTH ) ),
502 0 : aStrSum ( SW_RES( STR_SUM ) )
503 : {
504 0 : uno::Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext();
505 0 : m_xBreak = i18n::BreakIterator::create(xContext);
506 0 : pNumFmt = new SvNumberFormatter( xContext, LANGUAGE_SYSTEM );
507 :
508 0 : Init();
509 0 : }
510 :
511 0 : extern "C" SAL_DLLPUBLIC_EXPORT vcl::Window* SAL_CALL makeAutoFmtPreview(vcl::Window *pParent, VclBuilder::stringmap &)
512 : {
513 0 : return new AutoFmtPreview(pParent);
514 : }
515 :
516 0 : void AutoFmtPreview::Resize()
517 : {
518 0 : aPrvSize = Size(GetSizePixel().Width() - 6, GetSizePixel().Height() - 30);
519 0 : nLabelColWidth = (aPrvSize.Width() - 4) / 4 - 12;
520 0 : nDataColWidth1 = (aPrvSize.Width() - 4 - 2 * nLabelColWidth) / 3;
521 0 : nDataColWidth2 = (aPrvSize.Width() - 4 - 2 * nLabelColWidth) / 4;
522 0 : nRowHeight = (aPrvSize.Height() - 4) / 5;
523 0 : NotifyChange(aCurData);
524 0 : }
525 :
526 0 : void AutoFmtPreview::DetectRTL(SwWrtShell* pWrtShell)
527 : {
528 0 : if (!pWrtShell->IsCrsrInTbl()) // We haven't created the table yet
529 0 : mbRTL = Application::GetSettings().GetLayoutRTL();
530 : else
531 0 : mbRTL = pWrtShell->IsTableRightToLeft();
532 0 : }
533 :
534 0 : AutoFmtPreview::~AutoFmtPreview()
535 : {
536 0 : delete pNumFmt;
537 0 : }
538 :
539 0 : static void lcl_SetFontProperties(
540 : vcl::Font& rFont,
541 : const SvxFontItem& rFontItem,
542 : const SvxWeightItem& rWeightItem,
543 : const SvxPostureItem& rPostureItem )
544 : {
545 0 : rFont.SetFamily ( rFontItem.GetFamily() );
546 0 : rFont.SetName ( rFontItem.GetFamilyName() );
547 0 : rFont.SetStyleName ( rFontItem.GetStyleName() );
548 0 : rFont.SetCharSet ( rFontItem.GetCharSet() );
549 0 : rFont.SetPitch ( rFontItem.GetPitch() );
550 0 : rFont.SetWeight ( (FontWeight)rWeightItem.GetValue() );
551 0 : rFont.SetItalic ( (FontItalic)rPostureItem.GetValue() );
552 0 : }
553 :
554 : #define SETONALLFONTS( MethodName, Value ) \
555 : rFont.MethodName( Value ); \
556 : rCJKFont.MethodName( Value ); \
557 : rCTLFont.MethodName( Value );
558 :
559 0 : void AutoFmtPreview::MakeFonts( sal_uInt8 nIndex, vcl::Font& rFont, vcl::Font& rCJKFont, vcl::Font& rCTLFont )
560 : {
561 0 : const SwBoxAutoFmt& rBoxFmt = aCurData.GetBoxFmt( nIndex );
562 :
563 0 : rFont = rCJKFont = rCTLFont = GetFont();
564 0 : Size aFontSize( rFont.GetSize().Width(), 10 * GetDPIScaleFactor() );
565 :
566 0 : lcl_SetFontProperties( rFont, rBoxFmt.GetFont(), rBoxFmt.GetWeight(), rBoxFmt.GetPosture() );
567 0 : lcl_SetFontProperties( rCJKFont, rBoxFmt.GetCJKFont(), rBoxFmt.GetCJKWeight(), rBoxFmt.GetCJKPosture() );
568 0 : lcl_SetFontProperties( rCTLFont, rBoxFmt.GetCTLFont(), rBoxFmt.GetCTLWeight(), rBoxFmt.GetCTLPosture() );
569 :
570 0 : SETONALLFONTS( SetUnderline, (FontUnderline)rBoxFmt.GetUnderline().GetValue() );
571 0 : SETONALLFONTS( SetOverline, (FontUnderline)rBoxFmt.GetOverline().GetValue() );
572 0 : SETONALLFONTS( SetStrikeout, (FontStrikeout)rBoxFmt.GetCrossedOut().GetValue() );
573 0 : SETONALLFONTS( SetOutline, rBoxFmt.GetContour().GetValue() );
574 0 : SETONALLFONTS( SetShadow, rBoxFmt.GetShadowed().GetValue() );
575 0 : SETONALLFONTS( SetColor, rBoxFmt.GetColor().GetValue() );
576 0 : SETONALLFONTS( SetSize, aFontSize );
577 0 : SETONALLFONTS( SetTransparent, true );
578 0 : }
579 :
580 0 : sal_uInt8 AutoFmtPreview::GetFormatIndex( size_t nCol, size_t nRow ) const
581 : {
582 : static const sal_uInt8 pnFmtMap[] =
583 : {
584 : 0, 1, 2, 1, 3,
585 : 4, 5, 6, 5, 7,
586 : 8, 9, 10, 9, 11,
587 : 4, 5, 6, 5, 7,
588 : 12, 13, 14, 13, 15
589 : };
590 0 : return pnFmtMap[ maArray.GetCellIndex( nCol, nRow, mbRTL ) ];
591 : }
592 :
593 0 : const SvxBoxItem& AutoFmtPreview::GetBoxItem( size_t nCol, size_t nRow ) const
594 : {
595 0 : return aCurData.GetBoxFmt( GetFormatIndex( nCol, nRow ) ).GetBox();
596 : }
597 :
598 0 : void AutoFmtPreview::DrawString( size_t nCol, size_t nRow )
599 : {
600 : // Output of the cell text:
601 : sal_uLong nNum;
602 : double nVal;
603 0 : OUString cellString;
604 0 : sal_uInt8 nIndex = static_cast< sal_uInt8 >( maArray.GetCellIndex( nCol, nRow, mbRTL ) );
605 :
606 0 : switch( nIndex )
607 : {
608 0 : case 1: cellString = aStrJan; break;
609 0 : case 2: cellString = aStrFeb; break;
610 0 : case 3: cellString = aStrMar; break;
611 0 : case 5: cellString = aStrNorth; break;
612 0 : case 10: cellString = aStrMid; break;
613 0 : case 15: cellString = aStrSouth; break;
614 : case 4:
615 0 : case 20: cellString = aStrSum; break;
616 :
617 : case 6:
618 : case 8:
619 : case 16:
620 0 : case 18: nVal = nIndex;
621 0 : nNum = 5;
622 0 : goto MAKENUMSTR;
623 : case 17:
624 0 : case 7: nVal = nIndex;
625 0 : nNum = 6;
626 0 : goto MAKENUMSTR;
627 : case 11:
628 : case 12:
629 0 : case 13: nVal = nIndex;
630 0 : nNum = 12 == nIndex ? 10 : 9;
631 0 : goto MAKENUMSTR;
632 :
633 0 : case 9: nVal = 21; nNum = 7; goto MAKENUMSTR;
634 0 : case 14: nVal = 36; nNum = 11; goto MAKENUMSTR;
635 0 : case 19: nVal = 51; nNum = 7; goto MAKENUMSTR;
636 0 : case 21: nVal = 33; nNum = 13; goto MAKENUMSTR;
637 0 : case 22: nVal = 36; nNum = 14; goto MAKENUMSTR;
638 0 : case 23: nVal = 39; nNum = 13; goto MAKENUMSTR;
639 0 : case 24: nVal = 108; nNum = 15; goto MAKENUMSTR;
640 : MAKENUMSTR:
641 0 : if( aCurData.IsValueFormat() )
642 : {
643 0 : OUString sFmt;
644 : LanguageType eLng, eSys;
645 0 : aCurData.GetBoxFmt( (sal_uInt8)nNum ).GetValueFormat( sFmt, eLng, eSys );
646 :
647 : short nType;
648 : bool bNew;
649 : sal_Int32 nCheckPos;
650 : sal_uInt32 nKey = pNumFmt->GetIndexPuttingAndConverting( sFmt, eLng,
651 0 : eSys, nType, bNew, nCheckPos);
652 : Color* pDummy;
653 0 : pNumFmt->GetOutputString( nVal, nKey, cellString, &pDummy );
654 : }
655 : else
656 0 : cellString = OUString::number((sal_Int32)nVal);
657 0 : break;
658 :
659 : }
660 :
661 0 : if( !cellString.isEmpty() )
662 : {
663 0 : Size aStrSize;
664 0 : sal_uInt8 nFmtIndex = GetFormatIndex( nCol, nRow );
665 0 : Rectangle cellRect = maArray.GetCellRect( nCol, nRow );
666 0 : Point aPos = cellRect.TopLeft();
667 0 : long nRightX = 0;
668 :
669 0 : Size theMaxStrSize( cellRect.GetWidth() - FRAME_OFFSET,
670 0 : cellRect.GetHeight() - FRAME_OFFSET );
671 0 : if( aCurData.IsFont() )
672 : {
673 0 : vcl::Font aFont, aCJKFont, aCTLFont;
674 0 : MakeFonts( nFmtIndex, aFont, aCJKFont, aCTLFont );
675 0 : aScriptedText.SetFonts( &aFont, &aCJKFont, &aCTLFont );
676 : }
677 : else
678 0 : aScriptedText.SetDefaultFont();
679 :
680 0 : aScriptedText.SetText( cellString, m_xBreak );
681 0 : aStrSize = aScriptedText.GetTextSize();
682 :
683 0 : if( aCurData.IsFont() &&
684 0 : theMaxStrSize.Height() < aStrSize.Height() )
685 : {
686 : // If the string in this font does not
687 : // fit into the cell, the standard font
688 : // is taken again:
689 0 : aScriptedText.SetDefaultFont();
690 0 : aStrSize = aScriptedText.GetTextSize();
691 : }
692 :
693 0 : while( theMaxStrSize.Width() <= aStrSize.Width() &&
694 0 : cellString.getLength() > 1 )
695 : {
696 0 : cellString = cellString.copy(0, cellString.getLength() - 1 );
697 0 : aScriptedText.SetText( cellString, m_xBreak );
698 0 : aStrSize = aScriptedText.GetTextSize();
699 : }
700 :
701 0 : nRightX = cellRect.GetWidth() - aStrSize.Width() - FRAME_OFFSET;
702 :
703 : // vertical (always centering):
704 0 : aPos.Y() += (nRowHeight - aStrSize.Height()) / 2;
705 :
706 : // horizontal
707 0 : if( mbRTL )
708 0 : aPos.X() += nRightX;
709 0 : else if (aCurData.IsJustify())
710 : {
711 0 : const SvxAdjustItem& rAdj = aCurData.GetBoxFmt(nFmtIndex).GetAdjust();
712 0 : switch ( rAdj.GetAdjust() )
713 : {
714 : case SVX_ADJUST_LEFT:
715 0 : aPos.X() += FRAME_OFFSET;
716 0 : break;
717 : case SVX_ADJUST_RIGHT:
718 0 : aPos.X() += nRightX;
719 0 : break;
720 : default:
721 0 : aPos.X() += (cellRect.GetWidth() - aStrSize.Width())/2;
722 0 : break;
723 : }
724 : }
725 : else
726 : {
727 : // Standard align:
728 0 : if ( (nCol == 0) || (nIndex == 4) )
729 : {
730 : // Text-Label left or sum left aligned
731 0 : aPos.X() += FRAME_OFFSET;
732 : }
733 : else
734 : {
735 : // numbers/dates right aligned
736 0 : aPos.X() += nRightX;
737 : }
738 : }
739 :
740 0 : aScriptedText.DrawText( aPos );
741 0 : }
742 0 : }
743 :
744 : #undef FRAME_OFFSET
745 :
746 0 : void AutoFmtPreview::DrawStrings()
747 : {
748 0 : for( size_t nRow = 0; nRow < 5; ++nRow )
749 0 : for( size_t nCol = 0; nCol < 5; ++nCol )
750 0 : DrawString( nCol, nRow );
751 0 : }
752 :
753 0 : void AutoFmtPreview::DrawBackground()
754 : {
755 0 : for( size_t nRow = 0; nRow < 5; ++nRow )
756 : {
757 0 : for( size_t nCol = 0; nCol < 5; ++nCol )
758 : {
759 0 : SvxBrushItem aBrushItem( aCurData.GetBoxFmt( GetFormatIndex( nCol, nRow ) ).GetBackground() );
760 :
761 0 : aVD.Push( PushFlags::LINECOLOR | PushFlags::FILLCOLOR );
762 0 : aVD.SetLineColor();
763 0 : aVD.SetFillColor( aBrushItem.GetColor() );
764 0 : aVD.DrawRect( maArray.GetCellRect( nCol, nRow ) );
765 0 : aVD.Pop();
766 0 : }
767 : }
768 0 : }
769 :
770 0 : void AutoFmtPreview::PaintCells()
771 : {
772 : // 1) background
773 0 : if ( aCurData.IsBackground() )
774 0 : DrawBackground();
775 :
776 : // 2) values
777 0 : DrawStrings();
778 :
779 : // 3) border
780 0 : if ( aCurData.IsFrame() )
781 0 : maArray.DrawArray( aVD );
782 0 : }
783 :
784 0 : void AutoFmtPreview::Init()
785 : {
786 0 : SetBorderStyle( GetBorderStyle() | WindowBorderStyle::MONO );
787 0 : maArray.Initialize( 5, 5 );
788 0 : maArray.SetUseDiagDoubleClipping( false );
789 0 : CalcCellArray( false );
790 0 : CalcLineMap();
791 0 : }
792 :
793 0 : void AutoFmtPreview::CalcCellArray( bool _bFitWidth )
794 : {
795 0 : maArray.SetXOffset( 2 );
796 0 : maArray.SetAllColWidths( _bFitWidth ? nDataColWidth2 : nDataColWidth1 );
797 0 : maArray.SetColWidth( 0, nLabelColWidth );
798 0 : maArray.SetColWidth( 4, nLabelColWidth );
799 :
800 0 : maArray.SetYOffset( 2 );
801 0 : maArray.SetAllRowHeights( nRowHeight );
802 :
803 0 : aPrvSize.Width() = maArray.GetWidth() + 4;
804 0 : aPrvSize.Height() = maArray.GetHeight() + 4;
805 0 : }
806 :
807 0 : inline void lclSetStyleFromBorder( svx::frame::Style& rStyle, const ::editeng::SvxBorderLine* pBorder )
808 : {
809 0 : rStyle.Set( pBorder, 0.05, 5 );
810 0 : }
811 :
812 0 : void AutoFmtPreview::CalcLineMap()
813 : {
814 0 : for( size_t nRow = 0; nRow < 5; ++nRow )
815 : {
816 0 : for( size_t nCol = 0; nCol < 5; ++nCol )
817 : {
818 0 : svx::frame::Style aStyle;
819 :
820 0 : const SvxBoxItem& rItem = GetBoxItem( nCol, nRow );
821 0 : lclSetStyleFromBorder( aStyle, rItem.GetLeft() );
822 0 : maArray.SetCellStyleLeft( nCol, nRow, aStyle );
823 0 : lclSetStyleFromBorder( aStyle, rItem.GetRight() );
824 0 : maArray.SetCellStyleRight( nCol, nRow, aStyle );
825 0 : lclSetStyleFromBorder( aStyle, rItem.GetTop() );
826 0 : maArray.SetCellStyleTop( nCol, nRow, aStyle );
827 0 : lclSetStyleFromBorder( aStyle, rItem.GetBottom() );
828 0 : maArray.SetCellStyleBottom( nCol, nRow, aStyle );
829 :
830 : // FIXME - uncomment to draw diagonal borders
831 : // lclSetStyleFromBorder( aStyle, GetDiagItem( nCol, nRow, true ).GetLine() );
832 : // maArray.SetCellStyleTLBR( nCol, nRow, aStyle );
833 : // lclSetStyleFromBorder( aStyle, GetDiagItem( nCol, nRow, false ).GetLine() );
834 : // maArray.SetCellStyleBLTR( nCol, nRow, aStyle );
835 : }
836 : }
837 0 : }
838 :
839 0 : void AutoFmtPreview::NotifyChange( const SwTableAutoFmt& rNewData )
840 : {
841 0 : aCurData = rNewData;
842 0 : bFitWidth = aCurData.IsJustify();//sal_True; //???
843 0 : CalcCellArray( bFitWidth );
844 0 : CalcLineMap();
845 0 : DoPaint( Rectangle( Point(0,0), GetSizePixel() ) );
846 0 : }
847 :
848 0 : void AutoFmtPreview::DoPaint( const Rectangle& /*rRect*/ )
849 : {
850 0 : sal_uInt32 nOldDrawMode = aVD.GetDrawMode();
851 0 : if( GetSettings().GetStyleSettings().GetHighContrastMode() )
852 0 : aVD.SetDrawMode( DRAWMODE_SETTINGSLINE | DRAWMODE_SETTINGSFILL | DRAWMODE_SETTINGSTEXT | DRAWMODE_SETTINGSGRADIENT );
853 :
854 0 : Bitmap thePreview;
855 0 : Point aCenterPos;
856 0 : Size theWndSize = GetSizePixel();
857 0 : Color oldColor;
858 0 : vcl::Font aFont;
859 :
860 0 : aFont = aVD.GetFont();
861 0 : aFont.SetTransparent( true );
862 :
863 0 : aVD.SetFont ( aFont );
864 0 : aVD.SetLineColor ();
865 0 : const Color& rWinColor = GetSettings().GetStyleSettings().GetWindowColor();
866 0 : aVD.SetBackground ( Wallpaper(rWinColor) );
867 0 : aVD.SetFillColor ( rWinColor );
868 0 : aVD.SetOutputSizePixel ( aPrvSize );
869 :
870 : // Draw cells on virtual device
871 : // and save the result
872 0 : PaintCells();
873 0 : thePreview = aVD.GetBitmap( Point(0,0), aPrvSize );
874 :
875 : // Draw the Frame and center the preview:
876 : // (virtual Device for window output)
877 0 : aVD.SetOutputSizePixel( theWndSize );
878 0 : oldColor = aVD.GetLineColor();
879 0 : aVD.SetLineColor();
880 0 : aVD.DrawRect( Rectangle( Point(0,0), theWndSize ) );
881 0 : SetLineColor( oldColor );
882 0 : aCenterPos = Point( (theWndSize.Width() - aPrvSize.Width() ) / 2,
883 0 : (theWndSize.Height() - aPrvSize.Height()) / 2 );
884 0 : aVD.DrawBitmap( aCenterPos, thePreview );
885 :
886 : // Output in the preview window:
887 0 : DrawBitmap( Point(0,0), aVD.GetBitmap( Point(0,0), theWndSize ) );
888 :
889 0 : aVD.SetDrawMode( nOldDrawMode );
890 0 : }
891 :
892 0 : void AutoFmtPreview::Paint( const Rectangle& rRect )
893 : {
894 0 : DoPaint( rRect );
895 0 : }
896 :
897 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|