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