1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <com/sun/star/chart/ChartDataRowSource.hpp>
21 #include <com/sun/star/chart2/data/XDataProvider.hpp>
22 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
23 #include <com/sun/star/chart2/XChartDocument.hpp>
24 #include <com/sun/star/beans/PropertyState.hpp>
25 #include <com/sun/star/embed/EmbedVerbs.hpp>
26 #include <com/sun/star/embed/XEmbeddedObject.hpp>
28 #include <comphelper/classids.hxx>
29 #include <svx/charthelper.hxx>
30 #include <svtools/embedhlp.hxx>
36 #include <tablemgr.hxx>
38 #include <swabstdlg.hxx>
42 #include <unochart.hxx>
44 #include <comphelper/lok.hxx>
46 using namespace ::com::sun::star
;
48 // Adjust line height (dialogue)
49 void SwTableFUNC::ColWidthDlg(weld::Window
*pParent
)
52 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
53 ScopedVclPtr
<VclAbstractDialog
> pDlg(pFact
->CreateSwTableWidthDlg(pParent
, *this));
57 // Determine the width
58 SwTwips
SwTableFUNC::GetColWidth(sal_uInt16 nNum
) const
62 if( m_aCols
.Count() > 0 )
64 if(m_aCols
.Count() == GetColCount())
66 if(nNum
== m_aCols
.Count())
67 nWidth
= m_aCols
.GetRight() - m_aCols
[nNum
-1];
71 nWidth
= m_aCols
[nNum
] - m_aCols
.GetLeft();
73 nWidth
= m_aCols
[nNum
] - m_aCols
[nNum
-1];
78 SwTwips nRValid
= nNum
< GetColCount() ?
79 m_aCols
[GetRightSeparator(nNum
)] :
81 SwTwips nLValid
= nNum
?
82 m_aCols
[GetRightSeparator(nNum
- 1)] :
84 nWidth
= nRValid
- nLValid
;
88 nWidth
= m_aCols
.GetRight();
92 SwTwips
SwTableFUNC::GetMaxColWidth( sal_uInt16 nNum
) const
94 OSL_ENSURE(nNum
<= m_aCols
.Count(), "Index out of Area");
96 if ( GetColCount() > 0 )
98 // The maximum width arises from the own width and
99 // the width each of the neighbor cells reduced by MINLAY.
102 nMax
= GetColWidth(1) - MINLAY
;
105 nMax
= GetColWidth(nNum
-1);
106 if(nNum
== GetColCount())
109 nMax
+= GetColWidth(nNum
+1) - 2 * MINLAY
;
111 return nMax
+ GetColWidth(nNum
);
114 return GetColWidth(nNum
);
117 void SwTableFUNC::SetColWidth(sal_uInt16 nNum
, SwTwips nNewWidth
)
120 // move all of the following
121 bool bCurrentOnly
= false;
123 if ( m_aCols
.Count() > 0 )
125 if(m_aCols
.Count() != GetColCount())
127 SwTwips nWidth
= GetColWidth(nNum
);
129 int nDiff
= static_cast<int>(nNewWidth
- nWidth
);
131 m_aCols
[ GetRightSeparator(0) ] += nDiff
;
132 else if( nNum
< GetColCount() )
134 if(nDiff
< GetColWidth(nNum
+ 1) - MINLAY
)
135 m_aCols
[ GetRightSeparator(nNum
) ] += nDiff
;
138 int nDiffLeft
= nDiff
- static_cast<int>(GetColWidth(nNum
+ 1)) + int(MINLAY
);
139 m_aCols
[ GetRightSeparator(nNum
) ] += (nDiff
- nDiffLeft
);
140 m_aCols
[ GetRightSeparator(nNum
- 1) ] -= nDiffLeft
;
144 m_aCols
[ GetRightSeparator(nNum
-1) ] -= nDiff
;
147 m_aCols
.SetRight( std::min( nNewWidth
, SwTwips(m_aCols
.GetRightMax()) ) );
149 m_pSh
->StartAllAction();
150 m_pSh
->SetTabCols( m_aCols
, bCurrentOnly
);
151 m_pSh
->EndAllAction();
154 void SwTableFUNC::InitTabCols()
156 OSL_ENSURE(m_pSh
, "no Shell");
158 if( m_pFormat
&& m_pSh
)
159 m_pSh
->GetTabCols( m_aCols
);
162 SwTableFUNC::SwTableFUNC(SwWrtShell
*pShell
)
163 : m_pFormat(pShell
->GetTableFormat()),
168 SwTableFUNC::~SwTableFUNC()
172 void SwTableFUNC::UpdateChart()
174 //Update of the fields triggered by the user, all Charts of
175 //the table will be brought up to date
176 SwFrameFormat
*pFormat2
= m_pSh
->GetTableFormat();
177 if ( pFormat2
&& m_pSh
->HasOLEObj( pFormat2
->GetName() ) )
179 m_pSh
->StartAllAction();
180 m_pSh
->UpdateCharts( pFormat2
->GetName() );
181 m_pSh
->EndAllAction();
185 uno::Reference
< frame::XModel
> SwTableFUNC::InsertChart(
186 uno::Reference
< chart2::data::XDataProvider
> const &rxDataProvider
,
188 const OUString
&rCellRange
,
189 SwFlyFrameFormat
** ppFlyFrameFormat
)
191 uno::Reference
< frame::XModel
> xChartModel
;
192 m_pSh
->StartUndo( SwUndoId::UI_INSERT_CHART
);
193 m_pSh
->StartAllAction();
196 if (m_pSh
->IsCursorInTable())
198 aName
= m_pSh
->GetTableFormat()->GetName();
199 // insert node before table
200 m_pSh
->MoveTable( GotoCurrTable
, fnTableStart
);
202 if ( m_pSh
->IsCursorInTable() )
204 if ( aName
!= m_pSh
->GetTableFormat()->GetName() )
205 m_pSh
->Down( false ); // two adjacent tables
212 comphelper::EmbeddedObjectContainer aCnt
;
213 uno::Reference
< embed::XEmbeddedObject
> xObj
=
214 aCnt
.CreateEmbeddedObject( SvGlobalName( SO3_SCH_CLASSID
).GetByteSequence(), aObjName
);
216 ::svt::EmbeddedObjectRef
aEmbObjRef( xObj
, css::embed::Aspects::MSOLE_CONTENT
);
220 SwFlyFrameFormat
* pTmp
= nullptr;
221 m_pSh
->InsertOleObject( aEmbObjRef
, &pTmp
);
222 if (ppFlyFrameFormat
)
223 *ppFlyFrameFormat
= pTmp
;
225 xChartModel
.set( xObj
->getComponent(), uno::UNO_QUERY
);
226 if( xChartModel
.is() )
228 // Create a default chart type.
229 uno::Reference
<chart2::XChartDocument
> xChartDoc(xChartModel
, uno::UNO_QUERY
);
231 xChartDoc
->createDefaultChart();
233 xChartModel
->lockControllers(); //#i79578# don't request a new replacement image for charts to often - block change notifications
236 // set the table name at the OLE-node
237 if (!aName
.isEmpty())
238 m_pSh
->SetChartName( aName
);
240 m_pSh
->EndAllAction();
242 if (xObj
.is() && !comphelper::LibreOfficeKit::isActive())
244 // Let the chart be activated after the inserting (unless
245 // via LibreOfficeKit)
246 SfxInPlaceClient
* pClient
= m_pSh
->GetView().FindIPClient( xObj
, &m_pSh
->GetView().GetEditWin() );
249 pClient
= new SwOleClient( &m_pSh
->GetView(), &m_pSh
->GetView().GetEditWin(), aEmbObjRef
);
250 m_pSh
->SetCheckForOLEInCaption( true );
252 m_pSh
->CalcAndSetScale( aEmbObjRef
);
253 //#50270# We don't need to handle errors,
254 //this does the DoVerb in the SfxViewShell.
255 ErrCode nErr
= pClient
->DoVerb(embed::EmbedVerbs::MS_OLEVERB_SHOW
);
259 ChartHelper::AdaptDefaultsForChart( xObj
);
262 uno::Reference
< chart2::data::XDataReceiver
> xDataReceiver( xChartModel
, uno::UNO_QUERY
);
263 if (bFillWithData
&& xDataReceiver
.is() && rxDataProvider
.is())
265 xDataReceiver
->attachDataProvider( rxDataProvider
);
267 uno::Reference
< util::XNumberFormatsSupplier
> xNumberFormatsSupplier( m_pSh
->GetView().GetDocShell()->GetModel(), uno::UNO_QUERY
);
268 xDataReceiver
->attachNumberFormatsSupplier( xNumberFormatsSupplier
);
270 // default values for ranges that do not consist of a single row or column
271 bool bHasCategories
= true;
272 bool bFirstCellAsLabel
= true;
273 chart::ChartDataRowSource eDataRowSource
= chart::ChartDataRowSource_COLUMNS
;
275 SwRangeDescriptor aDesc
;
276 FillRangeDescriptor( aDesc
, rCellRange
);
277 bool bSingleRowCol
= aDesc
.nTop
== aDesc
.nBottom
|| aDesc
.nLeft
== aDesc
.nRight
;
281 sal_Int32 nRowLen
= aDesc
.nRight
- aDesc
.nLeft
+ 1;
282 sal_Int32 nColLen
= aDesc
.nBottom
- aDesc
.nTop
+ 1;
284 bHasCategories
= false;
285 if (nRowLen
== 1 && nColLen
== 1)
286 bFirstCellAsLabel
= false;
287 else if (nRowLen
> 1)
288 eDataRowSource
= chart::ChartDataRowSource_ROWS
;
289 else if (nColLen
> 1)
290 eDataRowSource
= chart::ChartDataRowSource_COLUMNS
;
292 OSL_FAIL("unexpected state" );
296 uno::Sequence
< beans::PropertyValue
> aArgs
{
297 beans::PropertyValue(
298 "CellRangeRepresentation", -1,
299 uno::Any( rCellRange
), beans::PropertyState_DIRECT_VALUE
),
300 beans::PropertyValue(
302 uno::Any( bHasCategories
), beans::PropertyState_DIRECT_VALUE
),
303 beans::PropertyValue(
304 "FirstCellAsLabel", -1,
305 uno::Any( bFirstCellAsLabel
), beans::PropertyState_DIRECT_VALUE
),
306 beans::PropertyValue(
308 uno::Any( eDataRowSource
), beans::PropertyState_DIRECT_VALUE
)
310 xDataReceiver
->setArguments( aArgs
);
313 m_pSh
->EndUndo( SwUndoId::UI_INSERT_CHART
);
315 if( xChartModel
.is() )
316 xChartModel
->unlockControllers(); //#i79578# don't request a new replacement image for charts to often
320 sal_uInt16
SwTableFUNC::GetCurColNum() const
322 const size_t nPos
= m_pSh
->GetCurTabColNum();
324 for( size_t i
= 0; i
< nPos
; i
++ )
325 if(m_aCols
.IsHidden(i
))
327 return nPos
- nCount
;
330 sal_uInt16
SwTableFUNC::GetColCount() const
333 for(size_t i
= 0; i
< m_aCols
.Count(); i
++ )
334 if(m_aCols
.IsHidden(i
))
336 return m_aCols
.Count() - nCount
;
339 int SwTableFUNC::GetRightSeparator(int nNum
) const
341 OSL_ENSURE( nNum
< static_cast<int>(GetColCount()) ,"Index out of range");
345 if( !m_aCols
.IsHidden(i
) )
352 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */