1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "tp_DataSource.hxx"
21 #include "Strings.hrc"
23 #include "chartview/ChartSfxItemIds.hxx"
25 #include "ChartTypeTemplateProvider.hxx"
26 #include "RangeSelectionHelper.hxx"
27 #include "DataSeriesHelper.hxx"
28 #include "tp_DataSourceControls.hxx"
29 #include "ControllerLockGuard.hxx"
30 #include "DataSourceHelper.hxx"
31 #include <com/sun/star/sheet/XRangeSelection.hpp>
32 #include <com/sun/star/table/XCellRange.hpp>
33 #include <com/sun/star/chart2/XChartType.hpp>
34 #include <com/sun/star/chart2/XChartTypeTemplate.hpp>
35 #include <com/sun/star/util/XModifiable.hpp>
36 #include <com/sun/star/chart2/data/XDataSink.hpp>
38 #include <vcl/msgbox.hxx>
39 #include <rtl/ustrbuf.hxx>
45 using namespace ::com::sun::star
;
46 using namespace ::com::sun::star::chart2
;
48 using ::com::sun::star::uno::Reference
;
49 using ::com::sun::star::uno::Sequence
;
54 const OUString
lcl_aLabelRole( "label" );
56 OUString
lcl_GetRoleLBEntry(
57 const OUString
& rRole
, const OUString
& rRange
)
59 OUStringBuffer
aEntry( rRole
);
60 aEntry
.append( "\t" );
61 aEntry
.append( OUString(
62 ::chart::DialogModel::ConvertRoleFromInternalToUI( rRole
)) );
63 aEntry
.append( "\t" );
64 aEntry
.append(OUString( rRange
));
66 OUString sFoo
= aEntry
.makeStringAndClear();
70 void lcl_UpdateCurrentRange(
71 SvTabListBox
& rOutListBox
,
72 const OUString
& rRole
, const OUString
& rRange
)
74 SvTreeListEntry
* pEntry
= rOutListBox
.FirstSelected();
76 rOutListBox
.SetEntryText( lcl_GetRoleLBEntry( rRole
, rRange
), pEntry
);
79 bool lcl_UpdateCurrentSeriesName(
80 SvTreeListBox
& rOutListBox
)
83 ::chart::SeriesEntry
* pEntry
= dynamic_cast< ::chart::SeriesEntry
* >( rOutListBox
.FirstSelected());
85 pEntry
->m_xDataSeries
.is() &&
86 pEntry
->m_xChartType
.is())
88 OUString
aLabel( ::chart::DataSeriesHelper::getDataSeriesLabel(
89 pEntry
->m_xDataSeries
,
90 pEntry
->m_xChartType
->getRoleOfSequenceForSeriesLabel()));
91 if( !aLabel
.isEmpty())
93 rOutListBox
.SetEntryText( pEntry
, aLabel
);
100 OUString
lcl_GetSelectedRole( const SvTabListBox
& rRoleListBox
, bool bUITranslated
= false )
103 SvTreeListEntry
* pEntry
= rRoleListBox
.FirstSelected();
105 aResult
= OUString( SvTabListBox::GetEntryText( pEntry
,
106 bUITranslated
? 1 : 0 ));
110 OUString
lcl_GetSelectedRolesRange( const SvTabListBox
& rRoleListBox
)
113 SvTreeListEntry
* pEntry
= rRoleListBox
.FirstSelected();
115 aResult
= OUString( SvTabListBox::GetEntryText( pEntry
, 2 ));
119 OUString
lcl_GetSequenceNameForLabel( ::chart::SeriesEntry
* pEntry
)
121 OUString
aResult( "values-y" );
123 pEntry
->m_xChartType
.is())
125 aResult
= pEntry
->m_xChartType
->getRoleOfSequenceForSeriesLabel();
130 static long lcl_pRoleListBoxTabs
[] =
131 { 3, // Number of Tabs
135 void lcl_enableRangeChoosing( bool bEnable
, Dialog
* pDialog
)
139 pDialog
->Show( !bEnable
);
140 pDialog
->SetModalInputMode( !bEnable
);
144 void lcl_addLSequenceToDataSource(
145 const Reference
< chart2::data::XLabeledDataSequence
> & xLSequence
,
146 const Reference
< chart2::data::XDataSource
> & xSource
)
148 Reference
< data::XDataSink
> xSink( xSource
, uno::UNO_QUERY
);
151 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aData( xSource
->getDataSequences());
152 aData
.realloc( aData
.getLength() + 1 );
153 aData
[ aData
.getLength() - 1 ] = xLSequence
;
154 xSink
->setData( aData
);
158 Reference
< chart2::data::XLabeledDataSequence
> lcl_findLSequenceWithOnlyLabel(
159 const Reference
< chart2::data::XDataSource
> & xDataSource
)
161 Reference
< chart2::data::XLabeledDataSequence
> xResult
;
162 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aSequences( xDataSource
->getDataSequences());
164 for( sal_Int32 i
=0; i
<aSequences
.getLength(); ++i
)
166 // no values are set but a label exists
167 if( ! aSequences
[i
]->getValues().is() &&
168 aSequences
[i
]->getLabel().is())
170 xResult
.set( aSequences
[i
] );
178 } // anonymous namespace
183 DataSourceTabPage::DataSourceTabPage(
184 vcl::Window
* pParent
,
185 DialogModel
& rDialogModel
,
186 ChartTypeTemplateProvider
* pTemplateProvider
,
187 Dialog
* pParentDialog
,
188 bool bHideDescription
/* = false */ ) :
189 ::svt::OWizardPage( pParent
191 ,"modules/schart/ui/tp_DataSource.ui"),
192 m_pTemplateProvider( pTemplateProvider
),
193 m_rDialogModel( rDialogModel
),
195 m_pCurrentRangeChoosingField( 0 ),
197 m_pParentDialog( pParentDialog
),
198 m_pTabPageNotifiable( dynamic_cast< TabPageNotifiable
* >( pParentDialog
))
201 get(m_pFT_CAPTION
,"FT_CAPTION_FOR_WIZARD");
202 get(m_pFT_SERIES
,"FT_SERIES");
204 get(m_pLB_SERIES
,"LB_SERIES");
206 get(m_pBTN_ADD
,"BTN_ADD");
207 get(m_pBTN_REMOVE
,"BTN_REMOVE");
208 get(m_pBTN_UP
,"BTN_UP");
209 get(m_pBTN_DOWN
,"BTN_DOWN");
210 get(m_pFT_ROLE
,"FT_ROLE");
211 get(m_pLB_ROLE
,"LB_ROLE");
212 get(m_pFT_RANGE
,"FT_RANGE");
213 get(m_pEDT_RANGE
,"EDT_RANGE");
214 get(m_pIMB_RANGE_MAIN
,"IMB_RANGE_MAIN");
215 get(m_pFT_CATEGORIES
,"FT_CATEGORIES");
216 get(m_pFT_DATALABELS
,"FT_DATALABELS");
217 get(m_pEDT_CATEGORIES
,"EDT_CATEGORIES");
218 get(m_pIMB_RANGE_CAT
,"IMB_RANGE_CAT");
220 m_pFT_CAPTION
->Show(!bHideDescription
);
222 m_aFixedTextRange
= OUString( m_pFT_RANGE
->GetText() );
223 this->SetText( SCH_RESSTR( STR_OBJECT_DATASERIES_PLURAL
) );
226 m_pLB_SERIES
->SetSelectHdl( LINK( this, DataSourceTabPage
, SeriesSelectionChangedHdl
));
228 m_pLB_ROLE
->SetSelectHdl( LINK( this, DataSourceTabPage
, RoleSelectionChangedHdl
));
230 m_pIMB_RANGE_MAIN
->SetClickHdl( LINK( this, DataSourceTabPage
, MainRangeButtonClickedHdl
));
231 m_pIMB_RANGE_CAT
->SetClickHdl( LINK( this, DataSourceTabPage
, CategoriesRangeButtonClickedHdl
));
233 m_pBTN_ADD
->SetClickHdl( LINK( this, DataSourceTabPage
, AddButtonClickedHdl
));
234 m_pBTN_REMOVE
->SetClickHdl( LINK( this, DataSourceTabPage
, RemoveButtonClickedHdl
));
236 m_pBTN_UP
->SetClickHdl( LINK( this, DataSourceTabPage
, UpButtonClickedHdl
));
237 m_pBTN_DOWN
->SetClickHdl( LINK( this, DataSourceTabPage
, DownButtonClickedHdl
));
239 m_pEDT_RANGE
->SetModifyHdl( LINK( this, DataSourceTabPage
, RangeModifiedHdl
));
240 m_pEDT_CATEGORIES
->SetModifyHdl( LINK( this, DataSourceTabPage
, RangeModifiedHdl
));
241 m_pEDT_RANGE
->SetUpdateDataHdl( LINK( this, DataSourceTabPage
, RangeUpdateDataHdl
));
242 m_pEDT_CATEGORIES
->SetUpdateDataHdl( LINK( this, DataSourceTabPage
, RangeUpdateDataHdl
));
244 // #i75179# enable setting the background to a different color
245 m_pEDT_RANGE
->SetStyle( m_pEDT_RANGE
->GetStyle() | WB_FORCECTRLBACKGROUND
);
246 m_pEDT_CATEGORIES
->SetStyle( m_pEDT_CATEGORIES
->GetStyle() | WB_FORCECTRLBACKGROUND
);
248 // set symbol font for arrows
249 // note: StarSymbol is substituted to OpenSymbol for OOo
250 vcl::Font
aSymbolFont( m_pBTN_UP
->GetFont());
251 aSymbolFont
.SetName( "StarSymbol" );
252 m_pBTN_UP
->SetControlFont( aSymbolFont
);
253 m_pBTN_DOWN
->SetControlFont( aSymbolFont
);
256 sal_Unicode
cBlackUpPointingTriangle( 0x25b2 );
257 sal_Unicode
cBlackDownPointingTriangle( 0x25bc );
258 m_pBTN_UP
->SetText( OUString( cBlackUpPointingTriangle
));
259 m_pBTN_DOWN
->SetText( OUString( cBlackDownPointingTriangle
));
262 m_pLB_ROLE
->SetTabs( lcl_pRoleListBoxTabs
, MAP_APPFONT
);
265 updateControlsFromDialogModel();
267 // select first series
268 if( m_pLB_SERIES
->First())
269 m_pLB_SERIES
->Select( m_pLB_SERIES
->First());
270 m_pLB_SERIES
->GrabFocus();
272 m_pBTN_UP
->SetAccessibleName(SCH_RESSTR(STR_BUTTON_UP
));
273 m_pBTN_DOWN
->SetAccessibleName(SCH_RESSTR(STR_BUTTON_DOWN
));
276 DataSourceTabPage::~DataSourceTabPage()
281 void DataSourceTabPage::dispose()
283 m_pFT_CAPTION
.clear();
284 m_pFT_SERIES
.clear();
285 m_pLB_SERIES
.clear();
287 m_pBTN_REMOVE
.clear();
293 m_pEDT_RANGE
.clear();
294 m_pIMB_RANGE_MAIN
.clear();
295 m_pFT_CATEGORIES
.clear();
296 m_pFT_DATALABELS
.clear();
297 m_pEDT_CATEGORIES
.clear();
298 m_pIMB_RANGE_CAT
.clear();
299 m_pCurrentRangeChoosingField
.clear();
300 m_pParentDialog
.clear();
301 ::svt::OWizardPage::dispose();
304 void DataSourceTabPage::ActivatePage()
306 OWizardPage::ActivatePage();
307 updateControlsFromDialogModel();
310 void DataSourceTabPage::initializePage()
314 void DataSourceTabPage::DeactivatePage()
317 svt::OWizardPage::DeactivatePage();
320 void DataSourceTabPage::commitPage()
322 commitPage(::svt::WizardTypes::eFinish
);
325 bool DataSourceTabPage::commitPage( ::svt::WizardTypes::CommitPageReason
/*eReason*/ )
327 //ranges may have been edited in the meanwhile (dirty is true in that case here)
330 updateModelFromControl( 0 /*update all*/ );
331 return true; //return false if this page should not be left
337 bool DataSourceTabPage::isRangeFieldContentValid( Edit
& rEdit
)
339 OUString
aRange( rEdit
.GetText());
340 bool bIsValid
= ( aRange
.isEmpty() ) ||
341 m_rDialogModel
.getRangeSelectionHelper()->verifyCellRange( aRange
);
345 rEdit
.SetControlForeground();
346 rEdit
.SetControlBackground();
350 rEdit
.SetControlBackground( RANGE_SELECTION_INVALID_RANGE_BACKGROUND_COLOR
);
351 rEdit
.SetControlForeground( RANGE_SELECTION_INVALID_RANGE_FOREGROUND_COLOR
);
357 bool DataSourceTabPage::isValid()
359 bool bRoleRangeValid
= true;
360 bool bCategoriesRangeValid
= true;
361 bool bHasSelectedEntry
= (m_pLB_SERIES
->FirstSelected() != 0);
363 if( bHasSelectedEntry
)
364 bRoleRangeValid
= isRangeFieldContentValid( *m_pEDT_RANGE
);
365 if( m_pEDT_CATEGORIES
->IsEnabled() )
366 bCategoriesRangeValid
= isRangeFieldContentValid( *m_pEDT_CATEGORIES
);
367 bool bValid
= ( bRoleRangeValid
&& bCategoriesRangeValid
);
369 if( m_pTabPageNotifiable
)
372 m_pTabPageNotifiable
->setValidPage( this );
374 m_pTabPageNotifiable
->setInvalidPage( this );
380 void DataSourceTabPage::setDirty()
385 void DataSourceTabPage::updateControlsFromDialogModel()
389 SeriesSelectionChangedHdl( 0 );
392 m_pEDT_CATEGORIES
->SetText( m_rDialogModel
.getCategoriesRange() );
394 updateControlState();
397 void DataSourceTabPage::fillSeriesListBox()
399 m_pLB_SERIES
->SetUpdateMode( false );
401 Reference
< XDataSeries
> xSelected
;
402 SeriesEntry
* pEntry
= dynamic_cast< SeriesEntry
* >( m_pLB_SERIES
->FirstSelected());
404 xSelected
.set( pEntry
->m_xDataSeries
);
406 bool bHasSelectedEntry
= (pEntry
!= 0);
407 SvTreeListEntry
* pSelectedEntry
= 0;
408 m_pLB_SERIES
->Clear();
410 ::std::vector
< DialogModel::tSeriesWithChartTypeByName
> aSeries(
411 m_rDialogModel
.getAllDataSeriesWithLabel() );
413 sal_Int32 nUnnamedSeriesIndex
= 1;
414 for( ::std::vector
< DialogModel::tSeriesWithChartTypeByName
>::const_iterator aIt
= aSeries
.begin();
415 aIt
!= aSeries
.end(); ++aIt
)
417 OUString
aLabel( (*aIt
).first
);
418 if( aLabel
.isEmpty())
420 if( nUnnamedSeriesIndex
> 1 )
422 OUString
aResString(::chart::SchResId( STR_DATA_UNNAMED_SERIES_WITH_INDEX
).toString());
424 // replace index of unnamed series
425 const OUString
aReplacementStr( "%NUMBER" );
426 sal_Int32 nIndex
= aResString
.indexOf( aReplacementStr
);
428 aLabel
= OUString( aResString
.replaceAt(
429 nIndex
, aReplacementStr
.getLength(),
430 OUString::number(nUnnamedSeriesIndex
)));
432 if( aLabel
.isEmpty() )
433 aLabel
= ::chart::SchResId( STR_DATA_UNNAMED_SERIES
).toString();
435 ++nUnnamedSeriesIndex
;
437 pEntry
= dynamic_cast< SeriesEntry
* >(
438 m_pLB_SERIES
->InsertEntry( aLabel
));
441 pEntry
->m_xDataSeries
.set( (*aIt
).second
.first
);
442 pEntry
->m_xChartType
.set( (*aIt
).second
.second
);
443 if( bHasSelectedEntry
&& ((*aIt
).second
.first
== xSelected
))
444 pSelectedEntry
= pEntry
;
448 if( bHasSelectedEntry
&& pSelectedEntry
)
449 m_pLB_SERIES
->Select( pSelectedEntry
);
451 m_pLB_SERIES
->SetUpdateMode( true );
454 void DataSourceTabPage::fillRoleListBox()
456 SeriesEntry
* pSeriesEntry
= dynamic_cast< SeriesEntry
* >( m_pLB_SERIES
->FirstSelected());
457 bool bHasSelectedEntry
= (pSeriesEntry
!= 0);
459 SvTreeListEntry
* pRoleEntry
= m_pLB_ROLE
->FirstSelected();
460 sal_uLong nRoleIndex
= SAL_MAX_UINT32
;
462 nRoleIndex
= m_pLB_ROLE
->GetModel()->GetAbsPos( pRoleEntry
);
464 if( bHasSelectedEntry
)
466 DialogModel::tRolesWithRanges
aRoles(
467 DialogModel::getRolesWithRanges(
468 pSeriesEntry
->m_xDataSeries
,
469 lcl_GetSequenceNameForLabel( pSeriesEntry
),
470 pSeriesEntry
->m_xChartType
));
473 m_pLB_ROLE
->SetUpdateMode( false );
475 m_pLB_ROLE
->RemoveSelection();
477 for( DialogModel::tRolesWithRanges::const_iterator
aIt( aRoles
.begin());
478 aIt
!= aRoles
.end(); ++ aIt
)
480 m_pLB_ROLE
->InsertEntry( lcl_GetRoleLBEntry( aIt
->first
, aIt
->second
));
483 // series may contain no roles, check listbox size before selecting entries
484 if( m_pLB_ROLE
->GetEntryCount() > 0 )
486 if( nRoleIndex
>= m_pLB_ROLE
->GetEntryCount())
488 m_pLB_ROLE
->Select( m_pLB_ROLE
->GetEntry( nRoleIndex
));
491 m_pLB_ROLE
->SetUpdateMode( true );
495 void DataSourceTabPage::updateControlState()
497 SvTreeListEntry
* pSeriesEntry
= m_pLB_SERIES
->FirstSelected();
498 bool bHasSelectedSeries
= (pSeriesEntry
!= 0);
499 bool bHasValidRole
= false;
500 bool bHasRangeChooser
= m_rDialogModel
.getRangeSelectionHelper()->hasRangeSelection();
502 if( bHasSelectedSeries
)
504 SvTreeListEntry
* pRoleEntry
= m_pLB_ROLE
->FirstSelected();
505 bHasValidRole
= (pRoleEntry
!= 0);
508 m_pBTN_ADD
->Enable( true );
509 m_pBTN_REMOVE
->Enable( bHasSelectedSeries
);
511 m_pBTN_UP
->Enable( bHasSelectedSeries
&& (pSeriesEntry
!= m_pLB_SERIES
->First()));
512 m_pBTN_DOWN
->Enable( bHasSelectedSeries
&& (pSeriesEntry
!= m_pLB_SERIES
->Last()));
514 bool bHasCategories
= m_rDialogModel
.isCategoryDiagram();
516 m_pFT_DATALABELS
->Show(!bHasCategories
);
517 m_pFT_CATEGORIES
->Show( bHasCategories
);
518 bool bShowIB
= bHasRangeChooser
;
520 m_pIMB_RANGE_CAT
->Show(bShowIB
);
522 m_pFT_SERIES
->Enable();
523 m_pLB_SERIES
->Enable();
525 m_pFT_ROLE
->Enable( bHasSelectedSeries
);
526 m_pLB_ROLE
->Enable( bHasSelectedSeries
);
528 m_pFT_RANGE
->Enable( bHasValidRole
);
529 m_pEDT_RANGE
->Enable( bHasValidRole
);
531 m_pIMB_RANGE_MAIN
->Show(bShowIB
);
536 IMPL_LINK_NOARG(DataSourceTabPage
, SeriesSelectionChangedHdl
)
538 m_rDialogModel
.startControllerLockTimer();
539 if( m_pLB_SERIES
->FirstSelected())
542 RoleSelectionChangedHdl( 0 );
544 updateControlState();
549 IMPL_LINK_NOARG(DataSourceTabPage
, RoleSelectionChangedHdl
)
551 m_rDialogModel
.startControllerLockTimer();
552 SvTreeListEntry
* pEntry
= m_pLB_ROLE
->FirstSelected();
555 OUString aSelectedRoleUI
= lcl_GetSelectedRole( *m_pLB_ROLE
, true );
556 OUString aSelectedRange
= lcl_GetSelectedRolesRange( *m_pLB_ROLE
);
558 // replace role in fixed text label
559 const OUString
aReplacementStr( "%VALUETYPE" );
560 sal_Int32 nIndex
= m_aFixedTextRange
.indexOf( aReplacementStr
);
563 m_pFT_RANGE
->SetText(
564 m_aFixedTextRange
.replaceAt(
565 nIndex
, aReplacementStr
.getLength(), aSelectedRoleUI
));
568 m_pEDT_RANGE
->SetText( aSelectedRange
);
575 IMPL_LINK_NOARG(DataSourceTabPage
, MainRangeButtonClickedHdl
)
577 OSL_ASSERT( m_pCurrentRangeChoosingField
== nullptr );
578 m_pCurrentRangeChoosingField
= m_pEDT_RANGE
;
579 if( !m_pEDT_RANGE
->GetText().isEmpty() &&
580 ! updateModelFromControl( m_pCurrentRangeChoosingField
))
583 SeriesEntry
* pEntry
= dynamic_cast< SeriesEntry
* >( m_pLB_SERIES
->FirstSelected());
584 bool bHasSelectedEntry
= (pEntry
!= 0);
586 OUString aSelectedRolesRange
= lcl_GetSelectedRolesRange( *m_pLB_ROLE
);
588 if( bHasSelectedEntry
&& (m_pLB_ROLE
->FirstSelected() != 0))
590 OUString
aUIStr(SCH_RESSTR(STR_DATA_SELECT_RANGE_FOR_SERIES
));
593 OUString
aReplacement( "%VALUETYPE" );
594 sal_Int32 nIndex
= aUIStr
.indexOf( aReplacement
);
597 aUIStr
= aUIStr
.replaceAt( nIndex
, aReplacement
.getLength(),
598 lcl_GetSelectedRole( *m_pLB_ROLE
, true ));
600 // replace series name
601 aReplacement
= "%SERIESNAME";
602 nIndex
= aUIStr
.indexOf( aReplacement
);
605 aUIStr
= aUIStr
.replaceAt( nIndex
, aReplacement
.getLength(),
606 OUString( m_pLB_SERIES
->GetEntryText( pEntry
)));
609 lcl_enableRangeChoosing( true, m_pParentDialog
);
610 m_rDialogModel
.getRangeSelectionHelper()->chooseRange( aSelectedRolesRange
, aUIStr
, *this );
613 m_pCurrentRangeChoosingField
= 0;
618 IMPL_LINK_NOARG(DataSourceTabPage
, CategoriesRangeButtonClickedHdl
)
620 OSL_ASSERT( m_pCurrentRangeChoosingField
== nullptr );
621 m_pCurrentRangeChoosingField
= m_pEDT_CATEGORIES
;
622 if( !m_pEDT_CATEGORIES
->GetText().isEmpty() &&
623 ! updateModelFromControl( m_pCurrentRangeChoosingField
))
626 OUString
aStr( SCH_RESSTR( m_pFT_CATEGORIES
->IsVisible() ? STR_DATA_SELECT_RANGE_FOR_CATEGORIES
: STR_DATA_SELECT_RANGE_FOR_DATALABELS
));
627 lcl_enableRangeChoosing( true, m_pParentDialog
);
628 m_rDialogModel
.getRangeSelectionHelper()->chooseRange(
629 m_rDialogModel
.getCategoriesRange(), aStr
, *this );
633 IMPL_LINK_NOARG(DataSourceTabPage
, AddButtonClickedHdl
)
635 m_rDialogModel
.startControllerLockTimer();
636 SeriesEntry
* pEntry
= dynamic_cast< SeriesEntry
* >( m_pLB_SERIES
->FirstSelected());
637 Reference
< XDataSeries
> xSeriesToInsertAfter
;
638 Reference
< XChartType
> xChartTypeForNewSeries
;
639 if( m_pTemplateProvider
)
640 m_rDialogModel
.setTemplate( m_pTemplateProvider
->getCurrentTemplate());
644 xSeriesToInsertAfter
.set( pEntry
->m_xDataSeries
);
645 xChartTypeForNewSeries
.set( pEntry
->m_xChartType
);
649 ::std::vector
< Reference
< XDataSeriesContainer
> > aCntVec(
650 m_rDialogModel
.getAllDataSeriesContainers());
651 if( ! aCntVec
.empty())
652 xChartTypeForNewSeries
.set( aCntVec
.front(), uno::UNO_QUERY
);
654 OSL_ENSURE( xChartTypeForNewSeries
.is(), "Cannot insert new series" );
656 m_rDialogModel
.insertSeriesAfter( xSeriesToInsertAfter
, xChartTypeForNewSeries
);
660 // note the box was cleared and refilled, so pEntry is invalid now
661 SvTreeListEntry
* pSelEntry
= m_pLB_SERIES
->FirstSelected();
664 SvTreeListEntry
* pNextEntry
= m_pLB_SERIES
->Next( pSelEntry
);
666 m_pLB_SERIES
->Select( pNextEntry
);
668 SeriesSelectionChangedHdl( 0 );
673 IMPL_LINK_NOARG(DataSourceTabPage
, RemoveButtonClickedHdl
)
675 m_rDialogModel
.startControllerLockTimer();
676 SeriesEntry
* pEntry
= dynamic_cast< SeriesEntry
* >( m_pLB_SERIES
->FirstSelected());
679 Reference
< XDataSeries
> xNewSelSeries
;
680 SeriesEntry
* pNewSelEntry
= dynamic_cast< SeriesEntry
* >(m_pLB_SERIES
->Next( pEntry
));
682 xNewSelSeries
.set( pNewSelEntry
->m_xDataSeries
);
685 pNewSelEntry
= dynamic_cast< SeriesEntry
* >( m_pLB_SERIES
->Prev( pEntry
));
687 xNewSelSeries
.set( pNewSelEntry
->m_xDataSeries
);
690 m_rDialogModel
.deleteSeries( pEntry
->m_xDataSeries
, pEntry
->m_xChartType
);
693 m_pLB_SERIES
->RemoveSelection();
696 // select previous or next series
697 //@improve: see methods GetModel()->GetAbsPos()/GetEntry() for absolute list positions
698 if( xNewSelSeries
.is())
700 pEntry
= dynamic_cast< SeriesEntry
* >( m_pLB_SERIES
->First());
703 if( pEntry
->m_xDataSeries
== xNewSelSeries
)
705 m_pLB_SERIES
->Select( pEntry
);
708 pEntry
= dynamic_cast< SeriesEntry
* >( m_pLB_SERIES
->Next( pEntry
));
711 SeriesSelectionChangedHdl( 0 );
717 IMPL_LINK_NOARG(DataSourceTabPage
, UpButtonClickedHdl
)
719 m_rDialogModel
.startControllerLockTimer();
720 SeriesEntry
* pEntry
= dynamic_cast< SeriesEntry
* >( m_pLB_SERIES
->FirstSelected());
721 bool bHasSelectedEntry
= (pEntry
!= 0);
723 if( bHasSelectedEntry
)
725 m_rDialogModel
.moveSeries( pEntry
->m_xDataSeries
, DialogModel::MOVE_UP
);
728 SeriesSelectionChangedHdl(0);
734 IMPL_LINK_NOARG(DataSourceTabPage
, DownButtonClickedHdl
)
736 m_rDialogModel
.startControllerLockTimer();
737 SeriesEntry
* pEntry
= dynamic_cast< SeriesEntry
* >( m_pLB_SERIES
->FirstSelected());
738 bool bHasSelectedEntry
= (pEntry
!= 0);
740 if( bHasSelectedEntry
)
742 m_rDialogModel
.moveSeries( pEntry
->m_xDataSeries
, DialogModel::MOVE_DOWN
);
745 SeriesSelectionChangedHdl(0);
751 IMPL_LINK( DataSourceTabPage
, RangeModifiedHdl
, Edit
*, pEdit
)
753 // note: isValid sets the color of the edit field
754 if( isRangeFieldContentValid( *pEdit
))
757 updateModelFromControl( pEdit
);
758 if( pEdit
== m_pEDT_RANGE
)
760 if( ! lcl_UpdateCurrentSeriesName( *m_pLB_SERIES
))
765 // enable/disable OK button
771 IMPL_LINK( DataSourceTabPage
, RangeUpdateDataHdl
, Edit
*, pEdit
)
773 // note: isValid sets the color of the edit field
774 if( isRangeFieldContentValid( *pEdit
))
777 updateModelFromControl( pEdit
);
778 if( pEdit
== m_pEDT_RANGE
)
780 if( ! lcl_UpdateCurrentSeriesName( *m_pLB_SERIES
))
784 // enable/disable OK button
790 void DataSourceTabPage::listeningFinished(
791 const OUString
& rNewRange
)
793 // rNewRange becomes invalid after removing the listener
794 OUString
aRange( rNewRange
);
796 m_rDialogModel
.startControllerLockTimer();
799 m_rDialogModel
.getRangeSelectionHelper()->stopRangeListening();
804 if( m_pCurrentRangeChoosingField
)
806 m_pCurrentRangeChoosingField
->SetText( aRange
);
807 m_pCurrentRangeChoosingField
->GrabFocus();
810 if( m_pCurrentRangeChoosingField
== m_pEDT_RANGE
)
812 m_pEDT_RANGE
->SetText( aRange
);
815 else if( m_pCurrentRangeChoosingField
== m_pEDT_CATEGORIES
)
817 m_pEDT_CATEGORIES
->SetText( aRange
);
821 updateModelFromControl( m_pCurrentRangeChoosingField
);
822 if( ! lcl_UpdateCurrentSeriesName( *m_pLB_SERIES
))
825 m_pCurrentRangeChoosingField
= 0;
827 updateControlState();
828 lcl_enableRangeChoosing( false, m_pParentDialog
);
831 void DataSourceTabPage::disposingRangeSelection()
833 m_rDialogModel
.getRangeSelectionHelper()->stopRangeListening( false );
836 bool DataSourceTabPage::updateModelFromControl( Edit
* pField
)
841 ControllerLockGuardUNO
aLockedControllers( m_rDialogModel
.getChartModel() );
843 // @todo: validity check of field content
845 bool bAll
= (pField
== 0);
846 Reference
< data::XDataProvider
> xDataProvider( m_rDialogModel
.getDataProvider());
848 if( bAll
|| (pField
== m_pEDT_CATEGORIES
) )
850 Reference
< data::XLabeledDataSequence
> xLabeledSeq( m_rDialogModel
.getCategories() );
851 if( xDataProvider
.is())
853 OUString
aRange( m_pEDT_CATEGORIES
->GetText());
854 if( !aRange
.isEmpty())
856 // create or change categories
857 if( !xLabeledSeq
.is())
859 xLabeledSeq
.set( DataSourceHelper::createLabeledDataSequence( Reference
< uno::XComponentContext
>(0)));
860 m_rDialogModel
.setCategories( xLabeledSeq
);
864 xLabeledSeq
->setValues( xDataProvider
->createDataSequenceByRangeRepresentation( aRange
));
866 catch( const uno::Exception
& ex
)
868 // should work as validation should have happened before
869 ASSERT_EXCEPTION( ex
);
872 else if( xLabeledSeq
.is())
874 // clear existing categories
876 m_rDialogModel
.setCategories( xLabeledSeq
);
881 SeriesEntry
* pSeriesEntry
= dynamic_cast< SeriesEntry
* >( m_pLB_SERIES
->FirstSelected());
882 bool bHasSelectedEntry
= (pSeriesEntry
!= 0);
884 if( bHasSelectedEntry
)
886 if( bAll
|| (pField
== m_pEDT_RANGE
) )
890 OUString aSelectedRole
= lcl_GetSelectedRole( *m_pLB_ROLE
);
891 OUString
aRange( m_pEDT_RANGE
->GetText());
892 OUString
aSequenceRole( aSelectedRole
);
893 bool bIsLabel
= (aSequenceRole
== lcl_aLabelRole
);
894 OUString
aSequenceNameForLabel( lcl_GetSequenceNameForLabel( pSeriesEntry
));
897 aSequenceRole
= aSequenceNameForLabel
;
899 Reference
< data::XDataSource
> xSource( pSeriesEntry
->m_xDataSeries
, uno::UNO_QUERY_THROW
);
900 Reference
< data::XLabeledDataSequence
> xLabeledSeq(
901 DataSeriesHelper::getDataSequenceByRole( xSource
, aSequenceRole
));
903 if( xDataProvider
.is())
907 if( ! xLabeledSeq
.is())
909 // check if there is already an "orphan" label sequence
910 xLabeledSeq
.set( lcl_findLSequenceWithOnlyLabel( xSource
));
911 if( ! xLabeledSeq
.is())
913 // no corresponding labeled data sequence for label found
914 xLabeledSeq
.set( DataSourceHelper::createLabeledDataSequence( Reference
< uno::XComponentContext
>(0)));
915 lcl_addLSequenceToDataSource( xLabeledSeq
, xSource
);
918 if( xLabeledSeq
.is())
920 if( !aRange
.isEmpty())
922 Reference
< data::XDataSequence
> xNewSeq
;
925 xNewSeq
.set( xDataProvider
->createDataSequenceByRangeRepresentation( aRange
));
927 catch( const uno::Exception
& ex
)
929 // should work as validation should have happened before
930 ASSERT_EXCEPTION( ex
);
934 // update range name by the full string provided
935 // by the data provider. E.g. "a1" might become
937 aRange
= xNewSeq
->getSourceRangeRepresentation();
938 Reference
< beans::XPropertySet
> xProp( xNewSeq
, uno::UNO_QUERY_THROW
);
939 xProp
->setPropertyValue( "Role" , uno::makeAny( lcl_aLabelRole
));
940 xLabeledSeq
->setLabel( xNewSeq
);
945 xLabeledSeq
->setLabel( Reference
< data::XDataSequence
>());
951 if( !aRange
.isEmpty())
953 Reference
< data::XDataSequence
> xNewSeq
;
956 xNewSeq
.set( xDataProvider
->createDataSequenceByRangeRepresentation( aRange
));
958 catch( const uno::Exception
& ex
)
960 // should work as validation should have happened before
961 ASSERT_EXCEPTION( ex
);
965 // update range name by the full string provided
966 // by the data provider. E.g. "a1:e1" might become
967 // "$Sheet1.$A$1:$E$1"
968 aRange
= xNewSeq
->getSourceRangeRepresentation();
970 Reference
< beans::XPropertySet
> xProp( xNewSeq
, uno::UNO_QUERY_THROW
);
971 xProp
->setPropertyValue( "Role" , uno::makeAny( aSelectedRole
));
972 if( !xLabeledSeq
.is())
974 if( aSelectedRole
== aSequenceNameForLabel
)
975 xLabeledSeq
.set( lcl_findLSequenceWithOnlyLabel( xSource
));
976 if( ! xLabeledSeq
.is())
978 xLabeledSeq
.set( DataSourceHelper::createLabeledDataSequence( Reference
< uno::XComponentContext
>(0)));
979 lcl_addLSequenceToDataSource( xLabeledSeq
, xSource
);
982 xLabeledSeq
->setValues( xNewSeq
);
988 lcl_UpdateCurrentRange( *m_pLB_ROLE
, aSelectedRole
, aRange
);
990 catch( const uno::Exception
& ex
)
993 ASSERT_EXCEPTION( ex
);
999 // @todo remove this when automatic view updates from calc, writer and own data sequences are available
1004 Reference
< util::XModifiable
> xModifiable( m_rDialogModel
.getChartModel(), uno::UNO_QUERY
);
1005 if( xModifiable
.is() )
1006 xModifiable
->setModified( sal_True
);
1007 const DialogModelTimeBasedInfo
& rInfo
= m_rDialogModel
.getTimeBasedInfo();
1008 if(rInfo
.bTimeBased
)
1010 m_rDialogModel
.setTimeBasedRange(rInfo
.bTimeBased
, rInfo
.nStart
, rInfo
.nEnd
);
1013 catch( const uno::Exception
& ex
)
1015 ASSERT_EXCEPTION( ex
);
1022 } // namespace chart
1024 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */