Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
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/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
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 .
18 : : */
19 : :
20 : : // header for class SvNumberformat
21 : : #include <svl/zformat.hxx>
22 : : // header for SvNumberFormatter
23 : : #include <svl/zforlist.hxx>
24 : :
25 : : #include "DataBrowser.hxx"
26 : : #include "DataBrowserModel.hxx"
27 : : #include "Strings.hrc"
28 : : #include "ContainerHelper.hxx"
29 : : #include "DataSeriesHelper.hxx"
30 : : #include "DiagramHelper.hxx"
31 : : #include "ChartModelHelper.hxx"
32 : : #include "CommonConverters.hxx"
33 : : #include "macros.hxx"
34 : : #include "NumberFormatterWrapper.hxx"
35 : : #include "servicenames_charttypes.hxx"
36 : : #include "ResId.hxx"
37 : : #include "Bitmaps.hrc"
38 : : #include "HelpIds.hrc"
39 : :
40 : : #include <vcl/fixed.hxx>
41 : : #include <vcl/image.hxx>
42 : : #include <vcl/msgbox.hxx>
43 : : #include <rtl/math.hxx>
44 : :
45 : : #include <com/sun/star/util/XCloneable.hpp>
46 : : #include <com/sun/star/chart2/XChartDocument.hpp>
47 : : #include <com/sun/star/chart2/XChartType.hpp>
48 : :
49 : : #include <com/sun/star/container/XIndexReplace.hpp>
50 : : #include <com/sun/star/util/XNumberFormats.hpp>
51 : :
52 : : #include <algorithm>
53 : : #include <functional>
54 : :
55 : : /* BROWSER_COLUMNSELECTION : single cells may be selected rather than only
56 : : entire rows
57 : : BROWSER_(H|V)LINES : show horizontal or vertical grid-lines
58 : :
59 : : BROWSER_AUTO_(H|V)SCROLL : scroll automated horizontally or vertically when
60 : : cursor is moved beyond the edge of the dialog
61 : : BROWSER_HIGHLIGHT_NONE : Do not mark the current row with selection color
62 : : (usually blue)
63 : :
64 : : */
65 : : #define BROWSER_STANDARD_FLAGS \
66 : : BROWSER_COLUMNSELECTION | \
67 : : BROWSER_HLINES | BROWSER_VLINES | \
68 : : BROWSER_AUTO_HSCROLL | BROWSER_AUTO_VSCROLL | \
69 : : BROWSER_HIGHLIGHT_NONE
70 : :
71 : : // BROWSER_HIDECURSOR would prevent flickering in edit fields, but navigating
72 : : // with shift up/down, and entering non-editable cells would be problematic,
73 : : // e.g. the first cell, or when being in read-only mode
74 : :
75 : : using namespace ::com::sun::star;
76 : : using ::com::sun::star::uno::Sequence;
77 : : using ::com::sun::star::uno::Reference;
78 : : using ::rtl::OUString;
79 : :
80 : : using namespace ::svt;
81 : :
82 : : namespace
83 : : {
84 : 0 : sal_Int32 lcl_getRowInData( long nRow )
85 : : {
86 : 0 : return static_cast< sal_Int32 >( nRow );
87 : : }
88 : :
89 : 0 : sal_Int32 lcl_getColumnInData( sal_uInt16 nCol )
90 : : {
91 : 0 : return static_cast< sal_Int32 >( nCol ) - 1;
92 : : }
93 : :
94 : : } // anonymous namespace
95 : :
96 : : // --------------------------------------------------------------------------------
97 : :
98 : : namespace chart
99 : : {
100 : :
101 : : // ----------------------------------------
102 : : namespace impl
103 : : {
104 : :
105 : : class SeriesHeaderEdit : public Edit
106 : : {
107 : : public:
108 : : SeriesHeaderEdit( Window * pParent );
109 : : virtual ~SeriesHeaderEdit();
110 : : virtual void MouseButtonDown( const MouseEvent& rMEvt );
111 : :
112 : : void setStartColumn( sal_Int32 nStartColumn );
113 : : sal_Int32 getStartColumn() const;
114 : : void SetShowWarningBox( bool bShowWarning = true );
115 : :
116 : : private:
117 : : sal_Int32 m_nStartColumn;
118 : : bool m_bShowWarningBox;
119 : : };
120 : :
121 : 0 : SeriesHeaderEdit::SeriesHeaderEdit( Window * pParent ) :
122 : : Edit( pParent ),
123 : : m_nStartColumn( 0 ),
124 : 0 : m_bShowWarningBox( false )
125 : 0 : {}
126 : :
127 : 0 : SeriesHeaderEdit::~SeriesHeaderEdit()
128 [ # # ]: 0 : {}
129 : :
130 : 0 : void SeriesHeaderEdit::setStartColumn( sal_Int32 nStartColumn )
131 : : {
132 : 0 : m_nStartColumn = nStartColumn;
133 : 0 : }
134 : :
135 : 0 : sal_Int32 SeriesHeaderEdit::getStartColumn() const
136 : : {
137 : 0 : return m_nStartColumn;
138 : : }
139 : :
140 : 0 : void SeriesHeaderEdit::SetShowWarningBox( bool bShowWarning )
141 : : {
142 : 0 : m_bShowWarningBox = bShowWarning;
143 : 0 : }
144 : :
145 : 0 : void SeriesHeaderEdit::MouseButtonDown( const MouseEvent& rMEvt )
146 : : {
147 : 0 : Edit::MouseButtonDown( rMEvt );
148 : :
149 [ # # ]: 0 : if( m_bShowWarningBox )
150 : : WarningBox( this, WinBits( WB_OK ),
151 [ # # ][ # # ]: 0 : String( SchResId( STR_INVALID_NUMBER ))).Execute();
[ # # ][ # # ]
[ # # ]
152 : 0 : }
153 : :
154 [ # # ][ # # ]: 0 : class SeriesHeader
155 : : {
156 : : public:
157 : : explicit SeriesHeader( Window * pParent );
158 : :
159 : : void SetColor( const Color & rCol );
160 : : void SetPos( const Point & rPos );
161 : : void SetWidth( sal_Int32 nWidth );
162 : : void SetChartType( const Reference< chart2::XChartType > & xChartType,
163 : : bool bSwapXAndYAxis );
164 : : void SetSeriesName( const String & rName );
165 : : void SetRange( sal_Int32 nStartCol, sal_Int32 nEndCol );
166 : :
167 : : void SetPixelPosX( sal_Int32 nPos );
168 : : void SetPixelWidth( sal_Int32 nWidth );
169 : :
170 : : sal_Int32 GetStartColumn() const;
171 : : sal_Int32 GetEndColumn() const;
172 : :
173 : : static sal_Int32 GetRelativeAppFontXPosForNameField();
174 : :
175 : : void Show();
176 : :
177 : : /** call this before destroying the class. This notifies the listeners to
178 : : changes of the edit field for the series name.
179 : : */
180 : : void applyChanges();
181 : :
182 : : void SetGetFocusHdl( const Link& rLink );
183 : :
184 : : void SetEditChangedHdl( const Link & rLink );
185 : :
186 : : bool HasFocus() const;
187 : :
188 : : private:
189 : : ::boost::shared_ptr< FixedImage > m_spSymbol;
190 : : ::boost::shared_ptr< SeriesHeaderEdit > m_spSeriesName;
191 : : ::boost::shared_ptr< FixedText > m_spColorBar;
192 : : OutputDevice * m_pDevice;
193 : : Link m_aChangeLink;
194 : :
195 : : void notifyChanges();
196 : : DECL_LINK( SeriesNameChanged, void * );
197 : : DECL_LINK( SeriesNameEdited, void * );
198 : :
199 : : static Image GetChartTypeImage(
200 : : const Reference< chart2::XChartType > & xChartType,
201 : : bool bSwapXAndYAxis
202 : : );
203 : :
204 : : sal_Int32 m_nStartCol, m_nEndCol;
205 : : sal_Int32 m_nWidth;
206 : : Point m_aPos;
207 : : bool m_bSeriesNameChangePending;
208 : : };
209 : :
210 : 0 : SeriesHeader::SeriesHeader( Window * pParent ) :
211 [ # # ]: 0 : m_spSymbol( new FixedImage( pParent, WB_NOBORDER )),
212 [ # # ]: 0 : m_spSeriesName( new SeriesHeaderEdit( pParent )),
213 [ # # ]: 0 : m_spColorBar( new FixedText( pParent, WB_NOBORDER )),
214 : : m_pDevice( pParent ),
215 : : m_nStartCol( 0 ),
216 : : m_nEndCol( 0 ),
217 : : m_nWidth( 42 ),
218 : : m_aPos( 0, 22 ),
219 [ # # ][ # # ]: 0 : m_bSeriesNameChangePending( false )
[ # # ][ # # ]
[ # # ]
220 : : {
221 [ # # ]: 0 : m_spSeriesName->EnableUpdateData( 4 * EDIT_UPDATEDATA_TIMEOUT ); // define is in vcl/edit.hxx
222 [ # # ][ # # ]: 0 : m_spSeriesName->SetUpdateDataHdl( LINK( this, SeriesHeader, SeriesNameChanged ));
223 [ # # ][ # # ]: 0 : m_spSeriesName->SetModifyHdl( LINK( this, SeriesHeader, SeriesNameEdited ));
224 [ # # ]: 0 : m_spSeriesName->SetHelpId( HID_SCH_DATA_SERIES_LABEL );
225 [ # # ]: 0 : Show();
226 : 0 : }
227 : :
228 : 0 : void SeriesHeader::notifyChanges()
229 : : {
230 [ # # ]: 0 : if( m_aChangeLink.IsSet())
231 : 0 : m_aChangeLink.Call( m_spSeriesName.get());
232 : :
233 : 0 : m_bSeriesNameChangePending = false;
234 : 0 : }
235 : :
236 : 0 : void SeriesHeader::applyChanges()
237 : : {
238 [ # # ]: 0 : if( m_bSeriesNameChangePending )
239 : : {
240 : 0 : notifyChanges();
241 : : }
242 : 0 : }
243 : :
244 : 0 : void SeriesHeader::SetColor( const Color & rCol )
245 : : {
246 : 0 : m_spColorBar->SetControlBackground( rCol );
247 : 0 : }
248 : :
249 : : const sal_Int32 nSymbolHeight = 10;
250 : : const sal_Int32 nSymbolDistance = 2;
251 : :
252 : 0 : sal_Int32 SeriesHeader::GetRelativeAppFontXPosForNameField()
253 : : {
254 : 0 : return nSymbolHeight + nSymbolDistance;
255 : : }
256 : :
257 : 0 : void SeriesHeader::SetPos( const Point & rPos )
258 : : {
259 : 0 : m_aPos = rPos;
260 : :
261 : : // chart type symbol
262 : 0 : Point aPos( rPos );
263 : 0 : aPos.setY( aPos.getY() + nSymbolDistance );
264 : 0 : Size aSize( nSymbolHeight, nSymbolHeight );
265 [ # # ][ # # ]: 0 : m_spSymbol->SetPosPixel( m_pDevice->LogicToPixel( aPos, MAP_APPFONT ));
[ # # ][ # # ]
266 [ # # ][ # # ]: 0 : m_spSymbol->SetSizePixel( m_pDevice->LogicToPixel( aSize, MAP_APPFONT ));
[ # # ][ # # ]
267 : 0 : aPos.setY( aPos.getY() - nSymbolDistance );
268 : :
269 : : // series name edit field
270 : 0 : aPos.setX( aPos.getX() + nSymbolHeight + nSymbolDistance );
271 : 0 : aSize.setWidth( m_nWidth - nSymbolHeight - nSymbolDistance );
272 : 0 : sal_Int32 nHeight = 12;
273 : 0 : aSize.setHeight( nHeight );
274 [ # # ][ # # ]: 0 : m_spSeriesName->SetPosPixel( m_pDevice->LogicToPixel( aPos, MAP_APPFONT ));
[ # # ][ # # ]
275 [ # # ][ # # ]: 0 : m_spSeriesName->SetSizePixel( m_pDevice->LogicToPixel( aSize, MAP_APPFONT ));
[ # # ][ # # ]
276 : :
277 : : // color bar
278 : 0 : aPos.setX( rPos.getX() + 1 );
279 : 0 : aPos.setY( aPos.getY() + nHeight + 2 );
280 : 0 : nHeight = 3;
281 : 0 : aSize.setWidth( m_nWidth - 1 );
282 : 0 : aSize.setHeight( nHeight );
283 [ # # ][ # # ]: 0 : m_spColorBar->SetPosPixel( m_pDevice->LogicToPixel( aPos, MAP_APPFONT ));
[ # # ][ # # ]
284 [ # # ][ # # ]: 0 : m_spColorBar->SetSizePixel( m_pDevice->LogicToPixel( aSize, MAP_APPFONT ));
[ # # ][ # # ]
285 : 0 : }
286 : :
287 : 0 : void SeriesHeader::SetWidth( sal_Int32 nWidth )
288 : : {
289 : 0 : m_nWidth = nWidth;
290 : 0 : SetPos( m_aPos );
291 : 0 : }
292 : :
293 : 0 : void SeriesHeader::SetPixelPosX( sal_Int32 nPos )
294 : : {
295 [ # # ][ # # ]: 0 : Point aPos( m_pDevice->LogicToPixel( m_aPos, MAP_APPFONT ));
[ # # ]
296 : 0 : aPos.setX( nPos );
297 [ # # ][ # # ]: 0 : SetPos( m_pDevice->PixelToLogic( aPos, MAP_APPFONT ));
[ # # ][ # # ]
298 : 0 : }
299 : :
300 : 0 : void SeriesHeader::SetPixelWidth( sal_Int32 nWidth )
301 : : {
302 [ # # ][ # # ]: 0 : SetWidth( m_pDevice->PixelToLogic( Size( nWidth, 0 ), MAP_APPFONT ).getWidth());
303 : 0 : }
304 : :
305 : 0 : void SeriesHeader::SetChartType(
306 : : const Reference< chart2::XChartType > & xChartType,
307 : : bool bSwapXAndYAxis
308 : : )
309 : : {
310 [ # # ]: 0 : m_spSymbol->SetImage( GetChartTypeImage( xChartType, bSwapXAndYAxis ) );
311 : 0 : }
312 : :
313 : 0 : void SeriesHeader::SetSeriesName( const String & rName )
314 : : {
315 : 0 : m_spSeriesName->SetText( rName );
316 : 0 : }
317 : :
318 : 0 : void SeriesHeader::SetRange( sal_Int32 nStartCol, sal_Int32 nEndCol )
319 : : {
320 : 0 : m_nStartCol = nStartCol;
321 [ # # ]: 0 : m_nEndCol = (nEndCol > nStartCol) ? nEndCol : nStartCol;
322 : 0 : m_spSeriesName->setStartColumn( nStartCol );
323 : 0 : }
324 : :
325 : 0 : sal_Int32 SeriesHeader::GetStartColumn() const
326 : : {
327 : 0 : return m_nStartCol;
328 : : }
329 : :
330 : 0 : sal_Int32 SeriesHeader::GetEndColumn() const
331 : : {
332 : 0 : return m_nEndCol;
333 : : }
334 : :
335 : 0 : void SeriesHeader::Show()
336 : : {
337 : 0 : m_spSymbol->Show();
338 : 0 : m_spSeriesName->Show();
339 : 0 : m_spColorBar->Show();
340 : 0 : }
341 : :
342 : 0 : void SeriesHeader::SetEditChangedHdl( const Link & rLink )
343 : : {
344 : 0 : m_aChangeLink = rLink;
345 : 0 : }
346 : :
347 : 0 : IMPL_LINK_NOARG(SeriesHeader, SeriesNameChanged)
348 : : {
349 : 0 : notifyChanges();
350 : 0 : return 0;
351 : : }
352 : :
353 : 0 : IMPL_LINK_NOARG(SeriesHeader, SeriesNameEdited)
354 : : {
355 : 0 : m_bSeriesNameChangePending = true;
356 : 0 : return 0;
357 : : }
358 : :
359 : 0 : void SeriesHeader::SetGetFocusHdl( const Link& rLink )
360 : : {
361 : 0 : m_spSeriesName->SetGetFocusHdl( rLink );
362 : 0 : }
363 : :
364 : 0 : bool SeriesHeader::HasFocus() const
365 : : {
366 : 0 : return m_spSeriesName->HasFocus();
367 : : }
368 : :
369 : 0 : Image SeriesHeader::GetChartTypeImage(
370 : : const Reference< chart2::XChartType > & xChartType,
371 : : bool bSwapXAndYAxis
372 : : )
373 : : {
374 [ # # ]: 0 : Image aResult;
375 [ # # ]: 0 : if( !xChartType.is())
376 : : return aResult;
377 [ # # ][ # # ]: 0 : OUString aChartTypeName( xChartType->getChartType());
378 : :
379 [ # # ][ # # ]: 0 : if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_AREA ))
380 : : {
381 [ # # ][ # # ]: 0 : aResult = Image( SchResId( IMG_TYPE_AREA ) );
[ # # ][ # # ]
382 : : }
383 [ # # ][ # # ]: 0 : else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_COLUMN ))
384 : : {
385 [ # # ]: 0 : if( bSwapXAndYAxis )
386 [ # # ][ # # ]: 0 : aResult = Image( SchResId( IMG_TYPE_BAR ) );
[ # # ][ # # ]
387 : : else
388 [ # # ][ # # ]: 0 : aResult = Image( SchResId( IMG_TYPE_COLUMN ) );
[ # # ][ # # ]
389 : : }
390 [ # # ][ # # ]: 0 : else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_LINE ))
391 : : {
392 [ # # ][ # # ]: 0 : aResult = Image( SchResId( IMG_TYPE_LINE ) );
[ # # ][ # # ]
393 : : }
394 [ # # ][ # # ]: 0 : else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_SCATTER ))
395 : : {
396 [ # # ][ # # ]: 0 : aResult = Image( SchResId( IMG_TYPE_XY ) );
[ # # ][ # # ]
397 : : }
398 [ # # ][ # # ]: 0 : else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_PIE ))
399 : : {
400 [ # # ][ # # ]: 0 : aResult = Image( SchResId( IMG_TYPE_PIE ) );
[ # # ][ # # ]
401 : : }
402 [ # # ]: 0 : else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_NET )
[ # # # # ]
[ # # ]
[ # # # # ]
403 [ # # ][ # # ]: 0 : || aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET ) )
[ # # ]
404 : : {
405 [ # # ][ # # ]: 0 : aResult = Image( SchResId( IMG_TYPE_NET ) );
[ # # ][ # # ]
406 : : }
407 [ # # ][ # # ]: 0 : else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK ))
408 : : {
409 : : // @todo: correct image for candle-stick type
410 [ # # ][ # # ]: 0 : aResult = Image( SchResId( IMG_TYPE_STOCK ) );
[ # # ][ # # ]
411 : : }
412 [ # # ][ # # ]: 0 : else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE ))
413 : : {
414 [ # # ][ # # ]: 0 : aResult = Image( SchResId( IMG_TYPE_BUBBLE ) );
[ # # ][ # # ]
415 : : }
416 : :
417 : 0 : return aResult;
418 : : }
419 : :
420 : : struct applyChangesFunctor : public ::std::unary_function< ::boost::shared_ptr< SeriesHeader >, void >
421 : : {
422 : 0 : void operator() ( ::boost::shared_ptr< SeriesHeader > spHeader )
423 : : {
424 : 0 : spHeader->applyChanges();
425 : 0 : }
426 : : };
427 : :
428 : : } // namespace impl
429 : : // ----------------------------------------
430 : :
431 : : namespace
432 : : {
433 : :
434 : : /** returns false, if no header as the focus.
435 : :
436 : : If a header has the focus, true is returned and the index of the header
437 : : with focus is set at pIndex if pOutIndex is not 0.
438 : : */
439 : 0 : bool lcl_SeriesHeaderHasFocus(
440 : : const ::std::vector< ::boost::shared_ptr< ::chart::impl::SeriesHeader > > & rSeriesHeader,
441 : : sal_Int32 * pOutIndex = 0 )
442 : : {
443 : 0 : sal_Int32 nIndex = 0;
444 [ # # ][ # # ]: 0 : for( ::std::vector< ::boost::shared_ptr< ::chart::impl::SeriesHeader > >::const_iterator aIt( rSeriesHeader.begin());
445 : 0 : aIt != rSeriesHeader.end(); ++aIt, ++nIndex )
446 : : {
447 [ # # ][ # # ]: 0 : if( (*aIt)->HasFocus())
448 : : {
449 [ # # ]: 0 : if( pOutIndex )
450 : 0 : *pOutIndex = nIndex;
451 : 0 : return true;
452 : : }
453 : : }
454 : 0 : return false;
455 : : }
456 : :
457 : 0 : sal_Int32 lcl_getColumnInDataOrHeader(
458 : : sal_uInt16 nCol, const ::std::vector< ::boost::shared_ptr< ::chart::impl::SeriesHeader > > & rSeriesHeader )
459 : : {
460 : 0 : sal_Int32 nColIdx = 0;
461 [ # # ]: 0 : bool bHeaderHasFocus( lcl_SeriesHeaderHasFocus( rSeriesHeader, &nColIdx ));
462 : :
463 [ # # ]: 0 : if( bHeaderHasFocus )
464 : 0 : nColIdx = lcl_getColumnInData( static_cast< sal_uInt16 >( rSeriesHeader[nColIdx]->GetStartColumn()));
465 : : else
466 : 0 : nColIdx = lcl_getColumnInData( nCol );
467 : :
468 : 0 : return nColIdx;
469 : : }
470 : :
471 : : } // anonymous namespace
472 : :
473 : :
474 : 0 : DataBrowser::DataBrowser( Window* pParent, const ResId& rId, bool bLiveUpdate ) :
475 : : ::svt::EditBrowseBox( pParent, rId, EBBF_SMART_TAB_TRAVEL | EBBF_HANDLE_COLUMN_TEXT, BROWSER_STANDARD_FLAGS ),
476 : : m_nSeekRow( 0 ),
477 : : m_bIsReadOnly( false ),
478 : : m_bIsDirty( false ),
479 : : m_bLiveUpdate( bLiveUpdate ),
480 : : m_bDataValid( true ),
481 : 0 : m_aNumberEditField( & EditBrowseBox::GetDataWindow(), WB_NOBORDER ),
482 : 0 : m_aTextEditField( & EditBrowseBox::GetDataWindow(), WB_NOBORDER ),
483 [ # # ]: 0 : m_rNumberEditController( new ::svt::FormattedFieldCellController( & m_aNumberEditField )),
484 [ # # ][ # # : 0 : m_rTextEditController( new ::svt::EditCellController( & m_aTextEditField ))
# # # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
485 : : {
486 : : double fNan;
487 : 0 : ::rtl::math::setNan( & fNan );
488 : 0 : m_aNumberEditField.SetDefaultValue( fNan );
489 : 0 : m_aNumberEditField.TreatAsNumber( sal_True );
490 [ # # ]: 0 : RenewTable();
491 : 0 : SetClean();
492 : 0 : }
493 : :
494 [ # # ][ # # ]: 0 : DataBrowser::~DataBrowser()
[ # # ][ # # ]
[ # # ][ # # ]
495 : : {
496 [ # # ]: 0 : }
497 : :
498 : 0 : bool DataBrowser::MayInsertRow() const
499 : : {
500 : 0 : return ! IsReadOnly()
501 [ # # ][ # # ]: 0 : && ( !lcl_SeriesHeaderHasFocus( m_aSeriesHeaders ));
502 : : }
503 : :
504 : 0 : bool DataBrowser::MayInsertColumn() const
505 : : {
506 : 0 : return ! IsReadOnly();
507 : : }
508 : :
509 : 0 : bool DataBrowser::MayDeleteRow() const
510 : : {
511 : 0 : return ! IsReadOnly()
512 : 0 : && ( !lcl_SeriesHeaderHasFocus( m_aSeriesHeaders ))
513 : 0 : && ( GetCurRow() >= 0 )
514 [ # # ][ # # : 0 : && ( GetRowCount() > 1 );
# # # # ]
515 : : }
516 : :
517 : 0 : bool DataBrowser::MayDeleteColumn() const
518 : : {
519 : : // if a series header has the focus
520 [ # # ]: 0 : if( lcl_SeriesHeaderHasFocus( m_aSeriesHeaders ))
521 : 0 : return true;
522 : :
523 : 0 : return ! IsReadOnly()
524 : 0 : && ( GetCurColumnId() > 1 )
525 [ # # ]: 0 : && ( ColCount() > 2 );
[ # # # # ]
526 : : }
527 : :
528 : 0 : bool DataBrowser::MaySwapRows() const
529 : : {
530 : 0 : return ! IsReadOnly()
531 : 0 : && ( !lcl_SeriesHeaderHasFocus( m_aSeriesHeaders ))
532 : 0 : && ( GetCurRow() >= 0 )
533 [ # # ][ # # : 0 : && ( GetCurRow() < GetRowCount() - 1 );
# # # # ]
534 : : }
535 : :
536 : 0 : bool DataBrowser::MaySwapColumns() const
537 : : {
538 : : // if a series header (except the last one) has the focus
539 : : {
540 : 0 : sal_Int32 nColIndex(0);
541 [ # # ][ # # ]: 0 : if( lcl_SeriesHeaderHasFocus( m_aSeriesHeaders, &nColIndex ))
542 : 0 : return (static_cast< sal_uInt32 >( nColIndex ) < (m_aSeriesHeaders.size() - 1));
543 : : }
544 : :
545 : 0 : sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders );
546 : 0 : return ! IsReadOnly()
547 : : && ( nColIdx > 0 )
548 : 0 : && ( nColIdx < ColCount()-2 )
549 : 0 : && m_apDataBrowserModel.get()
550 [ # # # # : 0 : && !m_apDataBrowserModel->isCategoriesColumn( nColIdx );
# # ][ # # ]
[ # # ]
551 : : }
552 : :
553 : 0 : void DataBrowser::clearHeaders()
554 : : {
555 [ # # ]: 0 : ::std::for_each( m_aSeriesHeaders.begin(), m_aSeriesHeaders.end(), impl::applyChangesFunctor());
556 : 0 : m_aSeriesHeaders.clear();
557 : 0 : }
558 : :
559 : 0 : void DataBrowser::RenewTable()
560 : : {
561 [ # # ]: 0 : if( ! m_apDataBrowserModel.get())
562 : 0 : return;
563 : :
564 : 0 : long nOldRow = GetCurRow();
565 : 0 : sal_uInt16 nOldColId = GetCurColumnId();
566 : :
567 [ # # ]: 0 : sal_Bool bLastUpdateMode = GetUpdateMode();
568 [ # # ]: 0 : SetUpdateMode( sal_False );
569 : :
570 [ # # ][ # # ]: 0 : if( IsModified() )
571 [ # # ]: 0 : SaveModified();
572 : :
573 [ # # ]: 0 : DeactivateCell();
574 : :
575 [ # # ]: 0 : RemoveColumns();
576 [ # # ][ # # ]: 0 : RowRemoved( 1, GetRowCount() );
577 : :
578 : : // for row numbers
579 : : InsertHandleColumn( static_cast< sal_uInt16 >(
580 [ # # ][ # # ]: 0 : GetDataWindow().LogicToPixel( Size( 42, 0 )).getWidth() ));
581 : :
582 [ # # ][ # # ]: 0 : OUString aDefaultSeriesName(SCH_RESSTR(STR_COLUMN_LABEL));
583 [ # # ][ # # ]: 0 : replaceParamterInString( aDefaultSeriesName, C2U("%COLUMNNUMBER"), OUString::valueOf( sal_Int32(24) ) );
584 [ # # ][ # # ]: 0 : sal_Int32 nColumnWidth = GetDataWindow().GetTextWidth( aDefaultSeriesName )
[ # # ]
585 [ # # ][ # # ]: 0 : + GetDataWindow().LogicToPixel( Point( 4 + impl::SeriesHeader::GetRelativeAppFontXPosForNameField(), 0 ), MAP_APPFONT ).X();
[ # # ]
586 [ # # ]: 0 : sal_Int32 nColumnCount = m_apDataBrowserModel->getColumnCount();
587 : : // nRowCount is a member of a base class
588 [ # # ]: 0 : sal_Int32 nRowCountLocal = m_apDataBrowserModel->getMaxRowCount();
589 [ # # ]: 0 : for( sal_Int32 nColIdx=1; nColIdx<=nColumnCount; ++nColIdx )
590 : : {
591 [ # # ][ # # ]: 0 : InsertDataColumn( static_cast< sal_uInt16 >( nColIdx ), GetColString( nColIdx ), nColumnWidth );
[ # # ]
592 : : }
593 : :
594 [ # # ]: 0 : RowInserted( 1, nRowCountLocal );
595 [ # # ][ # # ]: 0 : GoToRow( ::std::min( nOldRow, GetRowCount() - 1 ));
[ # # ]
596 [ # # ][ # # ]: 0 : GoToColumnId( ::std::min( nOldColId, static_cast< sal_uInt16 >( ColCount() - 1 )));
[ # # ]
597 : :
598 [ # # ]: 0 : Window * pWin = this->GetParent();
599 [ # # ]: 0 : if( !pWin )
600 : 0 : pWin = this;
601 : :
602 : : // fill series headers
603 [ # # ]: 0 : clearHeaders();
604 [ # # ]: 0 : const DataBrowserModel::tDataHeaderVector& aHeaders( m_apDataBrowserModel->getDataHeaders());
605 [ # # ]: 0 : Link aFocusLink( LINK( this, DataBrowser, SeriesHeaderGotFocus ));
606 [ # # ]: 0 : Link aSeriesHeaderChangedLink( LINK( this, DataBrowser, SeriesHeaderChanged ));
607 : :
608 [ # # ][ # # ]: 0 : for( DataBrowserModel::tDataHeaderVector::const_iterator aIt( aHeaders.begin());
609 : 0 : aIt != aHeaders.end(); ++aIt )
610 : : {
611 [ # # ][ # # ]: 0 : ::boost::shared_ptr< impl::SeriesHeader > spHeader( new impl::SeriesHeader( pWin ));
[ # # ]
612 [ # # ]: 0 : Reference< beans::XPropertySet > xSeriesProp( aIt->m_xDataSeries, uno::UNO_QUERY );
613 : 0 : sal_Int32 nColor = 0;
614 : : // @todo: Set "DraftColor", i.e. interpolated colors for gradients, bitmaps, etc.
615 [ # # # # ]: 0 : if( xSeriesProp.is() &&
[ # # ]
616 [ # # ][ # # ]: 0 : ( xSeriesProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("Color"))) >>= nColor ))
[ # # ][ # # ]
[ # # ]
[ # # # # ]
617 [ # # ]: 0 : spHeader->SetColor( Color( nColor ));
618 [ # # ]: 0 : spHeader->SetChartType( aIt->m_xChartType, aIt->m_bSwapXAndYAxis );
619 : : spHeader->SetSeriesName(
620 : : String( DataSeriesHelper::getDataSeriesLabel(
621 : 0 : aIt->m_xDataSeries,
622 : 0 : (aIt->m_xChartType.is() ?
623 [ # # ]: 0 : aIt->m_xChartType->getRoleOfSequenceForSeriesLabel() :
624 [ # # ]: 0 : OUString( RTL_CONSTASCII_USTRINGPARAM("values-y"))))));
[ # # # # ]
[ # # ][ # # ]
[ # # ][ # # ]
625 : : // index is 1-based, as 0 is for the column that contains the row-numbers
626 [ # # ]: 0 : spHeader->SetRange( aIt->m_nStartColumn + 1, aIt->m_nEndColumn + 1 );
627 [ # # ]: 0 : spHeader->SetGetFocusHdl( aFocusLink );
628 : 0 : spHeader->SetEditChangedHdl( aSeriesHeaderChangedLink );
629 [ # # ]: 0 : m_aSeriesHeaders.push_back( spHeader );
630 [ # # ]: 0 : }
631 : :
632 [ # # ]: 0 : ImplAdjustHeaderControls();
633 : 0 : SetDirty();
634 [ # # ]: 0 : SetUpdateMode( bLastUpdateMode );
635 [ # # ]: 0 : ActivateCell();
636 [ # # ]: 0 : Invalidate();
637 : : }
638 : :
639 : 0 : String DataBrowser::GetColString( sal_Int32 nColumnId ) const
640 : : {
641 : : OSL_ASSERT( m_apDataBrowserModel.get());
642 [ # # ]: 0 : if( nColumnId > 0 )
643 [ # # ]: 0 : return String( m_apDataBrowserModel->getRoleOfColumn( static_cast< sal_Int32 >( nColumnId ) - 1 ));
644 : 0 : return String();
645 : : }
646 : :
647 : 0 : String DataBrowser::GetRowString( sal_Int32 nRow ) const
648 : : {
649 [ # # ]: 0 : return rtl::OUString::valueOf(nRow + 1);
650 : : }
651 : :
652 : 0 : String DataBrowser::GetCellText( long nRow, sal_uInt16 nColumnId ) const
653 : : {
654 : 0 : String aResult;
655 : :
656 [ # # ]: 0 : if( nColumnId == 0 )
657 : : {
658 [ # # ][ # # ]: 0 : aResult = GetRowString( static_cast< sal_Int32 >( nRow ));
[ # # ]
659 : : }
660 [ # # # # ]: 0 : else if( nRow >= 0 &&
[ # # ]
661 : 0 : m_apDataBrowserModel.get())
662 : : {
663 : 0 : sal_Int32 nColIndex = static_cast< sal_Int32 >( nColumnId ) - 1;
664 : :
665 [ # # ][ # # ]: 0 : if( m_apDataBrowserModel->getCellType( nColIndex, nRow ) == DataBrowserModel::NUMBER )
666 : : {
667 [ # # ]: 0 : double fData( m_apDataBrowserModel->getCellNumber( nColIndex, nRow ));
668 : : sal_Int32 nLabelColor;
669 : 0 : bool bColorChanged = false;
670 : :
671 [ # # # # ]: 0 : if( ! ::rtl::math::isNan( fData ) &&
[ # # ]
672 : 0 : m_spNumberFormatterWrapper.get() )
673 : : aResult = String( m_spNumberFormatterWrapper->getFormattedString(
674 [ # # ]: 0 : GetNumberFormatKey( nRow, nColumnId ),
675 [ # # ][ # # ]: 0 : fData, nLabelColor, bColorChanged ));
[ # # ][ # # ]
676 : : }
677 [ # # ][ # # ]: 0 : else if( m_apDataBrowserModel->getCellType( nColIndex, nRow ) == DataBrowserModel::TEXTORDATE )
678 : : {
679 [ # # ]: 0 : uno::Any aAny = m_apDataBrowserModel->getCellAny( nColIndex, nRow );
680 : 0 : OUString aText;
681 : 0 : double fDouble=0.0;
682 [ # # ]: 0 : if( aAny>>=aText )
683 [ # # ]: 0 : aResult = aText;
684 [ # # ]: 0 : else if( aAny>>=fDouble )
685 : : {
686 : : sal_Int32 nLabelColor;
687 : 0 : bool bColorChanged = false;
688 [ # # ][ # # ]: 0 : sal_Int32 nDateNumberFormat = DiagramHelper::getDateNumberFormat( Reference< util::XNumberFormatsSupplier >( m_xChartDoc, uno::UNO_QUERY) );
689 [ # # ][ # # ]: 0 : if( ! ::rtl::math::isNan( fDouble ) && m_spNumberFormatterWrapper.get() )
[ # # ]
690 : : aResult = String( m_spNumberFormatterWrapper->getFormattedString(
691 [ # # ][ # # ]: 0 : nDateNumberFormat, fDouble, nLabelColor, bColorChanged ));
[ # # ][ # # ]
692 : 0 : }
693 : : }
694 : : else
695 : : {
696 : : OSL_ASSERT( m_apDataBrowserModel->getCellType( nColIndex, nRow ) == DataBrowserModel::TEXT );
697 [ # # ][ # # ]: 0 : aResult = m_apDataBrowserModel->getCellText( nColIndex, nRow );
698 : : }
699 : : }
700 : :
701 : 0 : return aResult;
702 : : }
703 : :
704 : 0 : double DataBrowser::GetCellNumber( long nRow, sal_uInt16 nColumnId ) const
705 : : {
706 : : double fResult;
707 : 0 : ::rtl::math::setNan( & fResult );
708 : :
709 [ # # # # ]: 0 : if(( nColumnId >= 1 ) && ( nRow >= 0 ) &&
[ # # ][ # # ]
710 : 0 : m_apDataBrowserModel.get())
711 : : {
712 : : fResult = m_apDataBrowserModel->getCellNumber(
713 [ # # ]: 0 : static_cast< sal_Int32 >( nColumnId ) - 1, nRow );
714 : : }
715 : :
716 : 0 : return fResult;
717 : : }
718 : :
719 : 0 : void DataBrowser::Resize()
720 : : {
721 : 0 : sal_Bool bLastUpdateMode = GetUpdateMode();
722 : 0 : SetUpdateMode( sal_False );
723 : :
724 : 0 : ::svt::EditBrowseBox::Resize();
725 : 0 : ImplAdjustHeaderControls();
726 : 0 : SetUpdateMode( bLastUpdateMode );
727 : 0 : }
728 : :
729 : 0 : bool DataBrowser::SetReadOnly( bool bNewState )
730 : : {
731 : 0 : bool bResult = m_bIsReadOnly;
732 : :
733 [ # # ]: 0 : if( m_bIsReadOnly != bNewState )
734 : : {
735 : 0 : m_bIsReadOnly = bNewState;
736 : 0 : Invalidate();
737 : 0 : DeactivateCell();
738 : : }
739 : :
740 : 0 : return bResult;
741 : : }
742 : :
743 : 0 : bool DataBrowser::IsReadOnly() const
744 : : {
745 : 0 : return m_bIsReadOnly;
746 : : }
747 : :
748 : :
749 : 0 : void DataBrowser::SetClean()
750 : : {
751 : 0 : m_bIsDirty = false;
752 : 0 : }
753 : :
754 : 0 : void DataBrowser::SetDirty()
755 : : {
756 [ # # ]: 0 : if( !m_bLiveUpdate )
757 : 0 : m_bIsDirty = true;
758 : 0 : }
759 : :
760 : 0 : void DataBrowser::CursorMoved()
761 : : {
762 : 0 : EditBrowseBox::CursorMoved();
763 : :
764 [ # # ][ # # ]: 0 : if( GetUpdateMode() && m_aCursorMovedHdlLink.IsSet())
[ # # ]
765 : 0 : m_aCursorMovedHdlLink.Call( this );
766 : 0 : }
767 : :
768 : 0 : void DataBrowser::SetCellModifiedHdl( const Link& rLink )
769 : : {
770 : 0 : m_aCellModifiedLink = rLink;
771 : 0 : }
772 : :
773 : 0 : void DataBrowser::MouseButtonDown( const BrowserMouseEvent& rEvt )
774 : : {
775 [ # # ]: 0 : if( !m_bDataValid )
776 : 0 : ShowWarningBox();
777 : : else
778 : 0 : EditBrowseBox::MouseButtonDown( rEvt );
779 : 0 : }
780 : :
781 : 0 : void DataBrowser::ShowWarningBox()
782 : : {
783 : : WarningBox( this, WinBits( WB_OK ),
784 [ # # ][ # # ]: 0 : String( SchResId( STR_INVALID_NUMBER ))).Execute();
[ # # ][ # # ]
[ # # ]
785 : 0 : }
786 : :
787 : 0 : bool DataBrowser::ShowQueryBox()
788 : : {
789 [ # # ][ # # ]: 0 : QueryBox* pQueryBox = new QueryBox( this, WB_YES_NO, String( SchResId( STR_DATA_EDITOR_INCORRECT_INPUT )));
[ # # ][ # # ]
790 : :
791 : 0 : return ( pQueryBox->Execute() == RET_YES );
792 : : }
793 : :
794 : 0 : bool DataBrowser::IsDataValid()
795 : : {
796 : 0 : bool bValid = true;
797 : 0 : const sal_Int32 nRow = lcl_getRowInData( GetCurRow());
798 : 0 : const sal_Int32 nCol = lcl_getColumnInData( GetCurColumnId());
799 : :
800 [ # # ]: 0 : if( m_apDataBrowserModel->getCellType( nCol, nRow ) == DataBrowserModel::NUMBER )
801 : : {
802 : 0 : sal_uInt32 nDummy = 0;
803 : 0 : double fDummy = 0.0;
804 [ # # ]: 0 : String aText( m_aNumberEditField.GetText());
805 : :
806 [ # # # # ]: 0 : if( aText.Len() > 0 &&
[ # # ][ # # ]
[ # # ]
807 : 0 : m_spNumberFormatterWrapper.get() &&
808 [ # # ]: 0 : m_spNumberFormatterWrapper->getSvNumberFormatter() &&
809 : : ! m_spNumberFormatterWrapper->getSvNumberFormatter()->IsNumberFormat(
810 [ # # ][ # # ]: 0 : aText, nDummy, fDummy ))
811 : : {
812 : 0 : bValid = false;
813 [ # # ]: 0 : }
814 : : }
815 : :
816 : 0 : return bValid;
817 : : }
818 : :
819 : 0 : bool DataBrowser::IsEnableItem()
820 : : {
821 : 0 : return m_bDataValid;
822 : : }
823 : :
824 : 0 : void DataBrowser::CellModified()
825 : : {
826 : 0 : m_bDataValid = IsDataValid();
827 : 0 : SetDirty();
828 [ # # ]: 0 : if( m_aCellModifiedLink.IsSet())
829 : 0 : m_aCursorMovedHdlLink.Call( this );
830 : 0 : }
831 : :
832 : 0 : void DataBrowser::SetDataFromModel(
833 : : const Reference< chart2::XChartDocument > & xChartDoc,
834 : : const Reference< uno::XComponentContext > & xContext )
835 : : {
836 [ # # ]: 0 : if( m_bLiveUpdate )
837 : : {
838 : 0 : m_xChartDoc.set( xChartDoc );
839 : : }
840 : : else
841 : : {
842 [ # # ]: 0 : Reference< util::XCloneable > xCloneable( xChartDoc, uno::UNO_QUERY );
843 [ # # ]: 0 : if( xCloneable.is())
844 [ # # ][ # # ]: 0 : m_xChartDoc.set( xCloneable->createClone(), uno::UNO_QUERY );
[ # # ]
845 : : }
846 : :
847 [ # # ]: 0 : m_apDataBrowserModel.reset( new DataBrowserModel( m_xChartDoc, xContext ));
848 : : m_spNumberFormatterWrapper.reset(
849 : : new NumberFormatterWrapper(
850 [ # # ][ # # ]: 0 : Reference< util::XNumberFormatsSupplier >( m_xChartDoc, uno::UNO_QUERY )));
[ # # ]
851 : :
852 [ # # ]: 0 : if( m_spNumberFormatterWrapper.get() )
853 : 0 : m_aNumberEditField.SetFormatter( m_spNumberFormatterWrapper->getSvNumberFormatter() );
854 : :
855 : 0 : RenewTable();
856 : :
857 : 0 : const sal_Int32 nColCnt = m_apDataBrowserModel->getColumnCount();
858 : 0 : const sal_Int32 nRowCnt = m_apDataBrowserModel->getMaxRowCount();
859 [ # # ][ # # ]: 0 : if( nRowCnt && nColCnt )
860 : : {
861 : 0 : GoToRow( 0 );
862 : 0 : GoToColumnId( 1 );
863 : : }
864 : 0 : SetClean();
865 : 0 : }
866 : :
867 : 0 : void DataBrowser::InsertColumn()
868 : : {
869 : 0 : sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders );
870 : :
871 [ # # ]: 0 : if( nColIdx >= 0 &&
[ # # # # ]
872 : 0 : m_apDataBrowserModel.get())
873 : : {
874 : : // save changes made to edit-field
875 [ # # ]: 0 : if( IsModified() )
876 : 0 : SaveModified();
877 : :
878 : 0 : m_apDataBrowserModel->insertDataSeries( nColIdx );
879 : 0 : RenewTable();
880 : : }
881 : 0 : }
882 : :
883 : 0 : void DataBrowser::InsertTextColumn()
884 : : {
885 : 0 : sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders );
886 : :
887 [ # # ]: 0 : if( nColIdx >= 0 &&
[ # # # # ]
888 : 0 : m_apDataBrowserModel.get())
889 : : {
890 : : // save changes made to edit-field
891 [ # # ]: 0 : if( IsModified() )
892 : 0 : SaveModified();
893 : :
894 : 0 : m_apDataBrowserModel->insertComplexCategoryLevel( nColIdx );
895 : 0 : RenewTable();
896 : : }
897 : 0 : }
898 : :
899 : 0 : void DataBrowser::RemoveColumn()
900 : : {
901 : 0 : sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders );
902 : :
903 [ # # ]: 0 : if( nColIdx >= 0 &&
[ # # # # ]
904 : 0 : m_apDataBrowserModel.get())
905 : : {
906 : : // save changes made to edit-field
907 [ # # ]: 0 : if( IsModified() )
908 : 0 : SaveModified();
909 : :
910 : 0 : m_bDataValid = true;
911 : 0 : m_apDataBrowserModel->removeDataSeriesOrComplexCategoryLevel( nColIdx );
912 : 0 : RenewTable();
913 : : }
914 : 0 : }
915 : :
916 : 0 : void DataBrowser::InsertRow()
917 : : {
918 : 0 : sal_Int32 nRowIdx = lcl_getRowInData( GetCurRow());
919 : :
920 [ # # ]: 0 : if( nRowIdx >= 0 &&
[ # # # # ]
921 : 0 : m_apDataBrowserModel.get())
922 : : {
923 : : // save changes made to edit-field
924 [ # # ]: 0 : if( IsModified() )
925 : 0 : SaveModified();
926 : :
927 : 0 : m_apDataBrowserModel->insertDataPointForAllSeries( nRowIdx );
928 : 0 : RenewTable();
929 : : }
930 : 0 : }
931 : :
932 : 0 : void DataBrowser::RemoveRow()
933 : : {
934 : 0 : sal_Int32 nRowIdx = lcl_getRowInData( GetCurRow());
935 : :
936 [ # # ]: 0 : if( nRowIdx >= 0 &&
[ # # # # ]
937 : 0 : m_apDataBrowserModel.get())
938 : : {
939 : : // save changes made to edit-field
940 [ # # ]: 0 : if( IsModified() )
941 : 0 : SaveModified();
942 : :
943 : 0 : m_bDataValid = true;
944 : 0 : m_apDataBrowserModel->removeDataPointForAllSeries( nRowIdx );
945 : 0 : RenewTable();
946 : : }
947 : 0 : }
948 : :
949 : 0 : void DataBrowser::SwapColumn()
950 : : {
951 : 0 : sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders );
952 : :
953 [ # # ]: 0 : if( nColIdx >= 0 &&
[ # # # # ]
954 : 0 : m_apDataBrowserModel.get())
955 : : {
956 : : // save changes made to edit-field
957 [ # # ]: 0 : if( IsModified() )
958 : 0 : SaveModified();
959 : :
960 : 0 : m_apDataBrowserModel->swapDataSeries( nColIdx );
961 : :
962 : : // keep cursor in swapped column
963 [ # # ]: 0 : if( GetCurColumnId() < ColCount() - 1 )
964 : : {
965 : 0 : Dispatch( BROWSER_CURSORRIGHT );
966 : : }
967 : 0 : RenewTable();
968 : : }
969 : 0 : }
970 : :
971 : 0 : void DataBrowser::SwapRow()
972 : : {
973 : 0 : sal_Int32 nRowIdx = lcl_getRowInData( GetCurRow());
974 : :
975 [ # # ]: 0 : if( nRowIdx >= 0 &&
[ # # # # ]
976 : 0 : m_apDataBrowserModel.get())
977 : : {
978 : : // save changes made to edit-field
979 [ # # ]: 0 : if( IsModified() )
980 : 0 : SaveModified();
981 : :
982 : 0 : m_apDataBrowserModel->swapDataPointForAllSeries( nRowIdx );
983 : :
984 : : // keep cursor in swapped row
985 [ # # ]: 0 : if( GetCurRow() < GetRowCount() - 1 )
986 : : {
987 : 0 : Dispatch( BROWSER_CURSORDOWN );
988 : : }
989 : 0 : RenewTable();
990 : : }
991 : 0 : }
992 : :
993 : 0 : void DataBrowser::SetCursorMovedHdl( const Link& rLink )
994 : : {
995 : 0 : m_aCursorMovedHdlLink = rLink;
996 : 0 : }
997 : :
998 : : // implementations for ::svt::EditBrowseBox (pure virtual methods)
999 : 0 : void DataBrowser::PaintCell(
1000 : : OutputDevice& rDev, const Rectangle& rRect, sal_uInt16 nColumnId ) const
1001 : : {
1002 : 0 : Point aPos( rRect.TopLeft());
1003 : 0 : aPos.X() += 1;
1004 : :
1005 [ # # ]: 0 : String aText = GetCellText( m_nSeekRow, nColumnId );
1006 [ # # ][ # # ]: 0 : Size TxtSize( GetDataWindow().GetTextWidth( aText ), GetDataWindow().GetTextHeight());
1007 : :
1008 : : // clipping
1009 [ # # # # : 0 : if( aPos.X() < rRect.Right() || aPos.X() + TxtSize.Width() > rRect.Right() ||
# # ][ # # ]
[ # # ]
1010 : 0 : aPos.Y() < rRect.Top() || aPos.Y() + TxtSize.Height() > rRect.Bottom())
1011 [ # # ][ # # ]: 0 : rDev.SetClipRegion( rRect );
[ # # ]
1012 : :
1013 : : // allow for a disabled control ...
1014 [ # # ]: 0 : sal_Bool bEnabled = IsEnabled();
1015 : 0 : Color aOriginalColor = rDev.GetTextColor();
1016 [ # # ]: 0 : if( ! bEnabled )
1017 [ # # ]: 0 : rDev.SetTextColor( GetSettings().GetStyleSettings().GetDisableColor() );
1018 : :
1019 : : // draw the text
1020 [ # # ]: 0 : rDev.DrawText( aPos, aText );
1021 : :
1022 : : // reset the color (if necessary)
1023 [ # # ]: 0 : if( ! bEnabled )
1024 [ # # ]: 0 : rDev.SetTextColor( aOriginalColor );
1025 : :
1026 [ # # ]: 0 : if( rDev.IsClipRegion())
1027 [ # # ][ # # ]: 0 : rDev.SetClipRegion();
1028 : 0 : }
1029 : :
1030 : 0 : sal_Bool DataBrowser::SeekRow( long nRow )
1031 : : {
1032 [ # # ]: 0 : if( ! EditBrowseBox::SeekRow( nRow ))
1033 : 0 : return sal_False;
1034 : :
1035 [ # # ]: 0 : if( nRow < 0 )
1036 : 0 : m_nSeekRow = - 1;
1037 : : else
1038 : 0 : m_nSeekRow = nRow;
1039 : :
1040 : 0 : return sal_True;
1041 : : }
1042 : :
1043 : 0 : sal_Bool DataBrowser::IsTabAllowed( sal_Bool bForward ) const
1044 : : {
1045 : 0 : long nRow = GetCurRow();
1046 : 0 : long nCol = GetCurColumnId();
1047 : :
1048 : : // column 0 is header-column
1049 : : long nBadCol = bForward
1050 : 0 : ? GetColumnCount() - 1
1051 [ # # ]: 0 : : 1;
1052 : : long nBadRow = bForward
1053 : 0 : ? GetRowCount() - 1
1054 [ # # ]: 0 : : 0;
1055 : :
1056 [ # # ]: 0 : if( !m_bDataValid )
1057 : : {
1058 : 0 : const_cast< DataBrowser* >( this )->ShowWarningBox();
1059 : 0 : return sal_False;
1060 : : }
1061 : :
1062 : : return ( nRow != nBadRow ||
1063 [ # # ][ # # ]: 0 : nCol != nBadCol );
1064 : : }
1065 : :
1066 : 0 : ::svt::CellController* DataBrowser::GetController( long nRow, sal_uInt16 nCol )
1067 : : {
1068 [ # # ]: 0 : if( m_bIsReadOnly )
1069 : 0 : return 0;
1070 : :
1071 [ # # ]: 0 : if( CellContainsNumbers( nRow, nCol ))
1072 : : {
1073 : 0 : m_aNumberEditField.UseInputStringForFormatting();
1074 : 0 : m_aNumberEditField.SetFormatKey( GetNumberFormatKey( nRow, nCol ));
1075 : 0 : return m_rNumberEditController;
1076 : : }
1077 : :
1078 : 0 : return m_rTextEditController;
1079 : : }
1080 : :
1081 : 0 : void DataBrowser::InitController(
1082 : : ::svt::CellControllerRef& rController, long nRow, sal_uInt16 nCol )
1083 : : {
1084 [ # # ]: 0 : if( rController == m_rTextEditController )
1085 : : {
1086 [ # # ]: 0 : String aText( GetCellText( nRow, nCol ) );
1087 [ # # ]: 0 : m_aTextEditField.SetText( aText );
1088 [ # # ][ # # ]: 0 : m_aTextEditField.SetSelection( Selection( 0, aText.Len() ));
1089 : : }
1090 [ # # ]: 0 : else if( rController == m_rNumberEditController )
1091 : : {
1092 : : // treat invalid and empty text as Nan
1093 [ # # ]: 0 : m_aNumberEditField.EnableNotANumber( true );
1094 [ # # ][ # # ]: 0 : if( ::rtl::math::isNan( GetCellNumber( nRow, nCol )))
1095 [ # # ][ # # ]: 0 : m_aNumberEditField.SetTextValue( String());
[ # # ]
1096 : : else
1097 [ # # ][ # # ]: 0 : m_aNumberEditField.SetValue( GetCellNumber( nRow, nCol ) );
1098 [ # # ]: 0 : String aText( m_aNumberEditField.GetText());
1099 [ # # ][ # # ]: 0 : m_aNumberEditField.SetSelection( Selection( 0, aText.Len()));
1100 : : }
1101 : : else
1102 : : {
1103 : : OSL_FAIL( "Invalid Controller" );
1104 : : }
1105 : 0 : }
1106 : :
1107 : 0 : bool DataBrowser::CellContainsNumbers( sal_Int32 nRow, sal_uInt16 nCol ) const
1108 : : {
1109 [ # # ]: 0 : if( ! m_apDataBrowserModel.get())
1110 : 0 : return false;
1111 : 0 : return (m_apDataBrowserModel->getCellType( lcl_getColumnInData( nCol ), lcl_getRowInData( nRow )) ==
1112 : 0 : DataBrowserModel::NUMBER);
1113 : : }
1114 : :
1115 : 0 : sal_uInt32 DataBrowser::GetNumberFormatKey( sal_Int32 nRow, sal_uInt16 nCol ) const
1116 : : {
1117 [ # # ]: 0 : if( ! m_apDataBrowserModel.get())
1118 : 0 : return 0;
1119 : 0 : return m_apDataBrowserModel->getNumberFormatKey( lcl_getColumnInData( nCol ), lcl_getRowInData( nRow ));
1120 : : }
1121 : :
1122 : 0 : bool DataBrowser::isDateString( rtl::OUString aInputString, double& fOutDateValue )
1123 : : {
1124 : 0 : sal_uInt32 nNumberFormat=0;
1125 [ # # ][ # # ]: 0 : SvNumberFormatter* pSvNumberFormatter = m_spNumberFormatterWrapper.get() ? m_spNumberFormatterWrapper->getSvNumberFormatter() : 0;
1126 [ # # ][ # # ]: 0 : if( !aInputString.isEmpty() && pSvNumberFormatter && pSvNumberFormatter->IsNumberFormat( aInputString, nNumberFormat, fOutDateValue ) )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
[ # # # # ]
1127 : : {
1128 [ # # ]: 0 : Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( m_xChartDoc, uno::UNO_QUERY );
1129 : 0 : Reference< util::XNumberFormats > xNumberFormats;
1130 [ # # ]: 0 : if( xNumberFormatsSupplier.is() )
1131 [ # # ][ # # ]: 0 : xNumberFormats = Reference< util::XNumberFormats >( xNumberFormatsSupplier->getNumberFormats() );
[ # # ]
1132 [ # # ][ # # ]: 0 : if( DiagramHelper::isDateNumberFormat( nNumberFormat, xNumberFormats ) )
1133 [ # # ][ # # ]: 0 : return true;
1134 : : }
1135 : 0 : return false;
1136 : : }
1137 : :
1138 : 0 : sal_Bool DataBrowser::SaveModified()
1139 : : {
1140 [ # # ]: 0 : if( ! IsModified() )
1141 : 0 : return sal_True;
1142 : :
1143 : 0 : sal_Bool bChangeValid = sal_True;
1144 : :
1145 : 0 : const sal_Int32 nRow = lcl_getRowInData( GetCurRow());
1146 : 0 : const sal_Int32 nCol = lcl_getColumnInData( GetCurColumnId());
1147 : :
1148 : : OSL_ENSURE( nRow >= 0 || nCol >= 0, "This cell should not be modified!" );
1149 : :
1150 [ # # ]: 0 : SvNumberFormatter* pSvNumberFormatter = m_spNumberFormatterWrapper.get() ? m_spNumberFormatterWrapper->getSvNumberFormatter() : 0;
1151 [ # # # # ]: 0 : switch( m_apDataBrowserModel->getCellType( nCol, nRow ))
1152 : : {
1153 : : case DataBrowserModel::NUMBER:
1154 : : {
1155 : 0 : sal_uInt32 nDummy = 0;
1156 : 0 : double fDummy = 0.0;
1157 [ # # ]: 0 : String aText( m_aNumberEditField.GetText());
1158 : : // an empty string is valid, if no numberformatter exists, all
1159 : : // values are treated as valid
1160 [ # # ][ # # ]: 0 : if( aText.Len() > 0 && pSvNumberFormatter &&
[ # # ][ # # ]
1161 [ # # ]: 0 : ! pSvNumberFormatter->IsNumberFormat( aText, nDummy, fDummy ) )
1162 : : {
1163 : 0 : bChangeValid = sal_False;
1164 : : }
1165 : : else
1166 : : {
1167 [ # # ]: 0 : double fData = m_aNumberEditField.GetValue();
1168 [ # # ]: 0 : bChangeValid = m_apDataBrowserModel->setCellNumber( nCol, nRow, fData );
1169 [ # # ]: 0 : }
1170 : : }
1171 : 0 : break;
1172 : : case DataBrowserModel::TEXTORDATE:
1173 : : {
1174 [ # # ][ # # ]: 0 : OUString aText( m_aTextEditField.GetText() );
[ # # ]
1175 : 0 : double fDateValue=0.0;
1176 : 0 : bChangeValid = sal_False;
1177 [ # # ][ # # ]: 0 : if( isDateString( aText, fDateValue ) )
1178 [ # # ][ # # ]: 0 : bChangeValid = m_apDataBrowserModel->setCellAny( nCol, nRow, uno::makeAny( fDateValue ) );
1179 [ # # ]: 0 : if(!bChangeValid)
1180 [ # # ][ # # ]: 0 : bChangeValid = m_apDataBrowserModel->setCellAny( nCol, nRow, uno::makeAny( aText ) );
1181 : : }
1182 : 0 : break;
1183 : : case DataBrowserModel::TEXT:
1184 : : {
1185 [ # # ][ # # ]: 0 : OUString aText( m_aTextEditField.GetText());
[ # # ]
1186 [ # # ]: 0 : bChangeValid = m_apDataBrowserModel->setCellText( nCol, nRow, aText );
1187 : : }
1188 : 0 : break;
1189 : : }
1190 : :
1191 : : // the first valid change changes this to true
1192 [ # # ]: 0 : if( bChangeValid )
1193 : : {
1194 : 0 : RowModified( GetCurRow(), GetCurColumnId());
1195 : 0 : ::svt::CellController* pCtrl = GetController( GetCurRow(), GetCurColumnId());
1196 [ # # ]: 0 : if( pCtrl )
1197 : 0 : pCtrl->ClearModified();
1198 : 0 : SetDirty();
1199 : : }
1200 : :
1201 : 0 : return bChangeValid;
1202 : : }
1203 : :
1204 : 0 : bool DataBrowser::EndEditing()
1205 : : {
1206 [ # # ]: 0 : if( IsModified())
1207 : 0 : SaveModified();
1208 : :
1209 : : // apply changes made to series headers
1210 [ # # ]: 0 : ::std::for_each( m_aSeriesHeaders.begin(), m_aSeriesHeaders.end(), impl::applyChangesFunctor());
1211 : :
1212 [ # # ]: 0 : if( m_bDataValid )
1213 : 0 : return true;
1214 : : else
1215 : 0 : return ShowQueryBox();
1216 : : }
1217 : :
1218 : 0 : sal_Int16 DataBrowser::GetFirstVisibleColumNumber() const
1219 : : {
1220 : 0 : return GetFirstVisibleColNumber();
1221 : : }
1222 : :
1223 : 0 : void DataBrowser::ColumnResized( sal_uInt16 nColId )
1224 : : {
1225 : 0 : sal_Bool bLastUpdateMode = GetUpdateMode();
1226 : 0 : SetUpdateMode( sal_False );
1227 : :
1228 : 0 : EditBrowseBox::ColumnResized( nColId );
1229 : 0 : ImplAdjustHeaderControls();
1230 : 0 : SetUpdateMode( bLastUpdateMode );
1231 : 0 : }
1232 : :
1233 : 0 : void DataBrowser::EndScroll()
1234 : : {
1235 : 0 : sal_Bool bLastUpdateMode = GetUpdateMode();
1236 : 0 : SetUpdateMode( sal_False );
1237 : :
1238 : 0 : EditBrowseBox::EndScroll();
1239 : 0 : RenewSeriesHeaders();
1240 : :
1241 : 0 : SetUpdateMode( bLastUpdateMode );
1242 : 0 : }
1243 : :
1244 : 0 : void DataBrowser::RenewSeriesHeaders()
1245 : : {
1246 [ # # ]: 0 : Window * pWin = this->GetParent();
1247 [ # # ]: 0 : if( !pWin )
1248 : 0 : pWin = this;
1249 : :
1250 [ # # ]: 0 : clearHeaders();
1251 [ # # ][ # # ]: 0 : DataBrowserModel::tDataHeaderVector aHeaders( m_apDataBrowserModel->getDataHeaders());
1252 [ # # ]: 0 : Link aFocusLink( LINK( this, DataBrowser, SeriesHeaderGotFocus ));
1253 [ # # ]: 0 : Link aSeriesHeaderChangedLink( LINK( this, DataBrowser, SeriesHeaderChanged ));
1254 : :
1255 [ # # ][ # # ]: 0 : for( DataBrowserModel::tDataHeaderVector::const_iterator aIt( aHeaders.begin());
[ # # ]
1256 : 0 : aIt != aHeaders.end(); ++aIt )
1257 : : {
1258 [ # # ][ # # ]: 0 : ::boost::shared_ptr< impl::SeriesHeader > spHeader( new impl::SeriesHeader( pWin ));
[ # # ]
1259 [ # # ]: 0 : Reference< beans::XPropertySet > xSeriesProp( aIt->m_xDataSeries, uno::UNO_QUERY );
1260 : 0 : sal_Int32 nColor = 0;
1261 [ # # # # ]: 0 : if( xSeriesProp.is() &&
[ # # ]
1262 [ # # ][ # # ]: 0 : ( xSeriesProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("Color"))) >>= nColor ))
[ # # ][ # # ]
[ # # ]
[ # # # # ]
1263 [ # # ]: 0 : spHeader->SetColor( Color( nColor ));
1264 [ # # ]: 0 : spHeader->SetChartType( aIt->m_xChartType, aIt->m_bSwapXAndYAxis );
1265 : : spHeader->SetSeriesName(
1266 : : String( DataSeriesHelper::getDataSeriesLabel(
1267 : 0 : aIt->m_xDataSeries,
1268 : 0 : (aIt->m_xChartType.is() ?
1269 [ # # ]: 0 : aIt->m_xChartType->getRoleOfSequenceForSeriesLabel() :
1270 [ # # ]: 0 : OUString( RTL_CONSTASCII_USTRINGPARAM("values-y"))))));
[ # # # # ]
[ # # ][ # # ]
[ # # ][ # # ]
1271 [ # # ]: 0 : spHeader->SetRange( aIt->m_nStartColumn + 1, aIt->m_nEndColumn + 1 );
1272 [ # # ]: 0 : spHeader->SetGetFocusHdl( aFocusLink );
1273 : 0 : spHeader->SetEditChangedHdl( aSeriesHeaderChangedLink );
1274 [ # # ]: 0 : m_aSeriesHeaders.push_back( spHeader );
1275 [ # # ]: 0 : }
1276 : :
1277 [ # # ]: 0 : ImplAdjustHeaderControls();
1278 : 0 : }
1279 : :
1280 : 0 : void DataBrowser::ImplAdjustHeaderControls()
1281 : : {
1282 [ # # ]: 0 : sal_uInt16 nColCount = this->GetColumnCount();
1283 [ # # ]: 0 : sal_uInt32 nCurrentPos = this->GetPosPixel().getX();
1284 : 0 : sal_uInt32 nMaxPos = nCurrentPos + this->GetOutputSizePixel().getWidth();
1285 : 0 : sal_uInt32 nStartPos = nCurrentPos;
1286 : :
1287 : : // width of header column
1288 [ # # ]: 0 : nCurrentPos += this->GetColumnWidth( 0 );
1289 : 0 : tSeriesHeaderContainer::iterator aIt( m_aSeriesHeaders.begin());
1290 : 0 : sal_uInt16 i = this->GetFirstVisibleColumNumber();
1291 [ # # ][ # # ]: 0 : while( (aIt != m_aSeriesHeaders.end()) && ((*aIt)->GetStartColumn() < i) )
[ # # ][ # # ]
[ # # # # ]
1292 : 0 : ++aIt;
1293 [ # # ][ # # ]: 0 : for( ; i < nColCount && aIt != m_aSeriesHeaders.end(); ++i )
[ # # ][ # # ]
[ # # # # ]
1294 : : {
1295 [ # # ]: 0 : if( (*aIt)->GetStartColumn() == i )
1296 : 0 : nStartPos = nCurrentPos;
1297 : :
1298 [ # # ]: 0 : nCurrentPos += (this->GetColumnWidth( i ));
1299 : :
1300 [ # # ]: 0 : if( (*aIt)->GetEndColumn() == i )
1301 : : {
1302 [ # # ]: 0 : if( nStartPos < nMaxPos )
1303 : : {
1304 [ # # ]: 0 : (*aIt)->SetPixelPosX( nStartPos + 2 );
1305 [ # # ]: 0 : (*aIt)->SetPixelWidth( nCurrentPos - nStartPos - 3 );
1306 : : }
1307 : : else
1308 : : // do not hide, to get focus events. Move outside the dialog for "hiding"
1309 [ # # ]: 0 : (*aIt)->SetPixelPosX( nMaxPos + 42 );
1310 : 0 : ++aIt;
1311 : : }
1312 : : }
1313 : 0 : }
1314 : :
1315 : 0 : IMPL_LINK( DataBrowser, SeriesHeaderGotFocus, impl::SeriesHeaderEdit*, pEdit )
1316 : : {
1317 [ # # ]: 0 : if( pEdit )
1318 : : {
1319 : 0 : pEdit->SetShowWarningBox( !m_bDataValid );
1320 : :
1321 [ # # ]: 0 : if( !m_bDataValid )
1322 : 0 : GoToCell( 0, 0 );
1323 : : else
1324 : : {
1325 : 0 : MakeFieldVisible( GetCurRow(), static_cast< sal_uInt16 >( pEdit->getStartColumn()), true /* bComplete */ );
1326 : 0 : ActivateCell();
1327 : 0 : m_aCursorMovedHdlLink.Call( this );
1328 : : }
1329 : : }
1330 : 0 : return 0;
1331 : : }
1332 : :
1333 : 0 : IMPL_LINK( DataBrowser, SeriesHeaderChanged, impl::SeriesHeaderEdit*, pEdit )
1334 : : {
1335 [ # # ]: 0 : if( pEdit )
1336 : : {
1337 : : Reference< chart2::XDataSeries > xSeries(
1338 [ # # ]: 0 : m_apDataBrowserModel->getDataSeriesByColumn( pEdit->getStartColumn() - 1 ));
1339 [ # # ]: 0 : Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY );
1340 [ # # ]: 0 : if( xSource.is())
1341 : : {
1342 : : Reference< chart2::XChartType > xChartType(
1343 [ # # ][ # # ]: 0 : m_apDataBrowserModel->getHeaderForSeries( xSeries ).m_xChartType );
1344 [ # # ]: 0 : if( xChartType.is())
1345 : : {
1346 : : Reference< chart2::data::XLabeledDataSequence > xLabeledSeq(
1347 [ # # ][ # # ]: 0 : DataSeriesHelper::getDataSequenceByRole( xSource, xChartType->getRoleOfSequenceForSeriesLabel()));
[ # # ]
1348 [ # # ]: 0 : if( xLabeledSeq.is())
1349 : : {
1350 [ # # ][ # # ]: 0 : Reference< container::XIndexReplace > xIndexReplace( xLabeledSeq->getLabel(), uno::UNO_QUERY );
[ # # ]
1351 [ # # ]: 0 : if( xIndexReplace.is())
1352 [ # # ]: 0 : xIndexReplace->replaceByIndex(
1353 [ # # ][ # # ]: 0 : 0, uno::makeAny( OUString( pEdit->GetText())));
[ # # ][ # # ]
[ # # ]
1354 : 0 : }
1355 : 0 : }
1356 : 0 : }
1357 : : }
1358 : 0 : return 0;
1359 : : }
1360 : :
1361 : 0 : sal_Int32 DataBrowser::GetTotalWidth() const
1362 : : {
1363 : 0 : sal_uLong nWidth = 0;
1364 [ # # ]: 0 : for ( sal_uInt16 nCol = 0; nCol < ColCount(); ++nCol )
1365 : 0 : nWidth += GetColumnWidth( nCol );
1366 : 0 : return static_cast< sal_Int32 >( nWidth );
1367 : : }
1368 : :
1369 : : } // namespace chart
1370 : :
1371 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|