1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: tp_DataSource.cxx,v $
10 * $Revision: 1.5.44.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_chart2.hxx"
34 #include "tp_DataSource.hxx"
35 #include "tp_DataSource.hrc"
36 #include "Strings.hrc"
38 #include "chartview/ChartSfxItemIds.hxx"
40 #include "ChartTypeTemplateProvider.hxx"
41 #include "RangeSelectionHelper.hxx"
42 #include "DataSeriesHelper.hxx"
43 #include "tp_DataSourceControls.hxx"
44 #include "ControllerLockGuard.hxx"
45 #include "DataSourceHelper.hxx"
46 #include <com/sun/star/sheet/XRangeSelection.hpp>
47 #include <com/sun/star/table/XCellRange.hpp>
48 #include <com/sun/star/chart2/XChartType.hpp>
49 #include <com/sun/star/chart2/XChartTypeTemplate.hpp>
50 #include <com/sun/star/util/XModifiable.hpp>
51 #include <com/sun/star/chart2/data/XDataSink.hpp>
54 #include <vcl/msgbox.hxx>
55 #include <rtl/ustrbuf.hxx>
61 using namespace ::com::sun::star
;
62 using namespace ::com::sun::star::chart2
;
64 using ::com::sun::star::uno::Reference
;
65 using ::com::sun::star::uno::Sequence
;
66 using ::rtl::OUString
;
67 using ::rtl::OUStringBuffer
;
69 // --------------------------------------------------------------------------------
74 const OUString
lcl_aLabelRole( RTL_CONSTASCII_USTRINGPARAM( "label" ));
76 String
lcl_GetRoleLBEntry(
77 const OUString
& rRole
, const OUString
& rRange
)
79 String
aEntry( rRole
);
82 ::chart::DialogModel::ConvertRoleFromInternalToUI( rRole
));
84 aEntry
+= String( rRange
);
89 void lcl_UpdateCurrentRange(
90 SvTabListBox
& rOutListBox
,
91 const OUString
& rRole
, const OUString
& rRange
)
93 SvLBoxEntry
* pEntry
= rOutListBox
.FirstSelected();
95 rOutListBox
.SetEntryText( lcl_GetRoleLBEntry( rRole
, rRange
), pEntry
);
98 bool lcl_UpdateCurrentSeriesName(
99 SvTreeListBox
& rOutListBox
)
101 bool bResult
= false;
102 ::chart::SeriesEntry
* pEntry
= dynamic_cast< ::chart::SeriesEntry
* >( rOutListBox
.FirstSelected());
104 pEntry
->m_xDataSeries
.is() &&
105 pEntry
->m_xChartType
.is())
107 String
aLabel( ::chart::DataSeriesHelper::getDataSeriesLabel(
108 pEntry
->m_xDataSeries
,
109 pEntry
->m_xChartType
->getRoleOfSequenceForSeriesLabel()));
112 rOutListBox
.SetEntryText( pEntry
, aLabel
);
119 OUString
lcl_GetSelectedRole( const SvTabListBox
& rRoleListBox
, bool bUITranslated
= false )
122 SvLBoxEntry
* pEntry
= rRoleListBox
.FirstSelected();
124 aResult
= OUString( rRoleListBox
.GetEntryText( pEntry
,
125 bUITranslated
? 1 : 0 ));
129 OUString
lcl_GetSelectedRolesRange( const SvTabListBox
& rRoleListBox
)
132 SvLBoxEntry
* pEntry
= rRoleListBox
.FirstSelected();
134 aResult
= OUString( rRoleListBox
.GetEntryText( pEntry
, 2 ));
138 OUString
lcl_GetSequenceNameForLabel( ::chart::SeriesEntry
* pEntry
)
140 OUString
aResult( RTL_CONSTASCII_USTRINGPARAM("values-y"));
142 pEntry
->m_xChartType
.is())
144 aResult
= pEntry
->m_xChartType
->getRoleOfSequenceForSeriesLabel();
149 static long lcl_pRoleListBoxTabs
[] =
150 { 3, // Number of Tabs
154 void lcl_ShowChooserButton(
155 ::chart::RangeSelectionButton
& rChooserButton
,
159 if( rChooserButton
.IsVisible() != bShow
)
161 rChooserButton
.Show( bShow
);
162 sal_Int32 nWidhtDiff
= 12 + 4;
164 nWidhtDiff
= -nWidhtDiff
;
165 Size aSize
= rChooserButton
.PixelToLogic( rEditField
.GetSizePixel(), MAP_APPFONT
);
166 aSize
.setWidth( aSize
.getWidth() + nWidhtDiff
);
167 rEditField
.SetSizePixel( rChooserButton
.LogicToPixel( aSize
, MAP_APPFONT
));
171 void lcl_enableRangeChoosing( bool bEnable
, Dialog
* pDialog
)
175 pDialog
->Show( bEnable
? FALSE
: TRUE
);
176 pDialog
->SetModalInputMode( bEnable
? FALSE
: TRUE
);
180 void lcl_addLSequenceToDataSource(
181 const Reference
< chart2::data::XLabeledDataSequence
> & xLSequence
,
182 const Reference
< chart2::data::XDataSource
> & xSource
)
184 Reference
< data::XDataSink
> xSink( xSource
, uno::UNO_QUERY
);
187 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aData( xSource
->getDataSequences());
188 aData
.realloc( aData
.getLength() + 1 );
189 aData
[ aData
.getLength() - 1 ] = xLSequence
;
190 xSink
->setData( aData
);
194 Reference
< chart2::data::XLabeledDataSequence
> lcl_findLSequenceWithOnlyLabel(
195 const Reference
< chart2::data::XDataSource
> & xDataSource
)
197 Reference
< chart2::data::XLabeledDataSequence
> xResult
;
198 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aSequences( xDataSource
->getDataSequences());
200 for( sal_Int32 i
=0; i
<aSequences
.getLength(); ++i
)
202 // no values are set but a label exists
203 if( ! aSequences
[i
]->getValues().is() &&
204 aSequences
[i
]->getLabel().is())
206 xResult
.set( aSequences
[i
] );
214 void lcl_shiftControlY( Control
& rControl
, long nYOffset
)
216 Point
aPos( rControl
.GetPosPixel());
217 aPos
.setY( aPos
.getY() + nYOffset
);
218 rControl
.SetPosPixel( aPos
);
221 void lcl_increaseHeightOfControl( Control
& rControl
, long nYOffset
)
223 Size
aSize( rControl
.GetSizePixel());
224 aSize
.setHeight( aSize
.getHeight () + nYOffset
);
225 rControl
.SetSizePixel( aSize
);
228 } // anonymous namespace
230 // --------------------------------------------------------------------------------
235 DataSourceTabPage::DataSourceTabPage(
237 DialogModel
& rDialogModel
,
238 ChartTypeTemplateProvider
* pTemplateProvider
,
239 Dialog
* pParentDialog
,
240 bool bHideDescription
/* = false */ ) :
241 ::svt::OWizardPage( pParent
, SchResId( TP_DATA_SOURCE
)),
243 m_aFT_CAPTION ( this, SchResId( FT_CAPTION_FOR_WIZARD
)),
244 m_aFT_SERIES ( this, SchResId( FT_SERIES
)),
245 m_apLB_SERIES( new SeriesListBox( this, SchResId( LB_SERIES
))),
246 m_aBTN_ADD ( this, SchResId( BTN_ADD
)),
247 m_aBTN_REMOVE ( this, SchResId( BTN_REMOVE
)),
248 m_aBTN_UP ( this, SchResId( BTN_UP
)),
249 m_aBTN_DOWN ( this, SchResId( BTN_DOWN
)),
250 m_aFT_ROLE ( this, SchResId( FT_ROLE
)),
251 m_aLB_ROLE ( this, SchResId( LB_ROLE
)),
252 m_aFT_RANGE ( this, SchResId( FT_RANGE
)),
253 m_aEDT_RANGE ( this, SchResId( EDT_RANGE
)),
254 m_aIMB_RANGE_MAIN ( this, SchResId( IMB_RANGE_MAIN
)),
255 m_aFT_CATEGORIES ( this, SchResId( FT_CATEGORIES
)),
256 m_aFT_DATALABELS ( this, SchResId( FT_DATALABELS
)),
257 m_aEDT_CATEGORIES ( this, SchResId( EDT_CATEGORIES
)),
258 m_aIMB_RANGE_CAT ( this, SchResId( IMB_RANGE_CAT
)),
260 m_pTemplateProvider( pTemplateProvider
),
261 m_rDialogModel( rDialogModel
),
263 m_pCurrentRangeChoosingField( 0 ),
265 m_pParentDialog( pParentDialog
),
266 m_pTabPageNotifiable( dynamic_cast< TabPageNotifiable
* >( pParentDialog
))
270 if( bHideDescription
)
272 // note: the offset should be a negative value for shifting upwards, the
273 // 4 is for the offset difference between a wizard page and a tab-page
274 long nYOffset
= - ( m_aFT_SERIES
.GetPosPixel().getY() - m_aFT_CAPTION
.GetPosPixel().getY() + 4 );
276 long nYResize
= - (nYOffset
- nUpShift
);
277 m_aFT_CAPTION
.Hide();
279 // shift list boxes and enlarge them by the space saved by hiding the caption
280 lcl_shiftControlY( m_aFT_SERIES
, nYOffset
);
281 lcl_shiftControlY( *(m_apLB_SERIES
.get()), nYOffset
);
282 lcl_increaseHeightOfControl( *(m_apLB_SERIES
.get()), nYResize
);
284 lcl_shiftControlY( m_aFT_ROLE
, nYOffset
);
285 lcl_shiftControlY( m_aLB_ROLE
, nYOffset
);
286 lcl_increaseHeightOfControl( m_aLB_ROLE
, nYResize
);
288 lcl_shiftControlY( m_aBTN_ADD
, nUpShift
);
289 lcl_shiftControlY( m_aBTN_REMOVE
, nUpShift
);
290 lcl_shiftControlY( m_aBTN_UP
, nUpShift
);
291 lcl_shiftControlY( m_aBTN_DOWN
, nUpShift
);
292 lcl_shiftControlY( m_aFT_RANGE
, nUpShift
);
293 lcl_shiftControlY( m_aEDT_RANGE
, nUpShift
);
294 lcl_shiftControlY( m_aIMB_RANGE_MAIN
, nUpShift
);
295 lcl_shiftControlY( m_aFT_CATEGORIES
, nUpShift
);
296 lcl_shiftControlY( m_aFT_DATALABELS
, nUpShift
);
297 lcl_shiftControlY( m_aEDT_CATEGORIES
, nUpShift
);
298 lcl_shiftControlY( m_aIMB_RANGE_CAT
, nUpShift
);
302 // make font of caption bold
303 Font
aFont( m_aFT_CAPTION
.GetControlFont() );
304 aFont
.SetWeight( WEIGHT_BOLD
);
305 m_aFT_CAPTION
.SetControlFont( aFont
);
308 m_aFT_CAPTION
.SetStyle( m_aFT_CAPTION
.GetStyle() | WB_NOLABEL
);
311 m_aFixedTextRange
= OUString( m_aFT_RANGE
.GetText() );
312 this->SetText( String( SchResId( STR_OBJECT_DATASERIES_PLURAL
) ) );
315 m_apLB_SERIES
->SetSelectHdl( LINK( this, DataSourceTabPage
, SeriesSelectionChangedHdl
));
317 m_aLB_ROLE
.SetWindowBits( WB_HSCROLL
| WB_CLIPCHILDREN
);
318 m_aLB_ROLE
.SetSelectionMode( SINGLE_SELECTION
);
319 m_aLB_ROLE
.SetSelectHdl( LINK( this, DataSourceTabPage
, RoleSelectionChangedHdl
));
321 m_aEDT_RANGE
.SetKeyInputHdl( LINK( this, DataSourceTabPage
, MainRangeButtonClickedHdl
));
322 m_aEDT_CATEGORIES
.SetKeyInputHdl( LINK( this, DataSourceTabPage
, CategoriesRangeButtonClickedHdl
));
324 m_aIMB_RANGE_MAIN
.SetClickHdl( LINK( this, DataSourceTabPage
, MainRangeButtonClickedHdl
));
325 m_aIMB_RANGE_CAT
.SetClickHdl( LINK( this, DataSourceTabPage
, CategoriesRangeButtonClickedHdl
));
327 m_aBTN_ADD
.SetClickHdl( LINK( this, DataSourceTabPage
, AddButtonClickedHdl
));
328 m_aBTN_REMOVE
.SetClickHdl( LINK( this, DataSourceTabPage
, RemoveButtonClickedHdl
));
330 m_aBTN_UP
.SetClickHdl( LINK( this, DataSourceTabPage
, UpButtonClickedHdl
));
331 m_aBTN_DOWN
.SetClickHdl( LINK( this, DataSourceTabPage
, DownButtonClickedHdl
));
333 m_aEDT_RANGE
.SetModifyHdl( LINK( this, DataSourceTabPage
, RangeModifiedHdl
));
334 m_aEDT_CATEGORIES
.SetModifyHdl( LINK( this, DataSourceTabPage
, RangeModifiedHdl
));
335 m_aEDT_RANGE
.SetUpdateDataHdl( LINK( this, DataSourceTabPage
, RangeUpdateDataHdl
));
336 m_aEDT_CATEGORIES
.SetUpdateDataHdl( LINK( this, DataSourceTabPage
, RangeUpdateDataHdl
));
338 // #i75179# enable setting the background to a different color
339 m_aEDT_RANGE
.SetStyle( m_aEDT_RANGE
.GetStyle() | WB_FORCECTRLBACKGROUND
);
340 m_aEDT_CATEGORIES
.SetStyle( m_aEDT_CATEGORIES
.GetStyle() | WB_FORCECTRLBACKGROUND
);
342 // set symbol font for arrows
343 // note: StarSymbol is substituted to OpenSymbol for OOo
344 Font
aSymbolFont( m_aBTN_UP
.GetFont());
345 aSymbolFont
.SetName( String( RTL_CONSTASCII_USTRINGPARAM( "StarSymbol" )));
346 m_aBTN_UP
.SetControlFont( aSymbolFont
);
347 m_aBTN_DOWN
.SetControlFont( aSymbolFont
);
350 sal_Unicode
cBlackUpPointingTriangle( 0x25b2 );
351 sal_Unicode
cBlackDownPointingTriangle( 0x25bc );
352 m_aBTN_UP
.SetText( String( cBlackUpPointingTriangle
));
353 m_aBTN_DOWN
.SetText( String( cBlackDownPointingTriangle
));
356 m_aLB_ROLE
.SetTabs( lcl_pRoleListBoxTabs
, MAP_APPFONT
);
359 updateControlsFromDialogModel();
361 // select first series
362 if( m_apLB_SERIES
->First())
363 m_apLB_SERIES
->Select( m_apLB_SERIES
->First());
364 m_apLB_SERIES
->GrabFocus();
367 DataSourceTabPage::~DataSourceTabPage()
370 void DataSourceTabPage::ActivatePage()
372 OWizardPage::ActivatePage();
373 updateControlsFromDialogModel();
376 void DataSourceTabPage::initializePage()
380 void DataSourceTabPage::DeactivatePage()
383 svt::OWizardPage::DeactivatePage();
386 void DataSourceTabPage::commitPage()
391 sal_Bool
DataSourceTabPage::commitPage( CommitPageReason
/*eReason*/ )
393 //ranges may have been edited in the meanwhile (dirty is true in that case here)
396 updateModelFromControl( 0 /*update all*/ );
397 return sal_True
;//return false if this page should not be left
403 bool DataSourceTabPage::isRangeFieldContentValid( Edit
& rEdit
)
405 OUString
aRange( rEdit
.GetText());
406 bool bIsValid
= ( aRange
.getLength() == 0 ) ||
407 m_rDialogModel
.getRangeSelectionHelper()->verifyCellRange( aRange
);
411 rEdit
.SetControlForeground();
412 rEdit
.SetControlBackground();
416 rEdit
.SetControlBackground( RANGE_SELECTION_INVALID_RANGE_BACKGROUND_COLOR
);
417 rEdit
.SetControlForeground( RANGE_SELECTION_INVALID_RANGE_FOREGROUND_COLOR
);
423 bool DataSourceTabPage::isValid()
425 bool bRoleRangeValid
= true;
426 bool bCategoriesRangeValid
= true;
427 bool bHasSelectedEntry
= (m_apLB_SERIES
->FirstSelected() != 0);
429 if( bHasSelectedEntry
)
430 bRoleRangeValid
= isRangeFieldContentValid( m_aEDT_RANGE
);
431 if( m_aEDT_CATEGORIES
.IsEnabled() )
432 bCategoriesRangeValid
= isRangeFieldContentValid( m_aEDT_CATEGORIES
);
433 bool bValid
= ( bRoleRangeValid
&& bCategoriesRangeValid
);
435 if( m_pTabPageNotifiable
)
438 m_pTabPageNotifiable
->setValidPage( this );
440 m_pTabPageNotifiable
->setInvalidPage( this );
446 void DataSourceTabPage::setDirty()
451 void DataSourceTabPage::updateControlsFromDialogModel()
455 SeriesSelectionChangedHdl( 0 );
458 m_aEDT_CATEGORIES
.SetText( String( m_rDialogModel
.getCategoriesRange() ));
460 updateControlState();
463 void DataSourceTabPage::fillSeriesListBox()
465 m_apLB_SERIES
->SetUpdateMode( FALSE
);
467 Reference
< XDataSeries
> xSelected
;
468 SeriesEntry
* pEntry
= dynamic_cast< SeriesEntry
* >( m_apLB_SERIES
->FirstSelected());
470 xSelected
.set( pEntry
->m_xDataSeries
);
472 bool bHasSelectedEntry
= (pEntry
!= 0);
473 SvLBoxEntry
* pSelectedEntry
= 0;
474 m_apLB_SERIES
->Clear();
476 ::std::vector
< DialogModel::tSeriesWithChartTypeByName
> aSeries(
477 m_rDialogModel
.getAllDataSeriesWithLabel() );
479 sal_Int32 nUnnamedSeriesIndex
= 1;
480 for( ::std::vector
< DialogModel::tSeriesWithChartTypeByName
>::const_iterator aIt
= aSeries
.begin();
481 aIt
!= aSeries
.end(); ++aIt
)
483 String
aLabel( (*aIt
).first
);
486 if( nUnnamedSeriesIndex
> 1 )
488 OUString
aResString( String( ::chart::SchResId( STR_DATA_UNNAMED_SERIES_WITH_INDEX
)));
490 // replace index of unnamed series
491 const OUString
aReplacementStr( RTL_CONSTASCII_USTRINGPARAM( "%NUMBER" ));
492 sal_Int32 nIndex
= aResString
.indexOf( aReplacementStr
);
494 aLabel
= String( aResString
.replaceAt(
495 nIndex
, aReplacementStr
.getLength(),
496 String::CreateFromInt32( nUnnamedSeriesIndex
)));
498 if( aLabel
.Len() == 0 )
499 aLabel
= String( ::chart::SchResId( STR_DATA_UNNAMED_SERIES
));
501 ++nUnnamedSeriesIndex
;
503 pEntry
= dynamic_cast< SeriesEntry
* >(
504 m_apLB_SERIES
->InsertEntry( aLabel
));
507 pEntry
->m_xDataSeries
.set( (*aIt
).second
.first
);
508 pEntry
->m_xChartType
.set( (*aIt
).second
.second
);
509 if( bHasSelectedEntry
&& ((*aIt
).second
.first
== xSelected
))
510 pSelectedEntry
= pEntry
;
514 if( bHasSelectedEntry
&& pSelectedEntry
)
515 m_apLB_SERIES
->Select( pSelectedEntry
);
517 m_apLB_SERIES
->SetUpdateMode( TRUE
);
520 void DataSourceTabPage::fillRoleListBox()
522 SeriesEntry
* pSeriesEntry
= dynamic_cast< SeriesEntry
* >( m_apLB_SERIES
->FirstSelected());
523 bool bHasSelectedEntry
= (pSeriesEntry
!= 0);
525 SvLBoxEntry
* pRoleEntry
= m_aLB_ROLE
.FirstSelected();
526 ULONG nRoleIndex
= SAL_MAX_UINT32
;
528 nRoleIndex
= m_aLB_ROLE
.GetModel()->GetAbsPos( pRoleEntry
);
530 if( bHasSelectedEntry
)
532 DialogModel::tRolesWithRanges
aRoles(
533 m_rDialogModel
.getRolesWithRanges(
534 pSeriesEntry
->m_xDataSeries
,
535 lcl_GetSequenceNameForLabel( pSeriesEntry
),
536 pSeriesEntry
->m_xChartType
));
539 m_aLB_ROLE
.SetUpdateMode( FALSE
);
541 m_aLB_ROLE
.RemoveSelection();
543 for( DialogModel::tRolesWithRanges::const_iterator
aIt( aRoles
.begin());
544 aIt
!= aRoles
.end(); ++ aIt
)
546 m_aLB_ROLE
.InsertEntry( lcl_GetRoleLBEntry( aIt
->first
, aIt
->second
));
549 // series may contain no roles, check listbox size before selecting entries
550 if( m_aLB_ROLE
.GetEntryCount() > 0 )
552 if( nRoleIndex
>= m_aLB_ROLE
.GetEntryCount())
554 m_aLB_ROLE
.Select( m_aLB_ROLE
.GetEntry( nRoleIndex
));
557 m_aLB_ROLE
.SetUpdateMode( TRUE
);
561 void DataSourceTabPage::updateControlState()
563 SvLBoxEntry
* pSeriesEntry
= m_apLB_SERIES
->FirstSelected();
564 bool bHasSelectedSeries
= (pSeriesEntry
!= 0);
565 bool bHasValidRole
= false;
566 bool bHasRangeChooser
= m_rDialogModel
.getRangeSelectionHelper()->hasRangeSelection();
568 if( bHasSelectedSeries
)
570 SvLBoxEntry
* pRoleEntry
= m_aLB_ROLE
.FirstSelected();
571 bHasValidRole
= (pRoleEntry
!= 0);
574 m_aBTN_ADD
.Enable( true );
575 m_aBTN_REMOVE
.Enable( bHasSelectedSeries
);
577 m_aBTN_UP
.Enable( bHasSelectedSeries
&& (pSeriesEntry
!= m_apLB_SERIES
->First()));
578 m_aBTN_DOWN
.Enable( bHasSelectedSeries
&& (pSeriesEntry
!= m_apLB_SERIES
->Last()));
580 bool bHasCategories
= m_rDialogModel
.isCategoryDiagram();
582 m_aFT_DATALABELS
.Show(!bHasCategories
);
583 m_aFT_CATEGORIES
.Show( bHasCategories
);
584 BOOL bShowIB
= bHasRangeChooser
;
585 lcl_ShowChooserButton( m_aIMB_RANGE_CAT
, m_aEDT_CATEGORIES
, bShowIB
);
587 m_aFT_SERIES
.Enable();
588 m_apLB_SERIES
->Enable();
590 m_aFT_ROLE
.Enable( bHasSelectedSeries
);
591 m_aLB_ROLE
.Enable( bHasSelectedSeries
);
593 m_aFT_RANGE
.Enable( bHasValidRole
);
594 m_aEDT_RANGE
.Enable( bHasValidRole
);
595 lcl_ShowChooserButton( m_aIMB_RANGE_MAIN
, m_aEDT_RANGE
, bShowIB
);
599 IMPL_LINK( DataSourceTabPage
, SeriesSelectionChangedHdl
, void *, EMPTYARG
)
601 m_rDialogModel
.startControllerLockTimer();
602 if( m_apLB_SERIES
->FirstSelected())
605 RoleSelectionChangedHdl( 0 );
607 updateControlState();
612 IMPL_LINK( DataSourceTabPage
, RoleSelectionChangedHdl
, void *, EMPTYARG
)
614 m_rDialogModel
.startControllerLockTimer();
615 SvLBoxEntry
* pEntry
= m_aLB_ROLE
.FirstSelected();
618 OUString
aRange( m_aEDT_RANGE
.GetText());
619 OUString aSelectedRoleUI
= lcl_GetSelectedRole( m_aLB_ROLE
, true );
620 OUString aSelectedRange
= lcl_GetSelectedRolesRange( m_aLB_ROLE
);
622 // replace role in fixed text label
623 const OUString
aReplacementStr( RTL_CONSTASCII_USTRINGPARAM( "%VALUETYPE" ));
624 sal_Int32 nIndex
= m_aFixedTextRange
.indexOf( aReplacementStr
);
628 String( m_aFixedTextRange
.replaceAt(
629 nIndex
, aReplacementStr
.getLength(), aSelectedRoleUI
)));
632 m_aEDT_RANGE
.SetText( String( aSelectedRange
));
639 IMPL_LINK( DataSourceTabPage
, MainRangeButtonClickedHdl
, void *, EMPTYARG
)
641 OSL_ASSERT( m_pCurrentRangeChoosingField
== 0 );
642 m_pCurrentRangeChoosingField
= & m_aEDT_RANGE
;
643 if( m_aEDT_RANGE
.GetText().Len() > 0 &&
644 ! updateModelFromControl( m_pCurrentRangeChoosingField
))
647 SeriesEntry
* pEntry
= dynamic_cast< SeriesEntry
* >( m_apLB_SERIES
->FirstSelected());
648 bool bHasSelectedEntry
= (pEntry
!= 0);
650 OUString aSelectedRolesRange
= lcl_GetSelectedRolesRange( m_aLB_ROLE
);
652 if( bHasSelectedEntry
&& (m_aLB_ROLE
.FirstSelected() != 0))
654 String
aStr( SchResId( STR_DATA_SELECT_RANGE_FOR_SERIES
));
655 OUString
aUIStr( aStr
);
658 OUString
aReplacement( RTL_CONSTASCII_USTRINGPARAM( "%VALUETYPE" ));
659 sal_Int32 nIndex
= aUIStr
.indexOf( aReplacement
);
662 aUIStr
= aUIStr
.replaceAt( nIndex
, aReplacement
.getLength(),
663 lcl_GetSelectedRole( m_aLB_ROLE
, true ));
665 // replace series name
666 aReplacement
= C2U( "%SERIESNAME" );
667 nIndex
= aUIStr
.indexOf( aReplacement
);
670 aUIStr
= aUIStr
.replaceAt( nIndex
, aReplacement
.getLength(),
671 OUString( m_apLB_SERIES
->GetEntryText( pEntry
)));
674 lcl_enableRangeChoosing( true, m_pParentDialog
);
675 m_rDialogModel
.getRangeSelectionHelper()->chooseRange( aSelectedRolesRange
, aUIStr
, *this );
678 m_pCurrentRangeChoosingField
= 0;
683 IMPL_LINK( DataSourceTabPage
, CategoriesRangeButtonClickedHdl
, void *, EMPTYARG
)
685 OSL_ASSERT( m_pCurrentRangeChoosingField
== 0 );
686 m_pCurrentRangeChoosingField
= & m_aEDT_CATEGORIES
;
687 if( m_aEDT_CATEGORIES
.GetText().Len() > 0 &&
688 ! updateModelFromControl( m_pCurrentRangeChoosingField
))
691 String
aStr( SchResId( m_aFT_CATEGORIES
.IsVisible() ? STR_DATA_SELECT_RANGE_FOR_CATEGORIES
: STR_DATA_SELECT_RANGE_FOR_DATALABELS
));
692 lcl_enableRangeChoosing( true, m_pParentDialog
);
693 m_rDialogModel
.getRangeSelectionHelper()->chooseRange(
694 m_rDialogModel
.getCategoriesRange(), OUString( aStr
), *this );
698 IMPL_LINK( DataSourceTabPage
, AddButtonClickedHdl
, void *, EMPTYARG
)
700 m_rDialogModel
.startControllerLockTimer();
701 SeriesEntry
* pEntry
= dynamic_cast< SeriesEntry
* >( m_apLB_SERIES
->FirstSelected());
702 Reference
< XDataSeries
> xSeriesToInsertAfter
;
703 Reference
< XChartType
> xChartTypeForNewSeries
;
704 if( m_pTemplateProvider
)
705 m_rDialogModel
.setTemplate( m_pTemplateProvider
->getCurrentTemplate());
709 xSeriesToInsertAfter
.set( pEntry
->m_xDataSeries
);
710 xChartTypeForNewSeries
.set( pEntry
->m_xChartType
);
714 ::std::vector
< Reference
< XDataSeriesContainer
> > aCntVec(
715 m_rDialogModel
.getAllDataSeriesContainers());
716 if( ! aCntVec
.empty())
717 xChartTypeForNewSeries
.set( aCntVec
.front(), uno::UNO_QUERY
);
719 OSL_ENSURE( xChartTypeForNewSeries
.is(), "Cannot insert new series" );
721 m_rDialogModel
.insertSeriesAfter( xSeriesToInsertAfter
, xChartTypeForNewSeries
);
725 // note the box was cleared and refilled, so pEntry is invalid now
726 SvLBoxEntry
* pSelEntry
= m_apLB_SERIES
->FirstSelected();
729 SvLBoxEntry
* pNextEntry
= m_apLB_SERIES
->Next( pSelEntry
);
731 m_apLB_SERIES
->Select( pNextEntry
);
733 SeriesSelectionChangedHdl( 0 );
738 IMPL_LINK( DataSourceTabPage
, RemoveButtonClickedHdl
, void *, EMPTYARG
)
740 m_rDialogModel
.startControllerLockTimer();
741 SeriesEntry
* pEntry
= dynamic_cast< SeriesEntry
* >( m_apLB_SERIES
->FirstSelected());
744 Reference
< XDataSeries
> xNewSelSeries
;
745 SeriesEntry
* pNewSelEntry
= dynamic_cast< SeriesEntry
* >(
746 m_apLB_SERIES
->Next( pEntry
));
748 xNewSelSeries
.set( pNewSelEntry
->m_xDataSeries
);
751 pNewSelEntry
= dynamic_cast< SeriesEntry
* >( m_apLB_SERIES
->Prev( pEntry
));
753 xNewSelSeries
.set( pNewSelEntry
->m_xDataSeries
);
756 m_rDialogModel
.deleteSeries( pEntry
->m_xDataSeries
, pEntry
->m_xChartType
);
759 m_apLB_SERIES
->RemoveSelection();
762 // select previous or next series
763 //@improve: see methods GetModel()->GetAbsPos()/GetEntry() for absoulte list positions
764 if( xNewSelSeries
.is())
766 pEntry
= dynamic_cast< SeriesEntry
* >( m_apLB_SERIES
->First());
769 if( pEntry
->m_xDataSeries
== xNewSelSeries
)
771 m_apLB_SERIES
->Select( pEntry
);
774 pEntry
= dynamic_cast< SeriesEntry
* >( m_apLB_SERIES
->Next( pEntry
));
777 SeriesSelectionChangedHdl( 0 );
783 IMPL_LINK( DataSourceTabPage
, UpButtonClickedHdl
, void *, EMPTYARG
)
785 m_rDialogModel
.startControllerLockTimer();
786 SeriesEntry
* pEntry
= dynamic_cast< SeriesEntry
* >( m_apLB_SERIES
->FirstSelected());
787 bool bHasSelectedEntry
= (pEntry
!= 0);
789 if( bHasSelectedEntry
)
791 m_rDialogModel
.moveSeries( pEntry
->m_xDataSeries
, DialogModel::MOVE_UP
);
794 SeriesSelectionChangedHdl(0);
800 IMPL_LINK( DataSourceTabPage
, DownButtonClickedHdl
, void *, EMPTYARG
)
802 m_rDialogModel
.startControllerLockTimer();
803 SeriesEntry
* pEntry
= dynamic_cast< SeriesEntry
* >( m_apLB_SERIES
->FirstSelected());
804 bool bHasSelectedEntry
= (pEntry
!= 0);
806 if( bHasSelectedEntry
)
808 m_rDialogModel
.moveSeries( pEntry
->m_xDataSeries
, DialogModel::MOVE_DOWN
);
811 SeriesSelectionChangedHdl(0);
817 IMPL_LINK( DataSourceTabPage
, RangeModifiedHdl
, Edit
*, pEdit
)
819 if( isRangeFieldContentValid( *pEdit
))
822 // enable/disable OK button
828 IMPL_LINK( DataSourceTabPage
, RangeUpdateDataHdl
, Edit
*, pEdit
)
830 // note: isValid sets the color of the edit field
831 if( isRangeFieldContentValid( *pEdit
))
834 updateModelFromControl( pEdit
);
835 if( pEdit
== &m_aEDT_RANGE
)
837 if( ! lcl_UpdateCurrentSeriesName( *m_apLB_SERIES
))
841 // enable/disable OK button
847 void DataSourceTabPage::listeningFinished(
848 const ::rtl::OUString
& rNewRange
)
850 // rNewRange becomes invalid after removing the listener
851 OUString
aRange( rNewRange
);
853 m_rDialogModel
.startControllerLockTimer();
856 m_rDialogModel
.getRangeSelectionHelper()->stopRangeListening();
861 if( m_pCurrentRangeChoosingField
)
863 m_pCurrentRangeChoosingField
->SetText( String( aRange
));
864 m_pCurrentRangeChoosingField
->GrabFocus();
867 if( m_pCurrentRangeChoosingField
== & m_aEDT_RANGE
)
869 m_aEDT_RANGE
.SetText( String( aRange
));
872 else if( m_pCurrentRangeChoosingField
== & m_aEDT_CATEGORIES
)
874 m_aEDT_CATEGORIES
.SetText( String( aRange
));
878 updateModelFromControl( m_pCurrentRangeChoosingField
);
879 if( ! lcl_UpdateCurrentSeriesName( *m_apLB_SERIES
))
882 m_pCurrentRangeChoosingField
= 0;
884 updateControlState();
885 lcl_enableRangeChoosing( false, m_pParentDialog
);
888 void DataSourceTabPage::disposingRangeSelection()
890 m_rDialogModel
.getRangeSelectionHelper()->stopRangeListening( false );
893 bool DataSourceTabPage::updateModelFromControl( Edit
* pField
)
898 ControllerLockGuard
aLockedControllers( m_rDialogModel
.getChartModel() );
900 // @todo: validity check of field content
902 bool bAll
= (pField
== 0);
903 Reference
< data::XDataProvider
> xDataProvider( m_rDialogModel
.getDataProvider());
905 if( bAll
|| (pField
== & m_aEDT_CATEGORIES
) )
907 Reference
< data::XLabeledDataSequence
> xLabeledSeq( m_rDialogModel
.getCategories() );
908 if( xDataProvider
.is())
910 OUString
aRange( m_aEDT_CATEGORIES
.GetText());
911 if( aRange
.getLength())
913 // create or change categories
914 if( !xLabeledSeq
.is())
916 xLabeledSeq
.set( DataSourceHelper::createLabeledDataSequence( Reference
< uno::XComponentContext
>(0)));
917 m_rDialogModel
.setCategories( xLabeledSeq
);
921 xLabeledSeq
->setValues( xDataProvider
->createDataSequenceByRangeRepresentation( aRange
));
923 catch( const uno::Exception
& ex
)
925 // should work as validation should have happened before
926 ASSERT_EXCEPTION( ex
);
929 else if( xLabeledSeq
.is())
931 // clear existing categories
933 m_rDialogModel
.setCategories( xLabeledSeq
);
938 SeriesEntry
* pSeriesEntry
= dynamic_cast< SeriesEntry
* >( m_apLB_SERIES
->FirstSelected());
939 bool bHasSelectedEntry
= (pSeriesEntry
!= 0);
941 if( bHasSelectedEntry
)
943 if( bAll
|| (pField
== & m_aEDT_RANGE
) )
947 OUString aSelectedRole
= lcl_GetSelectedRole( m_aLB_ROLE
);
948 OUString
aRange( m_aEDT_RANGE
.GetText());
949 OUString
aSequenceRole( aSelectedRole
);
950 bool bIsLabel
= aSequenceRole
.equals( lcl_aLabelRole
);
951 OUString
aSequenceNameForLabel( lcl_GetSequenceNameForLabel( pSeriesEntry
));
954 aSequenceRole
= aSequenceNameForLabel
;
956 Reference
< data::XDataSource
> xSource( pSeriesEntry
->m_xDataSeries
, uno::UNO_QUERY_THROW
);
957 Reference
< data::XLabeledDataSequence
> xLabeledSeq(
958 DataSeriesHelper::getDataSequenceByRole( xSource
, aSequenceRole
));
960 if( xDataProvider
.is())
964 if( ! xLabeledSeq
.is())
966 // check if there is already an "orphan" label sequence
967 xLabeledSeq
.set( lcl_findLSequenceWithOnlyLabel( xSource
));
968 if( ! xLabeledSeq
.is())
970 // no corresponding labeled data sequence for label found
971 xLabeledSeq
.set( DataSourceHelper::createLabeledDataSequence( Reference
< uno::XComponentContext
>(0)));
972 lcl_addLSequenceToDataSource( xLabeledSeq
, xSource
);
975 if( xLabeledSeq
.is())
977 if( aRange
.getLength())
979 Reference
< data::XDataSequence
> xNewSeq
;
982 xNewSeq
.set( xDataProvider
->createDataSequenceByRangeRepresentation( aRange
));
984 catch( const uno::Exception
& ex
)
986 // should work as validation should have happened before
987 ASSERT_EXCEPTION( ex
);
991 // update range name by the full string provided
992 // by the data provider. E.g. "a1" might become
994 aRange
= xNewSeq
->getSourceRangeRepresentation();
995 Reference
< beans::XPropertySet
> xProp( xNewSeq
, uno::UNO_QUERY_THROW
);
996 xProp
->setPropertyValue( C2U("Role"), uno::makeAny( lcl_aLabelRole
));
997 xLabeledSeq
->setLabel( xNewSeq
);
1002 xLabeledSeq
->setLabel( Reference
< data::XDataSequence
>());
1008 if( aRange
.getLength())
1010 Reference
< data::XDataSequence
> xNewSeq
;
1013 xNewSeq
.set( xDataProvider
->createDataSequenceByRangeRepresentation( aRange
));
1015 catch( const uno::Exception
& ex
)
1017 // should work as validation should have happened before
1018 ASSERT_EXCEPTION( ex
);
1022 // update range name by the full string provided
1023 // by the data provider. E.g. "a1:e1" might become
1024 // "$Sheet1.$A$1:$E$1"
1025 aRange
= xNewSeq
->getSourceRangeRepresentation();
1027 Reference
< beans::XPropertySet
> xProp( xNewSeq
, uno::UNO_QUERY_THROW
);
1028 xProp
->setPropertyValue( C2U("Role"), uno::makeAny( aSelectedRole
));
1029 if( !xLabeledSeq
.is())
1031 if( aSelectedRole
.equals( aSequenceNameForLabel
))
1032 xLabeledSeq
.set( lcl_findLSequenceWithOnlyLabel( xSource
));
1033 if( ! xLabeledSeq
.is())
1035 xLabeledSeq
.set( DataSourceHelper::createLabeledDataSequence( Reference
< uno::XComponentContext
>(0)));
1036 lcl_addLSequenceToDataSource( xLabeledSeq
, xSource
);
1039 xLabeledSeq
->setValues( xNewSeq
);
1042 else if( xLabeledSeq
.is())
1044 // values cannot be deleted. This would also delete the Role (for labels)
1045 // xLabeledSeq->setValues( Reference< data::XDataSequence >());
1050 lcl_UpdateCurrentRange( m_aLB_ROLE
, aSelectedRole
, aRange
);
1052 catch( uno::Exception
& ex
)
1055 ASSERT_EXCEPTION( ex
);
1061 // @todo remove this when automatic view updates from calc, writer and own data sequences are available
1066 Reference
< util::XModifiable
> xModifiable( m_rDialogModel
.getChartModel(), uno::UNO_QUERY
);
1067 if( xModifiable
.is() )
1068 xModifiable
->setModified( sal_True
);
1070 catch( uno::Exception
& ex
)
1072 ASSERT_EXCEPTION( ex
);
1079 } // namespace chart