vcl: allow for overriding the default PDF rendering resolution
[LibreOffice.git] / chart2 / source / controller / dialogs / DataBrowser.cxx
blob86b258dd815816ce2efdfb4a963b73f44542837a
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 weld::Container* m_pParent;
215 weld::Container* m_pColorParent;
217 std::unique_ptr<weld::Container> m_xContainer1;
218 std::unique_ptr<weld::Container> m_xContainer2;
219 std::unique_ptr<weld::Image> m_spSymbol;
220 std::unique_ptr<SeriesHeaderEdit> m_spSeriesName;
221 std::unique_ptr<weld::Image> m_spColorBar;
222 VclPtr< OutputDevice> m_xDevice;
223 Link<SeriesHeaderEdit&,void> m_aChangeLink;
224 Color m_aColor;
226 void notifyChanges();
227 DECL_LINK( ImplUpdateDataHdl, Timer*, void );
228 DECL_LINK( SeriesNameEdited, SeriesHeaderEdit&, void );
230 static OUString GetChartTypeImage(
231 const Reference< chart2::XChartType > & xChartType,
232 bool bSwapXAndYAxis
235 sal_Int32 m_nStartCol, m_nEndCol;
236 sal_Int32 m_nWidth;
237 bool m_bSeriesNameChangePending;
240 SeriesHeader::SeriesHeader(weld::Container* pParent, weld::Container* pColorParent)
241 : m_aUpdateDataTimer("UpdateDataTimer")
242 , m_xBuilder1(Application::CreateBuilder(pParent, "modules/schart/ui/columnfragment.ui"))
243 , m_xBuilder2(Application::CreateBuilder(pColorParent, "modules/schart/ui/imagefragment.ui"))
244 , m_pParent(pParent)
245 , m_pColorParent(pColorParent)
246 , m_xContainer1(m_xBuilder1->weld_container("container"))
247 , m_xContainer2(m_xBuilder2->weld_container("container"))
248 , m_spSymbol(m_xBuilder1->weld_image("image"))
249 , m_spSeriesName(new SeriesHeaderEdit(m_xBuilder1->weld_entry("entry")))
250 , m_spColorBar(m_xBuilder2->weld_image("image"))
251 , m_xDevice(Application::GetDefaultDevice())
252 , m_nStartCol( 0 )
253 , m_nEndCol( 0 )
254 , m_nWidth( 42 )
255 , m_bSeriesNameChangePending( false )
257 m_aUpdateDataTimer.SetInvokeHandler(LINK(this, SeriesHeader, ImplUpdateDataHdl));
258 m_aUpdateDataTimer.SetDebugName( "SeriesHeader UpdateDataTimer" );
259 m_aUpdateDataTimer.SetTimeout(4 * EDIT_UPDATEDATA_TIMEOUT);
261 m_spSeriesName->SetModifyHdl(LINK(this, SeriesHeader, SeriesNameEdited));
262 Show();
265 SeriesHeader::~SeriesHeader()
267 m_aUpdateDataTimer.Stop();
268 m_pParent->move(m_xContainer1.get(), nullptr);
269 m_pColorParent->move(m_xContainer2.get(), nullptr);
272 void SeriesHeader::notifyChanges()
274 m_aChangeLink.Call(*m_spSeriesName);
275 m_bSeriesNameChangePending = false;
278 void SeriesHeader::applyChanges()
280 if( m_bSeriesNameChangePending )
282 notifyChanges();
286 void SeriesHeader::SetColor( const Color & rCol )
288 m_aColor = rCol;
291 void SeriesHeader::SetPos()
293 // chart type symbol
294 Size aSize( nSymbolHeight, nSymbolHeight );
295 aSize = m_xDevice->LogicToPixel(aSize, MapMode(MapUnit::MapAppFont));
296 m_spSymbol->set_size_request(aSize.Width(), aSize.Height());
298 // series name edit field
299 aSize.setWidth(nSymbolDistance);
300 aSize = m_xDevice->LogicToPixel(aSize, MapMode(MapUnit::MapAppFont));
301 m_spSeriesName->set_margin_left(aSize.Width() + 2);
302 aSize.setWidth( m_nWidth - nSymbolHeight - nSymbolDistance );
303 sal_Int32 nHeight = 12;
304 aSize.setHeight( nHeight );
305 aSize = m_xDevice->LogicToPixel(aSize, MapMode(MapUnit::MapAppFont));
306 m_spSeriesName->set_size_request(aSize.Width(), aSize.Height());
308 // color bar
309 aSize.setWidth(1);
310 aSize = m_xDevice->LogicToPixel(aSize, MapMode(MapUnit::MapAppFont));
311 m_spColorBar->set_margin_left(aSize.Width() + 2);
312 nHeight = 3;
313 aSize.setWidth( m_nWidth - 1 );
314 aSize.setHeight( nHeight );
315 aSize = m_xDevice->LogicToPixel(aSize, MapMode(MapUnit::MapAppFont));
316 m_spColorBar->set_size_request(aSize.Width(), aSize.Height());
318 auto xVirDev(m_spColorBar->create_virtual_device());
319 xVirDev->SetOutputSizePixel(aSize);
320 xVirDev->SetFillColor(m_aColor);
321 xVirDev->SetLineColor(m_aColor);
322 xVirDev->DrawRect(tools::Rectangle(Point(0, 0), aSize));
323 m_spColorBar->set_image(xVirDev.get());
326 void SeriesHeader::SetWidth( sal_Int32 nWidth )
328 m_nWidth = nWidth;
329 SetPos();
332 void SeriesHeader::SetPixelWidth( sal_Int32 nWidth )
334 SetWidth( m_xDevice->PixelToLogic(Size(nWidth, 0), MapMode(MapUnit::MapAppFont)).getWidth());
337 void SeriesHeader::SetChartType(
338 const Reference< chart2::XChartType > & xChartType,
339 bool bSwapXAndYAxis
342 m_spSymbol->set_from_icon_name( GetChartTypeImage( xChartType, bSwapXAndYAxis ) );
345 void SeriesHeader::SetSeriesName( const OUString & rName )
347 m_spSeriesName->SetText(rName);
350 void SeriesHeader::SetRange( sal_Int32 nStartCol, sal_Int32 nEndCol )
352 m_nStartCol = nStartCol;
353 m_nEndCol = std::max(nEndCol, nStartCol);
354 m_spSeriesName->setStartColumn( nStartCol );
357 void SeriesHeader::Show()
359 m_spSymbol->show();
360 m_spSeriesName->Show();
361 m_spColorBar->show();
364 void SeriesHeader::Hide()
366 m_spSymbol->hide();
367 m_spSeriesName->Hide();
368 m_spColorBar->hide();
371 void SeriesHeader::SetEditChangedHdl( const Link<SeriesHeaderEdit&,void> & rLink )
373 m_aChangeLink = rLink;
376 IMPL_LINK_NOARG(SeriesHeader, ImplUpdateDataHdl, Timer*, void)
378 notifyChanges();
381 IMPL_LINK_NOARG(SeriesHeader, SeriesNameEdited, SeriesHeaderEdit&, void)
383 m_bSeriesNameChangePending = true;
384 m_aUpdateDataTimer.Start();
387 void SeriesHeader::SetGetFocusHdl( const Link<SeriesHeaderEdit&,void>& rLink )
389 m_spSeriesName->SetGetFocusHdl( rLink );
392 bool SeriesHeader::HasFocus() const
394 return m_spSeriesName->HasFocus();
397 OUString SeriesHeader::GetChartTypeImage(
398 const Reference< chart2::XChartType > & xChartType,
399 bool bSwapXAndYAxis
402 OUString aResult;
403 if( !xChartType.is())
404 return aResult;
405 OUString aChartTypeName( xChartType->getChartType());
407 if( aChartTypeName == CHART2_SERVICE_NAME_CHARTTYPE_AREA )
409 aResult = BMP_TYPE_AREA;
411 else if( aChartTypeName == CHART2_SERVICE_NAME_CHARTTYPE_COLUMN )
413 if( bSwapXAndYAxis )
414 aResult = BMP_TYPE_BAR;
415 else
416 aResult = BMP_TYPE_COLUMN;
418 else if( aChartTypeName == CHART2_SERVICE_NAME_CHARTTYPE_LINE )
420 aResult = BMP_TYPE_LINE;
422 else if( aChartTypeName == CHART2_SERVICE_NAME_CHARTTYPE_SCATTER )
424 aResult = BMP_TYPE_XY;
426 else if( aChartTypeName == CHART2_SERVICE_NAME_CHARTTYPE_PIE )
428 aResult = BMP_TYPE_PIE;
430 else if( aChartTypeName == CHART2_SERVICE_NAME_CHARTTYPE_NET
431 || aChartTypeName == CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET )
433 aResult = BMP_TYPE_NET;
435 else if( aChartTypeName == CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK )
437 // @todo: correct image for candle-stick type
438 aResult = BMP_TYPE_STOCK;
440 else if( aChartTypeName == CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE )
442 aResult = BMP_TYPE_BUBBLE;
445 return aResult;
448 } // namespace impl
450 namespace
453 /** returns false, if no header as the focus.
455 If a header has the focus, true is returned and the index of the header
456 with focus is set at pIndex if pOutIndex is not 0.
458 bool lcl_SeriesHeaderHasFocus(
459 const std::vector< std::shared_ptr< ::chart::impl::SeriesHeader > > & rSeriesHeader,
460 sal_Int32 * pOutIndex = nullptr )
462 sal_Int32 nIndex = 0;
463 for (auto const& elem : rSeriesHeader)
465 if(elem->HasFocus())
467 if( pOutIndex )
468 *pOutIndex = nIndex;
469 return true;
471 ++nIndex;
473 return false;
476 sal_Int32 lcl_getColumnInDataOrHeader(
477 sal_uInt16 nCol, const std::vector< std::shared_ptr< ::chart::impl::SeriesHeader > > & rSeriesHeader )
479 sal_Int32 nColIdx = 0;
480 bool bHeaderHasFocus( lcl_SeriesHeaderHasFocus( rSeriesHeader, &nColIdx ));
482 if( bHeaderHasFocus )
483 nColIdx = lcl_getColumnInData( static_cast< sal_uInt16 >( rSeriesHeader[nColIdx]->GetStartColumn()));
484 else
485 nColIdx = lcl_getColumnInData( nCol );
487 return nColIdx;
490 } // anonymous namespace
492 DataBrowser::DataBrowser(const css::uno::Reference<css::awt::XWindow> &rParent,
493 weld::Container* pColumns, weld::Container* pColors) :
494 ::svt::EditBrowseBox(VCLUnoHelper::GetWindow(rParent),
495 EditBrowseBoxFlags::SMART_TAB_TRAVEL | EditBrowseBoxFlags::HANDLE_COLUMN_TEXT,
496 WB_BORDER | WB_TABSTOP, BrowserStdFlags ),
497 m_nSeekRow( 0 ),
498 m_bIsReadOnly( false ),
499 m_bDataValid( true ),
500 m_aNumberEditField( VclPtr<FormattedField>::Create( & EditBrowseBox::GetDataWindow(), WB_NOBORDER ) ),
501 m_aTextEditField( VclPtr<Edit>::Create( & EditBrowseBox::GetDataWindow(), WB_NOBORDER ) ),
502 m_pColumnsWin(pColumns),
503 m_pColorsWin(pColors),
504 m_rNumberEditController( new ::svt::FormattedFieldCellController( m_aNumberEditField.get() )),
505 m_rTextEditController( new ::svt::EditCellController( m_aTextEditField.get() ))
507 double fNan;
508 ::rtl::math::setNan( & fNan );
509 m_aNumberEditField->SetDefaultValue( fNan );
510 m_aNumberEditField->TreatAsNumber( true );
511 RenewTable();
514 DataBrowser::~DataBrowser()
516 disposeOnce();
519 void DataBrowser::dispose()
521 m_aSeriesHeaders.clear();
522 m_aNumberEditField.disposeAndClear();
523 m_aTextEditField.disposeAndClear();
524 ::svt::EditBrowseBox::dispose();
527 bool DataBrowser::MayInsertRow() const
529 return ! IsReadOnly()
530 && ( !lcl_SeriesHeaderHasFocus( m_aSeriesHeaders ));
533 bool DataBrowser::MayInsertColumn() const
535 return ! IsReadOnly();
538 bool DataBrowser::MayDeleteRow() const
540 return ! IsReadOnly()
541 && ( !lcl_SeriesHeaderHasFocus( m_aSeriesHeaders ))
542 && ( GetCurRow() >= 0 )
543 && ( GetRowCount() > 1 );
546 bool DataBrowser::MayDeleteColumn() const
548 // if a series header has the focus
549 if( lcl_SeriesHeaderHasFocus( m_aSeriesHeaders ))
550 return true;
552 return ! IsReadOnly()
553 && ( GetCurColumnId() > 1 )
554 && ( ColCount() > 2 );
557 bool DataBrowser::MayMoveUpRows() const
559 return ! IsReadOnly()
560 && ( !lcl_SeriesHeaderHasFocus( m_aSeriesHeaders ))
561 && ( GetCurRow() > 0 )
562 && ( GetCurRow() <= GetRowCount() - 1 );
565 bool DataBrowser::MayMoveDownRows() const
567 return ! IsReadOnly()
568 && ( !lcl_SeriesHeaderHasFocus( m_aSeriesHeaders ))
569 && ( GetCurRow() >= 0 )
570 && ( GetCurRow() < GetRowCount() - 1 );
573 bool DataBrowser::MayMoveLeftColumns() const
575 // if a series header (except the last one) has the focus
577 sal_Int32 nColIndex(0);
578 if( lcl_SeriesHeaderHasFocus( m_aSeriesHeaders, &nColIndex ))
579 return (static_cast< sal_uInt32 >( nColIndex ) <= (m_aSeriesHeaders.size() - 1)) && (static_cast< sal_uInt32 >( nColIndex ) != 0);
582 sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders );
583 return ! IsReadOnly()
584 && ( nColIdx > 1 )
585 && ( nColIdx <= ColCount() - 2 )
586 && m_apDataBrowserModel.get()
587 && !m_apDataBrowserModel->isCategoriesColumn( nColIdx );
590 bool DataBrowser::MayMoveRightColumns() const
592 // if a series header (except the last one) has the focus
594 sal_Int32 nColIndex(0);
595 if( lcl_SeriesHeaderHasFocus( m_aSeriesHeaders, &nColIndex ))
596 return (static_cast< sal_uInt32 >( nColIndex ) < (m_aSeriesHeaders.size() - 1));
599 sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders );
600 return ! IsReadOnly()
601 && ( nColIdx > 0 )
602 && ( nColIdx < ColCount()-2 )
603 && m_apDataBrowserModel.get()
604 && !m_apDataBrowserModel->isCategoriesColumn( nColIdx );
607 void DataBrowser::clearHeaders()
609 for( const auto& spHeader : m_aSeriesHeaders )
610 spHeader->applyChanges();
611 m_aSeriesHeaders.clear();
614 void DataBrowser::RenewTable()
616 if (!m_apDataBrowserModel)
617 return;
619 long nOldRow = GetCurRow();
620 sal_uInt16 nOldColId = GetCurColumnId();
622 bool bLastUpdateMode = GetUpdateMode();
623 SetUpdateMode( false );
625 if( IsModified() )
626 SaveModified();
628 DeactivateCell();
630 RemoveColumns();
631 RowRemoved( 1, GetRowCount() );
633 // for row numbers
634 InsertHandleColumn( static_cast< sal_uInt16 >(
635 GetDataWindow().LogicToPixel( Size( 42, 0 )).getWidth() ));
637 OUString aDefaultSeriesName(SchResId(STR_COLUMN_LABEL));
638 replaceParamterInString( aDefaultSeriesName, "%COLUMNNUMBER", OUString::number( 24 ) );
639 sal_Int32 nColumnWidth = GetDataWindow().GetTextWidth( aDefaultSeriesName )
640 + GetDataWindow().LogicToPixel(Point(8 + impl::SeriesHeader::GetRelativeAppFontXPosForNameField(), 0), MapMode(MapUnit::MapAppFont)).X();
641 sal_Int32 nColumnCount = m_apDataBrowserModel->getColumnCount();
642 // nRowCount is a member of a base class
643 sal_Int32 nRowCountLocal = m_apDataBrowserModel->getMaxRowCount();
644 for( sal_Int32 nColIdx=1; nColIdx<=nColumnCount; ++nColIdx )
646 InsertDataColumn( static_cast< sal_uInt16 >( nColIdx ), GetColString( nColIdx ), nColumnWidth );
649 RowInserted( 1, nRowCountLocal );
650 GoToRow( std::min( nOldRow, GetRowCount() - 1 ));
651 GoToColumnId( std::min( nOldColId, static_cast< sal_uInt16 >( ColCount() - 1 )));
653 // fill series headers
654 clearHeaders();
655 const DataBrowserModel::tDataHeaderVector& aHeaders( m_apDataBrowserModel->getDataHeaders());
656 Link<impl::SeriesHeaderEdit&,void> aFocusLink( LINK( this, DataBrowser, SeriesHeaderGotFocus ));
657 Link<impl::SeriesHeaderEdit&,void> aSeriesHeaderChangedLink( LINK( this, DataBrowser, SeriesHeaderChanged ));
659 for (auto const& elemHeader : aHeaders)
661 std::shared_ptr< impl::SeriesHeader > spHeader( new impl::SeriesHeader( m_pColumnsWin, m_pColorsWin ));
662 Reference< beans::XPropertySet > xSeriesProp( elemHeader.m_xDataSeries, uno::UNO_QUERY );
663 sal_Int32 nColor = 0;
664 // @todo: Set "DraftColor", i.e. interpolated colors for gradients, bitmaps, etc.
665 if( xSeriesProp.is() &&
666 ( xSeriesProp->getPropertyValue( "Color" ) >>= nColor ))
667 spHeader->SetColor( Color( nColor ));
668 spHeader->SetChartType( elemHeader.m_xChartType, elemHeader.m_bSwapXAndYAxis );
669 spHeader->SetSeriesName(
670 DataSeriesHelper::getDataSeriesLabel(
671 elemHeader.m_xDataSeries,
672 (elemHeader.m_xChartType.is() ?
673 elemHeader.m_xChartType->getRoleOfSequenceForSeriesLabel() :
674 OUString("values-y"))));
675 // index is 1-based, as 0 is for the column that contains the row-numbers
676 spHeader->SetRange( elemHeader.m_nStartColumn + 1, elemHeader.m_nEndColumn + 1 );
677 spHeader->SetGetFocusHdl( aFocusLink );
678 spHeader->SetEditChangedHdl( aSeriesHeaderChangedLink );
679 m_aSeriesHeaders.push_back( spHeader );
682 ImplAdjustHeaderControls();
683 SetUpdateMode( bLastUpdateMode );
684 ActivateCell();
685 Invalidate();
688 OUString DataBrowser::GetColString( sal_Int32 nColumnId ) const
690 OSL_ASSERT(m_apDataBrowserModel);
691 if( nColumnId > 0 )
692 return m_apDataBrowserModel->getRoleOfColumn( nColumnId - 1 );
693 return OUString();
696 OUString DataBrowser::GetCellText( long nRow, sal_uInt16 nColumnId ) const
698 OUString aResult;
700 if( nColumnId == 0 )
702 aResult = OUString::number(static_cast< sal_Int32 >( nRow ) + 1);
704 else if( nRow >= 0 && m_apDataBrowserModel.get())
706 sal_Int32 nColIndex = static_cast< sal_Int32 >( nColumnId ) - 1;
708 if( m_apDataBrowserModel->getCellType( nColIndex ) == DataBrowserModel::NUMBER )
710 double fData( m_apDataBrowserModel->getCellNumber( nColIndex, nRow ));
711 Color nLabelColor;
713 if( ! ::rtl::math::isNan( fData ) &&
714 m_spNumberFormatterWrapper.get() )
716 bool bColorChanged = false;
717 aResult = m_spNumberFormatterWrapper->getFormattedString(
718 GetNumberFormatKey( nColumnId ),
719 fData, nLabelColor, bColorChanged );
722 else if( m_apDataBrowserModel->getCellType( nColIndex ) == DataBrowserModel::TEXTORDATE )
724 uno::Any aAny = m_apDataBrowserModel->getCellAny( nColIndex, nRow );
725 OUString aText;
726 double fDouble=0.0;
727 if( aAny>>=aText )
728 aResult = aText;
729 else if( aAny>>=fDouble )
731 if( ! ::rtl::math::isNan( fDouble ) && m_spNumberFormatterWrapper.get() )
733 // If a numberformat was available here we could directly
734 // obtain the corresponding edit format in
735 // getDateTimeInputNumberFormat() instead of doing the
736 // guess work.
737 sal_Int32 nNumberFormat = DiagramHelper::getDateTimeInputNumberFormat(
738 Reference< util::XNumberFormatsSupplier >( m_xChartDoc, uno::UNO_QUERY), fDouble );
739 Color nLabelColor;
740 bool bColorChanged = false;
741 aResult = m_spNumberFormatterWrapper->getFormattedString(
742 nNumberFormat, fDouble, nLabelColor, bColorChanged );
746 else
748 OSL_ASSERT( m_apDataBrowserModel->getCellType( nColIndex ) == DataBrowserModel::TEXT );
749 aResult = m_apDataBrowserModel->getCellText( nColIndex, nRow );
753 return aResult;
756 double DataBrowser::GetCellNumber( long nRow, sal_uInt16 nColumnId ) const
758 double fResult;
759 ::rtl::math::setNan( & fResult );
761 if(( nColumnId >= 1 ) && ( nRow >= 0 ) &&
762 m_apDataBrowserModel.get())
764 fResult = m_apDataBrowserModel->getCellNumber(
765 static_cast< sal_Int32 >( nColumnId ) - 1, nRow );
768 return fResult;
771 void DataBrowser::Resize()
773 bool bLastUpdateMode = GetUpdateMode();
774 SetUpdateMode( false );
776 ::svt::EditBrowseBox::Resize();
777 ImplAdjustHeaderControls();
778 SetUpdateMode( bLastUpdateMode );
781 void DataBrowser::SetReadOnly( bool bNewState )
783 if( m_bIsReadOnly != bNewState )
785 m_bIsReadOnly = bNewState;
786 Invalidate();
787 DeactivateCell();
791 void DataBrowser::CursorMoved()
793 EditBrowseBox::CursorMoved();
795 if( GetUpdateMode() )
796 m_aCursorMovedHdlLink.Call( this );
799 void DataBrowser::MouseButtonDown( const BrowserMouseEvent& rEvt )
801 if( !m_bDataValid )
802 ShowWarningBox();
803 else
804 EditBrowseBox::MouseButtonDown( rEvt );
807 void DataBrowser::ShowWarningBox()
809 std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(GetFrameWeld(),
810 VclMessageType::Warning, VclButtonsType::Ok,
811 SchResId(STR_INVALID_NUMBER)));
812 xWarn->run();
815 bool DataBrowser::ShowQueryBox()
817 std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetFrameWeld(),
818 VclMessageType::Question, VclButtonsType::YesNo,
819 SchResId(STR_DATA_EDITOR_INCORRECT_INPUT)));
820 return xQueryBox->run() == RET_YES;
823 bool DataBrowser::IsDataValid() const
825 bool bValid = true;
826 const sal_Int32 nCol = lcl_getColumnInData( GetCurColumnId());
828 if( m_apDataBrowserModel->getCellType( nCol ) == DataBrowserModel::NUMBER )
830 sal_uInt32 nDummy = 0;
831 double fDummy = 0.0;
832 OUString aText( m_aNumberEditField->GetText());
834 if( !aText.isEmpty() &&
835 m_spNumberFormatterWrapper.get() &&
836 m_spNumberFormatterWrapper->getSvNumberFormatter() &&
837 ! m_spNumberFormatterWrapper->getSvNumberFormatter()->IsNumberFormat(
838 aText, nDummy, fDummy ))
840 bValid = false;
844 return bValid;
847 void DataBrowser::CellModified()
849 m_bDataValid = IsDataValid();
850 m_aCursorMovedHdlLink.Call( this );
853 void DataBrowser::SetDataFromModel(
854 const Reference< chart2::XChartDocument > & xChartDoc,
855 const Reference< uno::XComponentContext > & xContext )
857 m_xChartDoc.set( xChartDoc );
859 m_apDataBrowserModel.reset( new DataBrowserModel( m_xChartDoc, xContext ));
860 m_spNumberFormatterWrapper.reset(
861 new NumberFormatterWrapper(
862 Reference< util::XNumberFormatsSupplier >( m_xChartDoc, uno::UNO_QUERY )));
864 m_aNumberEditField->SetFormatter( m_spNumberFormatterWrapper->getSvNumberFormatter() );
866 RenewTable();
868 const sal_Int32 nColCnt = m_apDataBrowserModel->getColumnCount();
869 const sal_Int32 nRowCnt = m_apDataBrowserModel->getMaxRowCount();
870 if( nRowCnt && nColCnt )
872 GoToRow( 0 );
873 GoToColumnId( 1 );
877 void DataBrowser::InsertColumn()
879 sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders );
881 if( nColIdx >= 0 &&
882 m_apDataBrowserModel.get())
884 // save changes made to edit-field
885 if( IsModified() )
886 SaveModified();
888 m_apDataBrowserModel->insertDataSeries( nColIdx );
889 RenewTable();
893 void DataBrowser::InsertTextColumn()
895 sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders );
897 if( nColIdx >= 0 &&
898 m_apDataBrowserModel.get())
900 // save changes made to edit-field
901 if( IsModified() )
902 SaveModified();
904 m_apDataBrowserModel->insertComplexCategoryLevel( nColIdx );
905 RenewTable();
909 void DataBrowser::RemoveColumn()
911 sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders );
913 if( nColIdx >= 0 &&
914 m_apDataBrowserModel.get())
916 // save changes made to edit-field
917 if( IsModified() )
918 SaveModified();
920 m_bDataValid = true;
921 m_apDataBrowserModel->removeDataSeriesOrComplexCategoryLevel( nColIdx );
922 RenewTable();
926 void DataBrowser::InsertRow()
928 sal_Int32 nRowIdx = lcl_getRowInData( GetCurRow());
930 if( nRowIdx >= 0 &&
931 m_apDataBrowserModel.get())
933 // save changes made to edit-field
934 if( IsModified() )
935 SaveModified();
937 m_apDataBrowserModel->insertDataPointForAllSeries( nRowIdx );
938 RenewTable();
942 void DataBrowser::RemoveRow()
944 sal_Int32 nRowIdx = lcl_getRowInData( GetCurRow());
946 if( nRowIdx >= 0 &&
947 m_apDataBrowserModel.get())
949 // save changes made to edit-field
950 if( IsModified() )
951 SaveModified();
953 m_bDataValid = true;
954 m_apDataBrowserModel->removeDataPointForAllSeries( nRowIdx );
955 RenewTable();
959 void DataBrowser::MoveLeftColumn()
961 sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders );
963 if( nColIdx > 0 &&
964 m_apDataBrowserModel.get())
966 // save changes made to edit-field
967 if( IsModified() )
968 SaveModified();
970 m_apDataBrowserModel->swapDataSeries( nColIdx - 1 );
972 // keep cursor in swapped column
973 if(( 0 < GetCurColumnId() ) && ( GetCurColumnId() <= ColCount() - 1 ))
975 Dispatch( BROWSER_CURSORLEFT );
977 RenewTable();
981 void DataBrowser::MoveRightColumn()
983 sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders );
985 if( nColIdx >= 0 &&
986 m_apDataBrowserModel.get())
988 // save changes made to edit-field
989 if( IsModified() )
990 SaveModified();
992 m_apDataBrowserModel->swapDataSeries( nColIdx );
994 // keep cursor in swapped column
995 if( GetCurColumnId() < ColCount() - 1 )
997 Dispatch( BROWSER_CURSORRIGHT );
999 RenewTable();
1003 void DataBrowser::MoveUpRow()
1005 sal_Int32 nRowIdx = lcl_getRowInData( GetCurRow());
1007 if( nRowIdx > 0 &&
1008 m_apDataBrowserModel.get())
1010 // save changes made to edit-field
1011 if( IsModified() )
1012 SaveModified();
1014 m_apDataBrowserModel->swapDataPointForAllSeries( nRowIdx - 1 );
1016 // keep cursor in swapped row
1017 if(( 0 < GetCurRow() ) && ( GetCurRow() <= GetRowCount() - 1 ))
1019 Dispatch( BROWSER_CURSORUP );
1021 RenewTable();
1025 void DataBrowser::MoveDownRow()
1027 sal_Int32 nRowIdx = lcl_getRowInData( GetCurRow());
1029 if( nRowIdx >= 0 &&
1030 m_apDataBrowserModel.get())
1032 // save changes made to edit-field
1033 if( IsModified() )
1034 SaveModified();
1036 m_apDataBrowserModel->swapDataPointForAllSeries( nRowIdx );
1038 // keep cursor in swapped row
1039 if( GetCurRow() < GetRowCount() - 1 )
1041 Dispatch( BROWSER_CURSORDOWN );
1043 RenewTable();
1047 void DataBrowser::SetCursorMovedHdl( const Link<DataBrowser*,void>& rLink )
1049 m_aCursorMovedHdlLink = rLink;
1052 // implementations for ::svt::EditBrowseBox (pure virtual methods)
1053 void DataBrowser::PaintCell(
1054 OutputDevice& rDev, const tools::Rectangle& rRect, sal_uInt16 nColumnId ) const
1056 Point aPos( rRect.TopLeft());
1057 aPos.AdjustX(1 );
1059 OUString aText = GetCellText( m_nSeekRow, nColumnId );
1060 Size TxtSize( GetDataWindow().GetTextWidth( aText ), GetDataWindow().GetTextHeight());
1062 // clipping
1063 if( aPos.X() < rRect.Right() || aPos.X() + TxtSize.Width() > rRect.Right() ||
1064 aPos.Y() < rRect.Top() || aPos.Y() + TxtSize.Height() > rRect.Bottom())
1065 rDev.SetClipRegion(vcl::Region(rRect));
1067 // allow for a disabled control ...
1068 bool bEnabled = IsEnabled();
1069 Color aOriginalColor = rDev.GetTextColor();
1070 if( ! bEnabled )
1071 rDev.SetTextColor( GetSettings().GetStyleSettings().GetDisableColor() );
1073 // draw the text
1074 rDev.DrawText( aPos, aText );
1076 // reset the color (if necessary)
1077 if( ! bEnabled )
1078 rDev.SetTextColor( aOriginalColor );
1080 if( rDev.IsClipRegion())
1081 rDev.SetClipRegion();
1084 bool DataBrowser::SeekRow( long nRow )
1086 if( ! EditBrowseBox::SeekRow( nRow ))
1087 return false;
1089 if( nRow < 0 )
1090 m_nSeekRow = - 1;
1091 else
1092 m_nSeekRow = nRow;
1094 return true;
1097 bool DataBrowser::IsTabAllowed( bool bForward ) const
1099 long nRow = GetCurRow();
1100 long nCol = GetCurColumnId();
1102 // column 0 is header-column
1103 long nBadCol = bForward
1104 ? GetColumnCount() - 1
1105 : 1;
1106 long nBadRow = bForward
1107 ? GetRowCount() - 1
1108 : 0;
1110 if( !m_bDataValid )
1112 const_cast< DataBrowser* >( this )->ShowWarningBox();
1113 return false;
1116 return ( nRow != nBadRow ||
1117 nCol != nBadCol );
1120 ::svt::CellController* DataBrowser::GetController( long /*nRow*/, sal_uInt16 nCol )
1122 if( m_bIsReadOnly )
1123 return nullptr;
1125 if( CellContainsNumbers( nCol ))
1127 m_aNumberEditField->UseInputStringForFormatting();
1128 m_aNumberEditField->SetFormatKey( GetNumberFormatKey( nCol ));
1129 return m_rNumberEditController.get();
1132 return m_rTextEditController.get();
1135 void DataBrowser::InitController(
1136 ::svt::CellControllerRef& rController, long nRow, sal_uInt16 nCol )
1138 if( rController == m_rTextEditController )
1140 OUString aText( GetCellText( nRow, nCol ) );
1141 m_aTextEditField->SetText( aText );
1142 m_aTextEditField->SetSelection( Selection( 0, aText.getLength() ));
1144 else if( rController == m_rNumberEditController )
1146 // treat invalid and empty text as Nan
1147 m_aNumberEditField->EnableNotANumber( true );
1148 if( ::rtl::math::isNan( GetCellNumber( nRow, nCol )))
1149 m_aNumberEditField->SetTextValue( OUString());
1150 else
1151 m_aNumberEditField->SetValue( GetCellNumber( nRow, nCol ) );
1152 OUString aText( m_aNumberEditField->GetText());
1153 m_aNumberEditField->SetSelection( Selection( 0, aText.getLength()));
1155 else
1157 OSL_FAIL( "Invalid Controller" );
1161 bool DataBrowser::CellContainsNumbers( sal_uInt16 nCol ) const
1163 if (!m_apDataBrowserModel)
1164 return false;
1165 return m_apDataBrowserModel->getCellType( lcl_getColumnInData( nCol )) == DataBrowserModel::NUMBER;
1168 sal_uInt32 DataBrowser::GetNumberFormatKey( sal_uInt16 nCol ) const
1170 if (!m_apDataBrowserModel)
1171 return 0;
1172 return m_apDataBrowserModel->getNumberFormatKey( lcl_getColumnInData( nCol ) );
1175 bool DataBrowser::isDateTimeString( const OUString& aInputString, double& fOutDateTimeValue )
1177 sal_uInt32 nNumberFormat=0;
1178 SvNumberFormatter* pSvNumberFormatter = m_spNumberFormatterWrapper.get() ? m_spNumberFormatterWrapper->getSvNumberFormatter() : nullptr;
1179 if( !aInputString.isEmpty() && pSvNumberFormatter && pSvNumberFormatter->IsNumberFormat( aInputString, nNumberFormat, fOutDateTimeValue ) )
1181 SvNumFormatType nType = pSvNumberFormatter->GetType( nNumberFormat);
1182 return (nType & SvNumFormatType::DATE) || (nType & SvNumFormatType::TIME);
1184 return false;
1187 bool DataBrowser::SaveModified()
1189 if( ! IsModified() )
1190 return true;
1192 bool bChangeValid = true;
1194 const sal_Int32 nRow = lcl_getRowInData( GetCurRow());
1195 const sal_Int32 nCol = lcl_getColumnInData( GetCurColumnId());
1197 OSL_ENSURE( nRow >= 0 || nCol >= 0, "This cell should not be modified!" );
1199 SvNumberFormatter* pSvNumberFormatter = m_spNumberFormatterWrapper.get() ? m_spNumberFormatterWrapper->getSvNumberFormatter() : nullptr;
1200 switch( m_apDataBrowserModel->getCellType( nCol ))
1202 case DataBrowserModel::NUMBER:
1204 sal_uInt32 nDummy = 0;
1205 double fDummy = 0.0;
1206 OUString aText( m_aNumberEditField->GetText());
1207 // an empty string is valid, if no numberformatter exists, all
1208 // values are treated as valid
1209 if( !aText.isEmpty() && pSvNumberFormatter &&
1210 ! pSvNumberFormatter->IsNumberFormat( aText, nDummy, fDummy ) )
1212 bChangeValid = false;
1214 else
1216 double fData = m_aNumberEditField->GetValue();
1217 bChangeValid = m_apDataBrowserModel->setCellNumber( nCol, nRow, fData );
1220 break;
1221 case DataBrowserModel::TEXTORDATE:
1223 OUString aText( m_aTextEditField->GetText() );
1224 double fValue = 0.0;
1225 bChangeValid = false;
1226 if( isDateTimeString( aText, fValue ) )
1227 bChangeValid = m_apDataBrowserModel->setCellAny( nCol, nRow, uno::Any( fValue ) );
1228 if(!bChangeValid)
1229 bChangeValid = m_apDataBrowserModel->setCellAny( nCol, nRow, uno::Any( aText ) );
1231 break;
1232 case DataBrowserModel::TEXT:
1234 OUString aText( m_aTextEditField->GetText());
1235 bChangeValid = m_apDataBrowserModel->setCellText( nCol, nRow, aText );
1237 break;
1240 // the first valid change changes this to true
1241 if( bChangeValid )
1243 RowModified( GetCurRow(), GetCurColumnId());
1244 ::svt::CellController* pCtrl = GetController( GetCurRow(), GetCurColumnId());
1245 if( pCtrl )
1246 pCtrl->ClearModified();
1249 return bChangeValid;
1252 bool DataBrowser::EndEditing()
1254 SaveModified();
1256 // apply changes made to series headers
1257 for( const auto& spHeader : m_aSeriesHeaders )
1258 spHeader->applyChanges();
1260 if( m_bDataValid )
1261 return true;
1262 else
1263 return ShowQueryBox();
1266 void DataBrowser::ColumnResized( sal_uInt16 nColId )
1268 bool bLastUpdateMode = GetUpdateMode();
1269 SetUpdateMode( false );
1271 EditBrowseBox::ColumnResized( nColId );
1272 ImplAdjustHeaderControls();
1273 SetUpdateMode( bLastUpdateMode );
1276 void DataBrowser::EndScroll()
1278 bool bLastUpdateMode = GetUpdateMode();
1279 SetUpdateMode( false );
1281 EditBrowseBox::EndScroll();
1282 RenewSeriesHeaders();
1284 SetUpdateMode( bLastUpdateMode );
1287 void DataBrowser::RenewSeriesHeaders()
1289 clearHeaders();
1290 DataBrowserModel::tDataHeaderVector aHeaders( m_apDataBrowserModel->getDataHeaders());
1291 Link<impl::SeriesHeaderEdit&,void> aFocusLink( LINK( this, DataBrowser, SeriesHeaderGotFocus ));
1292 Link<impl::SeriesHeaderEdit&,void> aSeriesHeaderChangedLink( LINK( this, DataBrowser, SeriesHeaderChanged ));
1294 for (auto const& elemHeader : aHeaders)
1296 std::shared_ptr< impl::SeriesHeader > spHeader( new impl::SeriesHeader( m_pColumnsWin, m_pColorsWin ));
1297 Reference< beans::XPropertySet > xSeriesProp(elemHeader.m_xDataSeries, uno::UNO_QUERY);
1298 sal_Int32 nColor = 0;
1299 if( xSeriesProp.is() &&
1300 ( xSeriesProp->getPropertyValue( "Color" ) >>= nColor ))
1301 spHeader->SetColor( Color( nColor ));
1302 spHeader->SetChartType( elemHeader.m_xChartType, elemHeader.m_bSwapXAndYAxis );
1303 spHeader->SetSeriesName(
1304 DataSeriesHelper::getDataSeriesLabel(
1305 elemHeader.m_xDataSeries,
1306 (elemHeader.m_xChartType.is() ?
1307 elemHeader.m_xChartType->getRoleOfSequenceForSeriesLabel() :
1308 OUString( "values-y"))));
1309 spHeader->SetRange( elemHeader.m_nStartColumn + 1, elemHeader.m_nEndColumn + 1 );
1310 spHeader->SetGetFocusHdl( aFocusLink );
1311 spHeader->SetEditChangedHdl( aSeriesHeaderChangedLink );
1312 m_aSeriesHeaders.push_back( spHeader );
1315 ImplAdjustHeaderControls();
1318 void DataBrowser::ImplAdjustHeaderControls()
1320 sal_uInt16 nColCount = GetColumnCount();
1321 sal_uInt32 nCurrentPos = GetPosPixel().getX();
1322 sal_uInt32 nMaxPos = nCurrentPos + GetOutputSizePixel().getWidth();
1323 sal_uInt32 nStartPos = nCurrentPos;
1325 // width of header column
1326 nCurrentPos += GetColumnWidth( 0 );
1328 weld::Container* pWin = m_pColumnsWin;
1329 weld::Container* pColorWin = m_pColorsWin;
1330 pWin->set_margin_left(nCurrentPos);
1331 pColorWin->set_margin_left(nCurrentPos);
1333 tSeriesHeaderContainer::iterator aIt( m_aSeriesHeaders.begin());
1334 sal_uInt16 i = GetFirstVisibleColNumber();
1335 while( (aIt != m_aSeriesHeaders.end()) && ((*aIt)->GetStartColumn() < i) )
1337 (*aIt)->Hide();
1338 ++aIt;
1340 for( ; i < nColCount && aIt != m_aSeriesHeaders.end(); ++i )
1342 if( (*aIt)->GetStartColumn() == i )
1343 nStartPos = nCurrentPos;
1345 nCurrentPos += (GetColumnWidth( i ));
1347 if( (*aIt)->GetEndColumn() == i )
1349 if( nStartPos < nMaxPos )
1351 (*aIt)->SetPixelWidth( nCurrentPos - nStartPos - 3 );
1352 (*aIt)->Show();
1354 if (pWin)
1356 pWin->set_margin_left(nStartPos);
1357 pColorWin->set_margin_left(nStartPos);
1358 pWin = pColorWin = nullptr;
1362 else
1363 (*aIt)->Hide();
1364 ++aIt;
1369 IMPL_LINK( DataBrowser, SeriesHeaderGotFocus, impl::SeriesHeaderEdit&, rEdit, void )
1371 rEdit.SetShowWarningBox( !m_bDataValid );
1373 if( !m_bDataValid )
1374 GoToCell( 0, 0 );
1375 else
1377 MakeFieldVisible( GetCurRow(), static_cast< sal_uInt16 >( rEdit.getStartColumn()) );
1378 ActivateCell();
1379 m_aCursorMovedHdlLink.Call( this );
1383 IMPL_LINK( DataBrowser, SeriesHeaderChanged, impl::SeriesHeaderEdit&, rEdit, void )
1385 Reference< chart2::XDataSeries > xSeries(
1386 m_apDataBrowserModel->getDataSeriesByColumn( rEdit.getStartColumn() - 1 ));
1387 Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY );
1388 if( xSource.is())
1390 Reference< chart2::XChartType > xChartType(
1391 m_apDataBrowserModel->getHeaderForSeries( xSeries ).m_xChartType );
1392 if( xChartType.is())
1394 Reference< chart2::data::XLabeledDataSequence > xLabeledSeq(
1395 DataSeriesHelper::getDataSequenceByRole( xSource, xChartType->getRoleOfSequenceForSeriesLabel()));
1396 if( xLabeledSeq.is())
1398 Reference< container::XIndexReplace > xIndexReplace( xLabeledSeq->getLabel(), uno::UNO_QUERY );
1399 if( xIndexReplace.is())
1400 xIndexReplace->replaceByIndex(
1401 0, uno::Any( rEdit.GetText()));
1407 } // namespace chart
1409 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */