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_RangeChooser.hxx"
21 #include "Strings.hrc"
24 #include "DataSourceHelper.hxx"
25 #include "DiagramHelper.hxx"
26 #include "ChartTypeTemplateProvider.hxx"
27 #include "DialogModel.hxx"
28 #include "RangeSelectionHelper.hxx"
29 #include <com/sun/star/awt/XTopWindow.hpp>
30 #include <com/sun/star/embed/EmbedStates.hpp>
31 #include <com/sun/star/embed/XComponentSupplier.hpp>
32 #include <svtools/miscopt.hxx>
36 void lcl_ShowChooserButton(
37 PushButton
& rChooserButton
,
40 if( rChooserButton
.IsVisible() != bShow
)
42 rChooserButton
.Show( bShow
);
46 void lcl_enableRangeChoosing( bool bEnable
, Dialog
* pDialog
)
50 pDialog
->Show( !bEnable
);
51 pDialog
->SetModalInputMode( !bEnable
);
55 } // anonymous namespace
59 using namespace ::com::sun::star
;
60 using namespace ::com::sun::star::chart2
;
62 using ::com::sun::star::uno::Reference
;
63 using ::com::sun::star::uno::Sequence
;
65 RangeChooserTabPage::RangeChooserTabPage( vcl::Window
* pParent
66 , DialogModel
& rDialogModel
67 , ChartTypeTemplateProvider
* pTemplateProvider
68 , Dialog
* pParentDialog
69 , bool bHideDescription
/* = false */ )
70 : OWizardPage( pParent
72 ,"modules/schart/ui/tp_RangeChooser.ui")
73 , m_nChangingControlCalls(0)
75 , m_xDataProvider( 0 )
76 , m_aLastValidRangeString()
77 , m_xCurrentChartTypeTemplate(0)
78 , m_pTemplateProvider(pTemplateProvider
)
79 , m_rDialogModel( rDialogModel
)
80 , m_pParentDialog( pParentDialog
)
81 , m_pTabPageNotifiable( dynamic_cast< TabPageNotifiable
* >( pParentDialog
))
83 get(m_pFT_Caption
, "FT_CAPTION_FOR_WIZARD");
84 get(m_pFT_Range
, "FT_RANGE");
85 get(m_pED_Range
, "ED_RANGE");
86 get(m_pIB_Range
, "IB_RANGE");
87 get(m_pRB_Rows
, "RB_DATAROWS");
88 get(m_pRB_Columns
, "RB_DATACOLS");
89 get(m_pCB_FirstRowAsLabel
, "CB_FIRST_ROW_ASLABELS");
90 get(m_pCB_FirstColumnAsLabel
, "CB_FIRST_COLUMN_ASLABELS");
91 get(m_pFTTitle
, "STR_PAGE_DATA_RANGE");// OH:remove later with dialog title
92 get(m_pFL_TimeBased
, "separator1");
93 get(m_pCB_TimeBased
, "CB_TIME_BASED");
94 get(m_pFT_TimeStart
, "label1");
95 get(m_pEd_TimeStart
, "ED_TIME_BASED_START");
96 get(m_pFT_TimeEnd
, "label2");
97 get(m_pEd_TimeEnd
, "ED_TIME_BASED_END");
99 m_pFT_Caption
->Show(!bHideDescription
);
101 this->SetText( m_pFTTitle
->GetText());// OH:remove later with dialog
103 // set defaults as long as DetectArguments does not work
104 m_pRB_Columns
->Check();
105 m_pCB_FirstColumnAsLabel
->Check();
106 m_pCB_FirstRowAsLabel
->Check();
108 // BM: Note, that the range selection is not available, if there is no view.
109 // This happens for charts having their own embedded spreadsheet. If you
110 // force to get the range selection here, this would mean when entering this
111 // page the calc view would be created in this case. So, I enable the
112 // button here, and in the worst case nothing happens when it is pressed.
113 // Not nice, but I see no better solution for the moment.
114 m_pIB_Range
->SetClickHdl( LINK( this, RangeChooserTabPage
, ChooseRangeHdl
));
116 // #i75179# enable setting the background to a different color
117 m_pED_Range
->SetStyle( m_pED_Range
->GetStyle() | WB_FORCECTRLBACKGROUND
);
119 m_pED_Range
->SetUpdateDataHdl( LINK( this, RangeChooserTabPage
, ControlChangedHdl
));
120 m_pED_Range
->SetModifyHdl( LINK( this, RangeChooserTabPage
, ControlEditedHdl
));
121 m_pRB_Rows
->SetToggleHdl( LINK( this, RangeChooserTabPage
, ControlChangedHdl
) );
122 m_pCB_FirstRowAsLabel
->SetToggleHdl( LINK( this, RangeChooserTabPage
, ControlChangedHdl
) );
123 m_pCB_FirstColumnAsLabel
->SetToggleHdl( LINK( this, RangeChooserTabPage
, ControlChangedHdl
) );
124 m_pCB_TimeBased
->SetToggleHdl( LINK( this, RangeChooserTabPage
, ControlChangedHdl
) );
125 m_pEd_TimeStart
->SetModifyHdl( LINK( this, RangeChooserTabPage
, ControlChangedHdl
) );
126 m_pEd_TimeEnd
->SetModifyHdl( LINK( this, RangeChooserTabPage
, ControlChangedHdl
) );
128 SvtMiscOptions aOpts
;
129 if ( !aOpts
.IsExperimentalMode() )
131 m_pFL_TimeBased
->Hide();
132 m_pCB_TimeBased
->Hide();
133 m_pFT_TimeStart
->Hide();
134 m_pEd_TimeStart
->Hide();
135 m_pFT_TimeEnd
->Hide();
136 m_pEd_TimeEnd
->Hide();
140 RangeChooserTabPage::~RangeChooserTabPage()
145 void RangeChooserTabPage::dispose()
147 m_pFT_Caption
.clear();
152 m_pRB_Columns
.clear();
153 m_pCB_FirstRowAsLabel
.clear();
154 m_pCB_FirstColumnAsLabel
.clear();
156 m_pFL_TimeBased
.clear();
157 m_pCB_TimeBased
.clear();
158 m_pFT_TimeStart
.clear();
159 m_pEd_TimeStart
.clear();
160 m_pFT_TimeEnd
.clear();
161 m_pEd_TimeEnd
.clear();
162 m_pParentDialog
.clear();
163 OWizardPage::dispose();
167 void RangeChooserTabPage::ActivatePage()
169 OWizardPage::ActivatePage();
170 initControlsFromModel();
173 void RangeChooserTabPage::initControlsFromModel()
175 m_nChangingControlCalls
++;
177 if(m_pTemplateProvider
)
178 m_xCurrentChartTypeTemplate
= m_pTemplateProvider
->getCurrentTemplate();
180 bool bUseColumns
= ! m_pRB_Rows
->IsChecked();
181 bool bFirstCellAsLabel
= bUseColumns
? m_pCB_FirstRowAsLabel
->IsChecked() : m_pCB_FirstColumnAsLabel
->IsChecked();
182 bool bHasCategories
= bUseColumns
? m_pCB_FirstColumnAsLabel
->IsChecked() : m_pCB_FirstRowAsLabel
->IsChecked();
184 bool bIsValid
= m_rDialogModel
.allArgumentsForRectRangeDetected();
186 m_rDialogModel
.detectArguments(m_aLastValidRangeString
, bUseColumns
, bFirstCellAsLabel
, bHasCategories
);
188 m_aLastValidRangeString
.clear();
190 m_pED_Range
->SetText( m_aLastValidRangeString
);
192 m_pRB_Rows
->Check( !bUseColumns
);
193 m_pRB_Columns
->Check( bUseColumns
);
195 m_pCB_FirstRowAsLabel
->Check( m_pRB_Rows
->IsChecked()?bHasCategories
:bFirstCellAsLabel
);
196 m_pCB_FirstColumnAsLabel
->Check( m_pRB_Columns
->IsChecked()?bHasCategories
:bFirstCellAsLabel
);
200 m_nChangingControlCalls
--;
203 void RangeChooserTabPage::DeactivatePage()
206 svt::OWizardPage::DeactivatePage();
209 void RangeChooserTabPage::commitPage()
211 commitPage(::svt::WizardTypes::eFinish
);
214 bool RangeChooserTabPage::commitPage( ::svt::WizardTypes::CommitPageReason
/*eReason*/ )
216 //ranges may have been edited in the meanwhile (dirty is true in that case here)
219 changeDialogModelAccordingToControls();
220 return true; // return false if this page should not be left
226 void RangeChooserTabPage::changeDialogModelAccordingToControls()
228 if(m_nChangingControlCalls
>0)
231 if( !m_xCurrentChartTypeTemplate
.is() )
233 if(m_pTemplateProvider
)
234 m_xCurrentChartTypeTemplate
.set( m_pTemplateProvider
->getCurrentTemplate());
235 if( !m_xCurrentChartTypeTemplate
.is())
237 OSL_FAIL( "Need a template to change data source" );
244 bool bFirstCellAsLabel
= ( m_pCB_FirstColumnAsLabel
->IsChecked() && !m_pRB_Columns
->IsChecked() )
245 || ( m_pCB_FirstRowAsLabel
->IsChecked() && !m_pRB_Rows
->IsChecked() );
246 bool bHasCategories
= ( m_pCB_FirstColumnAsLabel
->IsChecked() && m_pRB_Columns
->IsChecked() )
247 || ( m_pCB_FirstRowAsLabel
->IsChecked() && m_pRB_Rows
->IsChecked() );
248 bool bTimeBased
= m_pCB_TimeBased
->IsChecked();
250 Sequence
< beans::PropertyValue
> aArguments(
251 DataSourceHelper::createArguments(
252 m_pRB_Columns
->IsChecked(), bFirstCellAsLabel
, bHasCategories
) );
256 aArguments
.realloc( aArguments
.getLength() + 1 );
257 aArguments
[aArguments
.getLength() - 1] =
258 beans::PropertyValue( "TimeBased", -1, uno::makeAny(bTimeBased
),
259 beans::PropertyState_DIRECT_VALUE
);
262 // only if range is valid
263 if( m_aLastValidRangeString
.equals(m_pED_Range
->GetText()))
265 m_rDialogModel
.setTemplate( m_xCurrentChartTypeTemplate
);
266 aArguments
.realloc( aArguments
.getLength() + 1 );
267 aArguments
[aArguments
.getLength() - 1] =
268 beans::PropertyValue( "CellRangeRepresentation" , -1,
269 uno::makeAny( m_aLastValidRangeString
),
270 beans::PropertyState_DIRECT_VALUE
);
271 m_rDialogModel
.setData( aArguments
);
276 sal_Int32 nStart
= m_pEd_TimeStart
->GetText().toInt32();
277 sal_Int32 nEnd
= m_pEd_TimeEnd
->GetText().toInt32();
278 m_rDialogModel
.setTimeBasedRange(true, nStart
, nEnd
);
282 //@todo warn user that the selected range is not valid
283 //@todo better: disable OK-Button if range is invalid
287 bool RangeChooserTabPage::isValid()
289 OUString
aRange( m_pED_Range
->GetText());
290 bool bFirstCellAsLabel
= ( m_pCB_FirstColumnAsLabel
->IsChecked() && !m_pRB_Columns
->IsChecked() )
291 || ( m_pCB_FirstRowAsLabel
->IsChecked() && !m_pRB_Rows
->IsChecked() );
292 bool bHasCategories
= ( m_pCB_FirstColumnAsLabel
->IsChecked() && m_pRB_Columns
->IsChecked() )
293 || ( m_pCB_FirstRowAsLabel
->IsChecked() && m_pRB_Rows
->IsChecked() );
294 bool bIsValid
= ( aRange
.isEmpty() ) ||
295 m_rDialogModel
.getRangeSelectionHelper()->verifyArguments(
296 DataSourceHelper::createArguments(
297 aRange
, Sequence
< sal_Int32
>(), m_pRB_Columns
->IsChecked(), bFirstCellAsLabel
, bHasCategories
));
301 m_pED_Range
->SetControlForeground();
302 m_pED_Range
->SetControlBackground();
303 if( m_pTabPageNotifiable
)
304 m_pTabPageNotifiable
->setValidPage( this );
305 m_aLastValidRangeString
= aRange
;
309 m_pED_Range
->SetControlBackground( RANGE_SELECTION_INVALID_RANGE_BACKGROUND_COLOR
);
310 m_pED_Range
->SetControlForeground( RANGE_SELECTION_INVALID_RANGE_FOREGROUND_COLOR
);
311 if( m_pTabPageNotifiable
)
312 m_pTabPageNotifiable
->setInvalidPage( this );
315 // enable/disable controls
316 // #i79531# if the range is valid but an action of one of these buttons
317 // would render it invalid, the button should be disabled
320 bool bDataInColumns
= m_pRB_Columns
->IsChecked();
321 bool bIsSwappedRangeValid
= m_rDialogModel
.getRangeSelectionHelper()->verifyArguments(
322 DataSourceHelper::createArguments(
323 aRange
, Sequence
< sal_Int32
>(), ! bDataInColumns
, bHasCategories
, bFirstCellAsLabel
));
324 m_pRB_Rows
->Enable( bIsSwappedRangeValid
);
325 m_pRB_Columns
->Enable( bIsSwappedRangeValid
);
327 m_pCB_FirstRowAsLabel
->Enable(
328 m_rDialogModel
.getRangeSelectionHelper()->verifyArguments(
329 DataSourceHelper::createArguments(
330 aRange
, Sequence
< sal_Int32
>(), m_pRB_Columns
->IsChecked(),
331 bDataInColumns
? ! bFirstCellAsLabel
: bFirstCellAsLabel
,
332 bDataInColumns
? bHasCategories
: ! bHasCategories
)));
333 m_pCB_FirstColumnAsLabel
->Enable(
334 m_rDialogModel
.getRangeSelectionHelper()->verifyArguments(
335 DataSourceHelper::createArguments(
336 aRange
, Sequence
< sal_Int32
>(), m_pRB_Columns
->IsChecked(),
337 bDataInColumns
? bFirstCellAsLabel
: ! bFirstCellAsLabel
,
338 bDataInColumns
? ! bHasCategories
: bHasCategories
)));
342 m_pRB_Rows
->Enable( bIsValid
);
343 m_pRB_Columns
->Enable( bIsValid
);
344 m_pCB_FirstRowAsLabel
->Enable( bIsValid
);
345 m_pCB_FirstColumnAsLabel
->Enable( bIsValid
);
348 bool bShowIB
= m_rDialogModel
.getRangeSelectionHelper()->hasRangeSelection();
349 lcl_ShowChooserButton( *m_pIB_Range
, bShowIB
);
354 IMPL_LINK_NOARG(RangeChooserTabPage
, ControlEditedHdl
)
361 IMPL_LINK_NOARG(RangeChooserTabPage
, ControlChangedHdl
)
365 changeDialogModelAccordingToControls();
369 IMPL_LINK_NOARG(RangeChooserTabPage
, ChooseRangeHdl
)
371 OUString aRange
= m_pED_Range
->GetText();
372 // using assignment for broken gcc 3.3
373 OUString aTitle
= m_pFTTitle
->GetText();
375 lcl_enableRangeChoosing( true, m_pParentDialog
);
376 m_rDialogModel
.getRangeSelectionHelper()->chooseRange( aRange
, aTitle
, *this );
381 void RangeChooserTabPage::listeningFinished( const OUString
& rNewRange
)
383 //user has selected a new range
385 OUString
aRange( rNewRange
);
387 m_rDialogModel
.startControllerLockTimer();
390 m_rDialogModel
.getRangeSelectionHelper()->stopRangeListening();
392 //update dialog state
395 m_pED_Range
->SetText( aRange
);
396 m_pED_Range
->GrabFocus();
400 changeDialogModelAccordingToControls();
402 lcl_enableRangeChoosing( false, m_pParentDialog
);
404 void RangeChooserTabPage::disposingRangeSelection()
406 m_rDialogModel
.getRangeSelectionHelper()->stopRangeListening( false );
409 void RangeChooserTabPage::setDirty()
411 if( m_nChangingControlCalls
== 0 )
417 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */