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