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( Window * pParent );
105 : virtual ~SeriesHeaderEdit();
106 : virtual void MouseButtonDown( const MouseEvent& rMEvt ) SAL_OVERRIDE;
107 :
108 : void setStartColumn( sal_Int32 nStartColumn );
109 : sal_Int32 getStartColumn() const;
110 : void SetShowWarningBox( bool bShowWarning = true );
111 :
112 : private:
113 : sal_Int32 m_nStartColumn;
114 : bool m_bShowWarningBox;
115 : };
116 :
117 0 : SeriesHeaderEdit::SeriesHeaderEdit( 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 : sal_Int32 SeriesHeaderEdit::getStartColumn() const
134 : {
135 0 : return m_nStartColumn;
136 : }
137 :
138 0 : void SeriesHeaderEdit::SetShowWarningBox( bool bShowWarning )
139 : {
140 0 : m_bShowWarningBox = bShowWarning;
141 0 : }
142 :
143 0 : void SeriesHeaderEdit::MouseButtonDown( const MouseEvent& rMEvt )
144 : {
145 0 : Edit::MouseButtonDown( rMEvt );
146 :
147 0 : if( m_bShowWarningBox )
148 : WarningBox(this, WinBits( WB_OK ),
149 0 : SCH_RESSTR(STR_INVALID_NUMBER)).Execute();
150 0 : }
151 :
152 0 : class SeriesHeader
153 : {
154 : public:
155 : explicit SeriesHeader(Window * pParent, Window *pColorParent);
156 :
157 : void SetColor( const Color & rCol );
158 : void SetPos( const Point & rPos );
159 : void SetWidth( sal_Int32 nWidth );
160 : void SetChartType( const Reference< chart2::XChartType > & xChartType,
161 : bool bSwapXAndYAxis );
162 : void SetSeriesName( const OUString & rName );
163 : void SetRange( sal_Int32 nStartCol, sal_Int32 nEndCol );
164 :
165 : void SetPixelWidth( sal_Int32 nWidth );
166 :
167 : sal_Int32 GetStartColumn() const;
168 : sal_Int32 GetEndColumn() const;
169 :
170 : static sal_Int32 GetRelativeAppFontXPosForNameField();
171 :
172 : void Show();
173 : void Hide();
174 :
175 : /** call this before destroying the class. This notifies the listeners to
176 : changes of the edit field for the series name.
177 : */
178 : void applyChanges();
179 :
180 : void SetGetFocusHdl( const Link& rLink );
181 :
182 : void SetEditChangedHdl( const Link & rLink );
183 :
184 : bool HasFocus() const;
185 :
186 : private:
187 : ::boost::shared_ptr< FixedImage > m_spSymbol;
188 : ::boost::shared_ptr< SeriesHeaderEdit > m_spSeriesName;
189 : ::boost::shared_ptr< FixedText > m_spColorBar;
190 : OutputDevice * m_pDevice;
191 : Link m_aChangeLink;
192 :
193 : void notifyChanges();
194 : DECL_LINK( SeriesNameChanged, void * );
195 : DECL_LINK( SeriesNameEdited, void * );
196 :
197 : static Image GetChartTypeImage(
198 : const Reference< chart2::XChartType > & xChartType,
199 : bool bSwapXAndYAxis
200 : );
201 :
202 : sal_Int32 m_nStartCol, m_nEndCol;
203 : sal_Int32 m_nWidth;
204 : Point m_aPos;
205 : bool m_bSeriesNameChangePending;
206 : };
207 :
208 0 : SeriesHeader::SeriesHeader( Window * pParent, Window *pColorParent ) :
209 0 : m_spSymbol( new FixedImage( pParent, WB_NOBORDER )),
210 0 : m_spSeriesName( new SeriesHeaderEdit( pParent )),
211 0 : m_spColorBar( new FixedText( pColorParent, WB_NOBORDER )),
212 : m_pDevice( pParent ),
213 : m_nStartCol( 0 ),
214 : m_nEndCol( 0 ),
215 : m_nWidth( 42 ),
216 : m_aPos( 0, 22 ),
217 0 : m_bSeriesNameChangePending( false )
218 : {
219 0 : m_spSeriesName->EnableUpdateData( 4 * EDIT_UPDATEDATA_TIMEOUT ); // define is in vcl/edit.hxx
220 0 : m_spSeriesName->SetUpdateDataHdl( LINK( this, SeriesHeader, SeriesNameChanged ));
221 0 : m_spSeriesName->SetModifyHdl( LINK( this, SeriesHeader, SeriesNameEdited ));
222 0 : m_spSeriesName->SetHelpId( HID_SCH_DATA_SERIES_LABEL );
223 0 : Show();
224 0 : }
225 :
226 0 : void SeriesHeader::notifyChanges()
227 : {
228 0 : if( m_aChangeLink.IsSet())
229 0 : m_aChangeLink.Call( m_spSeriesName.get());
230 :
231 0 : m_bSeriesNameChangePending = false;
232 0 : }
233 :
234 0 : void SeriesHeader::applyChanges()
235 : {
236 0 : if( m_bSeriesNameChangePending )
237 : {
238 0 : notifyChanges();
239 : }
240 0 : }
241 :
242 0 : void SeriesHeader::SetColor( const Color & rCol )
243 : {
244 0 : m_spColorBar->SetControlBackground( rCol );
245 0 : }
246 :
247 : const sal_Int32 nSymbolHeight = 10;
248 : const sal_Int32 nSymbolDistance = 2;
249 :
250 0 : sal_Int32 SeriesHeader::GetRelativeAppFontXPosForNameField()
251 : {
252 0 : return nSymbolHeight + nSymbolDistance;
253 : }
254 :
255 0 : void SeriesHeader::SetPos( const Point & rPos )
256 : {
257 0 : m_aPos = rPos;
258 :
259 : // chart type symbol
260 0 : Size aSize( nSymbolHeight, nSymbolHeight );
261 0 : aSize = m_pDevice->LogicToPixel( aSize, MAP_APPFONT );
262 0 : m_spSymbol->set_width_request(aSize.Width());
263 0 : m_spSymbol->set_height_request(aSize.Height());
264 :
265 : // series name edit field
266 0 : aSize.setWidth(nSymbolDistance);
267 0 : aSize = m_pDevice->LogicToPixel( aSize, MAP_APPFONT );
268 0 : m_spSeriesName->set_margin_left(aSize.Width() + 2);
269 0 : aSize.setWidth( m_nWidth - nSymbolHeight - nSymbolDistance );
270 0 : sal_Int32 nHeight = 12;
271 0 : aSize.setHeight( nHeight );
272 0 : aSize = m_pDevice->LogicToPixel( aSize, MAP_APPFONT );
273 0 : m_spSeriesName->set_width_request(aSize.Width());
274 0 : m_spSeriesName->set_height_request(aSize.Height());
275 :
276 : // color bar
277 0 : aSize.setWidth(1);
278 0 : aSize = m_pDevice->LogicToPixel( aSize, MAP_APPFONT );
279 0 : m_spColorBar->set_margin_left(aSize.Width() + 2);
280 0 : nHeight = 3;
281 0 : aSize.setWidth( m_nWidth - 1 );
282 0 : aSize.setHeight( nHeight );
283 0 : aSize = m_pDevice->LogicToPixel( aSize, MAP_APPFONT );
284 0 : m_spColorBar->set_width_request(aSize.Width());
285 0 : m_spColorBar->set_height_request(aSize.Height());
286 0 : }
287 :
288 0 : void SeriesHeader::SetWidth( sal_Int32 nWidth )
289 : {
290 0 : m_nWidth = nWidth;
291 0 : SetPos( m_aPos );
292 0 : }
293 :
294 0 : void SeriesHeader::SetPixelWidth( sal_Int32 nWidth )
295 : {
296 0 : SetWidth( m_pDevice->PixelToLogic( Size( nWidth, 0 ), MAP_APPFONT ).getWidth());
297 0 : }
298 :
299 0 : void SeriesHeader::SetChartType(
300 : const Reference< chart2::XChartType > & xChartType,
301 : bool bSwapXAndYAxis
302 : )
303 : {
304 0 : m_spSymbol->SetImage( GetChartTypeImage( xChartType, bSwapXAndYAxis ) );
305 0 : }
306 :
307 0 : void SeriesHeader::SetSeriesName( const OUString & rName )
308 : {
309 0 : m_spSeriesName->SetText( rName );
310 0 : }
311 :
312 0 : void SeriesHeader::SetRange( sal_Int32 nStartCol, sal_Int32 nEndCol )
313 : {
314 0 : m_nStartCol = nStartCol;
315 0 : m_nEndCol = (nEndCol > nStartCol) ? nEndCol : nStartCol;
316 0 : m_spSeriesName->setStartColumn( nStartCol );
317 0 : }
318 :
319 0 : sal_Int32 SeriesHeader::GetStartColumn() const
320 : {
321 0 : return m_nStartCol;
322 : }
323 :
324 0 : sal_Int32 SeriesHeader::GetEndColumn() const
325 : {
326 0 : return m_nEndCol;
327 : }
328 :
329 0 : void SeriesHeader::Show()
330 : {
331 0 : m_spSymbol->Show();
332 0 : m_spSeriesName->Show();
333 0 : m_spColorBar->Show();
334 0 : }
335 :
336 0 : void SeriesHeader::Hide()
337 : {
338 0 : m_spSymbol->Hide();
339 0 : m_spSeriesName->Hide();
340 0 : m_spColorBar->Hide();
341 0 : }
342 :
343 0 : void SeriesHeader::SetEditChangedHdl( const Link & rLink )
344 : {
345 0 : m_aChangeLink = rLink;
346 0 : }
347 :
348 0 : IMPL_LINK_NOARG(SeriesHeader, SeriesNameChanged)
349 : {
350 0 : notifyChanges();
351 0 : return 0;
352 : }
353 :
354 0 : IMPL_LINK_NOARG(SeriesHeader, SeriesNameEdited)
355 : {
356 0 : m_bSeriesNameChangePending = true;
357 0 : return 0;
358 : }
359 :
360 0 : void SeriesHeader::SetGetFocusHdl( const Link& rLink )
361 : {
362 0 : m_spSeriesName->SetGetFocusHdl( rLink );
363 0 : }
364 :
365 0 : bool SeriesHeader::HasFocus() const
366 : {
367 0 : return m_spSeriesName->HasFocus();
368 : }
369 :
370 0 : Image SeriesHeader::GetChartTypeImage(
371 : const Reference< chart2::XChartType > & xChartType,
372 : bool bSwapXAndYAxis
373 : )
374 : {
375 0 : Image aResult;
376 0 : if( !xChartType.is())
377 0 : return aResult;
378 0 : OUString aChartTypeName( xChartType->getChartType());
379 :
380 0 : if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_AREA ))
381 : {
382 0 : aResult = Image( SchResId( IMG_TYPE_AREA ) );
383 : }
384 0 : else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_COLUMN ))
385 : {
386 0 : if( bSwapXAndYAxis )
387 0 : aResult = Image( SchResId( IMG_TYPE_BAR ) );
388 : else
389 0 : aResult = Image( SchResId( IMG_TYPE_COLUMN ) );
390 : }
391 0 : else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_LINE ))
392 : {
393 0 : aResult = Image( SchResId( IMG_TYPE_LINE ) );
394 : }
395 0 : else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_SCATTER ))
396 : {
397 0 : aResult = Image( SchResId( IMG_TYPE_XY ) );
398 : }
399 0 : else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_PIE ))
400 : {
401 0 : aResult = Image( SchResId( IMG_TYPE_PIE ) );
402 : }
403 0 : else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_NET )
404 0 : || aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET ) )
405 : {
406 0 : aResult = Image( SchResId( IMG_TYPE_NET ) );
407 : }
408 0 : else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK ))
409 : {
410 : // @todo: correct image for candle-stick type
411 0 : aResult = Image( SchResId( IMG_TYPE_STOCK ) );
412 : }
413 0 : else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE ))
414 : {
415 0 : aResult = Image( SchResId( IMG_TYPE_BUBBLE ) );
416 : }
417 :
418 0 : return aResult;
419 : }
420 :
421 : struct applyChangesFunctor : public ::std::unary_function< ::boost::shared_ptr< SeriesHeader >, void >
422 : {
423 0 : void operator() ( ::boost::shared_ptr< SeriesHeader > spHeader )
424 : {
425 0 : spHeader->applyChanges();
426 0 : }
427 : };
428 :
429 : } // namespace impl
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 0 : DataBrowser::DataBrowser( Window* pParent, WinBits nStyle, bool bLiveUpdate ) :
474 : ::svt::EditBrowseBox( pParent, nStyle, EBBF_SMART_TAB_TRAVEL | EBBF_HANDLE_COLUMN_TEXT, BROWSER_STANDARD_FLAGS ),
475 : m_nSeekRow( 0 ),
476 : m_bIsReadOnly( false ),
477 : m_bIsDirty( false ),
478 : m_bLiveUpdate( bLiveUpdate ),
479 : m_bDataValid( true ),
480 0 : m_aNumberEditField( & EditBrowseBox::GetDataWindow(), WB_NOBORDER ),
481 0 : m_aTextEditField( & EditBrowseBox::GetDataWindow(), WB_NOBORDER ),
482 0 : m_rNumberEditController( new ::svt::FormattedFieldCellController( & m_aNumberEditField )),
483 0 : m_rTextEditController( new ::svt::EditCellController( & m_aTextEditField ))
484 : {
485 : double fNan;
486 0 : ::rtl::math::setNan( & fNan );
487 0 : m_aNumberEditField.SetDefaultValue( fNan );
488 0 : m_aNumberEditField.TreatAsNumber( true );
489 0 : RenewTable();
490 0 : SetClean();
491 0 : }
492 :
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 0 : && ( 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( 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, "%COLUMNNUMBER", OUString::number( 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 : Dialog* pDialog = GetParentDialog();
599 0 : Window* pWin = pDialog->get<VclContainer>("columns");
600 0 : Window* pColorWin = pDialog->get<VclContainer>("colorcolumns");
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, pColorWin ));
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( "Color" ) >>= nColor ))
617 0 : spHeader->SetColor( Color( nColor ));
618 0 : spHeader->SetChartType( aIt->m_xChartType, aIt->m_bSwapXAndYAxis );
619 : spHeader->SetSeriesName(
620 : OUString( DataSeriesHelper::getDataSeriesLabel(
621 0 : aIt->m_xDataSeries,
622 0 : (aIt->m_xChartType.is() ?
623 0 : aIt->m_xChartType->getRoleOfSequenceForSeriesLabel() :
624 0 : OUString("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 : OUString DataBrowser::GetColString( sal_Int32 nColumnId ) const
640 : {
641 : OSL_ASSERT( m_apDataBrowserModel.get());
642 0 : if( nColumnId > 0 )
643 0 : return OUString( m_apDataBrowserModel->getRoleOfColumn( static_cast< sal_Int32 >( nColumnId ) - 1 ));
644 0 : return OUString();
645 : }
646 :
647 0 : OUString DataBrowser::GetRowString( sal_Int32 nRow ) const
648 : {
649 0 : return OUString::number(nRow + 1);
650 : }
651 :
652 0 : OUString DataBrowser::GetCellText( long nRow, sal_uInt16 nColumnId ) const
653 : {
654 0 : OUString 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 0 : aResult = 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 0 : aResult = 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( 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 0 : void DataBrowser::SetClean()
749 : {
750 0 : m_bIsDirty = false;
751 0 : }
752 :
753 0 : void DataBrowser::SetDirty()
754 : {
755 0 : if( !m_bLiveUpdate )
756 0 : m_bIsDirty = true;
757 0 : }
758 :
759 0 : void DataBrowser::CursorMoved()
760 : {
761 0 : EditBrowseBox::CursorMoved();
762 :
763 0 : if( GetUpdateMode() && m_aCursorMovedHdlLink.IsSet())
764 0 : m_aCursorMovedHdlLink.Call( this );
765 0 : }
766 :
767 0 : void DataBrowser::SetCellModifiedHdl( const Link& rLink )
768 : {
769 0 : m_aCellModifiedLink = rLink;
770 0 : }
771 :
772 0 : void DataBrowser::MouseButtonDown( const BrowserMouseEvent& rEvt )
773 : {
774 0 : if( !m_bDataValid )
775 0 : ShowWarningBox();
776 : else
777 0 : EditBrowseBox::MouseButtonDown( rEvt );
778 0 : }
779 :
780 0 : void DataBrowser::ShowWarningBox()
781 : {
782 : WarningBox(this, WinBits( WB_OK ),
783 0 : SCH_RESSTR(STR_INVALID_NUMBER)).Execute();
784 0 : }
785 :
786 0 : bool DataBrowser::ShowQueryBox()
787 : {
788 0 : QueryBox* pQueryBox = new QueryBox(this, WB_YES_NO, SCH_RESSTR(STR_DATA_EDITOR_INCORRECT_INPUT));
789 :
790 0 : return ( pQueryBox->Execute() == RET_YES );
791 : }
792 :
793 0 : bool DataBrowser::IsDataValid()
794 : {
795 0 : bool bValid = true;
796 0 : const sal_Int32 nRow = lcl_getRowInData( GetCurRow());
797 0 : const sal_Int32 nCol = lcl_getColumnInData( GetCurColumnId());
798 :
799 0 : if( m_apDataBrowserModel->getCellType( nCol, nRow ) == DataBrowserModel::NUMBER )
800 : {
801 0 : sal_uInt32 nDummy = 0;
802 0 : double fDummy = 0.0;
803 0 : OUString aText( m_aNumberEditField.GetText());
804 :
805 0 : if( !aText.isEmpty() &&
806 0 : m_spNumberFormatterWrapper.get() &&
807 0 : m_spNumberFormatterWrapper->getSvNumberFormatter() &&
808 : ! m_spNumberFormatterWrapper->getSvNumberFormatter()->IsNumberFormat(
809 0 : aText, nDummy, fDummy ))
810 : {
811 0 : bValid = false;
812 0 : }
813 : }
814 :
815 0 : return bValid;
816 : }
817 :
818 0 : bool DataBrowser::IsEnableItem()
819 : {
820 0 : return m_bDataValid;
821 : }
822 :
823 0 : void DataBrowser::CellModified()
824 : {
825 0 : m_bDataValid = IsDataValid();
826 0 : SetDirty();
827 0 : if( m_aCellModifiedLink.IsSet())
828 0 : m_aCursorMovedHdlLink.Call( this );
829 0 : }
830 :
831 0 : void DataBrowser::SetDataFromModel(
832 : const Reference< chart2::XChartDocument > & xChartDoc,
833 : const Reference< uno::XComponentContext > & xContext )
834 : {
835 0 : if( m_bLiveUpdate )
836 : {
837 0 : m_xChartDoc.set( xChartDoc );
838 : }
839 : else
840 : {
841 0 : Reference< util::XCloneable > xCloneable( xChartDoc, uno::UNO_QUERY );
842 0 : if( xCloneable.is())
843 0 : m_xChartDoc.set( xCloneable->createClone(), uno::UNO_QUERY );
844 : }
845 :
846 0 : m_apDataBrowserModel.reset( new DataBrowserModel( m_xChartDoc, xContext ));
847 : m_spNumberFormatterWrapper.reset(
848 : new NumberFormatterWrapper(
849 0 : Reference< util::XNumberFormatsSupplier >( m_xChartDoc, uno::UNO_QUERY )));
850 :
851 0 : if( m_spNumberFormatterWrapper.get() )
852 0 : m_aNumberEditField.SetFormatter( m_spNumberFormatterWrapper->getSvNumberFormatter() );
853 :
854 0 : RenewTable();
855 :
856 0 : const sal_Int32 nColCnt = m_apDataBrowserModel->getColumnCount();
857 0 : const sal_Int32 nRowCnt = m_apDataBrowserModel->getMaxRowCount();
858 0 : if( nRowCnt && nColCnt )
859 : {
860 0 : GoToRow( 0 );
861 0 : GoToColumnId( 1 );
862 : }
863 0 : SetClean();
864 0 : }
865 :
866 0 : void DataBrowser::InsertColumn()
867 : {
868 0 : sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders );
869 :
870 0 : if( nColIdx >= 0 &&
871 0 : m_apDataBrowserModel.get())
872 : {
873 : // save changes made to edit-field
874 0 : if( IsModified() )
875 0 : SaveModified();
876 :
877 0 : m_apDataBrowserModel->insertDataSeries( nColIdx );
878 0 : RenewTable();
879 : }
880 0 : }
881 :
882 0 : void DataBrowser::InsertTextColumn()
883 : {
884 0 : sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders );
885 :
886 0 : if( nColIdx >= 0 &&
887 0 : m_apDataBrowserModel.get())
888 : {
889 : // save changes made to edit-field
890 0 : if( IsModified() )
891 0 : SaveModified();
892 :
893 0 : m_apDataBrowserModel->insertComplexCategoryLevel( nColIdx );
894 0 : RenewTable();
895 : }
896 0 : }
897 :
898 0 : void DataBrowser::RemoveColumn()
899 : {
900 0 : sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders );
901 :
902 0 : if( nColIdx >= 0 &&
903 0 : m_apDataBrowserModel.get())
904 : {
905 : // save changes made to edit-field
906 0 : if( IsModified() )
907 0 : SaveModified();
908 :
909 0 : m_bDataValid = true;
910 0 : m_apDataBrowserModel->removeDataSeriesOrComplexCategoryLevel( nColIdx );
911 0 : RenewTable();
912 : }
913 0 : }
914 :
915 0 : void DataBrowser::InsertRow()
916 : {
917 0 : sal_Int32 nRowIdx = lcl_getRowInData( GetCurRow());
918 :
919 0 : if( nRowIdx >= 0 &&
920 0 : m_apDataBrowserModel.get())
921 : {
922 : // save changes made to edit-field
923 0 : if( IsModified() )
924 0 : SaveModified();
925 :
926 0 : m_apDataBrowserModel->insertDataPointForAllSeries( nRowIdx );
927 0 : RenewTable();
928 : }
929 0 : }
930 :
931 0 : void DataBrowser::RemoveRow()
932 : {
933 0 : sal_Int32 nRowIdx = lcl_getRowInData( GetCurRow());
934 :
935 0 : if( nRowIdx >= 0 &&
936 0 : m_apDataBrowserModel.get())
937 : {
938 : // save changes made to edit-field
939 0 : if( IsModified() )
940 0 : SaveModified();
941 :
942 0 : m_bDataValid = true;
943 0 : m_apDataBrowserModel->removeDataPointForAllSeries( nRowIdx );
944 0 : RenewTable();
945 : }
946 0 : }
947 :
948 0 : void DataBrowser::SwapColumn()
949 : {
950 0 : sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders );
951 :
952 0 : if( nColIdx >= 0 &&
953 0 : m_apDataBrowserModel.get())
954 : {
955 : // save changes made to edit-field
956 0 : if( IsModified() )
957 0 : SaveModified();
958 :
959 0 : m_apDataBrowserModel->swapDataSeries( nColIdx );
960 :
961 : // keep cursor in swapped column
962 0 : if( GetCurColumnId() < ColCount() - 1 )
963 : {
964 0 : Dispatch( BROWSER_CURSORRIGHT );
965 : }
966 0 : RenewTable();
967 : }
968 0 : }
969 :
970 0 : void DataBrowser::SwapRow()
971 : {
972 0 : sal_Int32 nRowIdx = lcl_getRowInData( GetCurRow());
973 :
974 0 : if( nRowIdx >= 0 &&
975 0 : m_apDataBrowserModel.get())
976 : {
977 : // save changes made to edit-field
978 0 : if( IsModified() )
979 0 : SaveModified();
980 :
981 0 : m_apDataBrowserModel->swapDataPointForAllSeries( nRowIdx );
982 :
983 : // keep cursor in swapped row
984 0 : if( GetCurRow() < GetRowCount() - 1 )
985 : {
986 0 : Dispatch( BROWSER_CURSORDOWN );
987 : }
988 0 : RenewTable();
989 : }
990 0 : }
991 :
992 0 : void DataBrowser::SetCursorMovedHdl( const Link& rLink )
993 : {
994 0 : m_aCursorMovedHdlLink = rLink;
995 0 : }
996 :
997 : // implementations for ::svt::EditBrowseBox (pure virtual methods)
998 0 : void DataBrowser::PaintCell(
999 : OutputDevice& rDev, const Rectangle& rRect, sal_uInt16 nColumnId ) const
1000 : {
1001 0 : Point aPos( rRect.TopLeft());
1002 0 : aPos.X() += 1;
1003 :
1004 0 : OUString aText = GetCellText( m_nSeekRow, nColumnId );
1005 0 : Size TxtSize( GetDataWindow().GetTextWidth( aText ), GetDataWindow().GetTextHeight());
1006 :
1007 : // clipping
1008 0 : if( aPos.X() < rRect.Right() || aPos.X() + TxtSize.Width() > rRect.Right() ||
1009 0 : aPos.Y() < rRect.Top() || aPos.Y() + TxtSize.Height() > rRect.Bottom())
1010 0 : rDev.SetClipRegion(Region(rRect));
1011 :
1012 : // allow for a disabled control ...
1013 0 : sal_Bool bEnabled = IsEnabled();
1014 0 : Color aOriginalColor = rDev.GetTextColor();
1015 0 : if( ! bEnabled )
1016 0 : rDev.SetTextColor( GetSettings().GetStyleSettings().GetDisableColor() );
1017 :
1018 : // draw the text
1019 0 : rDev.DrawText( aPos, aText );
1020 :
1021 : // reset the color (if necessary)
1022 0 : if( ! bEnabled )
1023 0 : rDev.SetTextColor( aOriginalColor );
1024 :
1025 0 : if( rDev.IsClipRegion())
1026 0 : rDev.SetClipRegion();
1027 0 : }
1028 :
1029 0 : bool DataBrowser::SeekRow( long nRow )
1030 : {
1031 0 : if( ! EditBrowseBox::SeekRow( nRow ))
1032 0 : return false;
1033 :
1034 0 : if( nRow < 0 )
1035 0 : m_nSeekRow = - 1;
1036 : else
1037 0 : m_nSeekRow = nRow;
1038 :
1039 0 : return true;
1040 : }
1041 :
1042 0 : bool DataBrowser::IsTabAllowed( bool bForward ) const
1043 : {
1044 0 : long nRow = GetCurRow();
1045 0 : long nCol = GetCurColumnId();
1046 :
1047 : // column 0 is header-column
1048 : long nBadCol = bForward
1049 0 : ? GetColumnCount() - 1
1050 0 : : 1;
1051 : long nBadRow = bForward
1052 0 : ? GetRowCount() - 1
1053 0 : : 0;
1054 :
1055 0 : if( !m_bDataValid )
1056 : {
1057 0 : const_cast< DataBrowser* >( this )->ShowWarningBox();
1058 0 : return false;
1059 : }
1060 :
1061 0 : return ( nRow != nBadRow ||
1062 0 : nCol != nBadCol );
1063 : }
1064 :
1065 0 : ::svt::CellController* DataBrowser::GetController( long nRow, sal_uInt16 nCol )
1066 : {
1067 0 : if( m_bIsReadOnly )
1068 0 : return 0;
1069 :
1070 0 : if( CellContainsNumbers( nRow, nCol ))
1071 : {
1072 0 : m_aNumberEditField.UseInputStringForFormatting();
1073 0 : m_aNumberEditField.SetFormatKey( GetNumberFormatKey( nRow, nCol ));
1074 0 : return m_rNumberEditController;
1075 : }
1076 :
1077 0 : return m_rTextEditController;
1078 : }
1079 :
1080 0 : void DataBrowser::InitController(
1081 : ::svt::CellControllerRef& rController, long nRow, sal_uInt16 nCol )
1082 : {
1083 0 : if( rController == m_rTextEditController )
1084 : {
1085 0 : OUString aText( GetCellText( nRow, nCol ) );
1086 0 : m_aTextEditField.SetText( aText );
1087 0 : m_aTextEditField.SetSelection( Selection( 0, aText.getLength() ));
1088 : }
1089 0 : else if( rController == m_rNumberEditController )
1090 : {
1091 : // treat invalid and empty text as Nan
1092 0 : m_aNumberEditField.EnableNotANumber( true );
1093 0 : if( ::rtl::math::isNan( GetCellNumber( nRow, nCol )))
1094 0 : m_aNumberEditField.SetTextValue( OUString());
1095 : else
1096 0 : m_aNumberEditField.SetValue( GetCellNumber( nRow, nCol ) );
1097 0 : OUString aText( m_aNumberEditField.GetText());
1098 0 : m_aNumberEditField.SetSelection( Selection( 0, aText.getLength()));
1099 : }
1100 : else
1101 : {
1102 : OSL_FAIL( "Invalid Controller" );
1103 : }
1104 0 : }
1105 :
1106 0 : bool DataBrowser::CellContainsNumbers( sal_Int32 nRow, sal_uInt16 nCol ) const
1107 : {
1108 0 : if( ! m_apDataBrowserModel.get())
1109 0 : return false;
1110 0 : return (m_apDataBrowserModel->getCellType( lcl_getColumnInData( nCol ), lcl_getRowInData( nRow )) ==
1111 0 : DataBrowserModel::NUMBER);
1112 : }
1113 :
1114 0 : sal_uInt32 DataBrowser::GetNumberFormatKey( sal_Int32 nRow, sal_uInt16 nCol ) const
1115 : {
1116 0 : if( ! m_apDataBrowserModel.get())
1117 0 : return 0;
1118 0 : return m_apDataBrowserModel->getNumberFormatKey( lcl_getColumnInData( nCol ), lcl_getRowInData( nRow ));
1119 : }
1120 :
1121 0 : bool DataBrowser::isDateString( const OUString& aInputString, double& fOutDateValue )
1122 : {
1123 0 : sal_uInt32 nNumberFormat=0;
1124 0 : SvNumberFormatter* pSvNumberFormatter = m_spNumberFormatterWrapper.get() ? m_spNumberFormatterWrapper->getSvNumberFormatter() : 0;
1125 0 : if( !aInputString.isEmpty() && pSvNumberFormatter && pSvNumberFormatter->IsNumberFormat( aInputString, nNumberFormat, fOutDateValue ) )
1126 : {
1127 0 : Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( m_xChartDoc, uno::UNO_QUERY );
1128 0 : Reference< util::XNumberFormats > xNumberFormats;
1129 0 : if( xNumberFormatsSupplier.is() )
1130 0 : xNumberFormats = Reference< util::XNumberFormats >( xNumberFormatsSupplier->getNumberFormats() );
1131 0 : if( DiagramHelper::isDateNumberFormat( nNumberFormat, xNumberFormats ) )
1132 0 : return true;
1133 : }
1134 0 : return false;
1135 : }
1136 :
1137 0 : bool DataBrowser::SaveModified()
1138 : {
1139 0 : if( ! IsModified() )
1140 0 : return true;
1141 :
1142 0 : bool bChangeValid = true;
1143 :
1144 0 : const sal_Int32 nRow = lcl_getRowInData( GetCurRow());
1145 0 : const sal_Int32 nCol = lcl_getColumnInData( GetCurColumnId());
1146 :
1147 : OSL_ENSURE( nRow >= 0 || nCol >= 0, "This cell should not be modified!" );
1148 :
1149 0 : SvNumberFormatter* pSvNumberFormatter = m_spNumberFormatterWrapper.get() ? m_spNumberFormatterWrapper->getSvNumberFormatter() : 0;
1150 0 : switch( m_apDataBrowserModel->getCellType( nCol, nRow ))
1151 : {
1152 : case DataBrowserModel::NUMBER:
1153 : {
1154 0 : sal_uInt32 nDummy = 0;
1155 0 : double fDummy = 0.0;
1156 0 : OUString aText( m_aNumberEditField.GetText());
1157 : // an empty string is valid, if no numberformatter exists, all
1158 : // values are treated as valid
1159 0 : if( !aText.isEmpty() && pSvNumberFormatter &&
1160 0 : ! pSvNumberFormatter->IsNumberFormat( aText, nDummy, fDummy ) )
1161 : {
1162 0 : bChangeValid = false;
1163 : }
1164 : else
1165 : {
1166 0 : double fData = m_aNumberEditField.GetValue();
1167 0 : bChangeValid = m_apDataBrowserModel->setCellNumber( nCol, nRow, fData );
1168 0 : }
1169 : }
1170 0 : break;
1171 : case DataBrowserModel::TEXTORDATE:
1172 : {
1173 0 : OUString aText( m_aTextEditField.GetText() );
1174 0 : double fDateValue = 0.0;
1175 0 : bChangeValid = false;
1176 0 : if( isDateString( aText, fDateValue ) )
1177 0 : bChangeValid = m_apDataBrowserModel->setCellAny( nCol, nRow, uno::makeAny( fDateValue ) );
1178 0 : if(!bChangeValid)
1179 0 : bChangeValid = m_apDataBrowserModel->setCellAny( nCol, nRow, uno::makeAny( aText ) );
1180 : }
1181 0 : break;
1182 : case DataBrowserModel::TEXT:
1183 : {
1184 0 : OUString aText( m_aTextEditField.GetText());
1185 0 : bChangeValid = m_apDataBrowserModel->setCellText( nCol, nRow, aText );
1186 : }
1187 0 : break;
1188 : }
1189 :
1190 : // the first valid change changes this to true
1191 0 : if( bChangeValid )
1192 : {
1193 0 : RowModified( GetCurRow(), GetCurColumnId());
1194 0 : ::svt::CellController* pCtrl = GetController( GetCurRow(), GetCurColumnId());
1195 0 : if( pCtrl )
1196 0 : pCtrl->ClearModified();
1197 0 : SetDirty();
1198 : }
1199 :
1200 0 : return bChangeValid;
1201 : }
1202 :
1203 0 : bool DataBrowser::EndEditing()
1204 : {
1205 0 : if( IsModified())
1206 0 : SaveModified();
1207 :
1208 : // apply changes made to series headers
1209 0 : ::std::for_each( m_aSeriesHeaders.begin(), m_aSeriesHeaders.end(), impl::applyChangesFunctor());
1210 :
1211 0 : if( m_bDataValid )
1212 0 : return true;
1213 : else
1214 0 : return ShowQueryBox();
1215 : }
1216 :
1217 0 : sal_Int16 DataBrowser::GetFirstVisibleColumNumber() const
1218 : {
1219 0 : return GetFirstVisibleColNumber();
1220 : }
1221 :
1222 0 : void DataBrowser::ColumnResized( sal_uInt16 nColId )
1223 : {
1224 0 : sal_Bool bLastUpdateMode = GetUpdateMode();
1225 0 : SetUpdateMode( false );
1226 :
1227 0 : EditBrowseBox::ColumnResized( nColId );
1228 0 : ImplAdjustHeaderControls();
1229 0 : SetUpdateMode( bLastUpdateMode );
1230 0 : }
1231 :
1232 0 : void DataBrowser::EndScroll()
1233 : {
1234 0 : sal_Bool bLastUpdateMode = GetUpdateMode();
1235 0 : SetUpdateMode( false );
1236 :
1237 0 : EditBrowseBox::EndScroll();
1238 0 : RenewSeriesHeaders();
1239 :
1240 0 : SetUpdateMode( bLastUpdateMode );
1241 0 : }
1242 :
1243 0 : void DataBrowser::RenewSeriesHeaders()
1244 : {
1245 0 : Dialog* pDialog = GetParentDialog();
1246 0 : Window* pWin = pDialog->get<VclContainer>("columns");
1247 0 : Window* pColorWin = pDialog->get<VclContainer>("colorcolumns");
1248 :
1249 0 : clearHeaders();
1250 0 : DataBrowserModel::tDataHeaderVector aHeaders( m_apDataBrowserModel->getDataHeaders());
1251 0 : Link aFocusLink( LINK( this, DataBrowser, SeriesHeaderGotFocus ));
1252 0 : Link aSeriesHeaderChangedLink( LINK( this, DataBrowser, SeriesHeaderChanged ));
1253 :
1254 0 : for( DataBrowserModel::tDataHeaderVector::const_iterator aIt( aHeaders.begin());
1255 0 : aIt != aHeaders.end(); ++aIt )
1256 : {
1257 0 : ::boost::shared_ptr< impl::SeriesHeader > spHeader( new impl::SeriesHeader( pWin, pColorWin ));
1258 0 : Reference< beans::XPropertySet > xSeriesProp( aIt->m_xDataSeries, uno::UNO_QUERY );
1259 0 : sal_Int32 nColor = 0;
1260 0 : if( xSeriesProp.is() &&
1261 0 : ( xSeriesProp->getPropertyValue( "Color" ) >>= nColor ))
1262 0 : spHeader->SetColor( Color( nColor ));
1263 0 : spHeader->SetChartType( aIt->m_xChartType, aIt->m_bSwapXAndYAxis );
1264 : spHeader->SetSeriesName(
1265 : DataSeriesHelper::getDataSeriesLabel(
1266 0 : aIt->m_xDataSeries,
1267 0 : (aIt->m_xChartType.is() ?
1268 0 : aIt->m_xChartType->getRoleOfSequenceForSeriesLabel() :
1269 0 : OUString( "values-y"))));
1270 0 : spHeader->SetRange( aIt->m_nStartColumn + 1, aIt->m_nEndColumn + 1 );
1271 0 : spHeader->SetGetFocusHdl( aFocusLink );
1272 0 : spHeader->SetEditChangedHdl( aSeriesHeaderChangedLink );
1273 0 : m_aSeriesHeaders.push_back( spHeader );
1274 0 : }
1275 :
1276 0 : ImplAdjustHeaderControls();
1277 0 : }
1278 :
1279 0 : void DataBrowser::ImplAdjustHeaderControls()
1280 : {
1281 0 : sal_uInt16 nColCount = this->GetColumnCount();
1282 0 : sal_uInt32 nCurrentPos = this->GetPosPixel().getX();
1283 0 : sal_uInt32 nMaxPos = nCurrentPos + this->GetOutputSizePixel().getWidth();
1284 0 : sal_uInt32 nStartPos = nCurrentPos;
1285 :
1286 : // width of header column
1287 0 : nCurrentPos += this->GetColumnWidth( 0 );
1288 :
1289 0 : Dialog* pDialog = GetParentDialog();
1290 0 : Window* pWin = pDialog->get<VclContainer>("columns");
1291 0 : Window* pColorWin = pDialog->get<VclContainer>("colorcolumns");
1292 0 : pWin->set_margin_left(nCurrentPos);
1293 0 : pColorWin->set_margin_left(nCurrentPos);
1294 :
1295 0 : tSeriesHeaderContainer::iterator aIt( m_aSeriesHeaders.begin());
1296 0 : sal_uInt16 i = this->GetFirstVisibleColumNumber();
1297 0 : while( (aIt != m_aSeriesHeaders.end()) && ((*aIt)->GetStartColumn() < i) )
1298 : {
1299 0 : (*aIt)->Hide();
1300 0 : ++aIt;
1301 : }
1302 0 : for( ; i < nColCount && aIt != m_aSeriesHeaders.end(); ++i )
1303 : {
1304 0 : if( (*aIt)->GetStartColumn() == i )
1305 0 : nStartPos = nCurrentPos;
1306 :
1307 0 : nCurrentPos += (this->GetColumnWidth( i ));
1308 :
1309 0 : if( (*aIt)->GetEndColumn() == i )
1310 : {
1311 0 : if( nStartPos < nMaxPos )
1312 : {
1313 0 : (*aIt)->SetPixelWidth( nCurrentPos - nStartPos - 3 );
1314 0 : (*aIt)->Show();
1315 :
1316 0 : if (pWin)
1317 : {
1318 0 : pWin->set_margin_left(nStartPos);
1319 0 : pColorWin->set_margin_left(nStartPos);
1320 0 : pWin = pColorWin = NULL;
1321 : }
1322 :
1323 : }
1324 : else
1325 0 : (*aIt)->Hide();
1326 0 : ++aIt;
1327 : }
1328 : }
1329 0 : }
1330 :
1331 0 : IMPL_LINK( DataBrowser, SeriesHeaderGotFocus, impl::SeriesHeaderEdit*, pEdit )
1332 : {
1333 0 : if( pEdit )
1334 : {
1335 0 : pEdit->SetShowWarningBox( !m_bDataValid );
1336 :
1337 0 : if( !m_bDataValid )
1338 0 : GoToCell( 0, 0 );
1339 : else
1340 : {
1341 0 : MakeFieldVisible( GetCurRow(), static_cast< sal_uInt16 >( pEdit->getStartColumn()), true /* bComplete */ );
1342 0 : ActivateCell();
1343 0 : m_aCursorMovedHdlLink.Call( this );
1344 : }
1345 : }
1346 0 : return 0;
1347 : }
1348 :
1349 0 : IMPL_LINK( DataBrowser, SeriesHeaderChanged, impl::SeriesHeaderEdit*, pEdit )
1350 : {
1351 0 : if( pEdit )
1352 : {
1353 : Reference< chart2::XDataSeries > xSeries(
1354 0 : m_apDataBrowserModel->getDataSeriesByColumn( pEdit->getStartColumn() - 1 ));
1355 0 : Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY );
1356 0 : if( xSource.is())
1357 : {
1358 : Reference< chart2::XChartType > xChartType(
1359 0 : m_apDataBrowserModel->getHeaderForSeries( xSeries ).m_xChartType );
1360 0 : if( xChartType.is())
1361 : {
1362 : Reference< chart2::data::XLabeledDataSequence > xLabeledSeq(
1363 0 : DataSeriesHelper::getDataSequenceByRole( xSource, xChartType->getRoleOfSequenceForSeriesLabel()));
1364 0 : if( xLabeledSeq.is())
1365 : {
1366 0 : Reference< container::XIndexReplace > xIndexReplace( xLabeledSeq->getLabel(), uno::UNO_QUERY );
1367 0 : if( xIndexReplace.is())
1368 0 : xIndexReplace->replaceByIndex(
1369 0 : 0, uno::makeAny( OUString( pEdit->GetText())));
1370 0 : }
1371 0 : }
1372 0 : }
1373 : }
1374 0 : return 0;
1375 : }
1376 :
1377 0 : } // namespace chart
1378 :
1379 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|