1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_chart2.hxx"
26
27 #include "tp_RangeChooser.hxx"
28 #include "tp_RangeChooser.hrc"
29 #include "Strings.hrc"
30 #include "ResId.hxx"
31 #include "macros.hxx"
32 #include "NoWarningThisInCTOR.hxx"
33 #include "DataSourceHelper.hxx"
34 #include "DiagramHelper.hxx"
35 #include "ChartTypeTemplateProvider.hxx"
36 #include "DialogModel.hxx"
37 #include "RangeSelectionHelper.hxx"
38 #include <com/sun/star/awt/XTopWindow.hpp>
39 #include <com/sun/star/embed/EmbedStates.hpp>
40 #include <com/sun/star/embed/XComponentSupplier.hpp>
41
42 namespace
43 {
lcl_ShowChooserButton(::chart::RangeSelectionButton & rChooserButton,Edit & rEditField,sal_Bool bShow)44 void lcl_ShowChooserButton(
45 ::chart::RangeSelectionButton & rChooserButton,
46 Edit & rEditField,
47 sal_Bool bShow )
48 {
49 if( rChooserButton.IsVisible() != bShow )
50 {
51 rChooserButton.Show( bShow );
52 sal_Int32 nWidhtDiff = 10 + 2;
53 if( bShow )
54 nWidhtDiff = -nWidhtDiff;
55 Size aSize = rChooserButton.PixelToLogic( rEditField.GetSizePixel(), MAP_APPFONT );
56 aSize.setWidth( aSize.getWidth() + nWidhtDiff );
57 rEditField.SetSizePixel( rChooserButton.LogicToPixel( aSize, MAP_APPFONT ));
58 }
59 }
lcl_enableRangeChoosing(bool bEnable,Dialog * pDialog)60 void lcl_enableRangeChoosing( bool bEnable, Dialog * pDialog )
61 {
62 if( pDialog )
63 {
64 pDialog->Show( bEnable ? sal_False : sal_True );
65 pDialog->SetModalInputMode( bEnable ? sal_False : sal_True );
66 }
67 }
lcl_shiftControlY(Control & rControl,long nYOffset)68 void lcl_shiftControlY( Control & rControl, long nYOffset )
69 {
70 Point aPos( rControl.GetPosPixel());
71 aPos.setY( aPos.getY() + nYOffset );
72 rControl.SetPosPixel( aPos );
73 }
74 } // anonymous namespace
75
76 //.............................................................................
77 namespace chart
78 {
79 //.............................................................................
80 using namespace ::com::sun::star;
81 using namespace ::com::sun::star::chart2;
82
83 using ::com::sun::star::uno::Reference;
84 using ::com::sun::star::uno::Sequence;
85
86
RangeChooserTabPage(Window * pParent,DialogModel & rDialogModel,ChartTypeTemplateProvider * pTemplateProvider,Dialog * pParentDialog,bool bHideDescription)87 RangeChooserTabPage::RangeChooserTabPage( Window* pParent
88 , DialogModel & rDialogModel
89 , ChartTypeTemplateProvider* pTemplateProvider
90 , Dialog * pParentDialog
91 , bool bHideDescription /* = false */ )
92
93 : OWizardPage( pParent, SchResId(TP_RANGECHOOSER) )
94
95 , m_aFT_Caption( this, SchResId( FT_CAPTION_FOR_WIZARD ) )
96 , m_aFT_Range( this, SchResId( FT_RANGE ) )
97 , m_aED_Range( this, SchResId( ED_RANGE ) )
98 , m_aIB_Range( this, SchResId( IB_RANGE ) )
99 , m_aRB_Rows( this, SchResId( RB_DATAROWS ) )
100 , m_aRB_Columns( this, SchResId( RB_DATACOLS ) )
101 , m_aCB_FirstRowAsLabel( this, SchResId( CB_FIRST_ROW_ASLABELS ) )
102 , m_aCB_FirstColumnAsLabel( this, SchResId( CB_FIRST_COLUMN_ASLABELS ) )
103 , m_nChangingControlCalls(0)
104 , m_bIsDirty(false)
105 , m_xDataProvider( 0 )
106 , m_aLastValidRangeString()
107 , m_xCurrentChartTypeTemplate(0)
108 , m_pTemplateProvider(pTemplateProvider)
109 , m_rDialogModel( rDialogModel )
110 , m_pParentDialog( pParentDialog )
111 , m_pTabPageNotifiable( dynamic_cast< TabPageNotifiable * >( pParentDialog ))
112 {
113 FreeResource();
114
115 if( bHideDescription )
116 {
117 // note: the offset should be a negative value for shifting upwards, the
118 // 4 is for the offset difference between a wizard page and a tab-page
119 long nYOffset = - ( m_aFT_Range.GetPosPixel().getY() - m_aFT_Caption.GetPosPixel().getY() + 4 );
120 m_aFT_Caption.Hide();
121
122 // shift all controls by the offset space saved by hiding the caption
123 lcl_shiftControlY( m_aFT_Range, nYOffset );
124 lcl_shiftControlY( m_aED_Range, nYOffset );
125 lcl_shiftControlY( m_aIB_Range, nYOffset );
126 lcl_shiftControlY( m_aRB_Rows, nYOffset );
127 lcl_shiftControlY( m_aRB_Columns, nYOffset );
128 lcl_shiftControlY( m_aCB_FirstRowAsLabel, nYOffset );
129 lcl_shiftControlY( m_aCB_FirstColumnAsLabel, nYOffset );
130 }
131 else
132 {
133 // make font of caption bold
134 Font aFont( m_aFT_Caption.GetControlFont() );
135 aFont.SetWeight( WEIGHT_BOLD );
136 m_aFT_Caption.SetControlFont( aFont );
137
138 // no mnemonic
139 m_aFT_Caption.SetStyle( m_aFT_Caption.GetStyle() | WB_NOLABEL );
140 }
141
142 this->SetText( String(SchResId(STR_PAGE_DATA_RANGE)) );
143 m_aIB_Range.SetQuickHelpText( String(SchResId(STR_TIP_SELECT_RANGE)) );
144
145 // set defaults as long as DetectArguments does not work
146 m_aRB_Columns.Check();
147 m_aCB_FirstColumnAsLabel.Check();
148 m_aCB_FirstRowAsLabel.Check();
149
150 // BM: Note, that the range selection is not available, if there is no view.
151 // This happens for charts having their own embedded spreadsheet. If you
152 // force to get the range selection here, this would mean when entering this
153 // page the calc view would be created in this case. So, I enable the
154 // button here, and in the worst case nothing happens when it is pressed.
155 // Not nice, but I see no better solution for the moment.
156 m_aIB_Range.SetClickHdl( LINK( this, RangeChooserTabPage, ChooseRangeHdl ));
157 m_aED_Range.SetKeyInputHdl( LINK( this, RangeChooserTabPage, ChooseRangeHdl ));
158
159 // #i75179# enable setting the background to a different color
160 m_aED_Range.SetStyle( m_aED_Range.GetStyle() | WB_FORCECTRLBACKGROUND );
161
162 m_aED_Range.SetUpdateDataHdl( LINK( this, RangeChooserTabPage, ControlChangedHdl ));
163 m_aED_Range.SetModifyHdl( LINK( this, RangeChooserTabPage, ControlEditedHdl ));
164 m_aRB_Rows.SetToggleHdl( LINK( this, RangeChooserTabPage, ControlChangedHdl ) );
165 m_aCB_FirstRowAsLabel.SetToggleHdl( LINK( this, RangeChooserTabPage, ControlChangedHdl ) );
166 m_aCB_FirstColumnAsLabel.SetToggleHdl( LINK( this, RangeChooserTabPage, ControlChangedHdl ) );
167 }
168
~RangeChooserTabPage()169 RangeChooserTabPage::~RangeChooserTabPage()
170 {
171 }
172
ActivatePage()173 void RangeChooserTabPage::ActivatePage()
174 {
175 OWizardPage::ActivatePage();
176 initControlsFromModel();
177 }
178
initControlsFromModel()179 void RangeChooserTabPage::initControlsFromModel()
180 {
181 m_nChangingControlCalls++;
182
183 if(m_pTemplateProvider)
184 {
185 m_xCurrentChartTypeTemplate = m_pTemplateProvider->getCurrentTemplate();
186 }
187
188 bool bUseColumns = ! m_aRB_Rows.IsChecked();
189 bool bFirstCellAsLabel = bUseColumns ? m_aCB_FirstRowAsLabel.IsChecked() : m_aCB_FirstColumnAsLabel.IsChecked();
190 bool bHasCategories = bUseColumns ? m_aCB_FirstColumnAsLabel.IsChecked() : m_aCB_FirstRowAsLabel.IsChecked();
191
192 bool bIsValid = m_rDialogModel.allArgumentsForRectRangeDetected();
193 if( bIsValid )
194 m_rDialogModel.detectArguments(
195 m_aLastValidRangeString, bUseColumns, bFirstCellAsLabel, bHasCategories );
196 else
197 m_aLastValidRangeString = String::EmptyString();
198
199 m_aED_Range.SetText( m_aLastValidRangeString );
200
201 m_aRB_Rows.Check( !bUseColumns );
202 m_aRB_Columns.Check( bUseColumns );
203
204 m_aCB_FirstRowAsLabel.Check( m_aRB_Rows.IsChecked()?bHasCategories:bFirstCellAsLabel );
205 m_aCB_FirstColumnAsLabel.Check( m_aRB_Columns.IsChecked()?bHasCategories:bFirstCellAsLabel );
206
207 isValid();
208
209 m_nChangingControlCalls--;
210 }
211
DeactivatePage()212 void RangeChooserTabPage::DeactivatePage()
213 {
214 commitPage();
215 svt::OWizardPage::DeactivatePage();
216 }
217
commitPage()218 void RangeChooserTabPage::commitPage()
219 {
220 commitPage(::svt::WizardTypes::eFinish);
221 }
222
commitPage(::svt::WizardTypes::CommitPageReason)223 sal_Bool RangeChooserTabPage::commitPage( ::svt::WizardTypes::CommitPageReason /*eReason*/ )
224 {
225 //ranges may have been edited in the meanwhile (dirty is true in that case here)
226 if( isValid() )
227 {
228 changeDialogModelAccordingToControls();
229 return sal_True;//return false if this page should not be left
230 }
231 else
232 return sal_False;
233 }
234
changeDialogModelAccordingToControls()235 void RangeChooserTabPage::changeDialogModelAccordingToControls()
236 {
237 if(m_nChangingControlCalls>0)
238 return;
239
240 if( !m_xCurrentChartTypeTemplate.is() )
241 {
242 if(m_pTemplateProvider)
243 m_xCurrentChartTypeTemplate.set( m_pTemplateProvider->getCurrentTemplate());
244 if( !m_xCurrentChartTypeTemplate.is())
245 {
246 OSL_ENSURE( false, "Need a template to change data source" );
247 return;
248 }
249 }
250
251 if( m_bIsDirty )
252 {
253 sal_Bool bFirstCellAsLabel = ( m_aCB_FirstColumnAsLabel.IsChecked() && !m_aRB_Columns.IsChecked() )
254 || ( m_aCB_FirstRowAsLabel.IsChecked() && !m_aRB_Rows.IsChecked() );
255 sal_Bool bHasCategories = ( m_aCB_FirstColumnAsLabel.IsChecked() && m_aRB_Columns.IsChecked() )
256 || ( m_aCB_FirstRowAsLabel.IsChecked() && m_aRB_Rows.IsChecked() );
257
258 Sequence< beans::PropertyValue > aArguments(
259 DataSourceHelper::createArguments(
260 m_aRB_Columns.IsChecked(), bFirstCellAsLabel, bHasCategories ) );
261
262 // only if range is valid
263 if( m_aLastValidRangeString.equals( m_aED_Range.GetText()))
264 {
265 m_rDialogModel.setTemplate( m_xCurrentChartTypeTemplate );
266 aArguments.realloc( aArguments.getLength() + 1 );
267 aArguments[aArguments.getLength() - 1] =
268 beans::PropertyValue( C2U("CellRangeRepresentation"), -1,
269 uno::makeAny( m_aLastValidRangeString ),
270 beans::PropertyState_DIRECT_VALUE );
271 m_rDialogModel.setData( aArguments );
272 m_bIsDirty = false;
273 }
274
275 //@todo warn user that the selected range is not valid
276 //@todo better: disable OK-Button if range is invalid
277 }
278 }
279
isValid()280 bool RangeChooserTabPage::isValid()
281 {
282 ::rtl::OUString aRange( m_aED_Range.GetText());
283 sal_Bool bFirstCellAsLabel = ( m_aCB_FirstColumnAsLabel.IsChecked() && !m_aRB_Columns.IsChecked() )
284 || ( m_aCB_FirstRowAsLabel.IsChecked() && !m_aRB_Rows.IsChecked() );
285 sal_Bool bHasCategories = ( m_aCB_FirstColumnAsLabel.IsChecked() && m_aRB_Columns.IsChecked() )
286 || ( m_aCB_FirstRowAsLabel.IsChecked() && m_aRB_Rows.IsChecked() );
287 bool bIsValid = aRange.isEmpty() ||
288 m_rDialogModel.getRangeSelectionHelper()->verifyArguments(
289 DataSourceHelper::createArguments(
290 aRange, Sequence< sal_Int32 >(), m_aRB_Columns.IsChecked(), bFirstCellAsLabel, bHasCategories ));
291
292 if( bIsValid )
293 {
294 m_aED_Range.SetControlForeground();
295 m_aED_Range.SetControlBackground();
296 if( m_pTabPageNotifiable )
297 m_pTabPageNotifiable->setValidPage( this );
298 m_aLastValidRangeString = aRange;
299 }
300 else
301 {
302 m_aED_Range.SetControlBackground( RANGE_SELECTION_INVALID_RANGE_BACKGROUND_COLOR );
303 m_aED_Range.SetControlForeground( RANGE_SELECTION_INVALID_RANGE_FOREGROUND_COLOR );
304 if( m_pTabPageNotifiable )
305 m_pTabPageNotifiable->setInvalidPage( this );
306 }
307
308 // enable/disable controls
309 // #i79531# if the range is valid but an action of one of these buttons
310 // would render it invalid, the button should be disabled
311 if( bIsValid )
312 {
313 bool bDataInColumns = m_aRB_Columns.IsChecked();
314 bool bIsSwappedRangeValid = m_rDialogModel.getRangeSelectionHelper()->verifyArguments(
315 DataSourceHelper::createArguments(
316 aRange, Sequence< sal_Int32 >(), ! bDataInColumns, bHasCategories, bFirstCellAsLabel ));
317 m_aRB_Rows.Enable( bIsSwappedRangeValid );
318 m_aRB_Columns.Enable( bIsSwappedRangeValid );
319
320 m_aCB_FirstRowAsLabel.Enable(
321 m_rDialogModel.getRangeSelectionHelper()->verifyArguments(
322 DataSourceHelper::createArguments(
323 aRange, Sequence< sal_Int32 >(), m_aRB_Columns.IsChecked(),
324 bDataInColumns ? ! bFirstCellAsLabel : bFirstCellAsLabel,
325 bDataInColumns ? bHasCategories : ! bHasCategories )));
326 m_aCB_FirstColumnAsLabel.Enable(
327 m_rDialogModel.getRangeSelectionHelper()->verifyArguments(
328 DataSourceHelper::createArguments(
329 aRange, Sequence< sal_Int32 >(), m_aRB_Columns.IsChecked(),
330 bDataInColumns ? bFirstCellAsLabel : ! bFirstCellAsLabel,
331 bDataInColumns ? ! bHasCategories : bHasCategories )));
332 }
333 else
334 {
335 m_aRB_Rows.Enable( bIsValid );
336 m_aRB_Columns.Enable( bIsValid );
337 m_aCB_FirstRowAsLabel.Enable( bIsValid );
338 m_aCB_FirstColumnAsLabel.Enable( bIsValid );
339 }
340 sal_Bool bShowIB = m_rDialogModel.getRangeSelectionHelper()->hasRangeSelection();
341 lcl_ShowChooserButton( m_aIB_Range, m_aED_Range, bShowIB );
342
343 return bIsValid;
344 }
345
IMPL_LINK(RangeChooserTabPage,ControlEditedHdl,void *,EMPTYARG)346 IMPL_LINK( RangeChooserTabPage, ControlEditedHdl, void*, EMPTYARG )
347 {
348 setDirty();
349 isValid();
350 return 0;
351 }
352
IMPL_LINK(RangeChooserTabPage,ControlChangedHdl,void *,EMPTYARG)353 IMPL_LINK( RangeChooserTabPage, ControlChangedHdl, void*, EMPTYARG )
354 {
355 setDirty();
356 if( isValid())
357 changeDialogModelAccordingToControls();
358 return 0;
359 }
360
IMPL_LINK(RangeChooserTabPage,ChooseRangeHdl,void *,EMPTYARG)361 IMPL_LINK( RangeChooserTabPage, ChooseRangeHdl, void *, EMPTYARG )
362 {
363 rtl::OUString aRange = m_aED_Range.GetText();
364 // using assignment for broken gcc 3.3
365 rtl::OUString aTitle = String( SchResId( STR_PAGE_DATA_RANGE ) );
366
367 lcl_enableRangeChoosing( true, m_pParentDialog );
368 m_rDialogModel.getRangeSelectionHelper()->chooseRange( aRange, aTitle, *this );
369
370 return 0;
371 }
372
373
listeningFinished(const::rtl::OUString & rNewRange)374 void RangeChooserTabPage::listeningFinished( const ::rtl::OUString & rNewRange )
375 {
376 //user has selected a new range
377
378 rtl::OUString aRange( rNewRange );
379
380 m_rDialogModel.startControllerLockTimer();
381
382 // stop listening
383 m_rDialogModel.getRangeSelectionHelper()->stopRangeListening();
384
385 //update dialog state
386 ToTop();
387 GrabFocus();
388 m_aED_Range.SetText( String( aRange ) );
389 m_aED_Range.GrabFocus();
390
391 setDirty();
392 if( isValid())
393 changeDialogModelAccordingToControls();
394
395 lcl_enableRangeChoosing( false, m_pParentDialog );
396 }
disposingRangeSelection()397 void RangeChooserTabPage::disposingRangeSelection()
398 {
399 m_rDialogModel.getRangeSelectionHelper()->stopRangeListening( false );
400 }
401
setDirty()402 void RangeChooserTabPage::setDirty()
403 {
404 if( m_nChangingControlCalls == 0 )
405 m_bIsDirty = true;
406 }
407
408 //.............................................................................
409 } //namespace chart
410 //.............................................................................
411