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 <ChartType.hxx>
24 #include <ChartTypeTemplateProvider.hxx>
25 #include <ChartTypeTemplate.hxx>
26 #include <ChartModel.hxx>
27 #include <RangeSelectionHelper.hxx>
28 #include <DataSeries.hxx>
29 #include <DataSeriesHelper.hxx>
30 #include <ControllerLockGuard.hxx>
31 #include <DataSourceHelper.hxx>
32 #include <LabeledDataSequence.hxx>
33 #include "DialogModel.hxx"
34 #include <o3tl/safeint.hxx>
35 #include <TabPageNotifiable.hxx>
36 #include <com/sun/star/chart2/data/XDataProvider.hpp>
38 #include <comphelper/diagnose_ex.hxx>
40 using namespace ::com::sun::star
;
41 using namespace ::com::sun::star::chart2
;
43 using ::com::sun::star::uno::Reference
;
48 constexpr OUString
lcl_aLabelRole( u
"label"_ustr
);
50 void lcl_UpdateCurrentRange(weld::TreeView
& rOutListBox
, const OUString
& rRole
,
51 const OUString
& rRange
)
53 int nEntry
= rOutListBox
.get_selected_index();
56 rOutListBox
.set_text(nEntry
, ::chart::DialogModel::ConvertRoleFromInternalToUI(rRole
), 0);
57 rOutListBox
.set_text(nEntry
, rRange
, 1);
58 ::chart::SeriesEntry
* pEntry
= weld::fromId
<::chart::SeriesEntry
*>(rOutListBox
.get_id(nEntry
));
59 pEntry
->m_sRole
= rRole
;
63 bool lcl_UpdateCurrentSeriesName(weld::TreeView
& rOutListBox
)
65 int nEntry
= rOutListBox
.get_selected_index();
70 ::chart::SeriesEntry
* pEntry
= weld::fromId
<::chart::SeriesEntry
*>(rOutListBox
.get_id(nEntry
));
71 if (pEntry
->m_xDataSeries
.is() && pEntry
->m_xChartType
.is())
73 OUString
aLabel(pEntry
->m_xDataSeries
->getLabelForRole(
74 pEntry
->m_xChartType
->getRoleOfSequenceForSeriesLabel()));
75 if (!aLabel
.isEmpty())
77 rOutListBox
.set_text(nEntry
, aLabel
);
84 OUString
lcl_GetSelectedRole(const weld::TreeView
& rRoleListBox
, bool bUITranslated
= false)
86 int nEntry
= rRoleListBox
.get_selected_index();
90 return rRoleListBox
.get_text(nEntry
);
91 ::chart::SeriesEntry
* pEntry
= weld::fromId
<::chart::SeriesEntry
*>(rRoleListBox
.get_id(nEntry
));
92 return pEntry
->m_sRole
;
97 OUString
lcl_GetSelectedRolesRange( const weld::TreeView
& rRoleListBox
)
100 int nEntry
= rRoleListBox
.get_selected_index();
102 aResult
= rRoleListBox
.get_text(nEntry
, 1);
106 OUString
lcl_GetSequenceNameForLabel(const ::chart::SeriesEntry
* pEntry
)
108 OUString
aResult(u
"values-y"_ustr
);
109 if (pEntry
&& pEntry
->m_xChartType
.is())
110 aResult
= pEntry
->m_xChartType
->getRoleOfSequenceForSeriesLabel();
114 void lcl_addLSequenceToDataSource(
115 const uno::Reference
< chart2::data::XLabeledDataSequence
> & xLSequence
,
116 const Reference
< ::chart::DataSeries
> & xSource
)
120 std::vector
< uno::Reference
< chart2::data::XLabeledDataSequence
> > aData
= xSource
->getDataSequences2();
121 aData
.push_back( xLSequence
);
122 xSource
->setData( aData
);
126 uno::Reference
< chart2::data::XLabeledDataSequence
> lcl_findLSequenceWithOnlyLabel(
127 const rtl::Reference
< ::chart::DataSeries
> & xDataSource
)
129 uno::Reference
< chart2::data::XLabeledDataSequence
> xResult
;
131 for( uno::Reference
< chart2::data::XLabeledDataSequence
> const & labeledDataSeq
: xDataSource
->getDataSequences2() )
133 // no values are set but a label exists
134 if( ! labeledDataSeq
->getValues().is() &&
135 labeledDataSeq
->getLabel().is())
137 xResult
= labeledDataSeq
;
145 } // anonymous namespace
150 DataSourceTabPage::DataSourceTabPage(weld::Container
* pPage
, weld::DialogController
* pController
,
151 DialogModel
& rDialogModel
,
152 ChartTypeTemplateProvider
* pTemplateProvider
,
153 bool bHideDescription
/* = false */)
154 : ::vcl::OWizardPage(pPage
, pController
, u
"modules/schart/ui/tp_DataSource.ui"_ustr
, u
"tp_DataSource"_ustr
)
155 , m_pTemplateProvider(pTemplateProvider
)
156 , m_rDialogModel(rDialogModel
)
157 , m_pCurrentRangeChoosingField( nullptr )
158 , m_bIsDirty( false )
159 , m_pTabPageNotifiable(dynamic_cast<TabPageNotifiable
*>(pController
))
160 , m_xFT_CAPTION(m_xBuilder
->weld_label(u
"FT_CAPTION_FOR_WIZARD"_ustr
))
161 , m_xFT_SERIES(m_xBuilder
->weld_label(u
"FT_SERIES"_ustr
))
162 , m_xLB_SERIES(m_xBuilder
->weld_tree_view(u
"LB_SERIES"_ustr
))
163 , m_xBTN_ADD(m_xBuilder
->weld_button(u
"BTN_ADD"_ustr
))
164 , m_xBTN_REMOVE(m_xBuilder
->weld_button(u
"BTN_REMOVE"_ustr
))
165 , m_xBTN_UP(m_xBuilder
->weld_button(u
"BTN_UP"_ustr
))
166 , m_xBTN_DOWN(m_xBuilder
->weld_button(u
"BTN_DOWN"_ustr
))
167 , m_xFT_ROLE(m_xBuilder
->weld_label(u
"FT_ROLE"_ustr
))
168 , m_xLB_ROLE(m_xBuilder
->weld_tree_view(u
"LB_ROLE"_ustr
))
169 , m_xFT_RANGE(m_xBuilder
->weld_label(u
"FT_RANGE"_ustr
))
170 , m_xEDT_RANGE(m_xBuilder
->weld_entry(u
"EDT_RANGE"_ustr
))
171 , m_xIMB_RANGE_MAIN(m_xBuilder
->weld_button(u
"IMB_RANGE_MAIN"_ustr
))
172 , m_xFT_CATEGORIES(m_xBuilder
->weld_label(u
"FT_CATEGORIES"_ustr
))
173 , m_xFT_DATALABELS(m_xBuilder
->weld_label(u
"FT_DATALABELS"_ustr
))
174 , m_xEDT_CATEGORIES(m_xBuilder
->weld_entry(u
"EDT_CATEGORIES"_ustr
))
175 , m_xIMB_RANGE_CAT(m_xBuilder
->weld_button(u
"IMB_RANGE_CAT"_ustr
))
177 m_xLB_SERIES
->set_size_request(m_xLB_SERIES
->get_approximate_digit_width() * 25,
178 m_xLB_SERIES
->get_height_rows(10));
179 m_xLB_ROLE
->set_size_request(m_xLB_ROLE
->get_approximate_digit_width() * 60,
180 m_xLB_ROLE
->get_height_rows(5));
181 m_xFT_CAPTION
->set_visible(!bHideDescription
);
183 m_aFixedTextRange
= m_xFT_RANGE
->get_label();
184 SetPageTitle(SchResId(STR_OBJECT_DATASERIES_PLURAL
));
187 m_xLB_SERIES
->connect_selection_changed(
188 LINK(this, DataSourceTabPage
, SeriesSelectionChangedHdl
));
189 m_xLB_ROLE
->connect_selection_changed(LINK(this, DataSourceTabPage
, RoleSelectionChangedHdl
));
191 m_xIMB_RANGE_MAIN
->connect_clicked(LINK(this, DataSourceTabPage
, MainRangeButtonClickedHdl
));
192 m_xIMB_RANGE_CAT
->connect_clicked(LINK(this, DataSourceTabPage
, CategoriesRangeButtonClickedHdl
));
194 m_xBTN_ADD
->connect_clicked(LINK(this, DataSourceTabPage
, AddButtonClickedHdl
));
195 m_xBTN_REMOVE
->connect_clicked(LINK(this, DataSourceTabPage
, RemoveButtonClickedHdl
));
197 m_xBTN_UP
->connect_clicked(LINK(this, DataSourceTabPage
, UpButtonClickedHdl
));
198 m_xBTN_DOWN
->connect_clicked(LINK(this, DataSourceTabPage
, DownButtonClickedHdl
));
200 m_xEDT_RANGE
->connect_changed(LINK(this, DataSourceTabPage
, RangeModifiedHdl
));
201 m_xEDT_CATEGORIES
->connect_changed(LINK( this, DataSourceTabPage
, RangeModifiedHdl
));
204 std::vector
<int> aWidths
{ o3tl::narrowing
<int>(m_xLB_ROLE
->get_approximate_digit_width() * 20) };
205 m_xLB_ROLE
->set_column_fixed_widths(aWidths
);
208 updateControlsFromDialogModel();
210 // select first series
211 if (m_xLB_SERIES
->n_children())
212 m_xLB_SERIES
->select(0);
215 void DataSourceTabPage::InsertRoleLBEntry(const OUString
& rRole
, const OUString
& rRange
)
217 m_aEntries
.emplace_back(new SeriesEntry
);
218 SeriesEntry
* pEntry
= m_aEntries
.back().get();
219 pEntry
->m_sRole
= rRole
;
220 m_xLB_ROLE
->append(weld::toId(pEntry
),
221 ::chart::DialogModel::ConvertRoleFromInternalToUI(rRole
));
222 m_xLB_ROLE
->set_text(m_xLB_ROLE
->n_children() - 1, rRange
, 1);
225 DataSourceTabPage::~DataSourceTabPage()
229 void DataSourceTabPage::Activate()
231 OWizardPage::Activate();
232 updateControlsFromDialogModel();
233 m_xLB_SERIES
->grab_focus();
236 void DataSourceTabPage::initializePage()
240 void DataSourceTabPage::Deactivate()
243 vcl::OWizardPage::Deactivate();
246 void DataSourceTabPage::commitPage()
248 commitPage(::vcl::WizardTypes::eFinish
);
251 bool DataSourceTabPage::commitPage( ::vcl::WizardTypes::CommitPageReason
/*eReason*/ )
253 //ranges may have been edited in the meanwhile (dirty is true in that case here)
256 updateModelFromControl();
257 return true; //return false if this page should not be left
263 bool DataSourceTabPage::isRangeFieldContentValid(weld::Entry
& rEdit
)
265 OUString
aRange(rEdit
.get_text());
266 bool bIsValid
= aRange
.isEmpty() ||
267 m_rDialogModel
.getRangeSelectionHelper()->verifyCellRange(aRange
);
268 rEdit
.set_message_type(bIsValid
? weld::EntryMessageType::Normal
: weld::EntryMessageType::Error
);
272 bool DataSourceTabPage::isValid()
274 bool bRoleRangeValid
= true;
275 bool bCategoriesRangeValid
= true;
276 bool bHasSelectedEntry
= (m_xLB_SERIES
->get_selected_index() != -1);
278 if (bHasSelectedEntry
)
279 bRoleRangeValid
= isRangeFieldContentValid(*m_xEDT_RANGE
);
280 if (m_xEDT_CATEGORIES
->get_sensitive())
281 bCategoriesRangeValid
= isRangeFieldContentValid( *m_xEDT_CATEGORIES
);
282 bool bValid
= ( bRoleRangeValid
&& bCategoriesRangeValid
);
284 if( m_pTabPageNotifiable
)
287 m_pTabPageNotifiable
->setValidPage( this );
289 m_pTabPageNotifiable
->setInvalidPage( this );
295 void DataSourceTabPage::setDirty()
300 void DataSourceTabPage::updateControlsFromDialogModel()
304 SeriesSelectionChangedHdl(*m_xLB_SERIES
);
307 m_xEDT_CATEGORIES
->set_text(m_rDialogModel
.getCategoriesRange());
309 updateControlState();
312 void DataSourceTabPage::fillSeriesListBox()
314 rtl::Reference
< DataSeries
> xSelected
;
315 SeriesEntry
* pEntry
= nullptr;
316 int nEntry
= m_xLB_SERIES
->get_selected_index();
319 pEntry
= weld::fromId
<SeriesEntry
*>(m_xLB_SERIES
->get_id(nEntry
));
320 xSelected
= pEntry
->m_xDataSeries
;
323 bool bHasSelectedEntry
= (pEntry
!= nullptr);
324 int nSelectedEntry
= -1;
326 m_xLB_SERIES
->freeze();
327 m_xLB_SERIES
->clear();
329 std::vector
< DialogModel::tSeriesWithChartTypeByName
> aSeries(
330 m_rDialogModel
.getAllDataSeriesWithLabel() );
332 sal_Int32 nUnnamedSeriesIndex
= 1;
334 for (auto const& series
: aSeries
)
336 OUString
aLabel(series
.first
);
337 if (aLabel
.isEmpty())
339 if( nUnnamedSeriesIndex
> 1 )
341 OUString
aResString(::chart::SchResId( STR_DATA_UNNAMED_SERIES_WITH_INDEX
));
343 // replace index of unnamed series
344 static constexpr OUString
aReplacementStr( u
"%NUMBER"_ustr
);
345 sal_Int32 nIndex
= aResString
.indexOf( aReplacementStr
);
347 aLabel
= aResString
.replaceAt(
348 nIndex
, aReplacementStr
.getLength(),
349 OUString::number(nUnnamedSeriesIndex
));
351 if( aLabel
.isEmpty() )
352 aLabel
= ::chart::SchResId( STR_DATA_UNNAMED_SERIES
);
354 ++nUnnamedSeriesIndex
;
357 m_aEntries
.emplace_back(new SeriesEntry
);
358 pEntry
= m_aEntries
.back().get();
359 pEntry
->m_xDataSeries
= series
.second
.first
;
360 pEntry
->m_xChartType
= series
.second
.second
;
361 m_xLB_SERIES
->append(weld::toId(pEntry
), aLabel
);
362 if (bHasSelectedEntry
&& series
.second
.first
== xSelected
)
363 nSelectedEntry
= nEntry
;
367 m_xLB_SERIES
->thaw();
369 if (bHasSelectedEntry
&& nSelectedEntry
!= -1)
370 m_xLB_SERIES
->select(nSelectedEntry
);
373 void DataSourceTabPage::fillRoleListBox()
375 int nSeriesEntry
= m_xLB_SERIES
->get_selected_index();
376 SeriesEntry
* pSeriesEntry
= nullptr;
377 if (nSeriesEntry
!= -1)
378 pSeriesEntry
= weld::fromId
<SeriesEntry
*>(m_xLB_SERIES
->get_id(nSeriesEntry
));
379 bool bHasSelectedEntry
= (pSeriesEntry
!= nullptr);
381 int nRoleIndex
= m_xLB_ROLE
->get_selected_index();
382 if (!bHasSelectedEntry
)
385 DialogModel::tRolesWithRanges
aRoles(
386 DialogModel::getRolesWithRanges(
387 pSeriesEntry
->m_xDataSeries
,
388 lcl_GetSequenceNameForLabel( pSeriesEntry
),
389 pSeriesEntry
->m_xChartType
));
392 m_xLB_ROLE
->freeze();
395 for (auto const& elemRole
: aRoles
)
397 InsertRoleLBEntry(elemRole
.first
, elemRole
.second
);
402 // series may contain no roles, check listbox size before selecting entries
403 if (m_xLB_ROLE
->n_children() > 0)
405 if (nRoleIndex
== -1 || nRoleIndex
>= m_xLB_ROLE
->n_children())
407 m_xLB_ROLE
->select(nRoleIndex
);
411 void DataSourceTabPage::updateControlState()
413 int nSeriesEntry
= m_xLB_SERIES
->get_selected_index();
414 bool bHasSelectedSeries
= nSeriesEntry
!= -1;
415 bool bHasValidRole
= false;
416 bool bHasRangeChooser
= m_rDialogModel
.getRangeSelectionHelper()->hasRangeSelection();
418 if( bHasSelectedSeries
)
420 int nRoleEntry
= m_xLB_ROLE
->get_selected_index();
421 bHasValidRole
= nRoleEntry
!= -1;
424 m_xBTN_ADD
->set_sensitive(true);
425 m_xBTN_REMOVE
->set_sensitive(bHasSelectedSeries
);
427 m_xBTN_UP
->set_sensitive(bHasSelectedSeries
&& (nSeriesEntry
!= 0));
428 m_xBTN_DOWN
->set_sensitive(bHasSelectedSeries
&& (nSeriesEntry
!= m_xLB_SERIES
->n_children() - 1));
430 bool bHasCategories
= m_rDialogModel
.isCategoryDiagram();
432 m_xFT_DATALABELS
->set_visible(!bHasCategories
);
433 m_xFT_CATEGORIES
->set_visible( bHasCategories
);
434 bool bShowIB
= bHasRangeChooser
;
436 m_xIMB_RANGE_CAT
->set_visible(bShowIB
);
438 m_xFT_ROLE
->set_sensitive(bHasSelectedSeries
);
439 m_xLB_ROLE
->set_sensitive(bHasSelectedSeries
);
441 m_xFT_RANGE
->set_sensitive(bHasValidRole
);
442 m_xEDT_RANGE
->set_sensitive(bHasValidRole
);
444 m_xFT_SERIES
->set_sensitive(true);
445 m_xLB_SERIES
->set_sensitive(true);
447 m_xIMB_RANGE_MAIN
->set_visible(bShowIB
);
452 IMPL_LINK_NOARG(DataSourceTabPage
, SeriesSelectionChangedHdl
, weld::TreeView
&, void)
454 m_rDialogModel
.startControllerLockTimer();
455 if (m_xLB_SERIES
->get_selected_index() != -1)
458 RoleSelectionChangedHdl(*m_xLB_ROLE
);
460 updateControlState();
463 IMPL_LINK_NOARG(DataSourceTabPage
, RoleSelectionChangedHdl
, weld::TreeView
&, void)
465 m_rDialogModel
.startControllerLockTimer();
466 int nEntry
= m_xLB_ROLE
->get_selected_index();
470 OUString aSelectedRoleUI
= lcl_GetSelectedRole( *m_xLB_ROLE
, true );
471 OUString aSelectedRange
= lcl_GetSelectedRolesRange( *m_xLB_ROLE
);
473 // replace role in fixed text label
474 static constexpr OUString
aReplacementStr( u
"%VALUETYPE"_ustr
);
475 sal_Int32 nIndex
= m_aFixedTextRange
.indexOf( aReplacementStr
);
478 m_xFT_RANGE
->set_label(
479 m_aFixedTextRange
.replaceAt(
480 nIndex
, aReplacementStr
.getLength(), aSelectedRoleUI
));
483 m_xEDT_RANGE
->set_text(aSelectedRange
);
487 IMPL_LINK_NOARG(DataSourceTabPage
, MainRangeButtonClickedHdl
, weld::Button
&, void)
489 OSL_ASSERT( m_pCurrentRangeChoosingField
== nullptr );
490 m_pCurrentRangeChoosingField
= m_xEDT_RANGE
.get();
491 if (!m_xEDT_RANGE
->get_text().isEmpty() &&
492 !updateModelFromControl( m_pCurrentRangeChoosingField
))
495 int nEntry
= m_xLB_SERIES
->get_selected_index();
496 bool bHasSelectedEntry
= (nEntry
!= -1);
498 OUString aSelectedRolesRange
= lcl_GetSelectedRolesRange(*m_xLB_ROLE
);
500 if (bHasSelectedEntry
&& (m_xLB_ROLE
->get_selected_index() != -1))
502 OUString
aUIStr(SchResId(STR_DATA_SELECT_RANGE_FOR_SERIES
));
505 OUString
aReplacement( u
"%VALUETYPE"_ustr
);
506 sal_Int32 nIndex
= aUIStr
.indexOf( aReplacement
);
509 aUIStr
= aUIStr
.replaceAt( nIndex
, aReplacement
.getLength(),
510 lcl_GetSelectedRole( *m_xLB_ROLE
, true ));
512 // replace series name
513 aReplacement
= "%SERIESNAME";
514 nIndex
= aUIStr
.indexOf( aReplacement
);
517 aUIStr
= aUIStr
.replaceAt(nIndex
, aReplacement
.getLength(),
518 m_xLB_SERIES
->get_text(nEntry
));
521 enableRangeChoosing(true, m_pDialogController
);
522 m_rDialogModel
.getRangeSelectionHelper()->chooseRange( aSelectedRolesRange
, aUIStr
, *this );
525 m_pCurrentRangeChoosingField
= nullptr;
528 IMPL_LINK_NOARG(DataSourceTabPage
, CategoriesRangeButtonClickedHdl
, weld::Button
&, void)
530 OSL_ASSERT( m_pCurrentRangeChoosingField
== nullptr );
531 m_pCurrentRangeChoosingField
= m_xEDT_CATEGORIES
.get();
532 if( !m_xEDT_CATEGORIES
->get_text().isEmpty() &&
533 ! updateModelFromControl( m_pCurrentRangeChoosingField
))
536 OUString
aStr(SchResId(m_xFT_CATEGORIES
->get_visible() ? STR_DATA_SELECT_RANGE_FOR_CATEGORIES
: STR_DATA_SELECT_RANGE_FOR_DATALABELS
));
537 enableRangeChoosing(true, m_pDialogController
);
538 m_rDialogModel
.getRangeSelectionHelper()->chooseRange(
539 m_rDialogModel
.getCategoriesRange(), aStr
, *this );
542 IMPL_LINK_NOARG(DataSourceTabPage
, AddButtonClickedHdl
, weld::Button
&, void)
544 m_rDialogModel
.startControllerLockTimer();
545 int nEntry
= m_xLB_SERIES
->get_selected_index();
546 rtl::Reference
< DataSeries
> xSeriesToInsertAfter
;
547 rtl::Reference
< ChartType
> xChartTypeForNewSeries
;
548 if( m_pTemplateProvider
)
549 m_rDialogModel
.setTemplate( m_pTemplateProvider
->getCurrentTemplate());
553 ::chart::SeriesEntry
* pEntry
= weld::fromId
<::chart::SeriesEntry
*>(m_xLB_SERIES
->get_id(nEntry
));
554 xSeriesToInsertAfter
= pEntry
->m_xDataSeries
;
555 xChartTypeForNewSeries
= pEntry
->m_xChartType
;
559 std::vector
< rtl::Reference
< ChartType
> > aCntVec(
560 m_rDialogModel
.getAllDataSeriesContainers());
561 if( ! aCntVec
.empty())
562 xChartTypeForNewSeries
= aCntVec
.front();
564 OSL_ENSURE( xChartTypeForNewSeries
.is(), "Cannot insert new series" );
566 m_rDialogModel
.insertSeriesAfter( xSeriesToInsertAfter
, xChartTypeForNewSeries
);
570 // note the box was cleared and refilled, so nEntry is invalid now
572 int nSelEntry
= m_xLB_SERIES
->get_selected_index();
576 if (nSelEntry
< m_xLB_SERIES
->n_children())
577 m_xLB_SERIES
->select(nSelEntry
);
579 SeriesSelectionChangedHdl(*m_xLB_SERIES
);
582 IMPL_LINK_NOARG(DataSourceTabPage
, RemoveButtonClickedHdl
, weld::Button
&, void)
584 m_rDialogModel
.startControllerLockTimer();
585 int nEntry
= m_xLB_SERIES
->get_selected_index();
589 SeriesEntry
* pEntry
= weld::fromId
<::chart::SeriesEntry
*>(m_xLB_SERIES
->get_id(nEntry
));
590 rtl::Reference
< DataSeries
> xNewSelSeries
;
591 SeriesEntry
* pNewSelEntry
= nullptr;
592 if (nEntry
+ 1 < m_xLB_SERIES
->n_children())
593 pNewSelEntry
= weld::fromId
<::chart::SeriesEntry
*>(m_xLB_SERIES
->get_id(nEntry
+ 1));
595 pNewSelEntry
= weld::fromId
<::chart::SeriesEntry
*>(m_xLB_SERIES
->get_id(nEntry
- 1));
597 xNewSelSeries
= pNewSelEntry
->m_xDataSeries
;
599 m_rDialogModel
.deleteSeries( pEntry
->m_xDataSeries
, pEntry
->m_xChartType
);
602 m_xLB_SERIES
->remove(nEntry
);
605 // select previous or next series
606 if (xNewSelSeries
.is())
608 for (int i
= 0; i
< m_xLB_SERIES
->n_children(); ++i
)
610 pEntry
= weld::fromId
<::chart::SeriesEntry
*>(m_xLB_SERIES
->get_id(i
));
611 if (pEntry
->m_xDataSeries
== xNewSelSeries
)
613 m_xLB_SERIES
->select(i
);
618 SeriesSelectionChangedHdl(*m_xLB_SERIES
);
621 IMPL_LINK_NOARG(DataSourceTabPage
, UpButtonClickedHdl
, weld::Button
&, void)
623 m_rDialogModel
.startControllerLockTimer();
625 int nEntry
= m_xLB_SERIES
->get_selected_index();
626 SeriesEntry
* pEntry
= nullptr;
628 pEntry
= weld::fromId
<SeriesEntry
*>(m_xLB_SERIES
->get_id(nEntry
));
630 bool bHasSelectedEntry
= (pEntry
!= nullptr);
632 if (bHasSelectedEntry
)
634 m_rDialogModel
.moveSeries( pEntry
->m_xDataSeries
, DialogModel::MoveDirection::Up
);
637 SeriesSelectionChangedHdl(*m_xLB_SERIES
);
641 IMPL_LINK_NOARG(DataSourceTabPage
, DownButtonClickedHdl
, weld::Button
&, void)
643 m_rDialogModel
.startControllerLockTimer();
645 int nEntry
= m_xLB_SERIES
->get_selected_index();
646 SeriesEntry
* pEntry
= nullptr;
648 pEntry
= weld::fromId
<SeriesEntry
*>(m_xLB_SERIES
->get_id(nEntry
));
650 bool bHasSelectedEntry
= (pEntry
!= nullptr);
652 if (bHasSelectedEntry
)
654 m_rDialogModel
.moveSeries( pEntry
->m_xDataSeries
, DialogModel::MoveDirection::Down
);
657 SeriesSelectionChangedHdl(*m_xLB_SERIES
);
661 IMPL_LINK(DataSourceTabPage
, RangeModifiedHdl
, weld::Entry
&, rEdit
, void)
663 // note: isValid sets the color of the edit field
664 if( isRangeFieldContentValid( rEdit
))
667 updateModelFromControl( &rEdit
);
668 if (&rEdit
== m_xEDT_RANGE
.get())
670 if( ! lcl_UpdateCurrentSeriesName( *m_xLB_SERIES
))
675 // enable/disable OK button
679 void DataSourceTabPage::listeningFinished(
680 const OUString
& rNewRange
)
682 // rNewRange becomes invalid after removing the listener
683 OUString
aRange( rNewRange
);
685 m_rDialogModel
.startControllerLockTimer();
688 m_rDialogModel
.getRangeSelectionHelper()->stopRangeListening();
691 if( m_pCurrentRangeChoosingField
)
693 m_pCurrentRangeChoosingField
->set_text(aRange
);
694 m_pCurrentRangeChoosingField
->grab_focus();
697 if (m_pCurrentRangeChoosingField
== m_xEDT_RANGE
.get())
699 m_xEDT_RANGE
->set_text(aRange
);
702 else if (m_pCurrentRangeChoosingField
== m_xEDT_CATEGORIES
.get())
704 m_xEDT_CATEGORIES
->set_text(aRange
);
708 updateModelFromControl(m_pCurrentRangeChoosingField
);
709 if (!lcl_UpdateCurrentSeriesName(*m_xLB_SERIES
))
712 m_pCurrentRangeChoosingField
= nullptr;
714 updateControlState();
715 enableRangeChoosing(false, m_pDialogController
);
718 void DataSourceTabPage::disposingRangeSelection()
720 m_rDialogModel
.getRangeSelectionHelper()->stopRangeListening( false );
723 bool DataSourceTabPage::updateModelFromControl(const weld::Entry
* pField
)
728 ControllerLockGuardUNO
aLockedControllers( m_rDialogModel
.getChartModel() );
730 // @todo: validity check of field content
732 bool bAll
= (pField
== nullptr);
733 Reference
< data::XDataProvider
> xDataProvider( m_rDialogModel
.getDataProvider());
735 if (bAll
|| (pField
== m_xEDT_CATEGORIES
.get()))
737 uno::Reference
< chart2::data::XLabeledDataSequence
> xLabeledSeq( m_rDialogModel
.getCategories() );
738 if( xDataProvider
.is())
740 OUString
aRange(m_xEDT_CATEGORIES
->get_text());
741 if (!aRange
.isEmpty())
743 // create or change categories
744 if( !xLabeledSeq
.is())
746 xLabeledSeq
= DataSourceHelper::createLabeledDataSequence();
747 m_rDialogModel
.setCategories( xLabeledSeq
);
751 xLabeledSeq
->setValues( xDataProvider
->createDataSequenceByRangeRepresentation( aRange
));
753 catch( const uno::Exception
& )
755 // should work as validation should have happened before
756 DBG_UNHANDLED_EXCEPTION("chart2");
759 else if( xLabeledSeq
.is())
761 // clear existing categories
763 m_rDialogModel
.setCategories( xLabeledSeq
);
768 int nSeriesEntry
= m_xLB_SERIES
->get_selected_index();
769 SeriesEntry
* pSeriesEntry
= nullptr;
770 if (nSeriesEntry
!= -1)
771 pSeriesEntry
= weld::fromId
<SeriesEntry
*>(m_xLB_SERIES
->get_id(nSeriesEntry
));
772 bool bHasSelectedEntry
= (pSeriesEntry
!= nullptr);
774 if( bHasSelectedEntry
)
776 if( bAll
|| (pField
== m_xEDT_RANGE
.get()) )
780 OUString aSelectedRole
= lcl_GetSelectedRole( *m_xLB_ROLE
);
781 OUString
aRange(m_xEDT_RANGE
->get_text());
782 OUString
aSequenceRole( aSelectedRole
);
783 bool bIsLabel
= (aSequenceRole
== lcl_aLabelRole
);
784 OUString
aSequenceNameForLabel( lcl_GetSequenceNameForLabel( pSeriesEntry
));
787 aSequenceRole
= aSequenceNameForLabel
;
789 uno::Reference
< chart2::data::XLabeledDataSequence
> xLabeledSeq
=
790 DataSeriesHelper::getDataSequenceByRole( pSeriesEntry
->m_xDataSeries
, aSequenceRole
);
792 if( xDataProvider
.is())
796 if( ! xLabeledSeq
.is())
798 // check if there is already an "orphan" label sequence
799 xLabeledSeq
= lcl_findLSequenceWithOnlyLabel( pSeriesEntry
->m_xDataSeries
);
800 if( ! xLabeledSeq
.is())
802 // no corresponding labeled data sequence for label found
803 xLabeledSeq
= DataSourceHelper::createLabeledDataSequence();
804 lcl_addLSequenceToDataSource( xLabeledSeq
, pSeriesEntry
->m_xDataSeries
);
807 if( xLabeledSeq
.is())
809 if( !aRange
.isEmpty())
811 Reference
< data::XDataSequence
> xNewSeq
;
814 xNewSeq
.set( xDataProvider
->createDataSequenceByRangeRepresentation( aRange
));
816 catch( const uno::Exception
& )
818 // should work as validation should have happened before
819 DBG_UNHANDLED_EXCEPTION("chart2");
823 // update range name by the full string provided
824 // by the data provider. E.g. "a1" might become
826 aRange
= xNewSeq
->getSourceRangeRepresentation();
827 Reference
< beans::XPropertySet
> xProp( xNewSeq
, uno::UNO_QUERY_THROW
);
828 xProp
->setPropertyValue( u
"Role"_ustr
, uno::Any( lcl_aLabelRole
));
830 //Labels should always include hidden cells, regardless of the setting chosen
831 xProp
->setPropertyValue( u
"IncludeHiddenCells"_ustr
, uno::Any(true));
832 xLabeledSeq
->setLabel( xNewSeq
);
837 xLabeledSeq
->setLabel( Reference
< data::XDataSequence
>());
843 if( !aRange
.isEmpty())
845 Reference
< data::XDataSequence
> xNewSeq
;
848 xNewSeq
.set( xDataProvider
->createDataSequenceByRangeRepresentation( aRange
));
850 catch( const uno::Exception
& )
852 // should work as validation should have happened before
853 DBG_UNHANDLED_EXCEPTION("chart2");
857 // update range name by the full string provided
858 // by the data provider. E.g. "a1:e1" might become
859 // "$Sheet1.$A$1:$E$1"
860 aRange
= xNewSeq
->getSourceRangeRepresentation();
862 Reference
< beans::XPropertySet
> xProp( xNewSeq
, uno::UNO_QUERY_THROW
);
863 xProp
->setPropertyValue( u
"Role"_ustr
, uno::Any( aSelectedRole
));
864 if( !xLabeledSeq
.is())
866 if( aSelectedRole
== aSequenceNameForLabel
)
867 xLabeledSeq
= lcl_findLSequenceWithOnlyLabel( pSeriesEntry
->m_xDataSeries
);
868 if( ! xLabeledSeq
.is())
870 xLabeledSeq
= DataSourceHelper::createLabeledDataSequence();
871 lcl_addLSequenceToDataSource( xLabeledSeq
, pSeriesEntry
->m_xDataSeries
);
874 xLabeledSeq
->setValues( xNewSeq
);
880 lcl_UpdateCurrentRange( *m_xLB_ROLE
, aSelectedRole
, aRange
);
882 catch( const uno::Exception
& )
884 DBG_UNHANDLED_EXCEPTION("chart2");
891 // @todo remove this when automatic view updates from calc, writer and own data sequences are available
896 if( m_rDialogModel
.getChartModel() )
897 m_rDialogModel
.getChartModel()->setModified( true );
898 const DialogModelTimeBasedInfo
& rInfo
= m_rDialogModel
.getTimeBasedInfo();
901 m_rDialogModel
.setTimeBasedRange(rInfo
.bTimeBased
, rInfo
.nStart
, rInfo
.nEnd
);
904 catch( const uno::Exception
& )
906 DBG_UNHANDLED_EXCEPTION("chart2");
915 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */