1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26
27 #include <com/sun/star/chart/ChartDataRowSource.hpp>
28 #include <com/sun/star/chart2/data/XDataProvider.hpp>
29 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
30 #include <com/sun/star/beans/PropertyState.hpp>
31
32 #include <sot/storage.hxx>
33 #include <sot/clsids.hxx>
34 #include <svx/charthelper.hxx>
35
36 #include "edtwin.hxx"
37 #include "errhdl.hxx"
38 #include "wrtsh.hxx"
39 #include "cmdid.h"
40 #include "frmatr.hxx"
41 #include "view.hxx"
42 #include "basesh.hxx"
43 #include "swundo.hxx"
44 #include "tablemgr.hxx"
45 #include "frmfmt.hxx"
46 #include "instable.hxx"
47 #include "swerror.h"
48 #include "table.hrc"
49 #include "swabstdlg.hxx"
50 #include "swcli.hxx"
51 #include "docsh.hxx"
52 #include "unotbl.hxx"
53 #include "unochart.hxx"
54
55 using namespace ::com::sun::star;
56
57 /*------------------------------------------------------------------------
58 Beschreibung: Zeilenhoehe einstellen (Dialog)
59 ------------------------------------------------------------------------*/
60
61
ColWidthDlg(Window * pParent)62 void SwTableFUNC::ColWidthDlg( Window *pParent )
63 {
64 InitTabCols();
65 SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
66 DBG_ASSERT(pFact, "SwAbstractDialogFactory fail!");
67
68 VclAbstractDialog* pDlg = pFact->CreateSwTableWidthDlg( pParent, *this ,DLG_COL_WIDTH );
69 DBG_ASSERT(pDlg, "Dialogdiet fail!");
70 pDlg->Execute();
71 delete pDlg;
72 }
73
74 /*--------------------------------------------------------------------
75 Beschreibung: Breite ermitteln
76 --------------------------------------------------------------------*/
77
78
GetColWidth(sal_uInt16 nNum) const79 SwTwips SwTableFUNC::GetColWidth(sal_uInt16 nNum) const
80 {
81 SwTwips nWidth = 0;
82
83 if( aCols.Count() > 0 )
84 {
85 if(aCols.Count() == GetColCount())
86 {
87 nWidth = (SwTwips)((nNum == aCols.Count()) ?
88 aCols.GetRight() - aCols[nNum-1] :
89 nNum == 0 ? aCols[nNum] - aCols.GetLeft() :
90 aCols[nNum] - aCols[nNum-1]);
91 }
92 else
93 {
94 SwTwips nRValid = nNum < GetColCount() ?
95 aCols[(sal_uInt16)GetRightSeparator((int)nNum)]:
96 aCols.GetRight();
97 SwTwips nLValid = nNum ?
98 aCols[(sal_uInt16)GetRightSeparator((int)nNum - 1)]:
99 aCols.GetLeft();
100 nWidth = nRValid - nLValid;
101 }
102 }
103 else
104 nWidth = aCols.GetRight();
105
106 return nWidth;
107 }
108
109
110
GetMaxColWidth(sal_uInt16 nNum) const111 SwTwips SwTableFUNC::GetMaxColWidth( sal_uInt16 nNum ) const
112 {
113 ASSERT(nNum <= aCols.Count(), "Index out of Area");
114
115 if ( GetColCount() > 0 )
116 {
117 // Die max. Breite ergibt sich aus der eigenen Breite und
118 // der Breite der Nachbarzellen um je MINLAY verringert
119 SwTwips nMax = nNum == 0 ?
120 GetColWidth(1) - MINLAY :
121 nNum == GetColCount() ?
122 GetColWidth( nNum-1 ) - MINLAY :
123 GetColWidth(nNum - 1) + GetColWidth( nNum + 1 ) - 2 * MINLAY;
124
125 return nMax + GetColWidth(nNum) ;
126 }
127 else
128 return GetColWidth(nNum);
129 }
130
131
132
SetColWidth(sal_uInt16 nNum,SwTwips nNewWidth)133 void SwTableFUNC::SetColWidth(sal_uInt16 nNum, SwTwips nNewWidth )
134 {
135 // aktuelle Breite setzen
136 // alle folgenden Verschieben
137 sal_Bool bCurrentOnly = sal_False;
138 SwTwips nWidth = 0;
139
140 if ( aCols.Count() > 0 )
141 {
142 if(aCols.Count() != GetColCount())
143 bCurrentOnly = sal_True;
144 nWidth = GetColWidth(nNum);
145
146 int nDiff = (int)(nNewWidth - nWidth);
147 if( !nNum )
148 aCols[ static_cast< sal_uInt16 >(GetRightSeparator(0)) ] += nDiff;
149 else if( nNum < GetColCount() )
150 {
151 if(nDiff < GetColWidth(nNum + 1) - MINLAY)
152 aCols[ static_cast< sal_uInt16 >(GetRightSeparator(nNum)) ] += nDiff;
153 else
154 {
155 int nDiffLeft = nDiff - (int)GetColWidth(nNum + 1) + (int)MINLAY;
156 aCols[ static_cast< sal_uInt16 >(GetRightSeparator(nNum)) ] += (nDiff - nDiffLeft);
157 aCols[ static_cast< sal_uInt16 >(GetRightSeparator(nNum - 1)) ] -= nDiffLeft;
158 }
159 }
160 else
161 aCols[ static_cast< sal_uInt16 >(GetRightSeparator(nNum-1)) ] -= nDiff;
162 }
163 else
164 aCols.SetRight( Min( nNewWidth, aCols.GetRightMax()) );
165
166 pSh->StartAllAction();
167 pSh->SetTabCols( aCols, bCurrentOnly );
168 pSh->EndAllAction();
169 }
170
171
172
InitTabCols()173 void SwTableFUNC::InitTabCols()
174 {
175 ASSERT(pSh, keine Shell);
176
177 if( pFmt && pSh)
178 pSh->GetTabCols( aCols );
179 }
180
181
182
SwTableFUNC(SwWrtShell * pShell,sal_Bool bCopyFmt)183 SwTableFUNC::SwTableFUNC(SwWrtShell *pShell, sal_Bool bCopyFmt)
184 : pFmt(pShell->GetTableFmt()),
185 pSh(pShell),
186 bCopy(bCopyFmt)
187 {
188 // gfs. das Format fuer die Bearbeitung kopieren
189 if( pFmt && bCopy )
190 pFmt = new SwFrmFmt( *pFmt );
191 }
192
193
194
~SwTableFUNC()195 SwTableFUNC::~SwTableFUNC()
196 {
197 if(bCopy)
198 delete pFmt;
199 }
200
UpdateChart()201 void SwTableFUNC::UpdateChart()
202 {
203 //Update der Felder in der Tabelle vom User ausgeloesst, alle
204 //Charts zu der Tabelle werden auf den neuesten Stand gebracht.
205 SwFrmFmt *pFmt2 = pSh->GetTableFmt();
206 if ( pFmt2 && pSh->HasOLEObj( pFmt2->GetName() ) )
207 {
208 pSh->StartAllAction();
209 pSh->UpdateCharts( pFmt2->GetName() );
210 pSh->EndAllAction();
211 }
212 }
213
InsertChart(uno::Reference<chart2::data::XDataProvider> & rxDataProvider,sal_Bool bFillWithData,const rtl::OUString & rCellRange,SwFlyFrmFmt ** ppFlyFrmFmt)214 uno::Reference< frame::XModel > SwTableFUNC::InsertChart(
215 uno::Reference< chart2::data::XDataProvider > &rxDataProvider,
216 sal_Bool bFillWithData,
217 const rtl::OUString &rCellRange,
218 SwFlyFrmFmt** ppFlyFrmFmt )
219 {
220 uno::Reference< frame::XModel > xChartModel;
221 pSh->StartUndo( UNDO_UI_INSERT_CHART );
222 pSh->StartAllAction();
223
224 String aName;
225 if (pSh->IsCrsrInTbl())
226 {
227 aName = pSh->GetTableFmt()->GetName();
228 // insert node before table
229 pSh->MoveTable( fnTableCurr, fnTableStart );
230 pSh->Up( sal_False, 1, sal_False );
231 if ( pSh->IsCrsrInTbl() )
232 {
233 if ( aName != pSh->GetTableFmt()->GetName() )
234 pSh->Down( sal_False, 1, sal_False ); // two adjacent tables
235 }
236 pSh->SplitNode();
237 }
238
239 // insert chart
240 ::rtl::OUString aObjName;
241 comphelper::EmbeddedObjectContainer aCnt;
242 uno::Reference < embed::XEmbeddedObject > xObj =
243 aCnt.CreateEmbeddedObject( SvGlobalName( SO3_SCH_CLASSID ).GetByteSequence(), aObjName );
244
245 ::svt::EmbeddedObjectRef aEmbObjRef( xObj, ::com::sun::star::embed::Aspects::MSOLE_CONTENT );
246 if ( xObj.is() )
247 {
248
249 SwFlyFrmFmt* pTmp = 0;
250 pSh->InsertOleObject( aEmbObjRef, &pTmp );
251 if (ppFlyFrmFmt)
252 *ppFlyFrmFmt = pTmp;
253
254 uno::Reference< embed::XComponentSupplier > xCompSupp( xObj, uno::UNO_QUERY );
255 if( xCompSupp.is())
256 {
257 xChartModel.set( xCompSupp->getComponent(), uno::UNO_QUERY );
258 if( xChartModel.is() )
259 xChartModel->lockControllers(); //#i79578# don't request a new replacement image for charts to often - block change notifications
260 }
261
262 // set the table name at the OLE-node
263 if (aName.Len())
264 pSh->SetChartName( aName );
265 }
266 pSh->EndAllAction();
267
268 if ( xObj.is() )
269 {
270 // Let the chart be activated after the inserting
271 SfxInPlaceClient* pClient = pSh->GetView().FindIPClient( xObj, &pSh->GetView().GetEditWin() );
272 if ( !pClient )
273 {
274 pClient = new SwOleClient( &pSh->GetView(), &pSh->GetView().GetEditWin(), aEmbObjRef );
275 pSh->SetCheckForOLEInCaption( sal_True );
276 }
277 pSh->CalcAndSetScale( aEmbObjRef );
278 //#50270# Error brauchen wir nicht handeln, das erledigt das
279 //DoVerb in der SfxViewShell
280 ErrCode nErr = pClient->DoVerb( SVVERB_SHOW );
281 (void) nErr;
282
283 // #121334#
284 ChartHelper::AdaptDefaultsForChart( xObj );
285 }
286
287 uno::Reference< chart2::data::XDataReceiver > xDataReceiver( xChartModel, uno::UNO_QUERY );
288 if (bFillWithData && xDataReceiver.is() && rxDataProvider.is())
289 {
290 xDataReceiver->attachDataProvider( rxDataProvider );
291
292 uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( pSh->GetView().GetDocShell()->GetModel(), uno::UNO_QUERY );
293 xDataReceiver->attachNumberFormatsSupplier( xNumberFormatsSupplier );
294
295 // default values for ranges that do not consist of a single row or column
296 bool bHasCategories = true;
297 bool bFirstCellAsLabel = true;
298 chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS;
299
300 SwRangeDescriptor aDesc;
301 FillRangeDescriptor( aDesc, rCellRange );
302 bool bSingleRowCol = aDesc.nTop == aDesc.nBottom || aDesc.nLeft == aDesc.nRight;
303 if (bSingleRowCol)
304 {
305 aDesc.Normalize();
306 sal_Int32 nRowLen = aDesc.nRight - aDesc.nLeft + 1;
307 sal_Int32 nColLen = aDesc.nBottom - aDesc.nTop + 1;
308
309 bHasCategories = false;
310 if (nRowLen == 1 && nColLen == 1)
311 bFirstCellAsLabel = false;
312 else if (nRowLen > 1)
313 eDataRowSource = chart::ChartDataRowSource_ROWS;
314 else if (nColLen > 1)
315 eDataRowSource = chart::ChartDataRowSource_COLUMNS;
316 else {
317 DBG_ERROR( "unexpected state" );
318 }
319 }
320
321 uno::Sequence< beans::PropertyValue > aArgs( 4 );
322 aArgs[0] = beans::PropertyValue(
323 ::rtl::OUString::createFromAscii("CellRangeRepresentation"), -1,
324 uno::makeAny( rCellRange ), beans::PropertyState_DIRECT_VALUE );
325 aArgs[1] = beans::PropertyValue(
326 ::rtl::OUString::createFromAscii("HasCategories"), -1,
327 uno::makeAny( bHasCategories ), beans::PropertyState_DIRECT_VALUE );
328 aArgs[2] = beans::PropertyValue(
329 ::rtl::OUString::createFromAscii("FirstCellAsLabel"), -1,
330 uno::makeAny( bFirstCellAsLabel ), beans::PropertyState_DIRECT_VALUE );
331 aArgs[3] = beans::PropertyValue(
332 ::rtl::OUString::createFromAscii("DataRowSource"), -1,
333 uno::makeAny( eDataRowSource ), beans::PropertyState_DIRECT_VALUE );
334 xDataReceiver->setArguments( aArgs );
335 }
336
337 pSh->EndUndo( UNDO_UI_INSERT_CHART );
338
339 if( xChartModel.is() )
340 xChartModel->unlockControllers(); //#i79578# don't request a new replacement image for charts to often
341 return xChartModel;
342 }
343
GetCurColNum() const344 sal_uInt16 SwTableFUNC::GetCurColNum() const
345 {
346 sal_uInt16 nPos = pSh->GetCurTabColNum();
347 sal_uInt16 nCount = 0;
348 for(sal_uInt16 i = 0; i < nPos; i++ )
349 if(aCols.IsHidden(i))
350 nCount ++;
351 return nPos - nCount;
352 }
353
354
355
356
GetColCount() const357 sal_uInt16 SwTableFUNC::GetColCount() const
358 {
359 sal_uInt16 nCount = 0;
360 for(sal_uInt16 i = 0; i < aCols.Count(); i++ )
361 if(aCols.IsHidden(i))
362 nCount ++;
363 return aCols.Count() - nCount;
364 }
365
366
367
GetRightSeparator(int nNum) const368 int SwTableFUNC::GetRightSeparator(int nNum) const
369 {
370 DBG_ASSERT( nNum < (int)GetColCount() ,"Index out of range");
371 int i = 0;
372 while( nNum >= 0 )
373 {
374 if( !aCols.IsHidden( static_cast< sal_uInt16 >(i)) )
375 nNum--;
376 i++;
377 }
378 return i - 1;
379 }
380
381
382
383