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 <ChartTypeTemplateProvider.hxx>
24 #include <RangeSelectionHelper.hxx>
25 #include <DataSeriesHelper.hxx>
26 #include <ControllerLockGuard.hxx>
27 #include <DataSourceHelper.hxx>
28 #include "DialogModel.hxx"
29 #include <TabPageNotifiable.hxx>
30 #include <com/sun/star/chart2/XChartType.hpp>
31 #include <com/sun/star/chart2/data/XDataProvider.hpp>
32 #include <com/sun/star/util/XModifiable.hpp>
33 #include <com/sun/star/chart2/data/XDataSink.hpp>
35 #include <tools/diagnose_ex.h>
37 using namespace ::com::sun::star
;
38 using namespace ::com::sun::star::chart2
;
40 using ::com::sun::star::uno::Reference
;
41 using ::com::sun::star::uno::Sequence
;
46 const OUString
lcl_aLabelRole( "label" );
48 void lcl_UpdateCurrentRange(weld::TreeView
& rOutListBox
, const OUString
& rRole
,
49 const OUString
& rRange
)
51 int nEntry
= rOutListBox
.get_selected_index();
54 rOutListBox
.set_text(nEntry
, ::chart::DialogModel::ConvertRoleFromInternalToUI(rRole
), 0);
55 rOutListBox
.set_text(nEntry
, rRange
, 1);
56 ::chart::SeriesEntry
* pEntry
= reinterpret_cast<::chart::SeriesEntry
*>(rOutListBox
.get_id(nEntry
).toInt64());
57 pEntry
->m_sRole
= rRole
;
61 bool lcl_UpdateCurrentSeriesName(weld::TreeView
& rOutListBox
)
63 int nEntry
= rOutListBox
.get_selected_index();
68 ::chart::SeriesEntry
* pEntry
= reinterpret_cast<::chart::SeriesEntry
*>(rOutListBox
.get_id(nEntry
).toInt64());
69 if (pEntry
->m_xDataSeries
.is() && pEntry
->m_xChartType
.is())
71 OUString
aLabel(::chart::DataSeriesHelper::getDataSeriesLabel(
72 pEntry
->m_xDataSeries
,
73 pEntry
->m_xChartType
->getRoleOfSequenceForSeriesLabel()));
74 if (!aLabel
.isEmpty())
76 rOutListBox
.set_text(nEntry
, aLabel
);
83 OUString
lcl_GetSelectedRole(const weld::TreeView
& rRoleListBox
, bool bUITranslated
= false)
85 int nEntry
= rRoleListBox
.get_selected_index();
89 return rRoleListBox
.get_text(nEntry
);
90 ::chart::SeriesEntry
* pEntry
= reinterpret_cast<::chart::SeriesEntry
*>(rRoleListBox
.get_id(nEntry
).toInt64());
91 return pEntry
->m_sRole
;
96 OUString
lcl_GetSelectedRolesRange( const weld::TreeView
& rRoleListBox
)
99 int nEntry
= rRoleListBox
.get_selected_index();
101 aResult
= rRoleListBox
.get_text(nEntry
, 1);
105 OUString
lcl_GetSequenceNameForLabel(const ::chart::SeriesEntry
* pEntry
)
107 OUString
aResult("values-y");
108 if (pEntry
&& pEntry
->m_xChartType
.is())
109 aResult
= pEntry
->m_xChartType
->getRoleOfSequenceForSeriesLabel();
113 void lcl_enableRangeChoosing(bool bEnable
, weld::DialogController
* pDialog
)
117 weld::Dialog
* pDlg
= pDialog
->getDialog();
118 pDlg
->set_modal(!bEnable
);
119 pDlg
->set_visible(!bEnable
);
122 void lcl_addLSequenceToDataSource(
123 const Reference
< chart2::data::XLabeledDataSequence
> & xLSequence
,
124 const Reference
< chart2::data::XDataSource
> & xSource
)
126 Reference
< data::XDataSink
> xSink( xSource
, uno::UNO_QUERY
);
129 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aData( xSource
->getDataSequences());
130 aData
.realloc( aData
.getLength() + 1 );
131 aData
[ aData
.getLength() - 1 ] = xLSequence
;
132 xSink
->setData( aData
);
136 Reference
< chart2::data::XLabeledDataSequence
> lcl_findLSequenceWithOnlyLabel(
137 const Reference
< chart2::data::XDataSource
> & xDataSource
)
139 Reference
< chart2::data::XLabeledDataSequence
> xResult
;
140 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aSequences( xDataSource
->getDataSequences());
142 for( sal_Int32 i
=0; i
<aSequences
.getLength(); ++i
)
144 // no values are set but a label exists
145 if( ! aSequences
[i
]->getValues().is() &&
146 aSequences
[i
]->getLabel().is())
148 xResult
.set( aSequences
[i
] );
156 } // anonymous namespace
161 DataSourceTabPage::DataSourceTabPage(weld::Container
* pPage
, weld::DialogController
* pController
,
162 DialogModel
& rDialogModel
,
163 ChartTypeTemplateProvider
* pTemplateProvider
,
164 bool bHideDescription
/* = false */)
165 : ::vcl::OWizardPage(pPage
, pController
, "modules/schart/ui/tp_DataSource.ui", "tp_DataSource")
166 , m_pTemplateProvider(pTemplateProvider
)
167 , m_rDialogModel(rDialogModel
)
168 , m_pCurrentRangeChoosingField( nullptr )
169 , m_bIsDirty( false )
170 , m_pTabPageNotifiable(dynamic_cast<TabPageNotifiable
*>(pController
))
171 , m_xFT_CAPTION(m_xBuilder
->weld_label("FT_CAPTION_FOR_WIZARD"))
172 , m_xFT_SERIES(m_xBuilder
->weld_label("FT_SERIES"))
173 , m_xLB_SERIES(m_xBuilder
->weld_tree_view("LB_SERIES"))
174 , m_xBTN_ADD(m_xBuilder
->weld_button("BTN_ADD"))
175 , m_xBTN_REMOVE(m_xBuilder
->weld_button("BTN_REMOVE"))
176 , m_xBTN_UP(m_xBuilder
->weld_button("BTN_UP"))
177 , m_xBTN_DOWN(m_xBuilder
->weld_button("BTN_DOWN"))
178 , m_xFT_ROLE(m_xBuilder
->weld_label("FT_ROLE"))
179 , m_xLB_ROLE(m_xBuilder
->weld_tree_view("LB_ROLE"))
180 , m_xFT_RANGE(m_xBuilder
->weld_label("FT_RANGE"))
181 , m_xEDT_RANGE(m_xBuilder
->weld_entry("EDT_RANGE"))
182 , m_xIMB_RANGE_MAIN(m_xBuilder
->weld_button("IMB_RANGE_MAIN"))
183 , m_xFT_CATEGORIES(m_xBuilder
->weld_label("FT_CATEGORIES"))
184 , m_xFT_DATALABELS(m_xBuilder
->weld_label("FT_DATALABELS"))
185 , m_xEDT_CATEGORIES(m_xBuilder
->weld_entry("EDT_CATEGORIES"))
186 , m_xIMB_RANGE_CAT(m_xBuilder
->weld_button("IMB_RANGE_CAT"))
188 m_xLB_SERIES
->set_size_request(m_xLB_SERIES
->get_approximate_digit_width() * 25,
189 m_xLB_SERIES
->get_height_rows(10));
190 m_xLB_ROLE
->set_size_request(m_xLB_ROLE
->get_approximate_digit_width() * 60,
191 m_xLB_ROLE
->get_height_rows(5));
192 m_xFT_CAPTION
->set_visible(!bHideDescription
);
194 m_aFixedTextRange
= m_xFT_RANGE
->get_label();
195 SetPageTitle(SchResId(STR_OBJECT_DATASERIES_PLURAL
));
198 m_xLB_SERIES
->connect_changed(LINK(this, DataSourceTabPage
, SeriesSelectionChangedHdl
));
199 m_xLB_ROLE
->connect_changed(LINK(this, DataSourceTabPage
, RoleSelectionChangedHdl
));
201 m_xIMB_RANGE_MAIN
->connect_clicked(LINK(this, DataSourceTabPage
, MainRangeButtonClickedHdl
));
202 m_xIMB_RANGE_CAT
->connect_clicked(LINK(this, DataSourceTabPage
, CategoriesRangeButtonClickedHdl
));
204 m_xBTN_ADD
->connect_clicked(LINK(this, DataSourceTabPage
, AddButtonClickedHdl
));
205 m_xBTN_REMOVE
->connect_clicked(LINK(this, DataSourceTabPage
, RemoveButtonClickedHdl
));
207 m_xBTN_UP
->connect_clicked(LINK(this, DataSourceTabPage
, UpButtonClickedHdl
));
208 m_xBTN_DOWN
->connect_clicked(LINK(this, DataSourceTabPage
, DownButtonClickedHdl
));
210 m_xEDT_RANGE
->connect_changed(LINK(this, DataSourceTabPage
, RangeModifiedHdl
));
211 m_xEDT_CATEGORIES
->connect_changed(LINK( this, DataSourceTabPage
, RangeModifiedHdl
));
214 std::vector
<int> aWidths
;
215 aWidths
.push_back(m_xLB_ROLE
->get_approximate_digit_width() * 20);
216 m_xLB_ROLE
->set_column_fixed_widths(aWidths
);
219 updateControlsFromDialogModel();
221 // select first series
222 if (m_xLB_SERIES
->n_children())
223 m_xLB_SERIES
->select(0);
226 void DataSourceTabPage::InsertRoleLBEntry(const OUString
& rRole
, const OUString
& rRange
)
228 m_aEntries
.emplace_back(new SeriesEntry
);
229 SeriesEntry
* pEntry
= m_aEntries
.back().get();
230 pEntry
->m_sRole
= rRole
;
231 m_xLB_ROLE
->append(OUString::number(reinterpret_cast<sal_Int64
>(pEntry
)),
232 ::chart::DialogModel::ConvertRoleFromInternalToUI(rRole
));
233 m_xLB_ROLE
->set_text(m_xLB_ROLE
->n_children() - 1, rRange
, 1);
236 DataSourceTabPage::~DataSourceTabPage()
240 void DataSourceTabPage::Activate()
242 OWizardPage::Activate();
243 updateControlsFromDialogModel();
244 m_xLB_SERIES
->grab_focus();
247 void DataSourceTabPage::initializePage()
251 void DataSourceTabPage::Deactivate()
254 vcl::OWizardPage::Deactivate();
257 void DataSourceTabPage::commitPage()
259 commitPage(::vcl::WizardTypes::eFinish
);
262 bool DataSourceTabPage::commitPage( ::vcl::WizardTypes::CommitPageReason
/*eReason*/ )
264 //ranges may have been edited in the meanwhile (dirty is true in that case here)
267 updateModelFromControl();
268 return true; //return false if this page should not be left
274 bool DataSourceTabPage::isRangeFieldContentValid(weld::Entry
& rEdit
)
276 OUString
aRange(rEdit
.get_text());
277 bool bIsValid
= aRange
.isEmpty() ||
278 m_rDialogModel
.getRangeSelectionHelper()->verifyCellRange(aRange
);
279 rEdit
.set_message_type(bIsValid
? weld::EntryMessageType::Normal
: weld::EntryMessageType::Error
);
283 bool DataSourceTabPage::isValid()
285 bool bRoleRangeValid
= true;
286 bool bCategoriesRangeValid
= true;
287 bool bHasSelectedEntry
= (m_xLB_SERIES
->get_selected_index() != -1);
289 if (bHasSelectedEntry
)
290 bRoleRangeValid
= isRangeFieldContentValid(*m_xEDT_RANGE
);
291 if (m_xEDT_CATEGORIES
->get_sensitive())
292 bCategoriesRangeValid
= isRangeFieldContentValid( *m_xEDT_CATEGORIES
);
293 bool bValid
= ( bRoleRangeValid
&& bCategoriesRangeValid
);
295 if( m_pTabPageNotifiable
)
298 m_pTabPageNotifiable
->setValidPage( this );
300 m_pTabPageNotifiable
->setInvalidPage( this );
306 void DataSourceTabPage::setDirty()
311 void DataSourceTabPage::updateControlsFromDialogModel()
315 SeriesSelectionChangedHdl(*m_xLB_SERIES
);
318 m_xEDT_CATEGORIES
->set_text(m_rDialogModel
.getCategoriesRange());
320 updateControlState();
323 void DataSourceTabPage::fillSeriesListBox()
325 Reference
< XDataSeries
> xSelected
;
326 SeriesEntry
* pEntry
= nullptr;
327 int nEntry
= m_xLB_SERIES
->get_selected_index();
330 pEntry
= reinterpret_cast<SeriesEntry
*>(m_xLB_SERIES
->get_id(nEntry
).toInt64());
331 xSelected
.set(pEntry
->m_xDataSeries
);
334 bool bHasSelectedEntry
= (pEntry
!= nullptr);
335 int nSelectedEntry
= -1;
337 m_xLB_SERIES
->freeze();
338 m_xLB_SERIES
->clear();
340 std::vector
< DialogModel::tSeriesWithChartTypeByName
> aSeries(
341 m_rDialogModel
.getAllDataSeriesWithLabel() );
343 sal_Int32 nUnnamedSeriesIndex
= 1;
345 for (auto const& series
: aSeries
)
347 OUString
aLabel(series
.first
);
348 if (aLabel
.isEmpty())
350 if( nUnnamedSeriesIndex
> 1 )
352 OUString
aResString(::chart::SchResId( STR_DATA_UNNAMED_SERIES_WITH_INDEX
));
354 // replace index of unnamed series
355 const OUString
aReplacementStr( "%NUMBER" );
356 sal_Int32 nIndex
= aResString
.indexOf( aReplacementStr
);
358 aLabel
= aResString
.replaceAt(
359 nIndex
, aReplacementStr
.getLength(),
360 OUString::number(nUnnamedSeriesIndex
));
362 if( aLabel
.isEmpty() )
363 aLabel
= ::chart::SchResId( STR_DATA_UNNAMED_SERIES
);
365 ++nUnnamedSeriesIndex
;
368 m_aEntries
.emplace_back(new SeriesEntry
);
369 pEntry
= m_aEntries
.back().get();
370 pEntry
->m_xDataSeries
.set(series
.second
.first
);
371 pEntry
->m_xChartType
.set(series
.second
.second
);
372 m_xLB_SERIES
->append(OUString::number(reinterpret_cast<sal_Int64
>(pEntry
)), aLabel
);
373 if (bHasSelectedEntry
&& series
.second
.first
== xSelected
)
374 nSelectedEntry
= nEntry
;
378 m_xLB_SERIES
->thaw();
380 if (bHasSelectedEntry
&& nSelectedEntry
!= -1)
381 m_xLB_SERIES
->select(nSelectedEntry
);
384 void DataSourceTabPage::fillRoleListBox()
386 int nSeriesEntry
= m_xLB_SERIES
->get_selected_index();
387 SeriesEntry
* pSeriesEntry
= nullptr;
388 if (nSeriesEntry
!= -1)
389 pSeriesEntry
= reinterpret_cast<SeriesEntry
*>(m_xLB_SERIES
->get_id(nSeriesEntry
).toInt64());
390 bool bHasSelectedEntry
= (pSeriesEntry
!= nullptr);
392 int nRoleIndex
= m_xLB_ROLE
->get_selected_index();
393 if (bHasSelectedEntry
)
395 DialogModel::tRolesWithRanges
aRoles(
396 DialogModel::getRolesWithRanges(
397 pSeriesEntry
->m_xDataSeries
,
398 lcl_GetSequenceNameForLabel( pSeriesEntry
),
399 pSeriesEntry
->m_xChartType
));
402 m_xLB_ROLE
->freeze();
405 for (auto const& elemRole
: aRoles
)
407 InsertRoleLBEntry(elemRole
.first
, elemRole
.second
);
412 // series may contain no roles, check listbox size before selecting entries
413 if (m_xLB_ROLE
->n_children() > 0)
415 if (nRoleIndex
== -1 || nRoleIndex
>= m_xLB_ROLE
->n_children())
417 m_xLB_ROLE
->select(nRoleIndex
);
422 void DataSourceTabPage::updateControlState()
424 int nSeriesEntry
= m_xLB_SERIES
->get_selected_index();
425 bool bHasSelectedSeries
= nSeriesEntry
!= -1;
426 bool bHasValidRole
= false;
427 bool bHasRangeChooser
= m_rDialogModel
.getRangeSelectionHelper()->hasRangeSelection();
429 if( bHasSelectedSeries
)
431 int nRoleEntry
= m_xLB_ROLE
->get_selected_index();
432 bHasValidRole
= nRoleEntry
!= -1;
435 m_xBTN_ADD
->set_sensitive(true);
436 m_xBTN_REMOVE
->set_sensitive(bHasSelectedSeries
);
438 m_xBTN_UP
->set_sensitive(bHasSelectedSeries
&& (nSeriesEntry
!= 0));
439 m_xBTN_DOWN
->set_sensitive(bHasSelectedSeries
&& (nSeriesEntry
!= m_xLB_SERIES
->n_children() - 1));
441 bool bHasCategories
= m_rDialogModel
.isCategoryDiagram();
443 m_xFT_DATALABELS
->set_visible(!bHasCategories
);
444 m_xFT_CATEGORIES
->set_visible( bHasCategories
);
445 bool bShowIB
= bHasRangeChooser
;
447 m_xIMB_RANGE_CAT
->set_visible(bShowIB
);
449 m_xFT_ROLE
->set_sensitive(bHasSelectedSeries
);
450 m_xLB_ROLE
->set_sensitive(bHasSelectedSeries
);
452 m_xFT_RANGE
->set_sensitive(bHasValidRole
);
453 m_xEDT_RANGE
->set_sensitive(bHasValidRole
);
455 m_xFT_SERIES
->set_sensitive(true);
456 m_xLB_SERIES
->set_sensitive(true);
458 m_xIMB_RANGE_MAIN
->set_visible(bShowIB
);
463 IMPL_LINK_NOARG(DataSourceTabPage
, SeriesSelectionChangedHdl
, weld::TreeView
&, void)
465 m_rDialogModel
.startControllerLockTimer();
466 if (m_xLB_SERIES
->get_selected_index() != -1)
469 RoleSelectionChangedHdl(*m_xLB_ROLE
);
471 updateControlState();
474 IMPL_LINK_NOARG(DataSourceTabPage
, RoleSelectionChangedHdl
, weld::TreeView
&, void)
476 m_rDialogModel
.startControllerLockTimer();
477 int nEntry
= m_xLB_ROLE
->get_selected_index();
480 OUString aSelectedRoleUI
= lcl_GetSelectedRole( *m_xLB_ROLE
, true );
481 OUString aSelectedRange
= lcl_GetSelectedRolesRange( *m_xLB_ROLE
);
483 // replace role in fixed text label
484 const OUString
aReplacementStr( "%VALUETYPE" );
485 sal_Int32 nIndex
= m_aFixedTextRange
.indexOf( aReplacementStr
);
488 m_xFT_RANGE
->set_label(
489 m_aFixedTextRange
.replaceAt(
490 nIndex
, aReplacementStr
.getLength(), aSelectedRoleUI
));
493 m_xEDT_RANGE
->set_text(aSelectedRange
);
498 IMPL_LINK_NOARG(DataSourceTabPage
, MainRangeButtonClickedHdl
, weld::Button
&, void)
500 OSL_ASSERT( m_pCurrentRangeChoosingField
== nullptr );
501 m_pCurrentRangeChoosingField
= m_xEDT_RANGE
.get();
502 if (!m_xEDT_RANGE
->get_text().isEmpty() &&
503 !updateModelFromControl( m_pCurrentRangeChoosingField
))
506 int nEntry
= m_xLB_SERIES
->get_selected_index();
507 bool bHasSelectedEntry
= (nEntry
!= -1);
509 OUString aSelectedRolesRange
= lcl_GetSelectedRolesRange(*m_xLB_ROLE
);
511 if (bHasSelectedEntry
&& (m_xLB_ROLE
->get_selected_index() != -1))
513 OUString
aUIStr(SchResId(STR_DATA_SELECT_RANGE_FOR_SERIES
));
516 OUString
aReplacement( "%VALUETYPE" );
517 sal_Int32 nIndex
= aUIStr
.indexOf( aReplacement
);
520 aUIStr
= aUIStr
.replaceAt( nIndex
, aReplacement
.getLength(),
521 lcl_GetSelectedRole( *m_xLB_ROLE
, true ));
523 // replace series name
524 aReplacement
= "%SERIESNAME";
525 nIndex
= aUIStr
.indexOf( aReplacement
);
528 aUIStr
= aUIStr
.replaceAt(nIndex
, aReplacement
.getLength(),
529 m_xLB_SERIES
->get_text(nEntry
));
532 lcl_enableRangeChoosing(true, m_pDialogController
);
533 m_rDialogModel
.getRangeSelectionHelper()->chooseRange( aSelectedRolesRange
, aUIStr
, *this );
536 m_pCurrentRangeChoosingField
= nullptr;
539 IMPL_LINK_NOARG(DataSourceTabPage
, CategoriesRangeButtonClickedHdl
, weld::Button
&, void)
541 OSL_ASSERT( m_pCurrentRangeChoosingField
== nullptr );
542 m_pCurrentRangeChoosingField
= m_xEDT_CATEGORIES
.get();
543 if( !m_xEDT_CATEGORIES
->get_text().isEmpty() &&
544 ! updateModelFromControl( m_pCurrentRangeChoosingField
))
547 OUString
aStr(SchResId(m_xFT_CATEGORIES
->get_visible() ? STR_DATA_SELECT_RANGE_FOR_CATEGORIES
: STR_DATA_SELECT_RANGE_FOR_DATALABELS
));
548 lcl_enableRangeChoosing(true, m_pDialogController
);
549 m_rDialogModel
.getRangeSelectionHelper()->chooseRange(
550 m_rDialogModel
.getCategoriesRange(), aStr
, *this );
553 IMPL_LINK_NOARG(DataSourceTabPage
, AddButtonClickedHdl
, weld::Button
&, void)
555 m_rDialogModel
.startControllerLockTimer();
556 int nEntry
= m_xLB_SERIES
->get_selected_index();
557 Reference
< XDataSeries
> xSeriesToInsertAfter
;
558 Reference
< XChartType
> xChartTypeForNewSeries
;
559 if( m_pTemplateProvider
)
560 m_rDialogModel
.setTemplate( m_pTemplateProvider
->getCurrentTemplate());
564 ::chart::SeriesEntry
* pEntry
= reinterpret_cast<::chart::SeriesEntry
*>(m_xLB_SERIES
->get_id(nEntry
).toInt64());
565 xSeriesToInsertAfter
.set(pEntry
->m_xDataSeries
);
566 xChartTypeForNewSeries
.set(pEntry
->m_xChartType
);
570 std::vector
< Reference
< XDataSeriesContainer
> > aCntVec(
571 m_rDialogModel
.getAllDataSeriesContainers());
572 if( ! aCntVec
.empty())
573 xChartTypeForNewSeries
.set( aCntVec
.front(), uno::UNO_QUERY
);
575 OSL_ENSURE( xChartTypeForNewSeries
.is(), "Cannot insert new series" );
577 m_rDialogModel
.insertSeriesAfter( xSeriesToInsertAfter
, xChartTypeForNewSeries
);
581 // note the box was cleared and refilled, so nEntry is invalid now
583 int nSelEntry
= m_xLB_SERIES
->get_selected_index();
587 if (nSelEntry
< m_xLB_SERIES
->n_children())
588 m_xLB_SERIES
->select(nSelEntry
);
590 SeriesSelectionChangedHdl(*m_xLB_SERIES
);
593 IMPL_LINK_NOARG(DataSourceTabPage
, RemoveButtonClickedHdl
, weld::Button
&, void)
595 m_rDialogModel
.startControllerLockTimer();
596 int nEntry
= m_xLB_SERIES
->get_selected_index();
599 SeriesEntry
* pEntry
= reinterpret_cast<::chart::SeriesEntry
*>(m_xLB_SERIES
->get_id(nEntry
).toInt64());
600 Reference
< XDataSeries
> xNewSelSeries
;
601 SeriesEntry
* pNewSelEntry
= nullptr;
602 if (nEntry
+ 1 < m_xLB_SERIES
->n_children())
603 pNewSelEntry
= reinterpret_cast<::chart::SeriesEntry
*>(m_xLB_SERIES
->get_id(nEntry
+ 1).toInt64());
605 pNewSelEntry
= reinterpret_cast<::chart::SeriesEntry
*>(m_xLB_SERIES
->get_id(nEntry
- 1).toInt64());
607 xNewSelSeries
.set(pNewSelEntry
->m_xDataSeries
);
609 m_rDialogModel
.deleteSeries( pEntry
->m_xDataSeries
, pEntry
->m_xChartType
);
612 m_xLB_SERIES
->remove(nEntry
);
615 // select previous or next series
616 if (xNewSelSeries
.is())
618 for (int i
= 0; i
< m_xLB_SERIES
->n_children(); ++i
)
620 pEntry
= reinterpret_cast<::chart::SeriesEntry
*>(m_xLB_SERIES
->get_id(i
).toInt64());
621 if (pEntry
->m_xDataSeries
== xNewSelSeries
)
623 m_xLB_SERIES
->select(i
);
628 SeriesSelectionChangedHdl(*m_xLB_SERIES
);
632 IMPL_LINK_NOARG(DataSourceTabPage
, UpButtonClickedHdl
, weld::Button
&, void)
634 m_rDialogModel
.startControllerLockTimer();
636 int nEntry
= m_xLB_SERIES
->get_selected_index();
637 SeriesEntry
* pEntry
= nullptr;
639 pEntry
= reinterpret_cast<SeriesEntry
*>(m_xLB_SERIES
->get_id(nEntry
).toInt64());
641 bool bHasSelectedEntry
= (pEntry
!= nullptr);
643 if (bHasSelectedEntry
)
645 m_rDialogModel
.moveSeries( pEntry
->m_xDataSeries
, DialogModel::MoveDirection::Up
);
648 SeriesSelectionChangedHdl(*m_xLB_SERIES
);
652 IMPL_LINK_NOARG(DataSourceTabPage
, DownButtonClickedHdl
, weld::Button
&, void)
654 m_rDialogModel
.startControllerLockTimer();
656 int nEntry
= m_xLB_SERIES
->get_selected_index();
657 SeriesEntry
* pEntry
= nullptr;
659 pEntry
= reinterpret_cast<SeriesEntry
*>(m_xLB_SERIES
->get_id(nEntry
).toInt64());
661 bool bHasSelectedEntry
= (pEntry
!= nullptr);
663 if (bHasSelectedEntry
)
665 m_rDialogModel
.moveSeries( pEntry
->m_xDataSeries
, DialogModel::MoveDirection::Down
);
668 SeriesSelectionChangedHdl(*m_xLB_SERIES
);
672 IMPL_LINK(DataSourceTabPage
, RangeModifiedHdl
, weld::Entry
&, rEdit
, void)
674 // note: isValid sets the color of the edit field
675 if( isRangeFieldContentValid( rEdit
))
678 updateModelFromControl( &rEdit
);
679 if (&rEdit
== m_xEDT_RANGE
.get())
681 if( ! lcl_UpdateCurrentSeriesName( *m_xLB_SERIES
))
686 // enable/disable OK button
690 void DataSourceTabPage::listeningFinished(
691 const OUString
& rNewRange
)
693 // rNewRange becomes invalid after removing the listener
694 OUString
aRange( rNewRange
);
696 m_rDialogModel
.startControllerLockTimer();
699 m_rDialogModel
.getRangeSelectionHelper()->stopRangeListening();
702 if( m_pCurrentRangeChoosingField
)
704 m_pCurrentRangeChoosingField
->set_text(aRange
);
705 m_pCurrentRangeChoosingField
->grab_focus();
708 if (m_pCurrentRangeChoosingField
== m_xEDT_RANGE
.get())
710 m_xEDT_RANGE
->set_text(aRange
);
713 else if (m_pCurrentRangeChoosingField
== m_xEDT_CATEGORIES
.get())
715 m_xEDT_CATEGORIES
->set_text(aRange
);
719 updateModelFromControl(m_pCurrentRangeChoosingField
);
720 if (!lcl_UpdateCurrentSeriesName(*m_xLB_SERIES
))
723 m_pCurrentRangeChoosingField
= nullptr;
725 updateControlState();
726 lcl_enableRangeChoosing(false, m_pDialogController
);
729 void DataSourceTabPage::disposingRangeSelection()
731 m_rDialogModel
.getRangeSelectionHelper()->stopRangeListening( false );
734 bool DataSourceTabPage::updateModelFromControl(const weld::Entry
* pField
)
739 ControllerLockGuardUNO
aLockedControllers( m_rDialogModel
.getChartModel() );
741 // @todo: validity check of field content
743 bool bAll
= (pField
== nullptr);
744 Reference
< data::XDataProvider
> xDataProvider( m_rDialogModel
.getDataProvider());
746 if (bAll
|| (pField
== m_xEDT_CATEGORIES
.get()))
748 Reference
< data::XLabeledDataSequence
> xLabeledSeq( m_rDialogModel
.getCategories() );
749 if( xDataProvider
.is())
751 OUString
aRange(m_xEDT_CATEGORIES
->get_text());
752 if (!aRange
.isEmpty())
754 // create or change categories
755 if( !xLabeledSeq
.is())
757 xLabeledSeq
.set( DataSourceHelper::createLabeledDataSequence() );
758 m_rDialogModel
.setCategories( xLabeledSeq
);
762 xLabeledSeq
->setValues( xDataProvider
->createDataSequenceByRangeRepresentation( aRange
));
764 catch( const uno::Exception
& )
766 // should work as validation should have happened before
767 DBG_UNHANDLED_EXCEPTION("chart2");
770 else if( xLabeledSeq
.is())
772 // clear existing categories
773 xLabeledSeq
.set(nullptr);
774 m_rDialogModel
.setCategories( xLabeledSeq
);
779 int nSeriesEntry
= m_xLB_SERIES
->get_selected_index();
780 SeriesEntry
* pSeriesEntry
= nullptr;
781 if (nSeriesEntry
!= -1)
782 pSeriesEntry
= reinterpret_cast<SeriesEntry
*>(m_xLB_SERIES
->get_id(nSeriesEntry
).toInt64());
783 bool bHasSelectedEntry
= (pSeriesEntry
!= nullptr);
785 if( bHasSelectedEntry
)
787 if( bAll
|| (pField
== m_xEDT_RANGE
.get()) )
791 OUString aSelectedRole
= lcl_GetSelectedRole( *m_xLB_ROLE
);
792 OUString
aRange(m_xEDT_RANGE
->get_text());
793 OUString
aSequenceRole( aSelectedRole
);
794 bool bIsLabel
= (aSequenceRole
== lcl_aLabelRole
);
795 OUString
aSequenceNameForLabel( lcl_GetSequenceNameForLabel( pSeriesEntry
));
798 aSequenceRole
= aSequenceNameForLabel
;
800 Reference
< data::XDataSource
> xSource( pSeriesEntry
->m_xDataSeries
, uno::UNO_QUERY_THROW
);
801 Reference
< data::XLabeledDataSequence
> xLabeledSeq(
802 DataSeriesHelper::getDataSequenceByRole( xSource
, aSequenceRole
));
804 if( xDataProvider
.is())
808 if( ! xLabeledSeq
.is())
810 // check if there is already an "orphan" label sequence
811 xLabeledSeq
.set( lcl_findLSequenceWithOnlyLabel( xSource
));
812 if( ! xLabeledSeq
.is())
814 // no corresponding labeled data sequence for label found
815 xLabeledSeq
.set( DataSourceHelper::createLabeledDataSequence() );
816 lcl_addLSequenceToDataSource( xLabeledSeq
, xSource
);
819 if( xLabeledSeq
.is())
821 if( !aRange
.isEmpty())
823 Reference
< data::XDataSequence
> xNewSeq
;
826 xNewSeq
.set( xDataProvider
->createDataSequenceByRangeRepresentation( aRange
));
828 catch( const uno::Exception
& )
830 // should work as validation should have happened before
831 DBG_UNHANDLED_EXCEPTION("chart2");
835 // update range name by the full string provided
836 // by the data provider. E.g. "a1" might become
838 aRange
= xNewSeq
->getSourceRangeRepresentation();
839 Reference
< beans::XPropertySet
> xProp( xNewSeq
, uno::UNO_QUERY_THROW
);
840 xProp
->setPropertyValue( "Role" , uno::Any( lcl_aLabelRole
));
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
.set( lcl_findLSequenceWithOnlyLabel( xSource
));
877 if( ! xLabeledSeq
.is())
879 xLabeledSeq
.set( DataSourceHelper::createLabeledDataSequence() );
880 lcl_addLSequenceToDataSource( xLabeledSeq
, xSource
);
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 Reference
< util::XModifiable
> xModifiable( m_rDialogModel
.getChartModel(), uno::UNO_QUERY
);
906 if( xModifiable
.is() )
907 xModifiable
->setModified( true );
908 const DialogModelTimeBasedInfo
& rInfo
= m_rDialogModel
.getTimeBasedInfo();
911 m_rDialogModel
.setTimeBasedRange(rInfo
.bTimeBased
, rInfo
.nStart
, rInfo
.nEnd
);
914 catch( const uno::Exception
& )
916 DBG_UNHANDLED_EXCEPTION("chart2");
925 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */