Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / chart2 / source / controller / dialogs / DataBrowser.cxx
blob10c1ecaffe44c2235af8d0071ab943d2bfd1fdb1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <svl/zforlist.hxx>
22 #include "DataBrowser.hxx"
23 #include "DataBrowserModel.hxx"
24 #include <strings.hrc>
25 #include <DataSeriesHelper.hxx>
26 #include <DiagramHelper.hxx>
27 #include <CommonConverters.hxx>
28 #include <NumberFormatterWrapper.hxx>
29 #include <servicenames_charttypes.hxx>
30 #include <ResId.hxx>
31 #include <bitmaps.hlst>
32 #include <helpids.h>
34 #include <vcl/weld.hxx>
35 #include <vcl/settings.hxx>
36 #include <vcl/svapp.hxx>
37 #include <vcl/virdev.hxx>
38 #include <rtl/math.hxx>
39 #include <osl/diagnose.h>
40 #include <toolkit/helper/vclunohelper.hxx>
42 #include <com/sun/star/util/XCloneable.hpp>
43 #include <com/sun/star/chart2/XChartDocument.hpp>
44 #include <com/sun/star/chart2/XChartType.hpp>
45 #include <com/sun/star/container/XIndexReplace.hpp>
47 #include <algorithm>
50 using namespace ::com::sun::star;
51 using ::com::sun::star::uno::Reference;
53 using namespace ::svt;
55 namespace
57 /* BrowserMode::COLUMNSELECTION : single cells may be selected rather than only
58 entire rows
59 BrowserMode::(H|V)LINES : show horizontal or vertical grid-lines
60 BrowserMode::AUTO_(H|V)SCROLL : scroll automated horizontally or vertically when
61 cursor is moved beyond the edge of the dialog
62 BrowserMode::HIDESELECT : Do not mark the current row with selection color
63 (usually blue)
64 ! BrowserMode::HIDECURSOR would prevent flickering in edit fields, but navigating
65 with shift up/down, and entering non-editable cells would be problematic,
66 e.g. the first cell, or when being in read-only mode
68 const BrowserMode BrowserStdFlags = BrowserMode::COLUMNSELECTION |
69 BrowserMode::HLINES | BrowserMode::VLINES |
70 BrowserMode::AUTO_HSCROLL | BrowserMode::AUTO_VSCROLL |
71 BrowserMode::HIDESELECT;
73 sal_Int32 lcl_getRowInData( long nRow )
75 return static_cast< sal_Int32 >( nRow );
78 sal_Int32 lcl_getColumnInData( sal_uInt16 nCol )
80 return static_cast< sal_Int32 >( nCol ) - 1;
83 } // anonymous namespace
85 namespace chart
88 namespace impl
91 class SeriesHeaderEdit
93 public:
94 explicit SeriesHeaderEdit(std::unique_ptr<weld::Entry> xControl);
96 void setStartColumn( sal_Int32 nStartColumn );
97 sal_Int32 getStartColumn() const { return m_nStartColumn;}
98 void SetShowWarningBox( bool bShowWarning );
100 OUString GetText() const { return m_xControl->get_text(); }
101 void SetText(const OUString& rText) { m_xControl->set_text(rText); }
103 bool HasFocus() const { return m_xControl->has_focus(); }
105 void Hide() { m_xControl->hide(); }
106 void Show() { m_xControl->show(); }
108 void set_size_request(int nWidth, int nHeight) { m_xControl->set_size_request(nWidth, nHeight); }
109 void set_margin_left(int nLeft) { m_xControl->set_margin_left(nLeft); }
111 void SetModifyHdl(const Link<SeriesHeaderEdit&,void>& rLink) { m_aModifyHdl = rLink; }
112 void SetGetFocusHdl(const Link<SeriesHeaderEdit&,void>& rLink) { m_aFocusInHdl = rLink; }
114 private:
115 DECL_LINK(NameEdited, weld::Entry&, void);
116 DECL_LINK(NameFocusIn, weld::Widget&, void);
117 DECL_LINK(MousePressHdl, const MouseEvent&, bool);
119 std::unique_ptr<weld::Entry> m_xControl;
120 Link<SeriesHeaderEdit&,void> m_aModifyHdl;
121 Link<SeriesHeaderEdit&,void> m_aFocusInHdl;
122 sal_Int32 m_nStartColumn;
123 bool m_bShowWarningBox;
126 SeriesHeaderEdit::SeriesHeaderEdit(std::unique_ptr<weld::Entry> xControl)
127 : m_xControl(std::move(xControl))
128 , m_nStartColumn(0)
129 , m_bShowWarningBox(false)
131 m_xControl->set_help_id(HID_SCH_DATA_SERIES_LABEL);
132 m_xControl->connect_changed(LINK(this, SeriesHeaderEdit, NameEdited));
133 m_xControl->connect_focus_in(LINK(this, SeriesHeaderEdit, NameFocusIn));
134 m_xControl->connect_mouse_press(LINK(this, SeriesHeaderEdit, MousePressHdl));
137 IMPL_LINK_NOARG(SeriesHeaderEdit, NameEdited, weld::Entry&, void)
139 m_aModifyHdl.Call(*this);
142 IMPL_LINK_NOARG(SeriesHeaderEdit, NameFocusIn, weld::Widget&, void)
144 m_aFocusInHdl.Call(*this);
147 void SeriesHeaderEdit::setStartColumn( sal_Int32 nStartColumn )
149 m_nStartColumn = nStartColumn;
152 void SeriesHeaderEdit::SetShowWarningBox( bool bShowWarning )
154 m_bShowWarningBox = bShowWarning;
157 IMPL_LINK_NOARG(SeriesHeaderEdit, MousePressHdl, const MouseEvent&, bool)
159 if (m_bShowWarningBox)
161 std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(m_xControl.get(),
162 VclMessageType::Warning, VclButtonsType::Ok,
163 SchResId(STR_INVALID_NUMBER)));
164 xWarn->run();
167 return false;
170 class SeriesHeader
172 public:
173 explicit SeriesHeader(weld::Container* pParent, weld::Container* pColorParent);
174 ~SeriesHeader();
176 void SetColor( const Color & rCol );
177 void SetPos();
178 void SetWidth( sal_Int32 nWidth );
179 void SetChartType( const Reference< chart2::XChartType > & xChartType,
180 bool bSwapXAndYAxis );
181 void SetSeriesName( const OUString & rName );
182 void SetRange( sal_Int32 nStartCol, sal_Int32 nEndCol );
184 void SetPixelWidth( sal_Int32 nWidth );
186 sal_Int32 GetStartColumn() const { return m_nStartCol;}
187 sal_Int32 GetEndColumn() const { return m_nEndCol;}
189 static const sal_Int32 nSymbolHeight = 10;
190 static const sal_Int32 nSymbolDistance = 2;
192 static sal_Int32 GetRelativeAppFontXPosForNameField() { return nSymbolHeight + nSymbolDistance; }
194 void Show();
195 void Hide();
197 /** call this before destroying the class. This notifies the listeners to
198 changes of the edit field for the series name.
200 void applyChanges();
202 void SetGetFocusHdl(const Link<SeriesHeaderEdit&,void>& rLink);
204 void SetEditChangedHdl( const Link<SeriesHeaderEdit&,void> & rLink );
206 bool HasFocus() const;
208 private:
209 Timer m_aUpdateDataTimer;
211 std::unique_ptr<weld::Builder> m_xBuilder1;
212 std::unique_ptr<weld::Builder> m_xBuilder2;
214 std::unique_ptr<weld::Container> m_xContainer1;
215 std::unique_ptr<weld::Container> m_xContainer2;
216 std::unique_ptr<weld::Image> m_spSymbol;
217 std::unique_ptr<SeriesHeaderEdit> m_spSeriesName;
218 std::unique_ptr<weld::Image> m_spColorBar;
219 VclPtr< OutputDevice> m_xDevice;
220 Link<SeriesHeaderEdit&,void> m_aChangeLink;
221 Color m_aColor;
223 void notifyChanges();
224 DECL_LINK( ImplUpdateDataHdl, Timer*, void );
225 DECL_LINK( SeriesNameEdited, SeriesHeaderEdit&, void );
227 static OUString GetChartTypeImage(
228 const Reference< chart2::XChartType > & xChartType,
229 bool bSwapXAndYAxis
232 sal_Int32 m_nStartCol, m_nEndCol;
233 sal_Int32 m_nWidth;
234 bool m_bSeriesNameChangePending;
237 SeriesHeader::SeriesHeader(weld::Container* pParent, weld::Container* pColorParent)
238 : m_aUpdateDataTimer("UpdateDataTimer")
239 , m_xBuilder1(Application::CreateBuilder(pParent, "modules/schart/ui/columnfragment.ui"))
240 , m_xBuilder2(Application::CreateBuilder(pColorParent, "modules/schart/ui/imagefragment.ui"))
241 , m_xContainer1(m_xBuilder1->weld_container("container"))
242 , m_xContainer2(m_xBuilder2->weld_container("container"))
243 , m_spSymbol(m_xBuilder1->weld_image("image"))
244 , m_spSeriesName(new SeriesHeaderEdit(m_xBuilder1->weld_entry("entry")))
245 , m_spColorBar(m_xBuilder2->weld_image("image"))
246 , m_xDevice(Application::GetDefaultDevice())
247 , m_nStartCol( 0 )
248 , m_nEndCol( 0 )
249 , m_nWidth( 42 )
250 , m_bSeriesNameChangePending( false )
252 m_aUpdateDataTimer.SetInvokeHandler(LINK(this, SeriesHeader, ImplUpdateDataHdl));
253 m_aUpdateDataTimer.SetDebugName( "SeriesHeader UpdateDataTimer" );
254 m_aUpdateDataTimer.SetTimeout(4 * EDIT_UPDATEDATA_TIMEOUT);
256 m_spSeriesName->SetModifyHdl(LINK(this, SeriesHeader, SeriesNameEdited));
257 Show();
260 SeriesHeader::~SeriesHeader()
262 m_aUpdateDataTimer.Stop();
263 m_xDevice.clear();
264 m_xBuilder2.reset();
265 m_xBuilder1.reset();
268 void SeriesHeader::notifyChanges()
270 m_aChangeLink.Call(*m_spSeriesName);
271 m_bSeriesNameChangePending = false;
274 void SeriesHeader::applyChanges()
276 if( m_bSeriesNameChangePending )
278 notifyChanges();
282 void SeriesHeader::SetColor( const Color & rCol )
284 m_aColor = rCol;
287 void SeriesHeader::SetPos()
289 // chart type symbol
290 Size aSize( nSymbolHeight, nSymbolHeight );
291 aSize = m_xDevice->LogicToPixel(aSize, MapMode(MapUnit::MapAppFont));
292 m_spSymbol->set_size_request(aSize.Width(), aSize.Height());
294 // series name edit field
295 aSize.setWidth(nSymbolDistance);
296 aSize = m_xDevice->LogicToPixel(aSize, MapMode(MapUnit::MapAppFont));
297 m_spSeriesName->set_margin_left(aSize.Width() + 2);
298 aSize.setWidth( m_nWidth - nSymbolHeight - nSymbolDistance );
299 sal_Int32 nHeight = 12;
300 aSize.setHeight( nHeight );
301 aSize = m_xDevice->LogicToPixel(aSize, MapMode(MapUnit::MapAppFont));
302 m_spSeriesName->set_size_request(aSize.Width(), aSize.Height());
304 // color bar
305 aSize.setWidth(1);
306 aSize = m_xDevice->LogicToPixel(aSize, MapMode(MapUnit::MapAppFont));
307 m_spColorBar->set_margin_left(aSize.Width() + 2);
308 nHeight = 3;
309 aSize.setWidth( m_nWidth - 1 );
310 aSize.setHeight( nHeight );
311 aSize = m_xDevice->LogicToPixel(aSize, MapMode(MapUnit::MapAppFont));
312 m_spColorBar->set_size_request(aSize.Width(), aSize.Height());
314 auto xVirDev(m_spColorBar->create_virtual_device());
315 xVirDev->SetOutputSizePixel(aSize);
316 xVirDev->SetFillColor(m_aColor);
317 xVirDev->SetLineColor(m_aColor);
318 xVirDev->DrawRect(tools::Rectangle(Point(0, 0), aSize));
319 m_spColorBar->set_image(xVirDev.get());
322 void SeriesHeader::SetWidth( sal_Int32 nWidth )
324 m_nWidth = nWidth;
325 SetPos();
328 void SeriesHeader::SetPixelWidth( sal_Int32 nWidth )
330 SetWidth( m_xDevice->PixelToLogic(Size(nWidth, 0), MapMode(MapUnit::MapAppFont)).getWidth());
333 void SeriesHeader::SetChartType(
334 const Reference< chart2::XChartType > & xChartType,
335 bool bSwapXAndYAxis
338 m_spSymbol->set_from_icon_name( GetChartTypeImage( xChartType, bSwapXAndYAxis ) );
341 void SeriesHeader::SetSeriesName( const OUString & rName )
343 m_spSeriesName->SetText(rName);
346 void SeriesHeader::SetRange( sal_Int32 nStartCol, sal_Int32 nEndCol )
348 m_nStartCol = nStartCol;
349 m_nEndCol = std::max(nEndCol, nStartCol);
350 m_spSeriesName->setStartColumn( nStartCol );
353 void SeriesHeader::Show()
355 m_spSymbol->show();
356 m_spSeriesName->Show();
357 m_spColorBar->show();
360 void SeriesHeader::Hide()
362 m_spSymbol->hide();
363 m_spSeriesName->Hide();
364 m_spColorBar->hide();
367 void SeriesHeader::SetEditChangedHdl( const Link<SeriesHeaderEdit&,void> & rLink )
369 m_aChangeLink = rLink;
372 IMPL_LINK_NOARG(SeriesHeader, ImplUpdateDataHdl, Timer*, void)
374 notifyChanges();
377 IMPL_LINK_NOARG(SeriesHeader, SeriesNameEdited, SeriesHeaderEdit&, void)
379 m_bSeriesNameChangePending = true;
380 m_aUpdateDataTimer.Start();
383 void SeriesHeader::SetGetFocusHdl( const Link<SeriesHeaderEdit&,void>& rLink )
385 m_spSeriesName->SetGetFocusHdl( rLink );
388 bool SeriesHeader::HasFocus() const
390 return m_spSeriesName->HasFocus();
393 OUString SeriesHeader::GetChartTypeImage(
394 const Reference< chart2::XChartType > & xChartType,
395 bool bSwapXAndYAxis
398 OUString aResult;
399 if( !xChartType.is())
400 return aResult;
401 OUString aChartTypeName( xChartType->getChartType());
403 if( aChartTypeName == CHART2_SERVICE_NAME_CHARTTYPE_AREA )
405 aResult = BMP_TYPE_AREA;
407 else if( aChartTypeName == CHART2_SERVICE_NAME_CHARTTYPE_COLUMN )
409 if( bSwapXAndYAxis )
410 aResult = BMP_TYPE_BAR;
411 else
412 aResult = BMP_TYPE_COLUMN;
414 else if( aChartTypeName == CHART2_SERVICE_NAME_CHARTTYPE_LINE )
416 aResult = BMP_TYPE_LINE;
418 else if( aChartTypeName == CHART2_SERVICE_NAME_CHARTTYPE_SCATTER )
420 aResult = BMP_TYPE_XY;
422 else if( aChartTypeName == CHART2_SERVICE_NAME_CHARTTYPE_PIE )
424 aResult = BMP_TYPE_PIE;
426 else if( aChartTypeName == CHART2_SERVICE_NAME_CHARTTYPE_NET
427 || aChartTypeName == CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET )
429 aResult = BMP_TYPE_NET;
431 else if( aChartTypeName == CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK )
433 // @todo: correct image for candle-stick type
434 aResult = BMP_TYPE_STOCK;
436 else if( aChartTypeName == CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE )
438 aResult = BMP_TYPE_BUBBLE;
441 return aResult;
444 } // namespace impl
446 namespace
449 /** returns false, if no header as the focus.
451 If a header has the focus, true is returned and the index of the header
452 with focus is set at pIndex if pOutIndex is not 0.
454 bool lcl_SeriesHeaderHasFocus(
455 const std::vector< std::shared_ptr< ::chart::impl::SeriesHeader > > & rSeriesHeader,
456 sal_Int32 * pOutIndex = nullptr )
458 sal_Int32 nIndex = 0;
459 for (auto const& elem : rSeriesHeader)
461 if(elem->HasFocus())
463 if( pOutIndex )
464 *pOutIndex = nIndex;
465 return true;
467 ++nIndex;
469 return false;
472 sal_Int32 lcl_getColumnInDataOrHeader(
473 sal_uInt16 nCol, const std::vector< std::shared_ptr< ::chart::impl::SeriesHeader > > & rSeriesHeader )
475 sal_Int32 nColIdx = 0;
476 bool bHeaderHasFocus( lcl_SeriesHeaderHasFocus( rSeriesHeader, &nColIdx ));
478 if( bHeaderHasFocus )
479 nColIdx = lcl_getColumnInData( static_cast< sal_uInt16 >( rSeriesHeader[nColIdx]->GetStartColumn()));
480 else
481 nColIdx = lcl_getColumnInData( nCol );
483 return nColIdx;
486 } // anonymous namespace
488 DataBrowser::DataBrowser(const css::uno::Reference<css::awt::XWindow> &rParent,
489 weld::Container* pColumns, weld::Container* pColors) :
490 ::svt::EditBrowseBox(VCLUnoHelper::GetWindow(rParent),
491 EditBrowseBoxFlags::SMART_TAB_TRAVEL | EditBrowseBoxFlags::HANDLE_COLUMN_TEXT,
492 WB_BORDER | WB_TABSTOP, BrowserStdFlags ),
493 m_nSeekRow( 0 ),
494 m_bIsReadOnly( false ),
495 m_bDataValid( true ),
496 m_aNumberEditField( VclPtr<FormattedField>::Create( & EditBrowseBox::GetDataWindow(), WB_NOBORDER ) ),
497 m_aTextEditField( VclPtr<Edit>::Create( & EditBrowseBox::GetDataWindow(), WB_NOBORDER ) ),
498 m_pColumnsWin(pColumns),
499 m_pColorsWin(pColors),
500 m_rNumberEditController( new ::svt::FormattedFieldCellController( m_aNumberEditField.get() )),
501 m_rTextEditController( new ::svt::EditCellController( m_aTextEditField.get() ))
503 double fNan;
504 ::rtl::math::setNan( & fNan );
505 m_aNumberEditField->SetDefaultValue( fNan );
506 m_aNumberEditField->TreatAsNumber( true );
507 RenewTable();
510 DataBrowser::~DataBrowser()
512 disposeOnce();
515 void DataBrowser::dispose()
517 m_aNumberEditField.disposeAndClear();
518 m_aTextEditField.disposeAndClear();
519 ::svt::EditBrowseBox::dispose();
522 bool DataBrowser::MayInsertRow() const
524 return ! IsReadOnly()
525 && ( !lcl_SeriesHeaderHasFocus( m_aSeriesHeaders ));
528 bool DataBrowser::MayInsertColumn() const
530 return ! IsReadOnly();
533 bool DataBrowser::MayDeleteRow() const
535 return ! IsReadOnly()
536 && ( !lcl_SeriesHeaderHasFocus( m_aSeriesHeaders ))
537 && ( GetCurRow() >= 0 )
538 && ( GetRowCount() > 1 );
541 bool DataBrowser::MayDeleteColumn() const
543 // if a series header has the focus
544 if( lcl_SeriesHeaderHasFocus( m_aSeriesHeaders ))
545 return true;
547 return ! IsReadOnly()
548 && ( GetCurColumnId() > 1 )
549 && ( ColCount() > 2 );
552 bool DataBrowser::MayMoveUpRows() const
554 return ! IsReadOnly()
555 && ( !lcl_SeriesHeaderHasFocus( m_aSeriesHeaders ))
556 && ( GetCurRow() > 0 )
557 && ( GetCurRow() <= GetRowCount() - 1 );
560 bool DataBrowser::MayMoveDownRows() const
562 return ! IsReadOnly()
563 && ( !lcl_SeriesHeaderHasFocus( m_aSeriesHeaders ))
564 && ( GetCurRow() >= 0 )
565 && ( GetCurRow() < GetRowCount() - 1 );
568 bool DataBrowser::MayMoveLeftColumns() const
570 // if a series header (except the last one) has the focus
572 sal_Int32 nColIndex(0);
573 if( lcl_SeriesHeaderHasFocus( m_aSeriesHeaders, &nColIndex ))
574 return (static_cast< sal_uInt32 >( nColIndex ) <= (m_aSeriesHeaders.size() - 1)) && (static_cast< sal_uInt32 >( nColIndex ) != 0);
577 sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders );
578 return ! IsReadOnly()
579 && ( nColIdx > 1 )
580 && ( nColIdx <= ColCount() - 2 )
581 && m_apDataBrowserModel.get()
582 && !m_apDataBrowserModel->isCategoriesColumn( nColIdx );
585 bool DataBrowser::MayMoveRightColumns() const
587 // if a series header (except the last one) has the focus
589 sal_Int32 nColIndex(0);
590 if( lcl_SeriesHeaderHasFocus( m_aSeriesHeaders, &nColIndex ))
591 return (static_cast< sal_uInt32 >( nColIndex ) < (m_aSeriesHeaders.size() - 1));
594 sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders );
595 return ! IsReadOnly()
596 && ( nColIdx > 0 )
597 && ( nColIdx < ColCount()-2 )
598 && m_apDataBrowserModel.get()
599 && !m_apDataBrowserModel->isCategoriesColumn( nColIdx );
602 void DataBrowser::clearHeaders()
604 for( const auto& spHeader : m_aSeriesHeaders )
605 spHeader->applyChanges();
606 m_aSeriesHeaders.clear();
609 void DataBrowser::RenewTable()
611 if (!m_apDataBrowserModel)
612 return;
614 long nOldRow = GetCurRow();
615 sal_uInt16 nOldColId = GetCurColumnId();
617 bool bLastUpdateMode = GetUpdateMode();
618 SetUpdateMode( false );
620 if( IsModified() )
621 SaveModified();
623 DeactivateCell();
625 RemoveColumns();
626 RowRemoved( 1, GetRowCount() );
628 // for row numbers
629 InsertHandleColumn( static_cast< sal_uInt16 >(
630 GetDataWindow().LogicToPixel( Size( 42, 0 )).getWidth() ));
632 OUString aDefaultSeriesName(SchResId(STR_COLUMN_LABEL));
633 replaceParamterInString( aDefaultSeriesName, "%COLUMNNUMBER", OUString::number( 24 ) );
634 sal_Int32 nColumnWidth = GetDataWindow().GetTextWidth( aDefaultSeriesName )
635 + GetDataWindow().LogicToPixel(Point(8 + impl::SeriesHeader::GetRelativeAppFontXPosForNameField(), 0), MapMode(MapUnit::MapAppFont)).X();
636 sal_Int32 nColumnCount = m_apDataBrowserModel->getColumnCount();
637 // nRowCount is a member of a base class
638 sal_Int32 nRowCountLocal = m_apDataBrowserModel->getMaxRowCount();
639 for( sal_Int32 nColIdx=1; nColIdx<=nColumnCount; ++nColIdx )
641 InsertDataColumn( static_cast< sal_uInt16 >( nColIdx ), GetColString( nColIdx ), nColumnWidth );
644 RowInserted( 1, nRowCountLocal );
645 GoToRow( std::min( nOldRow, GetRowCount() - 1 ));
646 GoToColumnId( std::min( nOldColId, static_cast< sal_uInt16 >( ColCount() - 1 )));
648 // fill series headers
649 clearHeaders();
650 const DataBrowserModel::tDataHeaderVector& aHeaders( m_apDataBrowserModel->getDataHeaders());
651 Link<impl::SeriesHeaderEdit&,void> aFocusLink( LINK( this, DataBrowser, SeriesHeaderGotFocus ));
652 Link<impl::SeriesHeaderEdit&,void> aSeriesHeaderChangedLink( LINK( this, DataBrowser, SeriesHeaderChanged ));
654 for (auto const& elemHeader : aHeaders)
656 std::shared_ptr< impl::SeriesHeader > spHeader( new impl::SeriesHeader( m_pColumnsWin, m_pColorsWin ));
657 Reference< beans::XPropertySet > xSeriesProp( elemHeader.m_xDataSeries, uno::UNO_QUERY );
658 sal_Int32 nColor = 0;
659 // @todo: Set "DraftColor", i.e. interpolated colors for gradients, bitmaps, etc.
660 if( xSeriesProp.is() &&
661 ( xSeriesProp->getPropertyValue( "Color" ) >>= nColor ))
662 spHeader->SetColor( Color( nColor ));
663 spHeader->SetChartType( elemHeader.m_xChartType, elemHeader.m_bSwapXAndYAxis );
664 spHeader->SetSeriesName(
665 DataSeriesHelper::getDataSeriesLabel(
666 elemHeader.m_xDataSeries,
667 (elemHeader.m_xChartType.is() ?
668 elemHeader.m_xChartType->getRoleOfSequenceForSeriesLabel() :
669 OUString("values-y"))));
670 // index is 1-based, as 0 is for the column that contains the row-numbers
671 spHeader->SetRange( elemHeader.m_nStartColumn + 1, elemHeader.m_nEndColumn + 1 );
672 spHeader->SetGetFocusHdl( aFocusLink );
673 spHeader->SetEditChangedHdl( aSeriesHeaderChangedLink );
674 m_aSeriesHeaders.push_back( spHeader );
677 ImplAdjustHeaderControls();
678 SetUpdateMode( bLastUpdateMode );
679 ActivateCell();
680 Invalidate();
683 OUString DataBrowser::GetColString( sal_Int32 nColumnId ) const
685 OSL_ASSERT(m_apDataBrowserModel);
686 if( nColumnId > 0 )
687 return m_apDataBrowserModel->getRoleOfColumn( nColumnId - 1 );
688 return OUString();
691 OUString DataBrowser::GetCellText( long nRow, sal_uInt16 nColumnId ) const
693 OUString aResult;
695 if( nColumnId == 0 )
697 aResult = OUString::number(static_cast< sal_Int32 >( nRow ) + 1);
699 else if( nRow >= 0 && m_apDataBrowserModel.get())
701 sal_Int32 nColIndex = static_cast< sal_Int32 >( nColumnId ) - 1;
703 if( m_apDataBrowserModel->getCellType( nColIndex ) == DataBrowserModel::NUMBER )
705 double fData( m_apDataBrowserModel->getCellNumber( nColIndex, nRow ));
706 Color nLabelColor;
708 if( ! ::rtl::math::isNan( fData ) &&
709 m_spNumberFormatterWrapper.get() )
711 bool bColorChanged = false;
712 aResult = m_spNumberFormatterWrapper->getFormattedString(
713 GetNumberFormatKey( nColumnId ),
714 fData, nLabelColor, bColorChanged );
717 else if( m_apDataBrowserModel->getCellType( nColIndex ) == DataBrowserModel::TEXTORDATE )
719 uno::Any aAny = m_apDataBrowserModel->getCellAny( nColIndex, nRow );
720 OUString aText;
721 double fDouble=0.0;
722 if( aAny>>=aText )
723 aResult = aText;
724 else if( aAny>>=fDouble )
726 if( ! ::rtl::math::isNan( fDouble ) && m_spNumberFormatterWrapper.get() )
728 // If a numberformat was available here we could directly
729 // obtain the corresponding edit format in
730 // getDateTimeInputNumberFormat() instead of doing the
731 // guess work.
732 sal_Int32 nNumberFormat = DiagramHelper::getDateTimeInputNumberFormat(
733 Reference< util::XNumberFormatsSupplier >( m_xChartDoc, uno::UNO_QUERY), fDouble );
734 Color nLabelColor;
735 bool bColorChanged = false;
736 aResult = m_spNumberFormatterWrapper->getFormattedString(
737 nNumberFormat, fDouble, nLabelColor, bColorChanged );
741 else
743 OSL_ASSERT( m_apDataBrowserModel->getCellType( nColIndex ) == DataBrowserModel::TEXT );
744 aResult = m_apDataBrowserModel->getCellText( nColIndex, nRow );
748 return aResult;
751 double DataBrowser::GetCellNumber( long nRow, sal_uInt16 nColumnId ) const
753 double fResult;
754 ::rtl::math::setNan( & fResult );
756 if(( nColumnId >= 1 ) && ( nRow >= 0 ) &&
757 m_apDataBrowserModel.get())
759 fResult = m_apDataBrowserModel->getCellNumber(
760 static_cast< sal_Int32 >( nColumnId ) - 1, nRow );
763 return fResult;
766 void DataBrowser::Resize()
768 bool bLastUpdateMode = GetUpdateMode();
769 SetUpdateMode( false );
771 ::svt::EditBrowseBox::Resize();
772 ImplAdjustHeaderControls();
773 SetUpdateMode( bLastUpdateMode );
776 void DataBrowser::SetReadOnly( bool bNewState )
778 if( m_bIsReadOnly != bNewState )
780 m_bIsReadOnly = bNewState;
781 Invalidate();
782 DeactivateCell();
786 void DataBrowser::CursorMoved()
788 EditBrowseBox::CursorMoved();
790 if( GetUpdateMode() )
791 m_aCursorMovedHdlLink.Call( this );
794 void DataBrowser::MouseButtonDown( const BrowserMouseEvent& rEvt )
796 if( !m_bDataValid )
797 ShowWarningBox();
798 else
799 EditBrowseBox::MouseButtonDown( rEvt );
802 void DataBrowser::ShowWarningBox()
804 std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(GetFrameWeld(),
805 VclMessageType::Warning, VclButtonsType::Ok,
806 SchResId(STR_INVALID_NUMBER)));
807 xWarn->run();
810 bool DataBrowser::ShowQueryBox()
812 std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetFrameWeld(),
813 VclMessageType::Question, VclButtonsType::YesNo,
814 SchResId(STR_DATA_EDITOR_INCORRECT_INPUT)));
815 return xQueryBox->run() == RET_YES;
818 bool DataBrowser::IsDataValid() const
820 bool bValid = true;
821 const sal_Int32 nCol = lcl_getColumnInData( GetCurColumnId());
823 if( m_apDataBrowserModel->getCellType( nCol ) == DataBrowserModel::NUMBER )
825 sal_uInt32 nDummy = 0;
826 double fDummy = 0.0;
827 OUString aText( m_aNumberEditField->GetText());
829 if( !aText.isEmpty() &&
830 m_spNumberFormatterWrapper.get() &&
831 m_spNumberFormatterWrapper->getSvNumberFormatter() &&
832 ! m_spNumberFormatterWrapper->getSvNumberFormatter()->IsNumberFormat(
833 aText, nDummy, fDummy ))
835 bValid = false;
839 return bValid;
842 void DataBrowser::CellModified()
844 m_bDataValid = IsDataValid();
845 m_aCursorMovedHdlLink.Call( this );
848 void DataBrowser::SetDataFromModel(
849 const Reference< chart2::XChartDocument > & xChartDoc,
850 const Reference< uno::XComponentContext > & xContext )
852 m_xChartDoc.set( xChartDoc );
854 m_apDataBrowserModel.reset( new DataBrowserModel( m_xChartDoc, xContext ));
855 m_spNumberFormatterWrapper.reset(
856 new NumberFormatterWrapper(
857 Reference< util::XNumberFormatsSupplier >( m_xChartDoc, uno::UNO_QUERY )));
859 m_aNumberEditField->SetFormatter( m_spNumberFormatterWrapper->getSvNumberFormatter() );
861 RenewTable();
863 const sal_Int32 nColCnt = m_apDataBrowserModel->getColumnCount();
864 const sal_Int32 nRowCnt = m_apDataBrowserModel->getMaxRowCount();
865 if( nRowCnt && nColCnt )
867 GoToRow( 0 );
868 GoToColumnId( 1 );
872 void DataBrowser::InsertColumn()
874 sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders );
876 if( nColIdx >= 0 &&
877 m_apDataBrowserModel.get())
879 // save changes made to edit-field
880 if( IsModified() )
881 SaveModified();
883 m_apDataBrowserModel->insertDataSeries( nColIdx );
884 RenewTable();
888 void DataBrowser::InsertTextColumn()
890 sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders );
892 if( nColIdx >= 0 &&
893 m_apDataBrowserModel.get())
895 // save changes made to edit-field
896 if( IsModified() )
897 SaveModified();
899 m_apDataBrowserModel->insertComplexCategoryLevel( nColIdx );
900 RenewTable();
904 void DataBrowser::RemoveColumn()
906 sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders );
908 if( nColIdx >= 0 &&
909 m_apDataBrowserModel.get())
911 // save changes made to edit-field
912 if( IsModified() )
913 SaveModified();
915 m_bDataValid = true;
916 m_apDataBrowserModel->removeDataSeriesOrComplexCategoryLevel( nColIdx );
917 RenewTable();
921 void DataBrowser::InsertRow()
923 sal_Int32 nRowIdx = lcl_getRowInData( GetCurRow());
925 if( nRowIdx >= 0 &&
926 m_apDataBrowserModel.get())
928 // save changes made to edit-field
929 if( IsModified() )
930 SaveModified();
932 m_apDataBrowserModel->insertDataPointForAllSeries( nRowIdx );
933 RenewTable();
937 void DataBrowser::RemoveRow()
939 sal_Int32 nRowIdx = lcl_getRowInData( GetCurRow());
941 if( nRowIdx >= 0 &&
942 m_apDataBrowserModel.get())
944 // save changes made to edit-field
945 if( IsModified() )
946 SaveModified();
948 m_bDataValid = true;
949 m_apDataBrowserModel->removeDataPointForAllSeries( nRowIdx );
950 RenewTable();
954 void DataBrowser::MoveLeftColumn()
956 sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders );
958 if( nColIdx > 0 &&
959 m_apDataBrowserModel.get())
961 // save changes made to edit-field
962 if( IsModified() )
963 SaveModified();
965 m_apDataBrowserModel->swapDataSeries( nColIdx - 1 );
967 // keep cursor in swapped column
968 if(( 0 < GetCurColumnId() ) && ( GetCurColumnId() <= ColCount() - 1 ))
970 Dispatch( BROWSER_CURSORLEFT );
972 RenewTable();
976 void DataBrowser::MoveRightColumn()
978 sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders );
980 if( nColIdx >= 0 &&
981 m_apDataBrowserModel.get())
983 // save changes made to edit-field
984 if( IsModified() )
985 SaveModified();
987 m_apDataBrowserModel->swapDataSeries( nColIdx );
989 // keep cursor in swapped column
990 if( GetCurColumnId() < ColCount() - 1 )
992 Dispatch( BROWSER_CURSORRIGHT );
994 RenewTable();
998 void DataBrowser::MoveUpRow()
1000 sal_Int32 nRowIdx = lcl_getRowInData( GetCurRow());
1002 if( nRowIdx > 0 &&
1003 m_apDataBrowserModel.get())
1005 // save changes made to edit-field
1006 if( IsModified() )
1007 SaveModified();
1009 m_apDataBrowserModel->swapDataPointForAllSeries( nRowIdx - 1 );
1011 // keep cursor in swapped row
1012 if(( 0 < GetCurRow() ) && ( GetCurRow() <= GetRowCount() - 1 ))
1014 Dispatch( BROWSER_CURSORUP );
1016 RenewTable();
1020 void DataBrowser::MoveDownRow()
1022 sal_Int32 nRowIdx = lcl_getRowInData( GetCurRow());
1024 if( nRowIdx >= 0 &&
1025 m_apDataBrowserModel.get())
1027 // save changes made to edit-field
1028 if( IsModified() )
1029 SaveModified();
1031 m_apDataBrowserModel->swapDataPointForAllSeries( nRowIdx );
1033 // keep cursor in swapped row
1034 if( GetCurRow() < GetRowCount() - 1 )
1036 Dispatch( BROWSER_CURSORDOWN );
1038 RenewTable();
1042 void DataBrowser::SetCursorMovedHdl( const Link<DataBrowser*,void>& rLink )
1044 m_aCursorMovedHdlLink = rLink;
1047 // implementations for ::svt::EditBrowseBox (pure virtual methods)
1048 void DataBrowser::PaintCell(
1049 OutputDevice& rDev, const tools::Rectangle& rRect, sal_uInt16 nColumnId ) const
1051 Point aPos( rRect.TopLeft());
1052 aPos.AdjustX(1 );
1054 OUString aText = GetCellText( m_nSeekRow, nColumnId );
1055 Size TxtSize( GetDataWindow().GetTextWidth( aText ), GetDataWindow().GetTextHeight());
1057 // clipping
1058 if( aPos.X() < rRect.Right() || aPos.X() + TxtSize.Width() > rRect.Right() ||
1059 aPos.Y() < rRect.Top() || aPos.Y() + TxtSize.Height() > rRect.Bottom())
1060 rDev.SetClipRegion(vcl::Region(rRect));
1062 // allow for a disabled control ...
1063 bool bEnabled = IsEnabled();
1064 Color aOriginalColor = rDev.GetTextColor();
1065 if( ! bEnabled )
1066 rDev.SetTextColor( GetSettings().GetStyleSettings().GetDisableColor() );
1068 // draw the text
1069 rDev.DrawText( aPos, aText );
1071 // reset the color (if necessary)
1072 if( ! bEnabled )
1073 rDev.SetTextColor( aOriginalColor );
1075 if( rDev.IsClipRegion())
1076 rDev.SetClipRegion();
1079 bool DataBrowser::SeekRow( long nRow )
1081 if( ! EditBrowseBox::SeekRow( nRow ))
1082 return false;
1084 if( nRow < 0 )
1085 m_nSeekRow = - 1;
1086 else
1087 m_nSeekRow = nRow;
1089 return true;
1092 bool DataBrowser::IsTabAllowed( bool bForward ) const
1094 long nRow = GetCurRow();
1095 long nCol = GetCurColumnId();
1097 // column 0 is header-column
1098 long nBadCol = bForward
1099 ? GetColumnCount() - 1
1100 : 1;
1101 long nBadRow = bForward
1102 ? GetRowCount() - 1
1103 : 0;
1105 if( !m_bDataValid )
1107 const_cast< DataBrowser* >( this )->ShowWarningBox();
1108 return false;
1111 return ( nRow != nBadRow ||
1112 nCol != nBadCol );
1115 ::svt::CellController* DataBrowser::GetController( long /*nRow*/, sal_uInt16 nCol )
1117 if( m_bIsReadOnly )
1118 return nullptr;
1120 if( CellContainsNumbers( nCol ))
1122 m_aNumberEditField->UseInputStringForFormatting();
1123 m_aNumberEditField->SetFormatKey( GetNumberFormatKey( nCol ));
1124 return m_rNumberEditController.get();
1127 return m_rTextEditController.get();
1130 void DataBrowser::InitController(
1131 ::svt::CellControllerRef& rController, long nRow, sal_uInt16 nCol )
1133 if( rController == m_rTextEditController )
1135 OUString aText( GetCellText( nRow, nCol ) );
1136 m_aTextEditField->SetText( aText );
1137 m_aTextEditField->SetSelection( Selection( 0, aText.getLength() ));
1139 else if( rController == m_rNumberEditController )
1141 // treat invalid and empty text as Nan
1142 m_aNumberEditField->EnableNotANumber( true );
1143 if( ::rtl::math::isNan( GetCellNumber( nRow, nCol )))
1144 m_aNumberEditField->SetTextValue( OUString());
1145 else
1146 m_aNumberEditField->SetValue( GetCellNumber( nRow, nCol ) );
1147 OUString aText( m_aNumberEditField->GetText());
1148 m_aNumberEditField->SetSelection( Selection( 0, aText.getLength()));
1150 else
1152 OSL_FAIL( "Invalid Controller" );
1156 bool DataBrowser::CellContainsNumbers( sal_uInt16 nCol ) const
1158 if (!m_apDataBrowserModel)
1159 return false;
1160 return m_apDataBrowserModel->getCellType( lcl_getColumnInData( nCol )) == DataBrowserModel::NUMBER;
1163 sal_uInt32 DataBrowser::GetNumberFormatKey( sal_uInt16 nCol ) const
1165 if (!m_apDataBrowserModel)
1166 return 0;
1167 return m_apDataBrowserModel->getNumberFormatKey( lcl_getColumnInData( nCol ) );
1170 bool DataBrowser::isDateTimeString( const OUString& aInputString, double& fOutDateTimeValue )
1172 sal_uInt32 nNumberFormat=0;
1173 SvNumberFormatter* pSvNumberFormatter = m_spNumberFormatterWrapper.get() ? m_spNumberFormatterWrapper->getSvNumberFormatter() : nullptr;
1174 if( !aInputString.isEmpty() && pSvNumberFormatter && pSvNumberFormatter->IsNumberFormat( aInputString, nNumberFormat, fOutDateTimeValue ) )
1176 SvNumFormatType nType = pSvNumberFormatter->GetType( nNumberFormat);
1177 return (nType & SvNumFormatType::DATE) || (nType & SvNumFormatType::TIME);
1179 return false;
1182 bool DataBrowser::SaveModified()
1184 if( ! IsModified() )
1185 return true;
1187 bool bChangeValid = true;
1189 const sal_Int32 nRow = lcl_getRowInData( GetCurRow());
1190 const sal_Int32 nCol = lcl_getColumnInData( GetCurColumnId());
1192 OSL_ENSURE( nRow >= 0 || nCol >= 0, "This cell should not be modified!" );
1194 SvNumberFormatter* pSvNumberFormatter = m_spNumberFormatterWrapper.get() ? m_spNumberFormatterWrapper->getSvNumberFormatter() : nullptr;
1195 switch( m_apDataBrowserModel->getCellType( nCol ))
1197 case DataBrowserModel::NUMBER:
1199 sal_uInt32 nDummy = 0;
1200 double fDummy = 0.0;
1201 OUString aText( m_aNumberEditField->GetText());
1202 // an empty string is valid, if no numberformatter exists, all
1203 // values are treated as valid
1204 if( !aText.isEmpty() && pSvNumberFormatter &&
1205 ! pSvNumberFormatter->IsNumberFormat( aText, nDummy, fDummy ) )
1207 bChangeValid = false;
1209 else
1211 double fData = m_aNumberEditField->GetValue();
1212 bChangeValid = m_apDataBrowserModel->setCellNumber( nCol, nRow, fData );
1215 break;
1216 case DataBrowserModel::TEXTORDATE:
1218 OUString aText( m_aTextEditField->GetText() );
1219 double fValue = 0.0;
1220 bChangeValid = false;
1221 if( isDateTimeString( aText, fValue ) )
1222 bChangeValid = m_apDataBrowserModel->setCellAny( nCol, nRow, uno::Any( fValue ) );
1223 if(!bChangeValid)
1224 bChangeValid = m_apDataBrowserModel->setCellAny( nCol, nRow, uno::Any( aText ) );
1226 break;
1227 case DataBrowserModel::TEXT:
1229 OUString aText( m_aTextEditField->GetText());
1230 bChangeValid = m_apDataBrowserModel->setCellText( nCol, nRow, aText );
1232 break;
1235 // the first valid change changes this to true
1236 if( bChangeValid )
1238 RowModified( GetCurRow(), GetCurColumnId());
1239 ::svt::CellController* pCtrl = GetController( GetCurRow(), GetCurColumnId());
1240 if( pCtrl )
1241 pCtrl->ClearModified();
1244 return bChangeValid;
1247 bool DataBrowser::EndEditing()
1249 SaveModified();
1251 // apply changes made to series headers
1252 for( const auto& spHeader : m_aSeriesHeaders )
1253 spHeader->applyChanges();
1255 if( m_bDataValid )
1256 return true;
1257 else
1258 return ShowQueryBox();
1261 void DataBrowser::ColumnResized( sal_uInt16 nColId )
1263 bool bLastUpdateMode = GetUpdateMode();
1264 SetUpdateMode( false );
1266 EditBrowseBox::ColumnResized( nColId );
1267 ImplAdjustHeaderControls();
1268 SetUpdateMode( bLastUpdateMode );
1271 void DataBrowser::EndScroll()
1273 bool bLastUpdateMode = GetUpdateMode();
1274 SetUpdateMode( false );
1276 EditBrowseBox::EndScroll();
1277 RenewSeriesHeaders();
1279 SetUpdateMode( bLastUpdateMode );
1282 void DataBrowser::RenewSeriesHeaders()
1284 clearHeaders();
1285 DataBrowserModel::tDataHeaderVector aHeaders( m_apDataBrowserModel->getDataHeaders());
1286 Link<impl::SeriesHeaderEdit&,void> aFocusLink( LINK( this, DataBrowser, SeriesHeaderGotFocus ));
1287 Link<impl::SeriesHeaderEdit&,void> aSeriesHeaderChangedLink( LINK( this, DataBrowser, SeriesHeaderChanged ));
1289 for (auto const& elemHeader : aHeaders)
1291 std::shared_ptr< impl::SeriesHeader > spHeader( new impl::SeriesHeader( m_pColumnsWin, m_pColorsWin ));
1292 Reference< beans::XPropertySet > xSeriesProp(elemHeader.m_xDataSeries, uno::UNO_QUERY);
1293 sal_Int32 nColor = 0;
1294 if( xSeriesProp.is() &&
1295 ( xSeriesProp->getPropertyValue( "Color" ) >>= nColor ))
1296 spHeader->SetColor( Color( nColor ));
1297 spHeader->SetChartType( elemHeader.m_xChartType, elemHeader.m_bSwapXAndYAxis );
1298 spHeader->SetSeriesName(
1299 DataSeriesHelper::getDataSeriesLabel(
1300 elemHeader.m_xDataSeries,
1301 (elemHeader.m_xChartType.is() ?
1302 elemHeader.m_xChartType->getRoleOfSequenceForSeriesLabel() :
1303 OUString( "values-y"))));
1304 spHeader->SetRange( elemHeader.m_nStartColumn + 1, elemHeader.m_nEndColumn + 1 );
1305 spHeader->SetGetFocusHdl( aFocusLink );
1306 spHeader->SetEditChangedHdl( aSeriesHeaderChangedLink );
1307 m_aSeriesHeaders.push_back( spHeader );
1310 ImplAdjustHeaderControls();
1313 void DataBrowser::ImplAdjustHeaderControls()
1315 sal_uInt16 nColCount = GetColumnCount();
1316 sal_uInt32 nCurrentPos = GetPosPixel().getX();
1317 sal_uInt32 nMaxPos = nCurrentPos + GetOutputSizePixel().getWidth();
1318 sal_uInt32 nStartPos = nCurrentPos;
1320 // width of header column
1321 nCurrentPos += GetColumnWidth( 0 );
1323 weld::Container* pWin = m_pColumnsWin;
1324 weld::Container* pColorWin = m_pColorsWin;
1325 pWin->set_margin_left(nCurrentPos);
1326 pColorWin->set_margin_left(nCurrentPos);
1328 tSeriesHeaderContainer::iterator aIt( m_aSeriesHeaders.begin());
1329 sal_uInt16 i = GetFirstVisibleColNumber();
1330 while( (aIt != m_aSeriesHeaders.end()) && ((*aIt)->GetStartColumn() < i) )
1332 (*aIt)->Hide();
1333 ++aIt;
1335 for( ; i < nColCount && aIt != m_aSeriesHeaders.end(); ++i )
1337 if( (*aIt)->GetStartColumn() == i )
1338 nStartPos = nCurrentPos;
1340 nCurrentPos += (GetColumnWidth( i ));
1342 if( (*aIt)->GetEndColumn() == i )
1344 if( nStartPos < nMaxPos )
1346 (*aIt)->SetPixelWidth( nCurrentPos - nStartPos - 3 );
1347 (*aIt)->Show();
1349 if (pWin)
1351 pWin->set_margin_left(nStartPos);
1352 pColorWin->set_margin_left(nStartPos);
1353 pWin = pColorWin = nullptr;
1357 else
1358 (*aIt)->Hide();
1359 ++aIt;
1364 IMPL_LINK( DataBrowser, SeriesHeaderGotFocus, impl::SeriesHeaderEdit&, rEdit, void )
1366 rEdit.SetShowWarningBox( !m_bDataValid );
1368 if( !m_bDataValid )
1369 GoToCell( 0, 0 );
1370 else
1372 MakeFieldVisible( GetCurRow(), static_cast< sal_uInt16 >( rEdit.getStartColumn()) );
1373 ActivateCell();
1374 m_aCursorMovedHdlLink.Call( this );
1378 IMPL_LINK( DataBrowser, SeriesHeaderChanged, impl::SeriesHeaderEdit&, rEdit, void )
1380 Reference< chart2::XDataSeries > xSeries(
1381 m_apDataBrowserModel->getDataSeriesByColumn( rEdit.getStartColumn() - 1 ));
1382 Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY );
1383 if( xSource.is())
1385 Reference< chart2::XChartType > xChartType(
1386 m_apDataBrowserModel->getHeaderForSeries( xSeries ).m_xChartType );
1387 if( xChartType.is())
1389 Reference< chart2::data::XLabeledDataSequence > xLabeledSeq(
1390 DataSeriesHelper::getDataSequenceByRole( xSource, xChartType->getRoleOfSequenceForSeriesLabel()));
1391 if( xLabeledSeq.is())
1393 Reference< container::XIndexReplace > xIndexReplace( xLabeledSeq->getLabel(), uno::UNO_QUERY );
1394 if( xIndexReplace.is())
1395 xIndexReplace->replaceByIndex(
1396 0, uno::Any( rEdit.GetText()));
1402 } // namespace chart
1404 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */