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