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