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