1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: tp_RangeChooser.cxx,v $
10 * $Revision: 1.5.44.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_chart2.hxx"
34 #include "tp_RangeChooser.hxx"
35 #include "tp_RangeChooser.hrc"
36 #include "Strings.hrc"
39 #include "NoWarningThisInCTOR.hxx"
40 #include "DataSourceHelper.hxx"
41 #include "DiagramHelper.hxx"
42 #include "ChartTypeTemplateProvider.hxx"
43 #include "DialogModel.hxx"
44 #include "RangeSelectionHelper.hxx"
45 #include <com/sun/star/awt/XTopWindow.hpp>
46 #include <com/sun/star/embed/EmbedStates.hpp>
47 #include <com/sun/star/embed/XComponentSupplier.hpp>
51 void lcl_ShowChooserButton(
52 ::chart::RangeSelectionButton
& rChooserButton
,
56 if( rChooserButton
.IsVisible() != bShow
)
58 rChooserButton
.Show( bShow
);
59 sal_Int32 nWidhtDiff
= 10 + 2;
61 nWidhtDiff
= -nWidhtDiff
;
62 Size aSize
= rChooserButton
.PixelToLogic( rEditField
.GetSizePixel(), MAP_APPFONT
);
63 aSize
.setWidth( aSize
.getWidth() + nWidhtDiff
);
64 rEditField
.SetSizePixel( rChooserButton
.LogicToPixel( aSize
, MAP_APPFONT
));
67 void lcl_enableRangeChoosing( bool bEnable
, Dialog
* pDialog
)
71 pDialog
->Show( bEnable
? FALSE
: TRUE
);
72 pDialog
->SetModalInputMode( bEnable
? FALSE
: TRUE
);
75 void lcl_shiftControlY( Control
& rControl
, long nYOffset
)
77 Point
aPos( rControl
.GetPosPixel());
78 aPos
.setY( aPos
.getY() + nYOffset
);
79 rControl
.SetPosPixel( aPos
);
81 } // anonymous namespace
83 //.............................................................................
86 //.............................................................................
87 using namespace ::com::sun::star
;
88 using namespace ::com::sun::star::chart2
;
90 using ::com::sun::star::uno::Reference
;
91 using ::com::sun::star::uno::Sequence
;
94 RangeChooserTabPage::RangeChooserTabPage( Window
* pParent
95 , DialogModel
& rDialogModel
96 , ChartTypeTemplateProvider
* pTemplateProvider
97 , Dialog
* pParentDialog
98 , bool bHideDescription
/* = false */ )
100 : OWizardPage( pParent
, SchResId(TP_RANGECHOOSER
) )
102 , m_aFT_Caption( this, SchResId( FT_CAPTION_FOR_WIZARD
) )
103 , m_aFT_Range( this, SchResId( FT_RANGE
) )
104 , m_aED_Range( this, SchResId( ED_RANGE
) )
105 , m_aIB_Range( this, SchResId( IB_RANGE
) )
106 , m_aRB_Rows( this, SchResId( RB_DATAROWS
) )
107 , m_aRB_Columns( this, SchResId( RB_DATACOLS
) )
108 , m_aCB_FirstRowAsLabel( this, SchResId( CB_FIRST_ROW_ASLABELS
) )
109 , m_aCB_FirstColumnAsLabel( this, SchResId( CB_FIRST_COLUMN_ASLABELS
) )
110 , m_nChangingControlCalls(0)
112 , m_xDataProvider( 0 )
113 , m_aLastValidRangeString()
114 , m_xCurrentChartTypeTemplate(0)
115 , m_pTemplateProvider(pTemplateProvider
)
116 , m_rDialogModel( rDialogModel
)
117 , m_pParentDialog( pParentDialog
)
118 , m_pTabPageNotifiable( dynamic_cast< TabPageNotifiable
* >( pParentDialog
))
122 if( bHideDescription
)
124 // note: the offset should be a negative value for shifting upwards, the
125 // 4 is for the offset difference between a wizard page and a tab-page
126 long nYOffset
= - ( m_aFT_Range
.GetPosPixel().getY() - m_aFT_Caption
.GetPosPixel().getY() + 4 );
127 m_aFT_Caption
.Hide();
129 // shift all controls by the offset space saved by hiding the caption
130 lcl_shiftControlY( m_aFT_Range
, nYOffset
);
131 lcl_shiftControlY( m_aED_Range
, nYOffset
);
132 lcl_shiftControlY( m_aIB_Range
, nYOffset
);
133 lcl_shiftControlY( m_aRB_Rows
, nYOffset
);
134 lcl_shiftControlY( m_aRB_Columns
, nYOffset
);
135 lcl_shiftControlY( m_aCB_FirstRowAsLabel
, nYOffset
);
136 lcl_shiftControlY( m_aCB_FirstColumnAsLabel
, nYOffset
);
140 // make font of caption bold
141 Font
aFont( m_aFT_Caption
.GetControlFont() );
142 aFont
.SetWeight( WEIGHT_BOLD
);
143 m_aFT_Caption
.SetControlFont( aFont
);
146 m_aFT_Caption
.SetStyle( m_aFT_Caption
.GetStyle() | WB_NOLABEL
);
149 this->SetText( String(SchResId(STR_PAGE_DATA_RANGE
)) );
150 m_aIB_Range
.SetQuickHelpText( String(SchResId(STR_TIP_SELECT_RANGE
)) );
152 // set defaults as long as DetectArguments does not work
153 m_aRB_Columns
.Check();
154 m_aCB_FirstColumnAsLabel
.Check();
155 m_aCB_FirstRowAsLabel
.Check();
157 // BM: Note, that the range selection is not available, if there is no view.
158 // This happens for charts having their own embedded spreadsheet. If you
159 // force to get the range selection here, this would mean when entering this
160 // page the calc view would be created in this case. So, I enable the
161 // button here, and in the worst case nothing happens when it is pressed.
162 // Not nice, but I see no better solution for the moment.
163 m_aIB_Range
.SetClickHdl( LINK( this, RangeChooserTabPage
, ChooseRangeHdl
));
164 m_aED_Range
.SetKeyInputHdl( LINK( this, RangeChooserTabPage
, ChooseRangeHdl
));
166 // #i75179# enable setting the background to a different color
167 m_aED_Range
.SetStyle( m_aED_Range
.GetStyle() | WB_FORCECTRLBACKGROUND
);
169 m_aED_Range
.SetUpdateDataHdl( LINK( this, RangeChooserTabPage
, ControlChangedHdl
));
170 m_aED_Range
.SetModifyHdl( LINK( this, RangeChooserTabPage
, ControlEditedHdl
));
171 m_aRB_Rows
.SetToggleHdl( LINK( this, RangeChooserTabPage
, ControlChangedHdl
) );
172 m_aCB_FirstRowAsLabel
.SetToggleHdl( LINK( this, RangeChooserTabPage
, ControlChangedHdl
) );
173 m_aCB_FirstColumnAsLabel
.SetToggleHdl( LINK( this, RangeChooserTabPage
, ControlChangedHdl
) );
176 RangeChooserTabPage::~RangeChooserTabPage()
180 void RangeChooserTabPage::ActivatePage()
182 OWizardPage::ActivatePage();
183 initControlsFromModel();
186 void RangeChooserTabPage::initControlsFromModel()
188 m_nChangingControlCalls
++;
190 if(m_pTemplateProvider
)
192 m_xCurrentChartTypeTemplate
= m_pTemplateProvider
->getCurrentTemplate();
195 bool bUseColumns
= ! m_aRB_Rows
.IsChecked();
196 bool bFirstCellAsLabel
= bUseColumns
? m_aCB_FirstRowAsLabel
.IsChecked() : m_aCB_FirstColumnAsLabel
.IsChecked();
197 bool bHasCategories
= bUseColumns
? m_aCB_FirstColumnAsLabel
.IsChecked() : m_aCB_FirstRowAsLabel
.IsChecked();
199 bool bIsValid
= m_rDialogModel
.allArgumentsForRectRangeDetected();
201 m_rDialogModel
.detectArguments(
202 m_aLastValidRangeString
, bUseColumns
, bFirstCellAsLabel
, bHasCategories
);
204 m_aLastValidRangeString
= String::EmptyString();
206 m_aED_Range
.SetText( m_aLastValidRangeString
);
208 m_aRB_Rows
.Check( !bUseColumns
);
209 m_aRB_Columns
.Check( bUseColumns
);
211 m_aCB_FirstRowAsLabel
.Check( m_aRB_Rows
.IsChecked()?bHasCategories
:bFirstCellAsLabel
);
212 m_aCB_FirstColumnAsLabel
.Check( m_aRB_Columns
.IsChecked()?bHasCategories
:bFirstCellAsLabel
);
216 m_nChangingControlCalls
--;
219 void RangeChooserTabPage::DeactivatePage()
222 svt::OWizardPage::DeactivatePage();
225 void RangeChooserTabPage::commitPage()
230 sal_Bool
RangeChooserTabPage::commitPage( CommitPageReason
/*eReason*/ )
232 //ranges may have been edited in the meanwhile (dirty is true in that case here)
235 changeDialogModelAccordingToControls();
236 return sal_True
;//return false if this page should not be left
242 void RangeChooserTabPage::changeDialogModelAccordingToControls()
244 if(m_nChangingControlCalls
>0)
247 if( !m_xCurrentChartTypeTemplate
.is() )
249 if(m_pTemplateProvider
)
250 m_xCurrentChartTypeTemplate
.set( m_pTemplateProvider
->getCurrentTemplate());
251 if( !m_xCurrentChartTypeTemplate
.is())
253 OSL_ENSURE( false, "Need a template to change data source" );
260 sal_Bool bFirstCellAsLabel
= ( m_aCB_FirstColumnAsLabel
.IsChecked() && !m_aRB_Columns
.IsChecked() )
261 || ( m_aCB_FirstRowAsLabel
.IsChecked() && !m_aRB_Rows
.IsChecked() );
262 sal_Bool bHasCategories
= ( m_aCB_FirstColumnAsLabel
.IsChecked() && m_aRB_Columns
.IsChecked() )
263 || ( m_aCB_FirstRowAsLabel
.IsChecked() && m_aRB_Rows
.IsChecked() );
265 Sequence
< beans::PropertyValue
> aArguments(
266 DataSourceHelper::createArguments(
267 m_aRB_Columns
.IsChecked(), bFirstCellAsLabel
, bHasCategories
) );
269 // only if range is valid
270 if( m_aLastValidRangeString
.equals( m_aED_Range
.GetText()))
272 m_rDialogModel
.setTemplate( m_xCurrentChartTypeTemplate
);
273 aArguments
.realloc( aArguments
.getLength() + 1 );
274 aArguments
[aArguments
.getLength() - 1] =
275 beans::PropertyValue( C2U("CellRangeRepresentation"), -1,
276 uno::makeAny( m_aLastValidRangeString
),
277 beans::PropertyState_DIRECT_VALUE
);
278 m_rDialogModel
.setData( aArguments
);
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 ::rtl::OUString
aRange( m_aED_Range
.GetText());
290 sal_Bool bFirstCellAsLabel
= ( m_aCB_FirstColumnAsLabel
.IsChecked() && !m_aRB_Columns
.IsChecked() )
291 || ( m_aCB_FirstRowAsLabel
.IsChecked() && !m_aRB_Rows
.IsChecked() );
292 sal_Bool bHasCategories
= ( m_aCB_FirstColumnAsLabel
.IsChecked() && m_aRB_Columns
.IsChecked() )
293 || ( m_aCB_FirstRowAsLabel
.IsChecked() && m_aRB_Rows
.IsChecked() );
294 bool bIsValid
= ( aRange
.getLength() == 0 ) ||
295 m_rDialogModel
.getRangeSelectionHelper()->verifyArguments(
296 DataSourceHelper::createArguments(
297 aRange
, Sequence
< sal_Int32
>(), m_aRB_Columns
.IsChecked(), bFirstCellAsLabel
, bHasCategories
));
301 m_aED_Range
.SetControlForeground();
302 m_aED_Range
.SetControlBackground();
303 if( m_pTabPageNotifiable
)
304 m_pTabPageNotifiable
->setValidPage( this );
305 m_aLastValidRangeString
= aRange
;
309 m_aED_Range
.SetControlBackground( RANGE_SELECTION_INVALID_RANGE_BACKGROUND_COLOR
);
310 m_aED_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_aRB_Columns
.IsChecked();
321 bool bIsSwappedRangeValid
= m_rDialogModel
.getRangeSelectionHelper()->verifyArguments(
322 DataSourceHelper::createArguments(
323 aRange
, Sequence
< sal_Int32
>(), ! bDataInColumns
, bHasCategories
, bFirstCellAsLabel
));
324 m_aRB_Rows
.Enable( bIsSwappedRangeValid
);
325 m_aRB_Columns
.Enable( bIsSwappedRangeValid
);
327 m_aCB_FirstRowAsLabel
.Enable(
328 m_rDialogModel
.getRangeSelectionHelper()->verifyArguments(
329 DataSourceHelper::createArguments(
330 aRange
, Sequence
< sal_Int32
>(), m_aRB_Columns
.IsChecked(),
331 bDataInColumns
? ! bFirstCellAsLabel
: bFirstCellAsLabel
,
332 bDataInColumns
? bHasCategories
: ! bHasCategories
)));
333 m_aCB_FirstColumnAsLabel
.Enable(
334 m_rDialogModel
.getRangeSelectionHelper()->verifyArguments(
335 DataSourceHelper::createArguments(
336 aRange
, Sequence
< sal_Int32
>(), m_aRB_Columns
.IsChecked(),
337 bDataInColumns
? bFirstCellAsLabel
: ! bFirstCellAsLabel
,
338 bDataInColumns
? ! bHasCategories
: bHasCategories
)));
342 m_aRB_Rows
.Enable( bIsValid
);
343 m_aRB_Columns
.Enable( bIsValid
);
344 m_aCB_FirstRowAsLabel
.Enable( bIsValid
);
345 m_aCB_FirstColumnAsLabel
.Enable( bIsValid
);
347 BOOL bShowIB
= m_rDialogModel
.getRangeSelectionHelper()->hasRangeSelection();
348 lcl_ShowChooserButton( m_aIB_Range
, m_aED_Range
, bShowIB
);
353 IMPL_LINK( RangeChooserTabPage
, ControlEditedHdl
, void*, EMPTYARG
)
360 IMPL_LINK( RangeChooserTabPage
, ControlChangedHdl
, void*, EMPTYARG
)
364 changeDialogModelAccordingToControls();
368 IMPL_LINK( RangeChooserTabPage
, ChooseRangeHdl
, void *, EMPTYARG
)
370 rtl::OUString aRange
= m_aED_Range
.GetText();
371 // using assignment for broken gcc 3.3
372 rtl::OUString aTitle
= ::rtl::OUString( String( SchResId( STR_PAGE_DATA_RANGE
) ));
374 lcl_enableRangeChoosing( true, m_pParentDialog
);
375 m_rDialogModel
.getRangeSelectionHelper()->chooseRange( aRange
, aTitle
, *this );
381 void RangeChooserTabPage::listeningFinished( const ::rtl::OUString
& rNewRange
)
383 //user has selected a new range
385 rtl::OUString
aRange( rNewRange
);
387 m_rDialogModel
.startControllerLockTimer();
390 m_rDialogModel
.getRangeSelectionHelper()->stopRangeListening();
392 //update dialog state
395 m_aED_Range
.SetText( String( aRange
) );
396 m_aED_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 )
415 //.............................................................................
417 //.............................................................................