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/XDataSeries.hpp>
37 #include <com/sun/star/chart2/data/XDataProvider.hpp>
39 #include <comphelper/diagnose_ex.hxx>
41 using namespace ::com::sun::star
;
42 using namespace ::com::sun::star::chart2
;
44 using ::com::sun::star::uno::Reference
;
49 constexpr OUString
lcl_aLabelRole( u
"label"_ustr
);
51 void lcl_UpdateCurrentRange(weld::TreeView
& rOutListBox
, const OUString
& rRole
,
52 const OUString
& rRange
)
54 int nEntry
= rOutListBox
.get_selected_index();
57 rOutListBox
.set_text(nEntry
, ::chart::DialogModel::ConvertRoleFromInternalToUI(rRole
), 0);
58 rOutListBox
.set_text(nEntry
, rRange
, 1);
59 ::chart::SeriesEntry
* pEntry
= weld::fromId
<::chart::SeriesEntry
*>(rOutListBox
.get_id(nEntry
));
60 pEntry
->m_sRole
= rRole
;
64 bool lcl_UpdateCurrentSeriesName(weld::TreeView
& rOutListBox
)
66 int nEntry
= rOutListBox
.get_selected_index();
71 ::chart::SeriesEntry
* pEntry
= weld::fromId
<::chart::SeriesEntry
*>(rOutListBox
.get_id(nEntry
));
72 if (pEntry
->m_xDataSeries
.is() && pEntry
->m_xChartType
.is())
74 OUString
aLabel(pEntry
->m_xDataSeries
->getLabelForRole(
75 pEntry
->m_xChartType
->getRoleOfSequenceForSeriesLabel()));
76 if (!aLabel
.isEmpty())
78 rOutListBox
.set_text(nEntry
, aLabel
);
85 OUString
lcl_GetSelectedRole(const weld::TreeView
& rRoleListBox
, bool bUITranslated
= false)
87 int nEntry
= rRoleListBox
.get_selected_index();
91 return rRoleListBox
.get_text(nEntry
);
92 ::chart::SeriesEntry
* pEntry
= weld::fromId
<::chart::SeriesEntry
*>(rRoleListBox
.get_id(nEntry
));
93 return pEntry
->m_sRole
;
98 OUString
lcl_GetSelectedRolesRange( const weld::TreeView
& rRoleListBox
)
101 int nEntry
= rRoleListBox
.get_selected_index();
103 aResult
= rRoleListBox
.get_text(nEntry
, 1);
107 OUString
lcl_GetSequenceNameForLabel(const ::chart::SeriesEntry
* pEntry
)
109 OUString
aResult("values-y");
110 if (pEntry
&& pEntry
->m_xChartType
.is())
111 aResult
= pEntry
->m_xChartType
->getRoleOfSequenceForSeriesLabel();
115 void lcl_enableRangeChoosing(bool bEnable
, weld::DialogController
* pDialog
)
119 weld::Dialog
* pDlg
= pDialog
->getDialog();
120 pDlg
->set_modal(!bEnable
);
121 pDlg
->set_visible(!bEnable
);
124 void lcl_addLSequenceToDataSource(
125 const uno::Reference
< chart2::data::XLabeledDataSequence
> & xLSequence
,
126 const Reference
< ::chart::DataSeries
> & xSource
)
130 std::vector
< uno::Reference
< chart2::data::XLabeledDataSequence
> > aData
= xSource
->getDataSequences2();
131 aData
.push_back( xLSequence
);
132 xSource
->setData( aData
);
136 uno::Reference
< chart2::data::XLabeledDataSequence
> lcl_findLSequenceWithOnlyLabel(
137 const rtl::Reference
< ::chart::DataSeries
> & xDataSource
)
139 uno::Reference
< chart2::data::XLabeledDataSequence
> xResult
;
141 for( uno::Reference
< chart2::data::XLabeledDataSequence
> const & labeledDataSeq
: xDataSource
->getDataSequences2() )
143 // no values are set but a label exists
144 if( ! labeledDataSeq
->getValues().is() &&
145 labeledDataSeq
->getLabel().is())
147 xResult
= labeledDataSeq
;
155 } // anonymous namespace
160 DataSourceTabPage::DataSourceTabPage(weld::Container
* pPage
, weld::DialogController
* pController
,
161 DialogModel
& rDialogModel
,
162 ChartTypeTemplateProvider
* pTemplateProvider
,
163 bool bHideDescription
/* = false */)
164 : ::vcl::OWizardPage(pPage
, pController
, "modules/schart/ui/tp_DataSource.ui", "tp_DataSource")
165 , m_pTemplateProvider(pTemplateProvider
)
166 , m_rDialogModel(rDialogModel
)
167 , m_pCurrentRangeChoosingField( nullptr )
168 , m_bIsDirty( false )
169 , m_pTabPageNotifiable(dynamic_cast<TabPageNotifiable
*>(pController
))
170 , m_xFT_CAPTION(m_xBuilder
->weld_label("FT_CAPTION_FOR_WIZARD"))
171 , m_xFT_SERIES(m_xBuilder
->weld_label("FT_SERIES"))
172 , m_xLB_SERIES(m_xBuilder
->weld_tree_view("LB_SERIES"))
173 , m_xBTN_ADD(m_xBuilder
->weld_button("BTN_ADD"))
174 , m_xBTN_REMOVE(m_xBuilder
->weld_button("BTN_REMOVE"))
175 , m_xBTN_UP(m_xBuilder
->weld_button("BTN_UP"))
176 , m_xBTN_DOWN(m_xBuilder
->weld_button("BTN_DOWN"))
177 , m_xFT_ROLE(m_xBuilder
->weld_label("FT_ROLE"))
178 , m_xLB_ROLE(m_xBuilder
->weld_tree_view("LB_ROLE"))
179 , m_xFT_RANGE(m_xBuilder
->weld_label("FT_RANGE"))
180 , m_xEDT_RANGE(m_xBuilder
->weld_entry("EDT_RANGE"))
181 , m_xIMB_RANGE_MAIN(m_xBuilder
->weld_button("IMB_RANGE_MAIN"))
182 , m_xFT_CATEGORIES(m_xBuilder
->weld_label("FT_CATEGORIES"))
183 , m_xFT_DATALABELS(m_xBuilder
->weld_label("FT_DATALABELS"))
184 , m_xEDT_CATEGORIES(m_xBuilder
->weld_entry("EDT_CATEGORIES"))
185 , m_xIMB_RANGE_CAT(m_xBuilder
->weld_button("IMB_RANGE_CAT"))
187 m_xLB_SERIES
->set_size_request(m_xLB_SERIES
->get_approximate_digit_width() * 25,
188 m_xLB_SERIES
->get_height_rows(10));
189 m_xLB_ROLE
->set_size_request(m_xLB_ROLE
->get_approximate_digit_width() * 60,
190 m_xLB_ROLE
->get_height_rows(5));
191 m_xFT_CAPTION
->set_visible(!bHideDescription
);
193 m_aFixedTextRange
= m_xFT_RANGE
->get_label();
194 SetPageTitle(SchResId(STR_OBJECT_DATASERIES_PLURAL
));
197 m_xLB_SERIES
->connect_changed(LINK(this, DataSourceTabPage
, SeriesSelectionChangedHdl
));
198 m_xLB_ROLE
->connect_changed(LINK(this, DataSourceTabPage
, RoleSelectionChangedHdl
));
200 m_xIMB_RANGE_MAIN
->connect_clicked(LINK(this, DataSourceTabPage
, MainRangeButtonClickedHdl
));
201 m_xIMB_RANGE_CAT
->connect_clicked(LINK(this, DataSourceTabPage
, CategoriesRangeButtonClickedHdl
));
203 m_xBTN_ADD
->connect_clicked(LINK(this, DataSourceTabPage
, AddButtonClickedHdl
));
204 m_xBTN_REMOVE
->connect_clicked(LINK(this, DataSourceTabPage
, RemoveButtonClickedHdl
));
206 m_xBTN_UP
->connect_clicked(LINK(this, DataSourceTabPage
, UpButtonClickedHdl
));
207 m_xBTN_DOWN
->connect_clicked(LINK(this, DataSourceTabPage
, DownButtonClickedHdl
));
209 m_xEDT_RANGE
->connect_changed(LINK(this, DataSourceTabPage
, RangeModifiedHdl
));
210 m_xEDT_CATEGORIES
->connect_changed(LINK( this, DataSourceTabPage
, RangeModifiedHdl
));
213 std::vector
<int> aWidths
{ o3tl::narrowing
<int>(m_xLB_ROLE
->get_approximate_digit_width() * 20) };
214 m_xLB_ROLE
->set_column_fixed_widths(aWidths
);
217 updateControlsFromDialogModel();
219 // select first series
220 if (m_xLB_SERIES
->n_children())
221 m_xLB_SERIES
->select(0);
224 void DataSourceTabPage::InsertRoleLBEntry(const OUString
& rRole
, const OUString
& rRange
)
226 m_aEntries
.emplace_back(new SeriesEntry
);
227 SeriesEntry
* pEntry
= m_aEntries
.back().get();
228 pEntry
->m_sRole
= rRole
;
229 m_xLB_ROLE
->append(weld::toId(pEntry
),
230 ::chart::DialogModel::ConvertRoleFromInternalToUI(rRole
));
231 m_xLB_ROLE
->set_text(m_xLB_ROLE
->n_children() - 1, rRange
, 1);
234 DataSourceTabPage::~DataSourceTabPage()
238 void DataSourceTabPage::Activate()
240 OWizardPage::Activate();
241 updateControlsFromDialogModel();
242 m_xLB_SERIES
->grab_focus();
245 void DataSourceTabPage::initializePage()
249 void DataSourceTabPage::Deactivate()
252 vcl::OWizardPage::Deactivate();
255 void DataSourceTabPage::commitPage()
257 commitPage(::vcl::WizardTypes::eFinish
);
260 bool DataSourceTabPage::commitPage( ::vcl::WizardTypes::CommitPageReason
/*eReason*/ )
262 //ranges may have been edited in the meanwhile (dirty is true in that case here)
265 updateModelFromControl();
266 return true; //return false if this page should not be left
272 bool DataSourceTabPage::isRangeFieldContentValid(weld::Entry
& rEdit
)
274 OUString
aRange(rEdit
.get_text());
275 bool bIsValid
= aRange
.isEmpty() ||
276 m_rDialogModel
.getRangeSelectionHelper()->verifyCellRange(aRange
);
277 rEdit
.set_message_type(bIsValid
? weld::EntryMessageType::Normal
: weld::EntryMessageType::Error
);
281 bool DataSourceTabPage::isValid()
283 bool bRoleRangeValid
= true;
284 bool bCategoriesRangeValid
= true;
285 bool bHasSelectedEntry
= (m_xLB_SERIES
->get_selected_index() != -1);
287 if (bHasSelectedEntry
)
288 bRoleRangeValid
= isRangeFieldContentValid(*m_xEDT_RANGE
);
289 if (m_xEDT_CATEGORIES
->get_sensitive())
290 bCategoriesRangeValid
= isRangeFieldContentValid( *m_xEDT_CATEGORIES
);
291 bool bValid
= ( bRoleRangeValid
&& bCategoriesRangeValid
);
293 if( m_pTabPageNotifiable
)
296 m_pTabPageNotifiable
->setValidPage( this );
298 m_pTabPageNotifiable
->setInvalidPage( this );
304 void DataSourceTabPage::setDirty()
309 void DataSourceTabPage::updateControlsFromDialogModel()
313 SeriesSelectionChangedHdl(*m_xLB_SERIES
);
316 m_xEDT_CATEGORIES
->set_text(m_rDialogModel
.getCategoriesRange());
318 updateControlState();
321 void DataSourceTabPage::fillSeriesListBox()
323 rtl::Reference
< DataSeries
> xSelected
;
324 SeriesEntry
* pEntry
= nullptr;
325 int nEntry
= m_xLB_SERIES
->get_selected_index();
328 pEntry
= weld::fromId
<SeriesEntry
*>(m_xLB_SERIES
->get_id(nEntry
));
329 xSelected
= pEntry
->m_xDataSeries
;
332 bool bHasSelectedEntry
= (pEntry
!= nullptr);
333 int nSelectedEntry
= -1;
335 m_xLB_SERIES
->freeze();
336 m_xLB_SERIES
->clear();
338 std::vector
< DialogModel::tSeriesWithChartTypeByName
> aSeries(
339 m_rDialogModel
.getAllDataSeriesWithLabel() );
341 sal_Int32 nUnnamedSeriesIndex
= 1;
343 for (auto const& series
: aSeries
)
345 OUString
aLabel(series
.first
);
346 if (aLabel
.isEmpty())
348 if( nUnnamedSeriesIndex
> 1 )
350 OUString
aResString(::chart::SchResId( STR_DATA_UNNAMED_SERIES_WITH_INDEX
));
352 // replace index of unnamed series
353 static constexpr OUString
aReplacementStr( u
"%NUMBER"_ustr
);
354 sal_Int32 nIndex
= aResString
.indexOf( aReplacementStr
);
356 aLabel
= aResString
.replaceAt(
357 nIndex
, aReplacementStr
.getLength(),
358 OUString::number(nUnnamedSeriesIndex
));
360 if( aLabel
.isEmpty() )
361 aLabel
= ::chart::SchResId( STR_DATA_UNNAMED_SERIES
);
363 ++nUnnamedSeriesIndex
;
366 m_aEntries
.emplace_back(new SeriesEntry
);
367 pEntry
= m_aEntries
.back().get();
368 pEntry
->m_xDataSeries
= series
.second
.first
;
369 pEntry
->m_xChartType
= series
.second
.second
;
370 m_xLB_SERIES
->append(weld::toId(pEntry
), aLabel
);
371 if (bHasSelectedEntry
&& series
.second
.first
== xSelected
)
372 nSelectedEntry
= nEntry
;
376 m_xLB_SERIES
->thaw();
378 if (bHasSelectedEntry
&& nSelectedEntry
!= -1)
379 m_xLB_SERIES
->select(nSelectedEntry
);
382 void DataSourceTabPage::fillRoleListBox()
384 int nSeriesEntry
= m_xLB_SERIES
->get_selected_index();
385 SeriesEntry
* pSeriesEntry
= nullptr;
386 if (nSeriesEntry
!= -1)
387 pSeriesEntry
= weld::fromId
<SeriesEntry
*>(m_xLB_SERIES
->get_id(nSeriesEntry
));
388 bool bHasSelectedEntry
= (pSeriesEntry
!= nullptr);
390 int nRoleIndex
= m_xLB_ROLE
->get_selected_index();
391 if (!bHasSelectedEntry
)
394 DialogModel::tRolesWithRanges
aRoles(
395 DialogModel::getRolesWithRanges(
396 pSeriesEntry
->m_xDataSeries
,
397 lcl_GetSequenceNameForLabel( pSeriesEntry
),
398 pSeriesEntry
->m_xChartType
));
401 m_xLB_ROLE
->freeze();
404 for (auto const& elemRole
: aRoles
)
406 InsertRoleLBEntry(elemRole
.first
, elemRole
.second
);
411 // series may contain no roles, check listbox size before selecting entries
412 if (m_xLB_ROLE
->n_children() > 0)
414 if (nRoleIndex
== -1 || nRoleIndex
>= m_xLB_ROLE
->n_children())
416 m_xLB_ROLE
->select(nRoleIndex
);
420 void DataSourceTabPage::updateControlState()
422 int nSeriesEntry
= m_xLB_SERIES
->get_selected_index();
423 bool bHasSelectedSeries
= nSeriesEntry
!= -1;
424 bool bHasValidRole
= false;
425 bool bHasRangeChooser
= m_rDialogModel
.getRangeSelectionHelper()->hasRangeSelection();
427 if( bHasSelectedSeries
)
429 int nRoleEntry
= m_xLB_ROLE
->get_selected_index();
430 bHasValidRole
= nRoleEntry
!= -1;
433 m_xBTN_ADD
->set_sensitive(true);
434 m_xBTN_REMOVE
->set_sensitive(bHasSelectedSeries
);
436 m_xBTN_UP
->set_sensitive(bHasSelectedSeries
&& (nSeriesEntry
!= 0));
437 m_xBTN_DOWN
->set_sensitive(bHasSelectedSeries
&& (nSeriesEntry
!= m_xLB_SERIES
->n_children() - 1));
439 bool bHasCategories
= m_rDialogModel
.isCategoryDiagram();
441 m_xFT_DATALABELS
->set_visible(!bHasCategories
);
442 m_xFT_CATEGORIES
->set_visible( bHasCategories
);
443 bool bShowIB
= bHasRangeChooser
;
445 m_xIMB_RANGE_CAT
->set_visible(bShowIB
);
447 m_xFT_ROLE
->set_sensitive(bHasSelectedSeries
);
448 m_xLB_ROLE
->set_sensitive(bHasSelectedSeries
);
450 m_xFT_RANGE
->set_sensitive(bHasValidRole
);
451 m_xEDT_RANGE
->set_sensitive(bHasValidRole
);
453 m_xFT_SERIES
->set_sensitive(true);
454 m_xLB_SERIES
->set_sensitive(true);
456 m_xIMB_RANGE_MAIN
->set_visible(bShowIB
);
461 IMPL_LINK_NOARG(DataSourceTabPage
, SeriesSelectionChangedHdl
, weld::TreeView
&, void)
463 m_rDialogModel
.startControllerLockTimer();
464 if (m_xLB_SERIES
->get_selected_index() != -1)
467 RoleSelectionChangedHdl(*m_xLB_ROLE
);
469 updateControlState();
472 IMPL_LINK_NOARG(DataSourceTabPage
, RoleSelectionChangedHdl
, weld::TreeView
&, void)
474 m_rDialogModel
.startControllerLockTimer();
475 int nEntry
= m_xLB_ROLE
->get_selected_index();
479 OUString aSelectedRoleUI
= lcl_GetSelectedRole( *m_xLB_ROLE
, true );
480 OUString aSelectedRange
= lcl_GetSelectedRolesRange( *m_xLB_ROLE
);
482 // replace role in fixed text label
483 static constexpr OUString
aReplacementStr( u
"%VALUETYPE"_ustr
);
484 sal_Int32 nIndex
= m_aFixedTextRange
.indexOf( aReplacementStr
);
487 m_xFT_RANGE
->set_label(
488 m_aFixedTextRange
.replaceAt(
489 nIndex
, aReplacementStr
.getLength(), aSelectedRoleUI
));
492 m_xEDT_RANGE
->set_text(aSelectedRange
);
496 IMPL_LINK_NOARG(DataSourceTabPage
, MainRangeButtonClickedHdl
, weld::Button
&, void)
498 OSL_ASSERT( m_pCurrentRangeChoosingField
== nullptr );
499 m_pCurrentRangeChoosingField
= m_xEDT_RANGE
.get();
500 if (!m_xEDT_RANGE
->get_text().isEmpty() &&
501 !updateModelFromControl( m_pCurrentRangeChoosingField
))
504 int nEntry
= m_xLB_SERIES
->get_selected_index();
505 bool bHasSelectedEntry
= (nEntry
!= -1);
507 OUString aSelectedRolesRange
= lcl_GetSelectedRolesRange(*m_xLB_ROLE
);
509 if (bHasSelectedEntry
&& (m_xLB_ROLE
->get_selected_index() != -1))
511 OUString
aUIStr(SchResId(STR_DATA_SELECT_RANGE_FOR_SERIES
));
514 OUString
aReplacement( "%VALUETYPE" );
515 sal_Int32 nIndex
= aUIStr
.indexOf( aReplacement
);
518 aUIStr
= aUIStr
.replaceAt( nIndex
, aReplacement
.getLength(),
519 lcl_GetSelectedRole( *m_xLB_ROLE
, true ));
521 // replace series name
522 aReplacement
= "%SERIESNAME";
523 nIndex
= aUIStr
.indexOf( aReplacement
);
526 aUIStr
= aUIStr
.replaceAt(nIndex
, aReplacement
.getLength(),
527 m_xLB_SERIES
->get_text(nEntry
));
530 lcl_enableRangeChoosing(true, m_pDialogController
);
531 m_rDialogModel
.getRangeSelectionHelper()->chooseRange( aSelectedRolesRange
, aUIStr
, *this );
534 m_pCurrentRangeChoosingField
= nullptr;
537 IMPL_LINK_NOARG(DataSourceTabPage
, CategoriesRangeButtonClickedHdl
, weld::Button
&, void)
539 OSL_ASSERT( m_pCurrentRangeChoosingField
== nullptr );
540 m_pCurrentRangeChoosingField
= m_xEDT_CATEGORIES
.get();
541 if( !m_xEDT_CATEGORIES
->get_text().isEmpty() &&
542 ! updateModelFromControl( m_pCurrentRangeChoosingField
))
545 OUString
aStr(SchResId(m_xFT_CATEGORIES
->get_visible() ? STR_DATA_SELECT_RANGE_FOR_CATEGORIES
: STR_DATA_SELECT_RANGE_FOR_DATALABELS
));
546 lcl_enableRangeChoosing(true, m_pDialogController
);
547 m_rDialogModel
.getRangeSelectionHelper()->chooseRange(
548 m_rDialogModel
.getCategoriesRange(), aStr
, *this );
551 IMPL_LINK_NOARG(DataSourceTabPage
, AddButtonClickedHdl
, weld::Button
&, void)
553 m_rDialogModel
.startControllerLockTimer();
554 int nEntry
= m_xLB_SERIES
->get_selected_index();
555 rtl::Reference
< DataSeries
> xSeriesToInsertAfter
;
556 rtl::Reference
< ChartType
> xChartTypeForNewSeries
;
557 if( m_pTemplateProvider
)
558 m_rDialogModel
.setTemplate( m_pTemplateProvider
->getCurrentTemplate());
562 ::chart::SeriesEntry
* pEntry
= weld::fromId
<::chart::SeriesEntry
*>(m_xLB_SERIES
->get_id(nEntry
));
563 xSeriesToInsertAfter
= pEntry
->m_xDataSeries
;
564 xChartTypeForNewSeries
= pEntry
->m_xChartType
;
568 std::vector
< rtl::Reference
< ChartType
> > aCntVec(
569 m_rDialogModel
.getAllDataSeriesContainers());
570 if( ! aCntVec
.empty())
571 xChartTypeForNewSeries
= aCntVec
.front();
573 OSL_ENSURE( xChartTypeForNewSeries
.is(), "Cannot insert new series" );
575 m_rDialogModel
.insertSeriesAfter( xSeriesToInsertAfter
, xChartTypeForNewSeries
);
579 // note the box was cleared and refilled, so nEntry is invalid now
581 int nSelEntry
= m_xLB_SERIES
->get_selected_index();
585 if (nSelEntry
< m_xLB_SERIES
->n_children())
586 m_xLB_SERIES
->select(nSelEntry
);
588 SeriesSelectionChangedHdl(*m_xLB_SERIES
);
591 IMPL_LINK_NOARG(DataSourceTabPage
, RemoveButtonClickedHdl
, weld::Button
&, void)
593 m_rDialogModel
.startControllerLockTimer();
594 int nEntry
= m_xLB_SERIES
->get_selected_index();
598 SeriesEntry
* pEntry
= weld::fromId
<::chart::SeriesEntry
*>(m_xLB_SERIES
->get_id(nEntry
));
599 rtl::Reference
< DataSeries
> xNewSelSeries
;
600 SeriesEntry
* pNewSelEntry
= nullptr;
601 if (nEntry
+ 1 < m_xLB_SERIES
->n_children())
602 pNewSelEntry
= weld::fromId
<::chart::SeriesEntry
*>(m_xLB_SERIES
->get_id(nEntry
+ 1));
604 pNewSelEntry
= weld::fromId
<::chart::SeriesEntry
*>(m_xLB_SERIES
->get_id(nEntry
- 1));
606 xNewSelSeries
= pNewSelEntry
->m_xDataSeries
;
608 m_rDialogModel
.deleteSeries( pEntry
->m_xDataSeries
, pEntry
->m_xChartType
);
611 m_xLB_SERIES
->remove(nEntry
);
614 // select previous or next series
615 if (xNewSelSeries
.is())
617 for (int i
= 0; i
< m_xLB_SERIES
->n_children(); ++i
)
619 pEntry
= weld::fromId
<::chart::SeriesEntry
*>(m_xLB_SERIES
->get_id(i
));
620 if (pEntry
->m_xDataSeries
== xNewSelSeries
)
622 m_xLB_SERIES
->select(i
);
627 SeriesSelectionChangedHdl(*m_xLB_SERIES
);
630 IMPL_LINK_NOARG(DataSourceTabPage
, UpButtonClickedHdl
, weld::Button
&, void)
632 m_rDialogModel
.startControllerLockTimer();
634 int nEntry
= m_xLB_SERIES
->get_selected_index();
635 SeriesEntry
* pEntry
= nullptr;
637 pEntry
= weld::fromId
<SeriesEntry
*>(m_xLB_SERIES
->get_id(nEntry
));
639 bool bHasSelectedEntry
= (pEntry
!= nullptr);
641 if (bHasSelectedEntry
)
643 m_rDialogModel
.moveSeries( pEntry
->m_xDataSeries
, DialogModel::MoveDirection::Up
);
646 SeriesSelectionChangedHdl(*m_xLB_SERIES
);
650 IMPL_LINK_NOARG(DataSourceTabPage
, DownButtonClickedHdl
, weld::Button
&, void)
652 m_rDialogModel
.startControllerLockTimer();
654 int nEntry
= m_xLB_SERIES
->get_selected_index();
655 SeriesEntry
* pEntry
= nullptr;
657 pEntry
= weld::fromId
<SeriesEntry
*>(m_xLB_SERIES
->get_id(nEntry
));
659 bool bHasSelectedEntry
= (pEntry
!= nullptr);
661 if (bHasSelectedEntry
)
663 m_rDialogModel
.moveSeries( pEntry
->m_xDataSeries
, DialogModel::MoveDirection::Down
);
666 SeriesSelectionChangedHdl(*m_xLB_SERIES
);
670 IMPL_LINK(DataSourceTabPage
, RangeModifiedHdl
, weld::Entry
&, rEdit
, void)
672 // note: isValid sets the color of the edit field
673 if( isRangeFieldContentValid( rEdit
))
676 updateModelFromControl( &rEdit
);
677 if (&rEdit
== m_xEDT_RANGE
.get())
679 if( ! lcl_UpdateCurrentSeriesName( *m_xLB_SERIES
))
684 // enable/disable OK button
688 void DataSourceTabPage::listeningFinished(
689 const OUString
& rNewRange
)
691 // rNewRange becomes invalid after removing the listener
692 OUString
aRange( rNewRange
);
694 m_rDialogModel
.startControllerLockTimer();
697 m_rDialogModel
.getRangeSelectionHelper()->stopRangeListening();
700 if( m_pCurrentRangeChoosingField
)
702 m_pCurrentRangeChoosingField
->set_text(aRange
);
703 m_pCurrentRangeChoosingField
->grab_focus();
706 if (m_pCurrentRangeChoosingField
== m_xEDT_RANGE
.get())
708 m_xEDT_RANGE
->set_text(aRange
);
711 else if (m_pCurrentRangeChoosingField
== m_xEDT_CATEGORIES
.get())
713 m_xEDT_CATEGORIES
->set_text(aRange
);
717 updateModelFromControl(m_pCurrentRangeChoosingField
);
718 if (!lcl_UpdateCurrentSeriesName(*m_xLB_SERIES
))
721 m_pCurrentRangeChoosingField
= nullptr;
723 updateControlState();
724 lcl_enableRangeChoosing(false, m_pDialogController
);
727 void DataSourceTabPage::disposingRangeSelection()
729 m_rDialogModel
.getRangeSelectionHelper()->stopRangeListening( false );
732 bool DataSourceTabPage::updateModelFromControl(const weld::Entry
* pField
)
737 ControllerLockGuardUNO
aLockedControllers( m_rDialogModel
.getChartModel() );
739 // @todo: validity check of field content
741 bool bAll
= (pField
== nullptr);
742 Reference
< data::XDataProvider
> xDataProvider( m_rDialogModel
.getDataProvider());
744 if (bAll
|| (pField
== m_xEDT_CATEGORIES
.get()))
746 uno::Reference
< chart2::data::XLabeledDataSequence
> xLabeledSeq( m_rDialogModel
.getCategories() );
747 if( xDataProvider
.is())
749 OUString
aRange(m_xEDT_CATEGORIES
->get_text());
750 if (!aRange
.isEmpty())
752 // create or change categories
753 if( !xLabeledSeq
.is())
755 xLabeledSeq
= DataSourceHelper::createLabeledDataSequence();
756 m_rDialogModel
.setCategories( xLabeledSeq
);
760 xLabeledSeq
->setValues( xDataProvider
->createDataSequenceByRangeRepresentation( aRange
));
762 catch( const uno::Exception
& )
764 // should work as validation should have happened before
765 DBG_UNHANDLED_EXCEPTION("chart2");
768 else if( xLabeledSeq
.is())
770 // clear existing categories
772 m_rDialogModel
.setCategories( xLabeledSeq
);
777 int nSeriesEntry
= m_xLB_SERIES
->get_selected_index();
778 SeriesEntry
* pSeriesEntry
= nullptr;
779 if (nSeriesEntry
!= -1)
780 pSeriesEntry
= weld::fromId
<SeriesEntry
*>(m_xLB_SERIES
->get_id(nSeriesEntry
));
781 bool bHasSelectedEntry
= (pSeriesEntry
!= nullptr);
783 if( bHasSelectedEntry
)
785 if( bAll
|| (pField
== m_xEDT_RANGE
.get()) )
789 OUString aSelectedRole
= lcl_GetSelectedRole( *m_xLB_ROLE
);
790 OUString
aRange(m_xEDT_RANGE
->get_text());
791 OUString
aSequenceRole( aSelectedRole
);
792 bool bIsLabel
= (aSequenceRole
== lcl_aLabelRole
);
793 OUString
aSequenceNameForLabel( lcl_GetSequenceNameForLabel( pSeriesEntry
));
796 aSequenceRole
= aSequenceNameForLabel
;
798 uno::Reference
< chart2::data::XLabeledDataSequence
> xLabeledSeq
=
799 DataSeriesHelper::getDataSequenceByRole( pSeriesEntry
->m_xDataSeries
, aSequenceRole
);
801 if( xDataProvider
.is())
805 if( ! xLabeledSeq
.is())
807 // check if there is already an "orphan" label sequence
808 xLabeledSeq
= lcl_findLSequenceWithOnlyLabel( pSeriesEntry
->m_xDataSeries
);
809 if( ! xLabeledSeq
.is())
811 // no corresponding labeled data sequence for label found
812 xLabeledSeq
= DataSourceHelper::createLabeledDataSequence();
813 lcl_addLSequenceToDataSource( xLabeledSeq
, pSeriesEntry
->m_xDataSeries
);
816 if( xLabeledSeq
.is())
818 if( !aRange
.isEmpty())
820 Reference
< data::XDataSequence
> xNewSeq
;
823 xNewSeq
.set( xDataProvider
->createDataSequenceByRangeRepresentation( aRange
));
825 catch( const uno::Exception
& )
827 // should work as validation should have happened before
828 DBG_UNHANDLED_EXCEPTION("chart2");
832 // update range name by the full string provided
833 // by the data provider. E.g. "a1" might become
835 aRange
= xNewSeq
->getSourceRangeRepresentation();
836 Reference
< beans::XPropertySet
> xProp( xNewSeq
, uno::UNO_QUERY_THROW
);
837 xProp
->setPropertyValue( "Role" , uno::Any( lcl_aLabelRole
));
839 //Labels should always include hidden cells, regardless of the setting chosen
840 xProp
->setPropertyValue( "IncludeHiddenCells", uno::Any(true));
841 xLabeledSeq
->setLabel( xNewSeq
);
846 xLabeledSeq
->setLabel( Reference
< data::XDataSequence
>());
852 if( !aRange
.isEmpty())
854 Reference
< data::XDataSequence
> xNewSeq
;
857 xNewSeq
.set( xDataProvider
->createDataSequenceByRangeRepresentation( aRange
));
859 catch( const uno::Exception
& )
861 // should work as validation should have happened before
862 DBG_UNHANDLED_EXCEPTION("chart2");
866 // update range name by the full string provided
867 // by the data provider. E.g. "a1:e1" might become
868 // "$Sheet1.$A$1:$E$1"
869 aRange
= xNewSeq
->getSourceRangeRepresentation();
871 Reference
< beans::XPropertySet
> xProp( xNewSeq
, uno::UNO_QUERY_THROW
);
872 xProp
->setPropertyValue( "Role" , uno::Any( aSelectedRole
));
873 if( !xLabeledSeq
.is())
875 if( aSelectedRole
== aSequenceNameForLabel
)
876 xLabeledSeq
= lcl_findLSequenceWithOnlyLabel( pSeriesEntry
->m_xDataSeries
);
877 if( ! xLabeledSeq
.is())
879 xLabeledSeq
= DataSourceHelper::createLabeledDataSequence();
880 lcl_addLSequenceToDataSource( xLabeledSeq
, pSeriesEntry
->m_xDataSeries
);
883 xLabeledSeq
->setValues( xNewSeq
);
889 lcl_UpdateCurrentRange( *m_xLB_ROLE
, aSelectedRole
, aRange
);
891 catch( const uno::Exception
& )
893 DBG_UNHANDLED_EXCEPTION("chart2");
900 // @todo remove this when automatic view updates from calc, writer and own data sequences are available
905 if( m_rDialogModel
.getChartModel() )
906 m_rDialogModel
.getChartModel()->setModified( true );
907 const DialogModelTimeBasedInfo
& rInfo
= m_rDialogModel
.getTimeBasedInfo();
910 m_rDialogModel
.setTimeBasedRange(rInfo
.bTimeBased
, rInfo
.nStart
, rInfo
.nEnd
);
913 catch( const uno::Exception
& )
915 DBG_UNHANDLED_EXCEPTION("chart2");
924 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */