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 :
21 : #include "sddll.hxx"
22 :
23 : #include <com/sun/star/beans/XMultiPropertyStates.hpp>
24 : #include <com/sun/star/frame/XController.hpp>
25 : #include <com/sun/star/view/XSelectionSupplier.hpp>
26 : #include <com/sun/star/style/XStyle.hpp>
27 : #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
28 :
29 : #include <comphelper/processfactory.hxx>
30 : #include <sfx2/viewfrm.hxx>
31 : #include <vcl/bmpacc.hxx>
32 : #include <vcl/layout.hxx>
33 : #include <vcl/settings.hxx>
34 :
35 : #include <svl/style.hxx>
36 : #include <sfx2/bindings.hxx>
37 : #include <sfx2/app.hxx>
38 : #include <sfx2/request.hxx>
39 : #include <sfx2/dispatch.hxx>
40 : #include <svx/svxids.hrc>
41 : #include <svx/svdetc.hxx>
42 : #include <editeng/boxitem.hxx>
43 : #include <editeng/borderline.hxx>
44 : #include <editeng/colritem.hxx>
45 : #include <editeng/eeitem.hxx>
46 : #include <svx/sdr/table/tabledesign.hxx>
47 :
48 : #include "TableDesignPane.hxx"
49 :
50 : #include "DrawDocShell.hxx"
51 : #include "ViewShellBase.hxx"
52 : #include "DrawViewShell.hxx"
53 : #include "DrawController.hxx"
54 : #include "glob.hrc"
55 : #include "sdresid.hxx"
56 : #include "EventMultiplexer.hxx"
57 :
58 : using namespace ::com::sun::star;
59 : using namespace ::com::sun::star::uno;
60 : using namespace ::com::sun::star::drawing;
61 : using namespace ::com::sun::star::container;
62 : using namespace ::com::sun::star::beans;
63 : using namespace ::com::sun::star::view;
64 : using namespace ::com::sun::star::style;
65 : using namespace ::com::sun::star::frame;
66 : using namespace ::com::sun::star::lang;
67 : using namespace ::com::sun::star::ui;
68 :
69 : namespace sd {
70 :
71 : static const sal_Int32 nPreviewColumns = 5;
72 : static const sal_Int32 nPreviewRows = 5;
73 : static const sal_Int32 nCellWidth = 12; // one pixel is shared with the next cell!
74 : static const sal_Int32 nCellHeight = 7; // one pixel is shared with the next cell!
75 : static const sal_Int32 nBitmapWidth = (nCellWidth * nPreviewColumns) - (nPreviewColumns - 1);
76 : static const sal_Int32 nBitmapHeight = (nCellHeight * nPreviewRows) - (nPreviewRows - 1);
77 :
78 :
79 :
80 :
81 0 : static const OUString* getPropertyNames()
82 : {
83 : static const OUString gPropNames[ CB_COUNT ] =
84 : {
85 : OUString("UseFirstRowStyle") ,
86 : OUString("UseLastRowStyle") ,
87 : OUString("UseBandingRowStyle") ,
88 : OUString("UseFirstColumnStyle") ,
89 : OUString("UseLastColumnStyle") ,
90 : OUString("UseBandingColumnStyle")
91 0 : };
92 0 : return &gPropNames[0];
93 : }
94 :
95 :
96 0 : TableDesignWidget::TableDesignWidget( VclBuilderContainer* pParent, ViewShellBase& rBase, bool bModal )
97 : : mrBase(rBase)
98 : , msTableTemplate("TableTemplate")
99 : , mbModal(bModal)
100 : , mbStyleSelected(false)
101 0 : , mbOptionsChanged(false)
102 : {
103 0 : pParent->get(m_pValueSet, "previews");
104 0 : m_pValueSet->SetStyle(m_pValueSet->GetStyle() | WB_NO_DIRECTSELECT | WB_FLATVALUESET | WB_ITEMBORDER);
105 0 : m_pValueSet->SetExtraSpacing(8);
106 0 : m_pValueSet->setModal(mbModal);
107 0 : if( !mbModal )
108 : {
109 0 : m_pValueSet->SetColor();
110 : }
111 : else
112 : {
113 0 : m_pValueSet->SetColor( Color( COL_WHITE ) );
114 0 : m_pValueSet->SetBackground( Color( COL_WHITE ) );
115 : }
116 0 : m_pValueSet->SetSelectHdl (LINK(this, TableDesignWidget, implValueSetHdl));
117 :
118 0 : const OUString* pPropNames = getPropertyNames();
119 0 : for (sal_uInt16 i = CB_HEADER_ROW; i <= CB_BANDED_COLUMNS; ++i)
120 : {
121 0 : pParent->get(m_aCheckBoxes[i], OUStringToOString(pPropNames[i], RTL_TEXTENCODING_UTF8));
122 0 : m_aCheckBoxes[i]->SetClickHdl( LINK( this, TableDesignWidget, implCheckBoxHdl ) );
123 : }
124 :
125 : // get current controller and initialize listeners
126 : try
127 : {
128 0 : mxView = Reference< XDrawView >::query(mrBase.GetController());
129 0 : addListener();
130 :
131 0 : Reference< XController > xController( mrBase.GetController(), UNO_QUERY_THROW );
132 0 : Reference< XStyleFamiliesSupplier > xFamiliesSupp( xController->getModel(), UNO_QUERY_THROW );
133 0 : Reference< XNameAccess > xFamilies( xFamiliesSupp->getStyleFamilies() );
134 0 : const OUString sFamilyName( "table" );
135 0 : mxTableFamily = Reference< XIndexAccess >( xFamilies->getByName( sFamilyName ), UNO_QUERY_THROW );
136 : }
137 0 : catch (const Exception&)
138 : {
139 : OSL_FAIL( "sd::CustomAnimationPane::CustomAnimationPane(), Exception caught!" );
140 : }
141 :
142 0 : onSelectionChanged();
143 0 : updateControls();
144 0 : }
145 :
146 :
147 :
148 0 : TableDesignWidget::~TableDesignWidget()
149 : {
150 0 : removeListener();
151 0 : }
152 :
153 :
154 :
155 0 : static SfxBindings* getBindings( ViewShellBase& rBase )
156 : {
157 0 : if( rBase.GetMainViewShell().get() && rBase.GetMainViewShell()->GetViewFrame() )
158 0 : return &rBase.GetMainViewShell()->GetViewFrame()->GetBindings();
159 : else
160 0 : return 0;
161 : }
162 :
163 :
164 :
165 0 : static SfxDispatcher* getDispatcher( ViewShellBase& rBase )
166 : {
167 0 : if( rBase.GetMainViewShell().get() && rBase.GetMainViewShell()->GetViewFrame() )
168 0 : return rBase.GetMainViewShell()->GetViewFrame()->GetDispatcher();
169 : else
170 0 : return 0;
171 : }
172 :
173 :
174 :
175 0 : IMPL_LINK_NOARG(TableDesignWidget, implValueSetHdl)
176 : {
177 0 : mbStyleSelected = true;
178 0 : if( !mbModal )
179 0 : ApplyStyle();
180 0 : return 0;
181 : }
182 :
183 :
184 :
185 0 : void TableDesignWidget::ApplyStyle()
186 : {
187 : try
188 : {
189 0 : OUString sStyleName;
190 0 : sal_Int32 nIndex = static_cast< sal_Int32 >( m_pValueSet->GetSelectItemId() ) - 1;
191 :
192 0 : if( (nIndex >= 0) && (nIndex < mxTableFamily->getCount()) )
193 : {
194 0 : Reference< XNameAccess > xNames( mxTableFamily, UNO_QUERY_THROW );
195 0 : sStyleName = xNames->getElementNames()[nIndex];
196 : }
197 :
198 0 : if( sStyleName.isEmpty() )
199 0 : return;
200 :
201 0 : SdrView* pView = mrBase.GetDrawView();
202 0 : if( mxSelectedTable.is() )
203 : {
204 0 : if( pView )
205 : {
206 0 : SfxRequest aReq( SID_TABLE_STYLE, SFX_CALLMODE_SYNCHRON, SFX_APP()->GetPool() );
207 0 : aReq.AppendItem( SfxStringItem( SID_TABLE_STYLE, sStyleName ) );
208 :
209 0 : rtl::Reference< sdr::SelectionController > xController( pView->getSelectionController() );
210 0 : if( xController.is() )
211 0 : xController->Execute( aReq );
212 :
213 0 : SfxBindings* pBindings = getBindings( mrBase );
214 0 : if( pBindings )
215 : {
216 0 : pBindings->Invalidate( SID_UNDO );
217 0 : pBindings->Invalidate( SID_REDO );
218 0 : }
219 : }
220 : }
221 : else
222 : {
223 0 : SfxDispatcher* pDispatcher = getDispatcher( mrBase );
224 0 : SfxStringItem aArg( SID_TABLE_STYLE, sStyleName );
225 0 : pDispatcher->Execute(SID_INSERT_TABLE, SFX_CALLMODE_ASYNCHRON, &aArg, 0 );
226 0 : }
227 : }
228 0 : catch( Exception& )
229 : {
230 : OSL_FAIL("TableDesignWidget::implValueSetHdl(), exception caught!");
231 : }
232 : }
233 :
234 :
235 :
236 0 : IMPL_LINK_NOARG(TableDesignWidget, implCheckBoxHdl)
237 : {
238 0 : mbOptionsChanged = true;
239 :
240 0 : if( !mbModal )
241 0 : ApplyOptions();
242 :
243 0 : FillDesignPreviewControl();
244 0 : return 0;
245 : }
246 :
247 :
248 :
249 0 : void TableDesignWidget::ApplyOptions()
250 : {
251 : static const sal_uInt16 gParamIds[CB_COUNT] =
252 : {
253 : ID_VAL_USEFIRSTROWSTYLE, ID_VAL_USELASTROWSTYLE, ID_VAL_USEBANDINGROWSTYLE,
254 : ID_VAL_USEFIRSTCOLUMNSTYLE, ID_VAL_USELASTCOLUMNSTYLE, ID_VAL_USEBANDINGCOLUMNSTYLE
255 : };
256 :
257 0 : if( mxSelectedTable.is() )
258 : {
259 0 : SfxRequest aReq( SID_TABLE_STYLE_SETTINGS, SFX_CALLMODE_SYNCHRON, SFX_APP()->GetPool() );
260 :
261 0 : for( sal_uInt16 i = CB_HEADER_ROW; i <= CB_BANDED_COLUMNS; ++i )
262 : {
263 0 : aReq.AppendItem( SfxBoolItem( gParamIds[i], m_aCheckBoxes[i]->IsChecked() ) );
264 : }
265 :
266 0 : SdrView* pView = mrBase.GetDrawView();
267 0 : if( pView )
268 : {
269 0 : rtl::Reference< sdr::SelectionController > xController( pView->getSelectionController() );
270 0 : if( xController.is() )
271 : {
272 0 : xController->Execute( aReq );
273 :
274 0 : SfxBindings* pBindings = getBindings( mrBase );
275 0 : if( pBindings )
276 : {
277 0 : pBindings->Invalidate( SID_UNDO );
278 0 : pBindings->Invalidate( SID_REDO );
279 : }
280 0 : }
281 0 : }
282 : }
283 0 : }
284 :
285 :
286 :
287 0 : void TableDesignWidget::onSelectionChanged()
288 : {
289 0 : Reference< XPropertySet > xNewSelection;
290 :
291 0 : if( mxView.is() ) try
292 : {
293 0 : Reference< XSelectionSupplier > xSel( mxView, UNO_QUERY_THROW );
294 0 : if (xSel.is())
295 : {
296 0 : Any aSel( xSel->getSelection() );
297 0 : Sequence< XShape > xShapeSeq;
298 0 : if( aSel >>= xShapeSeq )
299 : {
300 0 : if( xShapeSeq.getLength() == 1 )
301 0 : aSel <<= xShapeSeq[0];
302 : }
303 : else
304 : {
305 0 : Reference< XShapes > xShapes( aSel, UNO_QUERY );
306 0 : if( xShapes.is() && (xShapes->getCount() == 1) )
307 0 : aSel <<= xShapes->getByIndex(0);
308 : }
309 :
310 0 : Reference< XShapeDescriptor > xDesc( aSel, UNO_QUERY );
311 0 : if( xDesc.is() && ( xDesc->getShapeType() == "com.sun.star.drawing.TableShape" || xDesc->getShapeType() == "com.sun.star.presentation.TableShape" ) )
312 : {
313 0 : xNewSelection = Reference< XPropertySet >::query( xDesc );
314 0 : }
315 0 : }
316 : }
317 0 : catch( Exception& )
318 : {
319 : OSL_FAIL( "sd::TableDesignWidget::onSelectionChanged(), Exception caught!" );
320 : }
321 :
322 0 : if( mxSelectedTable != xNewSelection )
323 : {
324 0 : mxSelectedTable = xNewSelection;
325 0 : updateControls();
326 0 : }
327 0 : }
328 :
329 :
330 :
331 0 : void TableValueSet::Resize()
332 : {
333 0 : ValueSet::Resize();
334 : // Calculate the number of rows and columns.
335 0 : if( GetItemCount() > 0 )
336 : {
337 0 : Size aValueSetSize = GetSizePixel();
338 :
339 0 : Image aImage = GetItemImage(GetItemId(0));
340 0 : Size aItemSize = aImage.GetSizePixel();
341 :
342 0 : aItemSize.Width() += 10;
343 0 : aItemSize.Height() += 10;
344 0 : int nColumnCount = (aValueSetSize.Width() - GetScrollWidth()) / aItemSize.Width();
345 0 : if (nColumnCount < 1)
346 0 : nColumnCount = 1;
347 :
348 0 : int nRowCount = (GetItemCount() + nColumnCount - 1) / nColumnCount;
349 0 : if (nRowCount < 1)
350 0 : nRowCount = 1;
351 :
352 0 : int nVisibleRowCount = (aValueSetSize.Height()+2) / aItemSize.Height();
353 :
354 0 : SetColCount ((sal_uInt16)nColumnCount);
355 0 : SetLineCount ((sal_uInt16)nRowCount);
356 :
357 0 : if( !m_bModal )
358 : {
359 0 : WinBits nStyle = GetStyle() & ~(WB_VSCROLL);
360 0 : if( nRowCount > nVisibleRowCount )
361 : {
362 0 : nStyle |= WB_VSCROLL;
363 : }
364 0 : SetStyle( nStyle );
365 0 : }
366 : }
367 0 : }
368 :
369 0 : TableValueSet::TableValueSet(Window *pParent, WinBits nStyle)
370 : : ValueSet(pParent, nStyle)
371 0 : , m_bModal(false)
372 : {
373 0 : }
374 :
375 0 : void TableValueSet::DataChanged( const DataChangedEvent& /*rDCEvt*/ )
376 : {
377 0 : updateSettings();
378 0 : }
379 :
380 0 : void TableValueSet::updateSettings()
381 : {
382 0 : if( !m_bModal )
383 : {
384 0 : SetBackground( GetSettings().GetStyleSettings().GetWindowColor() );
385 0 : SetColor( GetSettings().GetStyleSettings().GetWindowColor() );
386 0 : SetExtraSpacing(8);
387 : }
388 0 : }
389 :
390 0 : extern "C" SAL_DLLPUBLIC_EXPORT ::Window* SAL_CALL makeTableValueSet(::Window *pParent, VclBuilder::stringmap &rMap)
391 : {
392 0 : WinBits nWinStyle = WB_TABSTOP;
393 0 : OString sBorder = VclBuilder::extractCustomProperty(rMap);
394 0 : if (!sBorder.isEmpty())
395 0 : nWinStyle |= WB_BORDER;
396 0 : return new TableValueSet(pParent, nWinStyle);
397 : }
398 :
399 :
400 :
401 0 : void TableDesignWidget::updateControls()
402 : {
403 : static const sal_Bool gDefaults[CB_COUNT] = { sal_True, sal_False, sal_True, sal_False, sal_False, sal_False };
404 :
405 0 : const bool bHasTable = mxSelectedTable.is();
406 0 : const OUString* pPropNames = getPropertyNames();
407 :
408 0 : for (sal_uInt16 i = CB_HEADER_ROW; i <= CB_BANDED_COLUMNS; ++i)
409 : {
410 0 : sal_Bool bUse = gDefaults[i];
411 0 : if( bHasTable ) try
412 : {
413 0 : mxSelectedTable->getPropertyValue( *pPropNames++ ) >>= bUse;
414 : }
415 0 : catch( Exception& )
416 : {
417 : OSL_FAIL("sd::TableDesignWidget::updateControls(), exception caught!");
418 : }
419 0 : m_aCheckBoxes[i]->Check(bUse ? true : false);
420 0 : m_aCheckBoxes[i]->Enable(bHasTable ? true : false);
421 : }
422 :
423 0 : FillDesignPreviewControl();
424 0 : m_pValueSet->updateSettings();
425 0 : m_pValueSet->Resize();
426 :
427 :
428 0 : sal_uInt16 nSelection = 0;
429 0 : if( mxSelectedTable.is() )
430 : {
431 0 : Reference< XNamed > xNamed( mxSelectedTable->getPropertyValue( "TableTemplate" ), UNO_QUERY );
432 0 : if( xNamed.is() )
433 : {
434 0 : const OUString sStyleName( xNamed->getName() );
435 :
436 0 : Reference< XNameAccess > xNames( mxTableFamily, UNO_QUERY );
437 0 : if( xNames.is() )
438 : {
439 0 : Sequence< OUString > aNames( xNames->getElementNames() );
440 0 : for( sal_Int32 nIndex = 0; nIndex < aNames.getLength(); nIndex++ )
441 : {
442 0 : if( aNames[nIndex] == sStyleName )
443 : {
444 0 : nSelection = (sal_uInt16)nIndex+1;
445 0 : break;
446 : }
447 0 : }
448 0 : }
449 0 : }
450 : }
451 0 : m_pValueSet->SelectItem( nSelection );
452 0 : }
453 :
454 :
455 :
456 0 : void TableDesignWidget::addListener()
457 : {
458 0 : Link aLink( LINK(this,TableDesignWidget,EventMultiplexerListener) );
459 : mrBase.GetEventMultiplexer()->AddEventListener (
460 : aLink,
461 : tools::EventMultiplexerEvent::EID_EDIT_VIEW_SELECTION
462 : | tools::EventMultiplexerEvent::EID_CURRENT_PAGE
463 : | tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED
464 : | tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED
465 0 : | tools::EventMultiplexerEvent::EID_DISPOSING);
466 0 : }
467 :
468 :
469 :
470 0 : void TableDesignWidget::removeListener()
471 : {
472 0 : Link aLink( LINK(this,TableDesignWidget,EventMultiplexerListener) );
473 0 : mrBase.GetEventMultiplexer()->RemoveEventListener( aLink );
474 0 : }
475 :
476 :
477 :
478 0 : IMPL_LINK(TableDesignWidget,EventMultiplexerListener,
479 : tools::EventMultiplexerEvent*,pEvent)
480 : {
481 0 : switch (pEvent->meEventId)
482 : {
483 : case tools::EventMultiplexerEvent::EID_CURRENT_PAGE:
484 : case tools::EventMultiplexerEvent::EID_EDIT_VIEW_SELECTION:
485 0 : onSelectionChanged();
486 0 : break;
487 :
488 : case tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED:
489 0 : mxView.clear();
490 0 : onSelectionChanged();
491 0 : break;
492 :
493 : case tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED:
494 0 : mxView = Reference<XDrawView>::query( mrBase.GetController() );
495 0 : onSelectionChanged();
496 0 : break;
497 : }
498 0 : return 0;
499 : }
500 :
501 :
502 :
503 0 : struct CellInfo
504 : {
505 : Color maCellColor;
506 : Color maTextColor;
507 : SvxBoxItem maBorder;
508 :
509 : explicit CellInfo( const Reference< XStyle >& xStyle );
510 : };
511 :
512 0 : CellInfo::CellInfo( const Reference< XStyle >& xStyle )
513 0 : : maBorder(SDRATTR_TABLE_BORDER)
514 : {
515 0 : SfxStyleSheet* pStyleSheet = SfxUnoStyleSheet::getUnoStyleSheet( xStyle );
516 0 : if( pStyleSheet )
517 : {
518 0 : SfxItemSet& rSet = pStyleSheet->GetItemSet();
519 :
520 : // get style fill color
521 0 : if( !GetDraftFillColor(rSet, maCellColor) )
522 0 : maCellColor.SetColor( COL_TRANSPARENT );
523 :
524 : // get style text color
525 0 : const SvxColorItem* pTextColor = dynamic_cast<const SvxColorItem*>( rSet.GetItem(EE_CHAR_COLOR) );
526 0 : if( pTextColor )
527 0 : maTextColor = pTextColor->GetValue();
528 : else
529 0 : maTextColor.SetColor( COL_TRANSPARENT );
530 :
531 : // get border
532 0 : const SvxBoxItem* pBoxItem = dynamic_cast<const SvxBoxItem*>(rSet.GetItem( SDRATTR_TABLE_BORDER ) );
533 0 : if( pBoxItem )
534 0 : maBorder = *pBoxItem;
535 : }
536 0 : }
537 :
538 :
539 :
540 : typedef std::vector< boost::shared_ptr< CellInfo > > CellInfoVector;
541 : typedef boost::shared_ptr< CellInfo > CellInfoMatrix[nPreviewColumns][nPreviewRows];
542 :
543 : struct TableStyleSettings
544 : {
545 : bool mbUseFirstRow;
546 : bool mbUseLastRow;
547 : bool mbUseFirstColumn;
548 : bool mbUseLastColumn;
549 : bool mbUseRowBanding;
550 : bool mbUseColumnBanding;
551 :
552 0 : TableStyleSettings()
553 : : mbUseFirstRow(true)
554 : , mbUseLastRow(false)
555 : , mbUseFirstColumn(false)
556 : , mbUseLastColumn(false)
557 : , mbUseRowBanding(true)
558 0 : , mbUseColumnBanding(false) {}
559 : };
560 :
561 :
562 :
563 0 : static void FillCellInfoVector( const Reference< XIndexAccess >& xTableStyle, CellInfoVector& rVector )
564 : {
565 : DBG_ASSERT( xTableStyle.is() && (xTableStyle->getCount() == sdr::table::style_count ), "sd::FillCellInfoVector(), invalid table style!" );
566 0 : if( xTableStyle.is() ) try
567 : {
568 0 : rVector.resize( sdr::table::style_count );
569 :
570 0 : for( sal_Int32 nStyle = 0; nStyle < sdr::table::style_count; ++nStyle )
571 : {
572 0 : Reference< XStyle > xStyle( xTableStyle->getByIndex( nStyle ), UNO_QUERY );
573 0 : if( xStyle.is() )
574 0 : rVector[nStyle].reset( new CellInfo( xStyle ) );
575 0 : }
576 : }
577 0 : catch(Exception&)
578 : {
579 : OSL_FAIL("sd::FillCellInfoVector(), exception caught!");
580 : }
581 0 : }
582 :
583 0 : static void FillCellInfoMatrix( const CellInfoVector& rStyle, const TableStyleSettings& rSettings, CellInfoMatrix& rMatrix )
584 : {
585 0 : for( sal_Int32 nRow = 0; nRow < nPreviewColumns; ++nRow )
586 : {
587 0 : const bool bFirstRow = rSettings.mbUseFirstRow && (nRow == 0);
588 0 : const bool bLastRow = rSettings.mbUseLastRow && (nRow == nPreviewColumns - 1);
589 :
590 0 : for( sal_Int32 nCol = 0; nCol < nPreviewColumns; ++nCol )
591 : {
592 0 : boost::shared_ptr< CellInfo > xCellInfo;
593 :
594 : // first and last row win first, if used and available
595 0 : if( bFirstRow )
596 : {
597 0 : xCellInfo = rStyle[sdr::table::first_row_style];
598 : }
599 0 : else if( bLastRow )
600 : {
601 0 : xCellInfo = rStyle[sdr::table::last_row_style];
602 : }
603 :
604 0 : if( !xCellInfo.get() )
605 : {
606 : // next come first and last column, if used and available
607 0 : if( rSettings.mbUseFirstColumn && (nCol == 0) )
608 : {
609 0 : xCellInfo = rStyle[sdr::table::first_column_style];
610 : }
611 0 : else if( rSettings.mbUseLastColumn && (nCol == nPreviewColumns-1) )
612 : {
613 0 : xCellInfo = rStyle[sdr::table::last_column_style];
614 : }
615 : }
616 :
617 0 : if( !xCellInfo.get() )
618 : {
619 0 : if( rSettings.mbUseRowBanding )
620 : {
621 0 : if( (nRow & 1) == 0 )
622 : {
623 0 : xCellInfo = rStyle[sdr::table::even_rows_style];
624 : }
625 : else
626 : {
627 0 : xCellInfo = rStyle[sdr::table::odd_rows_style];
628 : }
629 : }
630 : }
631 :
632 0 : if( !xCellInfo.get() )
633 : {
634 0 : if( rSettings.mbUseColumnBanding )
635 : {
636 0 : if( (nCol & 1) == 0 )
637 : {
638 0 : xCellInfo = rStyle[sdr::table::even_columns_style];
639 : }
640 : else
641 : {
642 0 : xCellInfo = rStyle[sdr::table::odd_columns_style];
643 : }
644 : }
645 : }
646 :
647 0 : if( !xCellInfo.get() )
648 : {
649 : // use default cell style if non found yet
650 0 : xCellInfo = rStyle[sdr::table::body_style];
651 : }
652 :
653 0 : rMatrix[nCol][nRow] = xCellInfo;
654 0 : }
655 : }
656 0 : }
657 :
658 :
659 :
660 0 : const Bitmap CreateDesignPreview( const Reference< XIndexAccess >& xTableStyle, const TableStyleSettings& rSettings, bool bIsPageDark )
661 : {
662 0 : CellInfoVector aCellInfoVector(sdr::table::style_count);
663 0 : FillCellInfoVector( xTableStyle, aCellInfoVector );
664 :
665 0 : CellInfoMatrix aMatrix;
666 0 : FillCellInfoMatrix( aCellInfoVector, rSettings, aMatrix );
667 :
668 : // bbbbbbbbbbbb w = 12 pixel
669 : // bccccccccccb h = 7 pixel
670 : // bccccccccccb b = border color
671 : // bcttttttttcb c = cell color
672 : // bccccccccccb t = text color
673 : // bccccccccccb
674 : // bbbbbbbbbbbb
675 :
676 :
677 0 : Bitmap aPreviewBmp( Size( nBitmapWidth, nBitmapHeight), 24, NULL );
678 0 : BitmapWriteAccess* pAccess = aPreviewBmp.AcquireWriteAccess();
679 0 : if( pAccess )
680 : {
681 0 : pAccess->Erase( Color( bIsPageDark ? COL_BLACK : COL_WHITE ) );
682 :
683 : // first draw cell background and text line previews
684 0 : sal_Int32 nY = 0;
685 : sal_Int32 nRow;
686 0 : for( nRow = 0; nRow < nPreviewRows; ++nRow, nY += nCellHeight-1 )
687 : {
688 0 : sal_Int32 nX = 0;
689 0 : for( sal_Int32 nCol = 0; nCol < nPreviewColumns; ++nCol, nX += nCellWidth-1 )
690 : {
691 0 : boost::shared_ptr< CellInfo > xCellInfo( aMatrix[nCol][nRow] );
692 :
693 0 : Color aTextColor( COL_AUTO );
694 0 : if( xCellInfo.get() )
695 : {
696 : // fill cell background
697 0 : const Rectangle aRect( nX, nY, nX + nCellWidth - 1, nY + nCellHeight - 1 );
698 :
699 0 : if( xCellInfo->maCellColor.GetColor() != COL_TRANSPARENT )
700 : {
701 0 : pAccess->SetFillColor( xCellInfo->maCellColor );
702 0 : pAccess->FillRect( aRect );
703 : }
704 :
705 0 : aTextColor = xCellInfo->maTextColor;
706 : }
707 :
708 : // draw text preview line
709 0 : if( aTextColor.GetColor() == COL_AUTO )
710 0 : aTextColor.SetColor( bIsPageDark ? COL_WHITE : COL_BLACK );
711 0 : pAccess->SetLineColor( aTextColor );
712 0 : const Point aPnt1( nX + 2, nY + ((nCellHeight - 1 ) >> 1) );
713 0 : const Point aPnt2( nX + nCellWidth - 3, aPnt1.Y() );
714 0 : pAccess->DrawLine( aPnt1, aPnt2 );
715 0 : }
716 : }
717 :
718 : // second draw border lines
719 0 : nY = 0;
720 0 : for( nRow = 0; nRow < nPreviewRows; ++nRow, nY += nCellHeight-1 )
721 : {
722 0 : sal_Int32 nX = 0;
723 0 : for( sal_Int32 nCol = 0; nCol < nPreviewColumns; ++nCol, nX += nCellWidth-1 )
724 : {
725 0 : boost::shared_ptr< CellInfo > xCellInfo( aMatrix[nCol][nRow] );
726 :
727 0 : if( xCellInfo.get() )
728 : {
729 0 : const Point aPntTL( nX, nY );
730 0 : const Point aPntTR( nX + nCellWidth - 1, nY );
731 0 : const Point aPntBL( nX, nY + nCellHeight - 1 );
732 0 : const Point aPntBR( nX + nCellWidth - 1, nY + nCellHeight - 1 );
733 :
734 0 : sal_Int32 border_diffs[8] = { 0,-1, 0,1, -1,0, 1,0 };
735 0 : sal_Int32* pDiff = &border_diffs[0];
736 :
737 : // draw top border
738 0 : for( sal_uInt16 nLine = 0; nLine < 4; ++nLine )
739 : {
740 0 : const ::editeng::SvxBorderLine* pBorderLine = xCellInfo->maBorder.GetLine(nLine);
741 0 : if( !pBorderLine || ((pBorderLine->GetOutWidth() == 0) && (pBorderLine->GetInWidth()==0)) )
742 0 : continue;
743 :
744 0 : sal_Int32 nBorderCol = nCol + *pDiff++;
745 0 : sal_Int32 nBorderRow = nRow + *pDiff++;
746 0 : if( (nBorderCol >= 0) && (nBorderCol < nPreviewColumns) && (nBorderRow >= 0) && (nBorderRow < nPreviewRows) )
747 : {
748 : // check border
749 0 : boost::shared_ptr< CellInfo > xBorderInfo( aMatrix[nBorderCol][nBorderRow] );
750 0 : if( xBorderInfo.get() )
751 : {
752 0 : const sal_uInt16 nOtherLine = nLine ^ 1;
753 0 : const ::editeng::SvxBorderLine* pBorderLine2 = xBorderInfo->maBorder.GetLine(nOtherLine^1);
754 0 : if( pBorderLine2 && pBorderLine2->HasPriority(*pBorderLine) )
755 0 : continue; // other border line wins
756 0 : }
757 : }
758 :
759 0 : pAccess->SetLineColor( pBorderLine->GetColor() );
760 0 : switch( nLine )
761 : {
762 0 : case 0: pAccess->DrawLine( aPntTL, aPntTR ); break;
763 0 : case 1: pAccess->DrawLine( aPntBL, aPntBR ); break;
764 0 : case 2: pAccess->DrawLine( aPntTL, aPntBL ); break;
765 0 : case 3: pAccess->DrawLine( aPntTR, aPntBR ); break;
766 : }
767 : }
768 : }
769 0 : }
770 : }
771 :
772 0 : aPreviewBmp.ReleaseAccess( pAccess );
773 : }
774 :
775 0 : return aPreviewBmp;
776 : }
777 :
778 0 : void TableDesignWidget::FillDesignPreviewControl()
779 : {
780 0 : sal_uInt16 nSelectedItem = m_pValueSet->GetSelectItemId();
781 0 : m_pValueSet->Clear();
782 : try
783 : {
784 0 : TableStyleSettings aSettings;
785 0 : if( mxSelectedTable.is() )
786 : {
787 0 : aSettings.mbUseFirstRow = m_aCheckBoxes[CB_HEADER_ROW]->IsChecked();
788 0 : aSettings.mbUseLastRow = m_aCheckBoxes[CB_TOTAL_ROW]->IsChecked();
789 0 : aSettings.mbUseRowBanding = m_aCheckBoxes[CB_BANDED_ROWS]->IsChecked();
790 0 : aSettings.mbUseFirstColumn = m_aCheckBoxes[CB_FIRST_COLUMN]->IsChecked();
791 0 : aSettings.mbUseLastColumn = m_aCheckBoxes[CB_LAST_COLUMN]->IsChecked();
792 0 : aSettings.mbUseColumnBanding = m_aCheckBoxes[CB_BANDED_COLUMNS]->IsChecked();
793 : }
794 :
795 0 : sal_Bool bIsPageDark = sal_False;
796 0 : if( mxView.is() )
797 : {
798 0 : Reference< XPropertySet > xPageSet( mxView->getCurrentPage(), UNO_QUERY );
799 0 : if( xPageSet.is() )
800 : {
801 0 : const OUString sIsBackgroundDark( "IsBackgroundDark" );
802 0 : xPageSet->getPropertyValue(sIsBackgroundDark) >>= bIsPageDark;
803 0 : }
804 : }
805 :
806 0 : sal_Int32 nCount = mxTableFamily->getCount();
807 0 : for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex ) try
808 : {
809 0 : Reference< XIndexAccess > xTableStyle( mxTableFamily->getByIndex( nIndex ), UNO_QUERY );
810 0 : if( xTableStyle.is() )
811 0 : m_pValueSet->InsertItem( sal::static_int_cast<sal_uInt16>( nIndex + 1 ), Image( CreateDesignPreview( xTableStyle, aSettings, bIsPageDark ) ) );
812 : }
813 0 : catch( Exception& )
814 : {
815 : OSL_FAIL("sd::TableDesignWidget::FillDesignPreviewControl(), exception caught!");
816 : }
817 0 : sal_Int32 nCols = 3;
818 0 : sal_Int32 nRows = (nCount+2)/3;
819 0 : m_pValueSet->SetColCount(nCols);
820 0 : m_pValueSet->SetLineCount(nRows);
821 0 : WinBits nStyle = m_pValueSet->GetStyle() & ~(WB_VSCROLL);
822 0 : m_pValueSet->SetStyle(nStyle);
823 0 : Size aSize(m_pValueSet->GetOptimalSize());
824 0 : aSize.Width() += (10 * nCols);
825 0 : aSize.Height() += (10 * nRows);
826 0 : m_pValueSet->set_width_request(aSize.Width());
827 0 : m_pValueSet->set_height_request(aSize.Height());
828 : }
829 0 : catch( Exception& )
830 : {
831 : OSL_FAIL("sd::TableDesignWidget::FillDesignPreviewControl(), exception caught!");
832 : }
833 0 : m_pValueSet->SelectItem(nSelectedItem);
834 0 : }
835 :
836 :
837 :
838 0 : short TableDesignDialog::Execute()
839 : {
840 0 : if( ModalDialog::Execute() )
841 : {
842 0 : if( aImpl.isStyleChanged() )
843 0 : aImpl.ApplyStyle();
844 :
845 0 : if( aImpl.isOptionsChanged() )
846 0 : aImpl.ApplyOptions();
847 0 : return RET_OK;
848 : }
849 0 : return RET_CANCEL;
850 : }
851 :
852 :
853 :
854 0 : ::Window * createTableDesignPanel( ::Window* pParent, ViewShellBase& rBase )
855 : {
856 0 : return new TableDesignPane( pParent, rBase );
857 : }
858 :
859 :
860 :
861 0 : void showTableDesignDialog( ::Window* pParent, ViewShellBase& rBase )
862 : {
863 0 : boost::scoped_ptr< TableDesignDialog > xDialog( new TableDesignDialog( pParent, rBase ) );
864 0 : xDialog->Execute();
865 0 : }
866 :
867 :
868 0 : }
869 :
870 :
871 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|