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