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