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 <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 :
26 : #include <sot/storage.hxx>
27 : #include <comphelper/classids.hxx>
28 : #include <svx/charthelper.hxx>
29 :
30 : #include "edtwin.hxx"
31 : #include "wrtsh.hxx"
32 : #include "cmdid.h"
33 : #include "frmatr.hxx"
34 : #include "view.hxx"
35 : #include "basesh.hxx"
36 : #include "swundo.hxx"
37 : #include "tablemgr.hxx"
38 : #include "frmfmt.hxx"
39 : #include "instable.hxx"
40 : #include "swerror.h"
41 : #include "table.hrc"
42 : #include "swabstdlg.hxx"
43 : #include "swcli.hxx"
44 : #include "docsh.hxx"
45 : #include "unotbl.hxx"
46 : #include "unochart.hxx"
47 : #include <boost/scoped_ptr.hpp>
48 :
49 : using namespace ::com::sun::star;
50 :
51 : // Adjust line height (dialogue)
52 0 : void SwTableFUNC::ColWidthDlg( vcl::Window *pParent )
53 : {
54 0 : InitTabCols();
55 0 : SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
56 : OSL_ENSURE(pFact, "SwAbstractDialogFactory fail!");
57 :
58 0 : boost::scoped_ptr<VclAbstractDialog> pDlg(pFact->CreateSwTableWidthDlg(pParent, *this));
59 : OSL_ENSURE(pDlg, "Dialog creation failed!");
60 0 : pDlg->Execute();
61 0 : }
62 :
63 : // Determine the width
64 0 : SwTwips SwTableFUNC::GetColWidth(sal_uInt16 nNum) const
65 : {
66 0 : SwTwips nWidth = 0;
67 :
68 0 : if( aCols.Count() > 0 )
69 : {
70 0 : if(aCols.Count() == GetColCount())
71 : {
72 0 : if(nNum == aCols.Count())
73 0 : nWidth = aCols.GetRight() - aCols[nNum-1];
74 : else
75 : {
76 0 : if(nNum == 0)
77 0 : nWidth = aCols[nNum] - aCols.GetLeft();
78 : else
79 0 : nWidth = aCols[nNum] - aCols[nNum-1];
80 : }
81 : }
82 : else
83 : {
84 0 : SwTwips nRValid = nNum < GetColCount() ?
85 0 : aCols[GetRightSeparator(nNum)] :
86 0 : aCols.GetRight();
87 : SwTwips nLValid = nNum ?
88 0 : aCols[GetRightSeparator(nNum - 1)] :
89 0 : aCols.GetLeft();
90 0 : nWidth = nRValid - nLValid;
91 : }
92 : }
93 : else
94 0 : nWidth = aCols.GetRight();
95 0 : return nWidth;
96 : }
97 :
98 0 : SwTwips SwTableFUNC::GetMaxColWidth( sal_uInt16 nNum ) const
99 : {
100 : OSL_ENSURE(nNum <= aCols.Count(), "Index out of Area");
101 :
102 0 : if ( GetColCount() > 0 )
103 : {
104 : // The maximum width arises from the own width and
105 : // the width each of the neighbor cells reduced by MINLAY.
106 : SwTwips nMax;
107 0 : if(nNum == 0)
108 0 : nMax = GetColWidth(1) - MINLAY;
109 : else
110 : {
111 0 : nMax = GetColWidth(nNum-1);
112 0 : if(nNum == GetColCount())
113 0 : nMax -= MINLAY;
114 : else
115 0 : nMax += GetColWidth(nNum+1) - 2 * MINLAY;
116 : }
117 0 : return nMax + GetColWidth(nNum);
118 : }
119 : else
120 0 : return GetColWidth(nNum);
121 : }
122 :
123 0 : void SwTableFUNC::SetColWidth(sal_uInt16 nNum, SwTwips nNewWidth )
124 : {
125 : // set current width
126 : // move all of the following
127 0 : bool bCurrentOnly = false;
128 :
129 0 : if ( aCols.Count() > 0 )
130 : {
131 0 : if(aCols.Count() != GetColCount())
132 0 : bCurrentOnly = true;
133 0 : SwTwips nWidth = GetColWidth(nNum);
134 :
135 0 : int nDiff = (int)(nNewWidth - nWidth);
136 0 : if( !nNum )
137 0 : aCols[ GetRightSeparator(0) ] += nDiff;
138 0 : else if( nNum < GetColCount() )
139 : {
140 0 : if(nDiff < GetColWidth(nNum + 1) - MINLAY)
141 0 : aCols[ GetRightSeparator(nNum) ] += nDiff;
142 : else
143 : {
144 0 : int nDiffLeft = nDiff - (int)GetColWidth(nNum + 1) + (int)MINLAY;
145 0 : aCols[ GetRightSeparator(nNum) ] += (nDiff - nDiffLeft);
146 0 : aCols[ GetRightSeparator(nNum - 1) ] -= nDiffLeft;
147 : }
148 : }
149 : else
150 0 : aCols[ GetRightSeparator(nNum-1) ] -= nDiff;
151 : }
152 : else
153 0 : aCols.SetRight( std::min( nNewWidth, aCols.GetRightMax()) );
154 :
155 0 : pSh->StartAllAction();
156 0 : pSh->SetTabCols( aCols, bCurrentOnly );
157 0 : pSh->EndAllAction();
158 0 : }
159 :
160 0 : void SwTableFUNC::InitTabCols()
161 : {
162 : OSL_ENSURE(pSh, "no Shell");
163 :
164 0 : if( pFormat && pSh)
165 0 : pSh->GetTabCols( aCols );
166 0 : }
167 :
168 0 : SwTableFUNC::SwTableFUNC(SwWrtShell *pShell, bool bCopyFormat)
169 0 : : pFormat(pShell->GetTableFormat()),
170 : pSh(pShell),
171 0 : bCopy(bCopyFormat)
172 : {
173 : // if applicable copy the format for edit
174 0 : if( pFormat && bCopy )
175 0 : pFormat = new SwFrameFormat( *pFormat );
176 0 : }
177 :
178 0 : SwTableFUNC::~SwTableFUNC()
179 : {
180 0 : if(bCopy)
181 0 : delete pFormat;
182 0 : }
183 :
184 0 : void SwTableFUNC::UpdateChart()
185 : {
186 : //Update of the fields triggered by the user, all Charts of
187 : //the table will be brought up to date
188 0 : SwFrameFormat *pFormat2 = pSh->GetTableFormat();
189 0 : if ( pFormat2 && pSh->HasOLEObj( pFormat2->GetName() ) )
190 : {
191 0 : pSh->StartAllAction();
192 0 : pSh->UpdateCharts( pFormat2->GetName() );
193 0 : pSh->EndAllAction();
194 : }
195 0 : }
196 :
197 0 : uno::Reference< frame::XModel > SwTableFUNC::InsertChart(
198 : uno::Reference< chart2::data::XDataProvider > &rxDataProvider,
199 : bool bFillWithData,
200 : const OUString &rCellRange,
201 : SwFlyFrameFormat** ppFlyFrameFormat )
202 : {
203 0 : uno::Reference< frame::XModel > xChartModel;
204 0 : pSh->StartUndo( UNDO_UI_INSERT_CHART );
205 0 : pSh->StartAllAction();
206 :
207 0 : OUString aName;
208 0 : if (pSh->IsCrsrInTable())
209 : {
210 0 : aName = pSh->GetTableFormat()->GetName();
211 : // insert node before table
212 0 : pSh->MoveTable( fnTableCurr, fnTableStart );
213 0 : pSh->Up( false, 1, false );
214 0 : if ( pSh->IsCrsrInTable() )
215 : {
216 0 : if ( aName != pSh->GetTableFormat()->GetName() )
217 0 : pSh->Down( false, 1, false ); // two adjacent tables
218 : }
219 0 : pSh->SplitNode();
220 : }
221 :
222 : // insert chart
223 0 : OUString aObjName;
224 0 : comphelper::EmbeddedObjectContainer aCnt;
225 : uno::Reference < embed::XEmbeddedObject > xObj =
226 0 : aCnt.CreateEmbeddedObject( SvGlobalName( SO3_SCH_CLASSID ).GetByteSequence(), aObjName );
227 :
228 0 : ::svt::EmbeddedObjectRef aEmbObjRef( xObj, ::com::sun::star::embed::Aspects::MSOLE_CONTENT );
229 0 : if ( xObj.is() )
230 : {
231 :
232 0 : SwFlyFrameFormat* pTmp = 0;
233 0 : pSh->InsertOleObject( aEmbObjRef, &pTmp );
234 0 : if (ppFlyFrameFormat)
235 0 : *ppFlyFrameFormat = pTmp;
236 :
237 0 : uno::Reference< embed::XComponentSupplier > xCompSupp( xObj, uno::UNO_QUERY );
238 0 : if( xCompSupp.is())
239 : {
240 0 : xChartModel.set( xCompSupp->getComponent(), uno::UNO_QUERY );
241 0 : if( xChartModel.is() )
242 : {
243 : // Create a default chart type.
244 0 : uno::Reference<chart2::XChartDocument> xChartDoc(xChartModel, uno::UNO_QUERY);
245 0 : if (xChartDoc.is())
246 0 : xChartDoc->createDefaultChart();
247 :
248 0 : xChartModel->lockControllers(); //#i79578# don't request a new replacement image for charts to often - block change notifications
249 : }
250 : }
251 :
252 : // set the table name at the OLE-node
253 0 : if (!aName.isEmpty())
254 0 : pSh->SetChartName( aName );
255 : }
256 0 : pSh->EndAllAction();
257 :
258 0 : if ( xObj.is() )
259 : {
260 : // Let the chart be activated after the inserting
261 0 : SfxInPlaceClient* pClient = pSh->GetView().FindIPClient( xObj, &pSh->GetView().GetEditWin() );
262 0 : if ( !pClient )
263 : {
264 0 : pClient = new SwOleClient( &pSh->GetView(), &pSh->GetView().GetEditWin(), aEmbObjRef );
265 0 : pSh->SetCheckForOLEInCaption( true );
266 : }
267 0 : pSh->CalcAndSetScale( aEmbObjRef );
268 : //#50270# We don't need to handle errors,
269 : //this does the DoVerb in the SfxViewShell.
270 0 : ErrCode nErr = pClient->DoVerb( SVVERB_SHOW );
271 : (void) nErr;
272 :
273 : // #i121334#
274 0 : ChartHelper::AdaptDefaultsForChart( xObj );
275 : }
276 :
277 0 : uno::Reference< chart2::data::XDataReceiver > xDataReceiver( xChartModel, uno::UNO_QUERY );
278 0 : if (bFillWithData && xDataReceiver.is() && rxDataProvider.is())
279 : {
280 0 : xDataReceiver->attachDataProvider( rxDataProvider );
281 :
282 0 : uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( pSh->GetView().GetDocShell()->GetModel(), uno::UNO_QUERY );
283 0 : xDataReceiver->attachNumberFormatsSupplier( xNumberFormatsSupplier );
284 :
285 : // default values for ranges that do not consist of a single row or column
286 0 : bool bHasCategories = true;
287 0 : bool bFirstCellAsLabel = true;
288 0 : chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS;
289 :
290 : SwRangeDescriptor aDesc;
291 0 : FillRangeDescriptor( aDesc, rCellRange );
292 0 : bool bSingleRowCol = aDesc.nTop == aDesc.nBottom || aDesc.nLeft == aDesc.nRight;
293 0 : if (bSingleRowCol)
294 : {
295 0 : aDesc.Normalize();
296 0 : sal_Int32 nRowLen = aDesc.nRight - aDesc.nLeft + 1;
297 0 : sal_Int32 nColLen = aDesc.nBottom - aDesc.nTop + 1;
298 :
299 0 : bHasCategories = false;
300 0 : if (nRowLen == 1 && nColLen == 1)
301 0 : bFirstCellAsLabel = false;
302 0 : else if (nRowLen > 1)
303 0 : eDataRowSource = chart::ChartDataRowSource_ROWS;
304 0 : else if (nColLen > 1)
305 0 : eDataRowSource = chart::ChartDataRowSource_COLUMNS;
306 : else {
307 : OSL_FAIL("unexpected state" );
308 : }
309 : }
310 :
311 0 : uno::Sequence< beans::PropertyValue > aArgs( 4 );
312 0 : aArgs[0] = beans::PropertyValue(
313 : OUString("CellRangeRepresentation"), -1,
314 0 : uno::makeAny( rCellRange ), beans::PropertyState_DIRECT_VALUE );
315 0 : aArgs[1] = beans::PropertyValue(
316 : OUString("HasCategories"), -1,
317 0 : uno::makeAny( bHasCategories ), beans::PropertyState_DIRECT_VALUE );
318 0 : aArgs[2] = beans::PropertyValue(
319 : OUString("FirstCellAsLabel"), -1,
320 0 : uno::makeAny( bFirstCellAsLabel ), beans::PropertyState_DIRECT_VALUE );
321 0 : aArgs[3] = beans::PropertyValue(
322 : OUString("DataRowSource"), -1,
323 0 : uno::makeAny( eDataRowSource ), beans::PropertyState_DIRECT_VALUE );
324 0 : xDataReceiver->setArguments( aArgs );
325 : }
326 :
327 0 : pSh->EndUndo( UNDO_UI_INSERT_CHART );
328 :
329 0 : if( xChartModel.is() )
330 0 : xChartModel->unlockControllers(); //#i79578# don't request a new replacement image for charts to often
331 0 : return xChartModel;
332 : }
333 :
334 0 : sal_uInt16 SwTableFUNC::GetCurColNum() const
335 : {
336 0 : const size_t nPos = pSh->GetCurTabColNum();
337 0 : size_t nCount = 0;
338 0 : for( size_t i = 0; i < nPos; i++ )
339 0 : if(aCols.IsHidden(i))
340 0 : nCount ++;
341 0 : return nPos - nCount;
342 : }
343 :
344 0 : sal_uInt16 SwTableFUNC::GetColCount() const
345 : {
346 0 : size_t nCount = 0;
347 0 : for(size_t i = 0; i < aCols.Count(); i++ )
348 0 : if(aCols.IsHidden(i))
349 0 : nCount ++;
350 0 : return aCols.Count() - nCount;
351 : }
352 :
353 0 : int SwTableFUNC::GetRightSeparator(int nNum) const
354 : {
355 : OSL_ENSURE( nNum < (int)GetColCount() ,"Index out of range");
356 0 : int i = 0;
357 0 : while( nNum >= 0 )
358 : {
359 0 : if( !aCols.IsHidden(i) )
360 0 : nNum--;
361 0 : i++;
362 : }
363 0 : return i - 1;
364 177 : }
365 :
366 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|