Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <memory>
31 : : #include <algorithm>
32 : :
33 : : #include <com/sun/star/chart/ChartDataRowSource.hpp>
34 : : #include <com/sun/star/chart2/data/LabelOrigin.hpp>
35 : : #include <cppuhelper/interfacecontainer.hxx>
36 : : #include <osl/mutex.hxx>
37 : : #include <vcl/svapp.hxx>
38 : : #include <svl/zforlist.hxx> // SvNumberFormatter
39 : : #include <svtools/chartprettypainter.hxx>
40 : :
41 : : #include <XMLRangeHelper.hxx>
42 : : #include <unochart.hxx>
43 : : #include <swtable.hxx>
44 : : #include <unoprnms.hxx>
45 : : #include <unomap.hxx>
46 : : #include <unomid.h>
47 : : #include <unocrsr.hxx>
48 : : #include <unotbl.hxx>
49 : : #include <doc.hxx>
50 : : #include <frmfmt.hxx>
51 : : #include <docsh.hxx>
52 : : #include <ndole.hxx>
53 : : #include <swtypes.hxx>
54 : : #include <unocore.hrc>
55 : : #include <docary.hxx>
56 : : #include <comphelper/servicehelper.hxx>
57 : : #include <comphelper/string.hxx>
58 : :
59 : : #define SN_DATA_PROVIDER "com.sun.star.chart2.data.DataProvider"
60 : : #define SN_DATA_SOURCE "com.sun.star.chart2.data.DataSource"
61 : : #define SN_DATA_SEQUENCE "com.sun.star.chart2.data.DataSequence"
62 : : #define SN_LABELED_DATA_SEQUENCE "com.sun.star.chart2.data.LabeledDataSequence"
63 : :
64 : : using namespace ::com::sun::star;
65 : : using ::rtl::OUString;
66 : :
67 : : // from unotbl.cxx
68 : : extern void lcl_GetCellPosition( const String &rCellName, sal_Int32 &rColumn, sal_Int32 &rRow);
69 : : extern String lcl_GetCellName( sal_Int32 nColumn, sal_Int32 nRow );
70 : : extern int lcl_CompareCellsByColFirst( const String &rCellName1, const String &rCellName2 );
71 : : extern int lcl_CompareCellsByRowFirst( const String &rCellName1, const String &rCellName2 );
72 : : extern int lcl_CompareCellRanges(
73 : : const String &rRange1StartCell, const String &rRange1EndCell,
74 : : const String &rRange2StartCell, const String &rRange2EndCell,
75 : : sal_Bool bCmpColsFirst );
76 : : extern void lcl_NormalizeRange( String &rCell1, String &rCell2 );
77 : :
78 : : //static
79 : 0 : void SwChartHelper::DoUpdateAllCharts( SwDoc* pDoc )
80 : : {
81 [ # # ]: 0 : if (!pDoc)
82 : 0 : return;
83 : :
84 : 0 : uno::Reference< frame::XModel > xRes;
85 : :
86 : : SwOLENode *pONd;
87 : : SwStartNode *pStNd;
88 [ # # ][ # # ]: 0 : SwNodeIndex aIdx( *pDoc->GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 );
89 [ # # ]: 0 : while( 0 != (pStNd = aIdx.GetNode().GetStartNode()) )
90 : : {
91 [ # # ]: 0 : aIdx++;
92 [ # # ][ # # ]: 0 : if (0 != ( pONd = aIdx.GetNode().GetOLENode() ) &&
[ # # ]
93 [ # # ][ # # ]: 0 : ChartPrettyPainter::IsChart( pONd->GetOLEObj().GetObject() ) )
94 : : {
95 : : // Load the object and set modified
96 : :
97 [ # # ]: 0 : uno::Reference < embed::XEmbeddedObject > xIP = pONd->GetOLEObj().GetOleRef();
98 [ # # ][ # # ]: 0 : if ( svt::EmbeddedObjectRef::TryRunningState( xIP ) )
99 : : {
100 : : try
101 : : {
102 [ # # ][ # # ]: 0 : uno::Reference< util::XModifiable > xModif( xIP->getComponent(), uno::UNO_QUERY_THROW );
[ # # ]
103 [ # # ][ # # ]: 0 : xModif->setModified( sal_True );
[ # # ]
104 : : }
105 [ # # ]: 0 : catch ( uno::Exception& )
106 : : {
107 : : }
108 : :
109 : 0 : }
110 : : }
111 [ # # ]: 0 : aIdx.Assign( *pStNd->EndOfSectionNode(), + 1 );
112 [ # # ]: 0 : }
113 : : }
114 : :
115 : 1432 : SwChartLockController_Helper::SwChartLockController_Helper( SwDoc *pDocument ) :
116 : : pDoc( pDocument )
117 : 1432 : , bIsLocked( false )
118 : : {
119 [ + - ]: 1432 : aUnlockTimer.SetTimeout( 1500 );
120 [ + - ]: 1432 : aUnlockTimer.SetTimeoutHdl( LINK( this, SwChartLockController_Helper, DoUnlockAllCharts ));
121 : 1432 : }
122 : :
123 : 1432 : SwChartLockController_Helper::~SwChartLockController_Helper()
124 : : {
125 [ - + ]: 1432 : if (pDoc) // still connected?
126 [ # # ]: 0 : Disconnect();
127 : 1432 : }
128 : :
129 : 0 : void SwChartLockController_Helper::StartOrContinueLocking()
130 : : {
131 [ # # ]: 0 : if (!bIsLocked)
132 : 0 : LockAllCharts();
133 : 0 : aUnlockTimer.Start(); // start or continue time of locking
134 : 0 : }
135 : :
136 : 1432 : void SwChartLockController_Helper::Disconnect()
137 : : {
138 : 1432 : aUnlockTimer.Stop();
139 : 1432 : UnlockAllCharts();
140 : 1432 : pDoc = 0;
141 : 1432 : }
142 : :
143 : 1432 : void SwChartLockController_Helper::LockUnlockAllCharts( sal_Bool bLock )
144 : : {
145 [ - + ]: 1432 : if (!pDoc)
146 : 1432 : return;
147 : :
148 : 1432 : const SwFrmFmts& rTblFmts = *pDoc->GetTblFrmFmts();
149 [ + + ]: 1659 : for( sal_uInt16 n = 0; n < rTblFmts.size(); ++n )
150 : : {
151 : : SwTable* pTmpTbl;
152 : : const SwTableNode* pTblNd;
153 : 227 : SwFrmFmt* pFmt = rTblFmts[ n ];
154 : :
155 [ + - + + ]: 454 : if( 0 != ( pTmpTbl = SwTable::FindTable( pFmt ) ) &&
[ + + ][ + - ]
156 : : 0 != ( pTblNd = pTmpTbl->GetTableNode() ) &&
157 : 227 : pTblNd->GetNodes().IsDocNodes() )
158 : : {
159 : 219 : uno::Reference< frame::XModel > xRes;
160 : :
161 [ + - ]: 219 : String aName( pTmpTbl->GetFrmFmt()->GetName() );
162 : : SwOLENode *pONd;
163 : : SwStartNode *pStNd;
164 [ + - ][ + - ]: 219 : SwNodeIndex aIdx( *pDoc->GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 );
165 [ + + ]: 251 : while( 0 != (pStNd = aIdx.GetNode().GetStartNode()) )
166 : : {
167 [ + - ]: 32 : aIdx++;
168 [ - + # # ]: 32 : if (0 != ( pONd = aIdx.GetNode().GetOLENode() ) &&
[ - + ]
169 : 0 : pONd->GetChartTblName().Len() > 0 /* is chart object? */)
170 : : {
171 [ # # ]: 0 : uno::Reference < embed::XEmbeddedObject > xIP = pONd->GetOLEObj().GetOleRef();
172 [ # # ][ # # ]: 0 : if ( svt::EmbeddedObjectRef::TryRunningState( xIP ) )
173 : : {
174 [ # # ][ # # ]: 0 : xRes = uno::Reference < frame::XModel >( xIP->getComponent(), uno::UNO_QUERY );
[ # # ][ # # ]
175 [ # # ]: 0 : if (xRes.is())
176 : : {
177 [ # # ]: 0 : if (bLock)
178 [ # # ][ # # ]: 0 : xRes->lockControllers();
179 : : else
180 [ # # ][ # # ]: 0 : xRes->unlockControllers();
181 : : }
182 : 0 : }
183 : : }
184 [ + - ]: 32 : aIdx.Assign( *pStNd->EndOfSectionNode(), + 1 );
185 [ + - ][ + - ]: 219 : }
186 : : }
187 : : }
188 : :
189 : 1432 : bIsLocked = bLock;
190 : : }
191 : :
192 : 0 : IMPL_LINK( SwChartLockController_Helper, DoUnlockAllCharts, Timer *, /*pTimer*/ )
193 : : {
194 : 0 : UnlockAllCharts();
195 : 0 : return 0;
196 : : }
197 : :
198 : 0 : static osl::Mutex & GetChartMutex()
199 : : {
200 [ # # ][ # # ]: 0 : static osl::Mutex aMutex;
[ # # ][ # # ]
201 : 0 : return aMutex;
202 : : }
203 : :
204 : 0 : static void LaunchModifiedEvent(
205 : : ::cppu::OInterfaceContainerHelper &rICH,
206 : : const uno::Reference< uno::XInterface > &rxI )
207 : : {
208 [ # # ]: 0 : lang::EventObject aEvtObj( rxI );
209 [ # # ]: 0 : cppu::OInterfaceIteratorHelper aIt( rICH );
210 [ # # ]: 0 : while (aIt.hasMoreElements())
211 : : {
212 [ # # ][ # # ]: 0 : uno::Reference< util::XModifyListener > xRef( aIt.next(), uno::UNO_QUERY );
213 [ # # ]: 0 : if (xRef.is())
214 [ # # ][ # # ]: 0 : xRef->modified( aEvtObj );
215 [ # # ][ # # ]: 0 : }
216 : 0 : }
217 : :
218 : : // rCellRangeName needs to be of one of the following formats:
219 : : // - e.g. "A2:E5" or
220 : : // - e.g. "Table1.A2:E5"
221 : 0 : sal_Bool FillRangeDescriptor(
222 : : SwRangeDescriptor &rDesc,
223 : : const String &rCellRangeName )
224 : : {
225 [ # # ]: 0 : xub_StrLen nToken = STRING_NOTFOUND == rCellRangeName.Search('.') ? 0 : 1;
226 [ # # ]: 0 : String aCellRangeNoTableName( rCellRangeName.GetToken( nToken, '.' ) );
227 [ # # ]: 0 : String aTLName( aCellRangeNoTableName.GetToken(0, ':') ); // name of top left cell
228 [ # # ]: 0 : String aBRName( aCellRangeNoTableName.GetToken(1, ':') ); // name of bottom right cell
229 [ # # ][ # # ]: 0 : if(!aTLName.Len() || !aBRName.Len())
[ # # ]
230 : 0 : return sal_False;
231 : :
232 : 0 : rDesc.nTop = rDesc.nLeft = rDesc.nBottom = rDesc.nRight = -1;
233 [ # # ]: 0 : lcl_GetCellPosition( aTLName, rDesc.nLeft, rDesc.nTop );
234 [ # # ]: 0 : lcl_GetCellPosition( aBRName, rDesc.nRight, rDesc.nBottom );
235 [ # # ]: 0 : rDesc.Normalize();
236 : : OSL_ENSURE( rDesc.nTop != -1 &&
237 : : rDesc.nLeft != -1 &&
238 : : rDesc.nBottom != -1 &&
239 : : rDesc.nRight != -1,
240 : : "failed to get range descriptor" );
241 : : OSL_ENSURE( rDesc.nTop <= rDesc.nBottom && rDesc.nLeft <= rDesc.nRight,
242 : : "invalid range descriptor");
243 [ # # ][ # # ]: 0 : return sal_True;
[ # # ]
244 : : }
245 : :
246 : 0 : static String GetCellRangeName( SwFrmFmt &rTblFmt, SwUnoCrsr &rTblCrsr )
247 : : {
248 [ # # ]: 0 : String aRes;
249 : :
250 : : //!! see also SwXTextTableCursor::getRangeName
251 : :
252 [ # # ]: 0 : SwUnoTableCrsr* pUnoTblCrsr = dynamic_cast<SwUnoTableCrsr*>(&rTblCrsr);
253 [ # # ]: 0 : if (!pUnoTblCrsr)
254 [ # # ]: 0 : return String();
255 [ # # ]: 0 : pUnoTblCrsr->MakeBoxSels();
256 : :
257 : : const SwStartNode* pStart;
258 : 0 : const SwTableBox* pStartBox = 0;
259 : 0 : const SwTableBox* pEndBox = 0;
260 : :
261 [ # # ]: 0 : pStart = pUnoTblCrsr->GetPoint()->nNode.GetNode().FindTableBoxStartNode();
262 [ # # ]: 0 : if (pStart)
263 : : {
264 [ # # ]: 0 : const SwTable* pTable = SwTable::FindTable( &rTblFmt );
265 [ # # ]: 0 : pEndBox = pTable->GetTblBox( pStart->GetIndex());
266 [ # # ][ # # ]: 0 : aRes = pEndBox->GetName();
[ # # ]
267 : :
268 [ # # ]: 0 : if(pUnoTblCrsr->HasMark())
269 : : {
270 [ # # ]: 0 : pStart = pUnoTblCrsr->GetMark()->nNode.GetNode().FindTableBoxStartNode();
271 [ # # ]: 0 : pStartBox = pTable->GetTblBox( pStart->GetIndex());
272 : : }
273 : : OSL_ENSURE( pStartBox, "start box not found" );
274 : : OSL_ENSURE( pEndBox, "end box not found" );
275 : : // need to switch start and end?
276 [ # # ][ # # ]: 0 : if (*pUnoTblCrsr->GetPoint() < *pUnoTblCrsr->GetMark())
277 : : {
278 : 0 : const SwTableBox* pTmpBox = pStartBox;
279 : 0 : pStartBox = pEndBox;
280 : 0 : pEndBox = pTmpBox;
281 : : }
282 : :
283 [ # # ][ # # ]: 0 : aRes = pStartBox->GetName();
[ # # ]
284 [ # # ]: 0 : aRes += (sal_Unicode)':';
285 [ # # ]: 0 : if (pEndBox)
286 [ # # ][ # # ]: 0 : aRes += pEndBox->GetName();
[ # # ]
287 : : else
288 [ # # ][ # # ]: 0 : aRes += pStartBox->GetName();
[ # # ]
289 : : }
290 : :
291 [ # # ][ # # ]: 0 : return aRes;
292 : : }
293 : :
294 : 0 : static String GetRangeRepFromTableAndCells( const String &rTableName,
295 : : const String &rStartCell, const String &rEndCell,
296 : : sal_Bool bForceEndCellName )
297 : : {
298 : : OSL_ENSURE( rTableName.Len(), "table name missing" );
299 : : OSL_ENSURE( rStartCell.Len(), "cell name missing" );
300 : 0 : String aRes( rTableName );
301 [ # # ]: 0 : aRes += (sal_Unicode) '.';
302 [ # # ]: 0 : aRes += rStartCell;
303 : :
304 [ # # ]: 0 : if (rEndCell.Len())
305 : : {
306 [ # # ]: 0 : aRes += (sal_Unicode) ':';
307 [ # # ]: 0 : aRes += rEndCell;
308 : : }
309 [ # # ]: 0 : else if (bForceEndCellName)
310 : : {
311 [ # # ]: 0 : aRes += (sal_Unicode) ':';
312 [ # # ]: 0 : aRes += rStartCell;
313 : : }
314 : :
315 : 0 : return aRes;
316 : : }
317 : :
318 : 0 : static sal_Bool GetTableAndCellsFromRangeRep(
319 : : const OUString &rRangeRepresentation,
320 : : String &rTblName,
321 : : String &rStartCell,
322 : : String &rEndCell,
323 : : sal_Bool bSortStartEndCells = sal_True )
324 : : {
325 : : // parse range representation for table name and cell/range names
326 : : // accepted format sth like: "Table1.A2:C5" , "Table2.A2.1:B3.2"
327 [ # # ]: 0 : String aTblName; // table name
328 : 0 : OUString aRange; // cell range
329 [ # # ]: 0 : String aStartCell; // name of top left cell
330 [ # # ]: 0 : String aEndCell; // name of bottom right cell
331 : 0 : sal_Int32 nIdx = rRangeRepresentation.indexOf( '.' );
332 [ # # ]: 0 : if (nIdx >= 0)
333 : : {
334 [ # # ]: 0 : aTblName = rRangeRepresentation.copy( 0, nIdx );
335 : 0 : aRange = rRangeRepresentation.copy( nIdx + 1 );
336 : 0 : sal_Int32 nPos = aRange.indexOf( ':' );
337 [ # # ]: 0 : if (nPos >= 0) // a cell-range like "Table1.A2:D4"
338 : : {
339 [ # # ]: 0 : aStartCell = aRange.copy( 0, nPos );
340 [ # # ]: 0 : aEndCell = aRange.copy( nPos + 1 );
341 : :
342 : : // need to switch start and end cell ?
343 : : // (does not check for normalization here)
344 [ # # ][ # # ]: 0 : if (bSortStartEndCells && 1 == lcl_CompareCellsByColFirst( aStartCell, aEndCell ))
[ # # ][ # # ]
345 : : {
346 [ # # ]: 0 : String aTmp( aStartCell );
347 [ # # ]: 0 : aStartCell = aEndCell;
348 [ # # ][ # # ]: 0 : aEndCell = aTmp;
349 : : }
350 : : }
351 : : else // a single cell like in "Table1.B3"
352 : : {
353 [ # # ][ # # ]: 0 : aStartCell = aEndCell = aRange;
354 : : }
355 : : }
356 : :
357 : 0 : sal_Bool bSuccess = aTblName.Len() != 0 &&
358 [ # # ][ # # ]: 0 : aStartCell.Len() != 0 && aEndCell.Len() != 0;
[ # # ]
359 [ # # ]: 0 : if (bSuccess)
360 : : {
361 [ # # ]: 0 : rTblName = aTblName;
362 [ # # ]: 0 : rStartCell = aStartCell;
363 [ # # ]: 0 : rEndCell = aEndCell;
364 : : }
365 [ # # ][ # # ]: 0 : return bSuccess;
[ # # ]
366 : : }
367 : :
368 : 0 : static void GetTableByName( const SwDoc &rDoc, const String &rTableName,
369 : : SwFrmFmt **ppTblFmt, SwTable **ppTable)
370 : : {
371 : 0 : SwFrmFmt *pTblFmt = NULL;
372 : :
373 : : // find frame format of table
374 : : //! see SwXTextTables::getByName
375 : 0 : sal_uInt16 nCount = rDoc.GetTblFrmFmtCount(sal_True);
376 [ # # ][ # # ]: 0 : for (sal_uInt16 i = 0; i < nCount && !pTblFmt; ++i)
[ # # ]
377 : : {
378 : 0 : SwFrmFmt& rTblFmt = rDoc.GetTblFrmFmt(i, sal_True);
379 [ # # ]: 0 : if(rTableName == rTblFmt.GetName())
380 : 0 : pTblFmt = &rTblFmt;
381 : : }
382 : :
383 [ # # ]: 0 : if (ppTblFmt)
384 : 0 : *ppTblFmt = pTblFmt;
385 : :
386 [ # # ]: 0 : if (ppTable)
387 [ # # ]: 0 : *ppTable = pTblFmt ? SwTable::FindTable( pTblFmt ) : 0;
388 : 0 : }
389 : :
390 : 0 : static void GetFormatAndCreateCursorFromRangeRep(
391 : : const SwDoc *pDoc,
392 : : const OUString &rRangeRepresentation, // must be a single range (i.e. so called sub-range)
393 : : SwFrmFmt **ppTblFmt, // will be set to the table format of the table used in the range representation
394 : : SwUnoCrsr **ppUnoCrsr ) // will be set to cursor spanning the cell range
395 : : // (cursor will be created!)
396 : : {
397 [ # # ]: 0 : String aTblName; // table name
398 [ # # ]: 0 : String aStartCell; // name of top left cell
399 [ # # ]: 0 : String aEndCell; // name of bottom right cell
400 : : sal_Bool bNamesFound = GetTableAndCellsFromRangeRep( rRangeRepresentation,
401 [ # # ]: 0 : aTblName, aStartCell, aEndCell );
402 : :
403 [ # # ]: 0 : if (!bNamesFound)
404 : : {
405 [ # # ]: 0 : if (ppTblFmt)
406 : 0 : *ppTblFmt = NULL;
407 [ # # ]: 0 : if (ppUnoCrsr)
408 : 0 : *ppUnoCrsr = NULL;
409 : : }
410 : : else
411 : : {
412 : 0 : SwFrmFmt *pTblFmt = NULL;
413 : :
414 : : // is the correct table format already provided?
415 [ # # ][ # # ]: 0 : if (*ppTblFmt != NULL && (*ppTblFmt)->GetName() == aTblName)
[ # # ][ # # ]
416 : 0 : pTblFmt = *ppTblFmt;
417 [ # # ]: 0 : else if (ppTblFmt)
418 [ # # ]: 0 : GetTableByName( *pDoc, aTblName, &pTblFmt, NULL );
419 : :
420 [ # # ]: 0 : if (ppTblFmt)
421 : 0 : *ppTblFmt = pTblFmt;
422 : :
423 [ # # ]: 0 : if (ppUnoCrsr != NULL)
424 : : {
425 : 0 : *ppUnoCrsr = NULL; // default result in case of failure
426 : :
427 [ # # ][ # # ]: 0 : SwTable *pTable = pTblFmt ? SwTable::FindTable( pTblFmt ) : 0;
428 : : // create new SwUnoCrsr spanning the specified range
429 : : //! see also SwXTextTable::GetRangeByName
430 : : // #i80314#
431 : : // perform validation check. Thus, pass <true> as 2nd parameter to <SwTable::GetTblBox(..)>
432 : : const SwTableBox* pTLBox =
433 [ # # ][ # # ]: 0 : pTable ? pTable->GetTblBox( aStartCell, true ) : 0;
434 [ # # ]: 0 : if(pTLBox)
435 : : {
436 : : // hier muessen die Actions aufgehoben werden
437 [ # # ]: 0 : UnoActionRemoveContext aRemoveContext(pTblFmt->GetDoc());
438 : 0 : const SwStartNode* pSttNd = pTLBox->GetSttNd();
439 [ # # ]: 0 : SwPosition aPos(*pSttNd);
440 : : // set cursor to top left box of range
441 [ # # ]: 0 : SwUnoCrsr* pUnoCrsr = pTblFmt->GetDoc()->CreateUnoCrsr(aPos, sal_True);
442 [ # # ]: 0 : pUnoCrsr->Move( fnMoveForward, fnGoNode );
443 : 0 : pUnoCrsr->SetRemainInSection( sal_False );
444 : : // #i80314#
445 : : // perform validation check. Thus, pass <true> as 2nd parameter to <SwTable::GetTblBox(..)>
446 [ # # ]: 0 : const SwTableBox* pBRBox = pTable->GetTblBox( aEndCell, true );
447 [ # # ]: 0 : if(pBRBox)
448 : : {
449 [ # # ]: 0 : pUnoCrsr->SetMark();
450 [ # # ]: 0 : pUnoCrsr->GetPoint()->nNode = *pBRBox->GetSttNd();
451 [ # # ]: 0 : pUnoCrsr->Move( fnMoveForward, fnGoNode );
452 : : SwUnoTableCrsr* pCrsr =
453 [ # # ]: 0 : dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr);
454 [ # # ]: 0 : pCrsr->MakeBoxSels();
455 : :
456 [ # # ]: 0 : if (ppUnoCrsr)
457 [ # # ]: 0 : *ppUnoCrsr = pCrsr;
458 : : }
459 : : else
460 : : {
461 [ # # ][ # # ]: 0 : delete pUnoCrsr;
462 [ # # ][ # # ]: 0 : }
463 : : }
464 : : }
465 [ # # ][ # # ]: 0 : }
[ # # ]
466 : 0 : }
467 : :
468 : 0 : static sal_Bool GetSubranges( const OUString &rRangeRepresentation,
469 : : uno::Sequence< OUString > &rSubRanges, sal_Bool bNormalize )
470 : : {
471 : 0 : sal_Bool bRes = sal_True;
472 [ # # ]: 0 : String aRangesStr( rRangeRepresentation );
473 [ # # ][ # # ]: 0 : xub_StrLen nLen = comphelper::string::getTokenCount(aRangesStr, ';');
474 [ # # ]: 0 : uno::Sequence< OUString > aRanges( nLen );
475 : :
476 : 0 : sal_Int32 nCnt = 0;
477 [ # # ]: 0 : if (nLen != 0)
478 : : {
479 [ # # ]: 0 : OUString *pRanges = aRanges.getArray();
480 [ # # ]: 0 : String aFirstTable;
481 [ # # ][ # # ]: 0 : for ( xub_StrLen i = 0; i < nLen && bRes; ++i)
[ # # ]
482 : : {
483 [ # # ]: 0 : String aRange( aRangesStr.GetToken( i, ';' ) );
484 [ # # ]: 0 : if (aRange.Len())
485 : : {
486 [ # # ]: 0 : pRanges[nCnt] = aRange;
487 : :
488 [ # # ][ # # ]: 0 : String aTableName, aStartCell, aEndCell;
[ # # ]
489 : : bRes &= GetTableAndCellsFromRangeRep( aRange,
490 [ # # ][ # # ]: 0 : aTableName, aStartCell, aEndCell );
491 : :
492 [ # # ]: 0 : if (bNormalize)
493 : : {
494 [ # # ]: 0 : lcl_NormalizeRange( aStartCell, aEndCell );
495 : : pRanges[nCnt] = GetRangeRepFromTableAndCells( aTableName,
496 [ # # ][ # # ]: 0 : aStartCell, aEndCell, sal_True );
[ # # ]
497 : : }
498 : :
499 : : // make sure to use only a single table
500 [ # # ]: 0 : if (nCnt == 0)
501 [ # # ]: 0 : aFirstTable = aTableName;
502 : : else
503 [ # # ]: 0 : bRes &= aFirstTable == aTableName;
504 : :
505 [ # # ][ # # ]: 0 : ++nCnt;
[ # # ]
506 : : }
507 [ # # ][ # # ]: 0 : }
508 : : }
509 [ # # ]: 0 : aRanges.realloc( nCnt );
510 : :
511 [ # # ]: 0 : rSubRanges = aRanges;
512 [ # # ][ # # ]: 0 : return bRes;
513 : : }
514 : :
515 : 0 : static void SortSubranges( uno::Sequence< OUString > &rSubRanges, sal_Bool bCmpByColumn )
516 : : {
517 : 0 : sal_Int32 nLen = rSubRanges.getLength();
518 [ # # ]: 0 : OUString *pSubRanges = rSubRanges.getArray();
519 : :
520 [ # # ]: 0 : String aSmallestTblName;
521 [ # # ]: 0 : String aSmallestStartCell;
522 [ # # ]: 0 : String aSmallestEndCell;
523 : :
524 [ # # ]: 0 : for (sal_Int32 i = 0; i < nLen; ++i)
525 : : {
526 : 0 : sal_Int32 nIdxOfSmallest = i;
527 : : GetTableAndCellsFromRangeRep( pSubRanges[nIdxOfSmallest],
528 [ # # ]: 0 : aSmallestTblName, aSmallestStartCell, aSmallestEndCell );
529 [ # # ]: 0 : if (aSmallestEndCell.Len() == 0)
530 [ # # ]: 0 : aSmallestEndCell = aSmallestStartCell;
531 : :
532 [ # # ]: 0 : for (sal_Int32 k = i+1; k < nLen; ++k)
533 : : {
534 : : // get cell names for sub range
535 [ # # ]: 0 : String aTblName;
536 [ # # ]: 0 : String aStartCell;
537 [ # # ]: 0 : String aEndCell;
538 : : GetTableAndCellsFromRangeRep( pSubRanges[k],
539 [ # # ]: 0 : aTblName, aStartCell, aEndCell );
540 [ # # ]: 0 : if (aEndCell.Len() == 0)
541 [ # # ]: 0 : aEndCell = aStartCell;
542 : :
543 : : // compare cell ranges ( is the new one smaller? )
544 [ # # ]: 0 : if (-1 == lcl_CompareCellRanges( aStartCell, aEndCell,
545 [ # # ]: 0 : aSmallestStartCell, aSmallestEndCell, bCmpByColumn ))
546 : : {
547 : 0 : nIdxOfSmallest = k;
548 [ # # ]: 0 : aSmallestTblName = aTblName;
549 [ # # ]: 0 : aSmallestStartCell = aStartCell;
550 [ # # ]: 0 : aSmallestEndCell = aEndCell;
551 : : }
552 [ # # ][ # # ]: 0 : }
[ # # ]
553 : :
554 : : // move smallest element to the start of the not sorted area
555 : 0 : OUString aTmp( pSubRanges[ nIdxOfSmallest ] );
556 : 0 : pSubRanges[ nIdxOfSmallest ] = pSubRanges[ i ];
557 : 0 : pSubRanges[ i ] = aTmp;
558 [ # # ][ # # ]: 0 : }
[ # # ]
559 : 0 : }
560 : :
561 : 0 : SwChartDataProvider::SwChartDataProvider( const SwDoc* pSwDoc ) :
562 [ # # ]: 0 : aEvtListeners( GetChartMutex() ),
563 [ # # ][ # # ]: 0 : pDoc( pSwDoc )
564 : : {
565 : 0 : bDisposed = sal_False;
566 : 0 : }
567 : :
568 [ # # ][ # # ]: 0 : SwChartDataProvider::~SwChartDataProvider()
569 : : {
570 [ # # ]: 0 : }
571 : :
572 : 0 : uno::Reference< chart2::data::XDataSource > SwChartDataProvider::Impl_createDataSource(
573 : : const uno::Sequence< beans::PropertyValue >& rArguments, sal_Bool bTestOnly )
574 : : throw (lang::IllegalArgumentException, uno::RuntimeException)
575 : : {
576 [ # # ]: 0 : SolarMutexGuard aGuard;
577 [ # # ]: 0 : if (bDisposed)
578 [ # # ]: 0 : throw lang::DisposedException();
579 : :
580 : 0 : uno::Reference< chart2::data::XDataSource > xRes;
581 : :
582 [ # # ]: 0 : if (!pDoc)
583 [ # # ]: 0 : throw uno::RuntimeException();
584 : :
585 : : // get arguments
586 : 0 : OUString aRangeRepresentation;
587 [ # # ]: 0 : uno::Sequence< sal_Int32 > aSequenceMapping;
588 : 0 : sal_Bool bFirstIsLabel = sal_False;
589 : 0 : sal_Bool bDtaSrcIsColumns = sal_True; // true : DataSource will be sequence of columns
590 : : // false: DataSource will be sequence of rows
591 : 0 : OUString aChartOleObjectName;//work around wrong writer ranges ( see Issue 58464 )
592 : 0 : sal_Int32 nArgs = rArguments.getLength();
593 : : OSL_ENSURE( nArgs != 0, "no properties provided" );
594 [ # # ]: 0 : if (nArgs == 0)
595 : : return xRes;
596 : 0 : const beans::PropertyValue *pArg = rArguments.getConstArray();
597 [ # # ]: 0 : for (sal_Int32 i = 0; i < nArgs; ++i)
598 : : {
599 [ # # ]: 0 : if ( pArg[i].Name == "DataRowSource" )
600 : : {
601 : : chart::ChartDataRowSource eSource;
602 [ # # ][ # # ]: 0 : if (!(pArg[i].Value >>= eSource))
603 : : {
604 : 0 : sal_Int32 nTmp = 0;
605 [ # # ]: 0 : if (!(pArg[i].Value >>= nTmp))
606 [ # # ]: 0 : throw lang::IllegalArgumentException();
607 : 0 : eSource = static_cast< chart::ChartDataRowSource >( nTmp );
608 : : }
609 : 0 : bDtaSrcIsColumns = eSource == chart::ChartDataRowSource_COLUMNS;
610 : : }
611 [ # # ]: 0 : else if ( pArg[i].Name == "FirstCellAsLabel" )
612 : : {
613 [ # # ]: 0 : if (!(pArg[i].Value >>= bFirstIsLabel))
614 [ # # ]: 0 : throw lang::IllegalArgumentException();
615 : : }
616 [ # # ]: 0 : else if ( pArg[i].Name == "CellRangeRepresentation" )
617 : : {
618 [ # # ]: 0 : if (!(pArg[i].Value >>= aRangeRepresentation))
619 [ # # ]: 0 : throw lang::IllegalArgumentException();
620 : : }
621 [ # # ]: 0 : else if ( pArg[i].Name == "SequenceMapping" )
622 : : {
623 [ # # ][ # # ]: 0 : if (!(pArg[i].Value >>= aSequenceMapping))
624 [ # # ]: 0 : throw lang::IllegalArgumentException();
625 : : }
626 [ # # ]: 0 : else if ( pArg[i].Name == "ChartOleObjectName" )
627 : : {
628 [ # # ]: 0 : if (!(pArg[i].Value >>= aChartOleObjectName))
629 [ # # ]: 0 : throw lang::IllegalArgumentException();
630 : : }
631 : : }
632 : :
633 [ # # ]: 0 : uno::Sequence< OUString > aSubRanges;
634 : : // get sub-ranges and check that they all are from the very same table
635 [ # # ]: 0 : sal_Bool bOk = GetSubranges( aRangeRepresentation, aSubRanges, sal_True );
636 : :
637 [ # # ][ # # ]: 0 : if (!bOk && pDoc && !aChartOleObjectName.isEmpty() )
[ # # ][ # # ]
638 : : {
639 : : //try to correct the range here
640 : : //work around wrong writer ranges ( see Issue 58464 )
641 [ # # ]: 0 : String aChartTableName;
642 : :
643 [ # # ]: 0 : const SwNodes& rNodes = pDoc->GetNodes();
644 [ # # ]: 0 : for( sal_uLong nN = rNodes.Count(); nN--; )
645 : : {
646 [ # # ]: 0 : SwNodePtr pNode = rNodes[nN];
647 [ # # ]: 0 : if( !pNode )
648 : 0 : continue;
649 : 0 : const SwOLENode* pOleNode = pNode->GetOLENode();
650 [ # # ]: 0 : if( !pOleNode )
651 : 0 : continue;
652 : 0 : const SwOLEObj& rOObj = pOleNode->GetOLEObj();
653 [ # # ][ # # ]: 0 : if( aChartOleObjectName.equals( rOObj.GetCurrentPersistName() ) )
654 : : {
655 [ # # ]: 0 : aChartTableName = pOleNode->GetChartTblName();
656 : 0 : break;
657 : : }
658 : : }
659 : :
660 [ # # ]: 0 : if( aChartTableName.Len() )
661 : : {
662 : : //the wrong range is still shifted one row down
663 : : //thus the first row is missing and an invalid row at the end is added.
664 : : //Therefore we need to shift the range one row up
665 : : SwRangeDescriptor aDesc;
666 [ # # ]: 0 : if (aRangeRepresentation.isEmpty())
667 : : return xRes; // we cant handle this thus returning an empty references
668 : 0 : aRangeRepresentation = aRangeRepresentation.copy( 1 ); // get rid of '.' to have only the cell range left
669 [ # # ][ # # ]: 0 : FillRangeDescriptor( aDesc, aRangeRepresentation );
[ # # ]
670 [ # # ]: 0 : aDesc.Normalize();
671 [ # # ]: 0 : if (aDesc.nTop <= 0) // no chance to shift the range one row up?
672 : : return xRes; // we cant handle this thus returning an empty references
673 : 0 : aDesc.nTop -= 1;
674 : 0 : aDesc.nBottom -= 1;
675 : :
676 [ # # ]: 0 : String aNewStartCell( lcl_GetCellName( aDesc.nLeft, aDesc.nTop ) );
677 [ # # ]: 0 : String aNewEndCell( lcl_GetCellName( aDesc.nRight, aDesc.nBottom ) );
678 : : aRangeRepresentation = GetRangeRepFromTableAndCells(
679 [ # # ][ # # ]: 0 : aChartTableName, aNewStartCell, aNewEndCell, sal_True );
[ # # ]
680 [ # # ][ # # ]: 0 : bOk = GetSubranges( aRangeRepresentation, aSubRanges, sal_True );
[ # # ]
681 [ # # ][ # # ]: 0 : }
682 : : }
683 [ # # ]: 0 : if (!bOk) // different tables used, or incorrect range specifiers
684 [ # # ]: 0 : throw lang::IllegalArgumentException();
685 : :
686 [ # # ]: 0 : SortSubranges( aSubRanges, bDtaSrcIsColumns );
687 : 0 : const OUString *pSubRanges = aSubRanges.getConstArray();
688 : : #if OSL_DEBUG_LEVEL > 1
689 : : {
690 : : sal_Int32 nSR = aSubRanges.getLength();
691 : : OUString *pSR = aSubRanges.getArray();
692 : : OUString aRg;
693 : : for (sal_Int32 i = 0; i < nSR; ++i)
694 : : {
695 : : aRg = pSR[i];
696 : : }
697 : : }
698 : : #endif
699 : :
700 : : // get table format for that single table from above
701 : 0 : SwFrmFmt *pTblFmt = 0; // pointer to table format
702 : 0 : SwUnoCrsr *pUnoCrsr = 0; // here required to check if the cells in the range do actually exist
703 : 0 : std::auto_ptr< SwUnoCrsr > pAuto( pUnoCrsr ); // to end lifetime of object pointed to by pUnoCrsr
704 [ # # ]: 0 : if (aSubRanges.getLength() > 0)
705 [ # # ]: 0 : GetFormatAndCreateCursorFromRangeRep( pDoc, pSubRanges[0], &pTblFmt, &pUnoCrsr );
706 [ # # ][ # # ]: 0 : if (!pTblFmt || !pUnoCrsr)
707 [ # # ]: 0 : throw lang::IllegalArgumentException();
708 : :
709 [ # # ]: 0 : if(pTblFmt)
710 : : {
711 [ # # ]: 0 : SwTable* pTable = SwTable::FindTable( pTblFmt );
712 [ # # ][ # # ]: 0 : if(pTable->IsTblComplex())
713 : : return xRes; // we cant handle this thus returning an empty references
714 : : else
715 : : {
716 : : // get a character map in the size of the table to mark
717 : : // all the ranges to use in
718 : 0 : sal_Int32 nRows = pTable->GetTabLines().size();
719 [ # # ]: 0 : sal_Int32 nCols = pTable->GetTabLines().front()->GetTabBoxes().size();
720 [ # # ]: 0 : std::vector< std::vector< sal_Char > > aMap( nRows );
721 [ # # ]: 0 : for (sal_Int32 i = 0; i < nRows; ++i)
722 [ # # ][ # # ]: 0 : aMap[i].resize( nCols );
723 : :
724 : : // iterate over subranges and mark used cells in above map
725 : : //!! by proceeding this way we automatically get rid of
726 : : //!! multiple listed or overlapping cell ranges which should
727 : : //!! just be ignored silently
728 : 0 : sal_Int32 nSubRanges = aSubRanges.getLength();
729 [ # # ]: 0 : for (sal_Int32 i = 0; i < nSubRanges; ++i)
730 : : {
731 [ # # ][ # # ]: 0 : String aTblName, aStartCell, aEndCell;
[ # # ]
732 : : sal_Bool bOk2 = GetTableAndCellsFromRangeRep(
733 [ # # ]: 0 : pSubRanges[i], aTblName, aStartCell, aEndCell );
734 : : (void) bOk2;
735 : : OSL_ENSURE( bOk2, "failed to get table and start/end cells" );
736 : :
737 : : sal_Int32 nStartRow, nStartCol, nEndRow, nEndCol;
738 [ # # ]: 0 : lcl_GetCellPosition( aStartCell, nStartCol, nStartRow );
739 [ # # ]: 0 : lcl_GetCellPosition( aEndCell, nEndCol, nEndRow );
740 : : OSL_ENSURE( nStartRow <= nEndRow && nStartCol <= nEndCol,
741 : : "cell range not normalized");
742 : :
743 : : // test if the ranges span more than the available cells
744 [ # # ][ # # ]: 0 : if( nStartRow < 0 || nEndRow >= nRows ||
[ # # ][ # # ]
745 : : nStartCol < 0 || nEndCol >= nCols )
746 : : {
747 [ # # ]: 0 : throw lang::IllegalArgumentException();
748 : : }
749 [ # # ]: 0 : for (sal_Int32 k1 = nStartRow; k1 <= nEndRow; ++k1)
750 : : {
751 [ # # ]: 0 : for (sal_Int32 k2 = nStartCol; k2 <= nEndCol; ++k2)
752 [ # # ][ # # ]: 0 : aMap[k1][k2] = 'x';
753 : : }
754 [ # # ][ # # ]: 0 : }
[ # # ]
755 : :
756 : : //
757 : : // find label and data sequences to use
758 : : //
759 : : sal_Int32 oi; // outer index (slower changing index)
760 : : sal_Int32 ii; // inner index (faster changing index)
761 [ # # ]: 0 : sal_Int32 oiEnd = bDtaSrcIsColumns ? nCols : nRows;
762 [ # # ]: 0 : sal_Int32 iiEnd = bDtaSrcIsColumns ? nRows : nCols;
763 [ # # ]: 0 : std::vector< sal_Int32 > aLabelIdx( oiEnd );
764 [ # # ]: 0 : std::vector< sal_Int32 > aDataStartIdx( oiEnd );
765 [ # # ]: 0 : std::vector< sal_Int32 > aDataLen( oiEnd );
766 [ # # ]: 0 : for (oi = 0; oi < oiEnd; ++oi)
767 : : {
768 [ # # ]: 0 : aLabelIdx[oi] = -1;
769 [ # # ]: 0 : aDataStartIdx[oi] = -1;
770 [ # # ]: 0 : aDataLen[oi] = 0;
771 : : }
772 : : //
773 [ # # ]: 0 : for (oi = 0; oi < oiEnd; ++oi)
774 : : {
775 : 0 : ii = 0;
776 [ # # ]: 0 : while (ii < iiEnd)
777 : : {
778 [ # # ][ # # ]: 0 : sal_Char &rChar = bDtaSrcIsColumns ? aMap[ii][oi] : aMap[oi][ii];
[ # # ][ # # ]
[ # # ]
779 : :
780 : : // label should be used but is not yet found?
781 [ # # ][ # # ]: 0 : if (rChar == 'x' && bFirstIsLabel && aLabelIdx[oi] == -1)
[ # # ][ # # ]
[ # # ]
782 : : {
783 [ # # ]: 0 : aLabelIdx[oi] = ii;
784 : 0 : rChar = 'L'; // setting a different char for labels here
785 : : // makes the test for the data sequence below
786 : : // easier
787 : : }
788 : :
789 : : // find data sequence
790 [ # # ][ # # ]: 0 : if (rChar == 'x' && aDataStartIdx[oi] == -1)
[ # # ][ # # ]
791 : : {
792 [ # # ]: 0 : aDataStartIdx[oi] = ii;
793 : :
794 : : // get length of data sequence
795 : 0 : sal_Int32 nL = 0;
796 : : sal_Char c;
797 [ # # ][ # # ]: 0 : while (ii< iiEnd && 'x' == (c = bDtaSrcIsColumns ? aMap[ii][oi] : aMap[oi][ii]))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
798 : : {
799 : 0 : ++nL; ++ii;
800 : : }
801 [ # # ]: 0 : aDataLen[oi] = nL;
802 : :
803 : : // check that there is no other seperate sequence of data
804 : : // to be found because that is not supported
805 [ # # ]: 0 : while (ii < iiEnd)
806 : : {
807 [ # # ][ # # ]: 0 : if ('x' == (c = bDtaSrcIsColumns ? aMap[ii][oi] : aMap[oi][ii]))
[ # # ][ # # ]
[ # # ][ # # ]
808 [ # # ]: 0 : throw lang::IllegalArgumentException();
809 : 0 : ++ii;
810 : : }
811 : : }
812 : : else
813 : 0 : ++ii;
814 : : }
815 : : }
816 : :
817 : : // make some other consistency checks while calculating
818 : : // the number of XLabeledDataSequence to build:
819 : : // - labels should always be used or not at all
820 : : // - the data sequences should have equal non-zero length
821 : 0 : sal_Int32 nNumLDS = 0;
822 [ # # ]: 0 : if (oiEnd > 0)
823 : : {
824 : 0 : sal_Int32 nFirstSeqLen = 0;
825 : 0 : sal_Int32 nFirstSeqLabelIdx = -1;
826 [ # # ]: 0 : for (oi = 0; oi < oiEnd; ++oi)
827 : : {
828 : 0 : sal_Bool bFirstFound = sal_False;
829 : : // row/col used at all?
830 [ # # ][ # # ]: 0 : if (aDataStartIdx[oi] != -1 &&
[ # # ][ # # ]
[ # # ]
831 [ # # ]: 0 : (!bFirstIsLabel || aLabelIdx[oi] != -1))
832 : : {
833 : 0 : ++nNumLDS;
834 [ # # ]: 0 : if (!bFirstFound)
835 : : {
836 [ # # ]: 0 : nFirstSeqLen = aDataLen[oi];
837 [ # # ]: 0 : nFirstSeqLabelIdx = aLabelIdx[oi];
838 : 0 : bFirstFound = sal_True;
839 : : }
840 : : else
841 : : {
842 [ # # ][ # # ]: 0 : if (nFirstSeqLen != aDataLen[oi] ||
[ # # ][ # # ]
843 [ # # ]: 0 : nFirstSeqLabelIdx != aLabelIdx[oi])
844 [ # # ]: 0 : throw lang::IllegalArgumentException();
845 : : }
846 : : }
847 : : }
848 : : }
849 [ # # ]: 0 : if (nNumLDS == 0)
850 [ # # ]: 0 : throw lang::IllegalArgumentException();
851 : :
852 : : // now we should have all necessary data to build a proper DataSource
853 : : // thus if we came this far there should be no further problem
854 [ # # ]: 0 : if (bTestOnly)
855 : : return xRes; // have createDataSourcePossible return true
856 : :
857 : : // create data source from found label and data sequences
858 [ # # ]: 0 : uno::Sequence< uno::Reference< chart2::data::XDataSequence > > aLabelSeqs( nNumLDS );
859 [ # # ]: 0 : uno::Reference< chart2::data::XDataSequence > *pLabelSeqs = aLabelSeqs.getArray();
860 [ # # ]: 0 : uno::Sequence< uno::Reference< chart2::data::XDataSequence > > aDataSeqs( nNumLDS );
861 [ # # ]: 0 : uno::Reference< chart2::data::XDataSequence > *pDataSeqs = aDataSeqs.getArray();
862 : 0 : sal_Int32 nSeqsIdx = 0;
863 [ # # ]: 0 : for (oi = 0; oi < oiEnd; ++oi)
864 : : {
865 : : // row/col not used? (see if-statement above where nNumLDS was counted)
866 [ # # ][ # # ]: 0 : if (!(aDataStartIdx[oi] != -1 &&
867 [ # # ][ # # ]: 0 : (!bFirstIsLabel || aLabelIdx[oi] != -1)))
[ # # ][ # # ]
868 : 0 : continue;
869 : :
870 : : // get cell ranges for label and data
871 : : //
872 : : SwRangeDescriptor aLabelDesc;
873 : : SwRangeDescriptor aDataDesc;
874 [ # # ]: 0 : if (bDtaSrcIsColumns) // use columns
875 : : {
876 [ # # ]: 0 : aLabelDesc.nTop = aLabelIdx[oi];
877 : 0 : aLabelDesc.nLeft = oi;
878 : 0 : aLabelDesc.nBottom = aLabelDesc.nTop;
879 : 0 : aLabelDesc.nRight = oi;
880 : :
881 [ # # ]: 0 : aDataDesc.nTop = aDataStartIdx[oi];
882 : 0 : aDataDesc.nLeft = oi;
883 [ # # ]: 0 : aDataDesc.nBottom = aDataDesc.nTop + aDataLen[oi] - 1;
884 : 0 : aDataDesc.nRight = oi;
885 : : }
886 : : else // use rows
887 : : {
888 : 0 : aLabelDesc.nTop = oi;
889 [ # # ]: 0 : aLabelDesc.nLeft = aLabelIdx[oi];
890 : 0 : aLabelDesc.nBottom = oi;
891 : 0 : aLabelDesc.nRight = aLabelDesc.nLeft;
892 : :
893 : 0 : aDataDesc.nTop = oi;
894 [ # # ]: 0 : aDataDesc.nLeft = aDataStartIdx[oi];
895 : 0 : aDataDesc.nBottom = oi;
896 [ # # ]: 0 : aDataDesc.nRight = aDataDesc.nLeft + aDataLen[oi] - 1;
897 : : }
898 [ # # ]: 0 : String aBaseName( pTblFmt->GetName() );
899 [ # # ]: 0 : aBaseName += '.';
900 : : //
901 [ # # ]: 0 : String aLabelRange;
902 [ # # ][ # # ]: 0 : if (aLabelIdx[oi] != -1)
903 : : {
904 [ # # ]: 0 : aLabelRange += aBaseName;
905 [ # # ][ # # ]: 0 : aLabelRange += lcl_GetCellName( aLabelDesc.nLeft, aLabelDesc.nTop );
[ # # ]
906 [ # # ]: 0 : aLabelRange += ':';
907 [ # # ][ # # ]: 0 : aLabelRange += lcl_GetCellName( aLabelDesc.nRight, aLabelDesc.nBottom );
[ # # ]
908 : : }
909 : : //
910 [ # # ]: 0 : String aDataRange;
911 [ # # ][ # # ]: 0 : if (aDataStartIdx[oi] != -1)
912 : : {
913 [ # # ]: 0 : aDataRange += aBaseName;
914 [ # # ][ # # ]: 0 : aDataRange += lcl_GetCellName( aDataDesc.nLeft, aDataDesc.nTop );
[ # # ]
915 [ # # ]: 0 : aDataRange += ':';
916 [ # # ][ # # ]: 0 : aDataRange += lcl_GetCellName( aDataDesc.nRight, aDataDesc.nBottom );
[ # # ]
917 : : }
918 : :
919 : : // get cursors spanning the cell ranges for label and data
920 : 0 : SwUnoCrsr *pLabelUnoCrsr = 0;
921 : 0 : SwUnoCrsr *pDataUnoCrsr = 0;
922 [ # # ][ # # ]: 0 : GetFormatAndCreateCursorFromRangeRep( pDoc, aLabelRange, &pTblFmt, &pLabelUnoCrsr);
923 [ # # ][ # # ]: 0 : GetFormatAndCreateCursorFromRangeRep( pDoc, aDataRange, &pTblFmt, &pDataUnoCrsr);
924 : :
925 : : // create XDataSequence's from cursors
926 [ # # ]: 0 : if (pLabelUnoCrsr)
927 [ # # ][ # # ]: 0 : pLabelSeqs[ nSeqsIdx ] = new SwChartDataSequence( *this, *pTblFmt, pLabelUnoCrsr );
[ # # ]
928 : : OSL_ENSURE( pDataUnoCrsr, "pointer to data sequence missing" );
929 [ # # ]: 0 : if (pDataUnoCrsr)
930 [ # # ][ # # ]: 0 : pDataSeqs [ nSeqsIdx ] = new SwChartDataSequence( *this, *pTblFmt, pDataUnoCrsr );
[ # # ]
931 [ # # ][ # # ]: 0 : if (pLabelUnoCrsr || pDataUnoCrsr)
932 : 0 : ++nSeqsIdx;
933 [ # # ][ # # ]: 0 : }
[ # # ]
934 : : OSL_ENSURE( nSeqsIdx == nNumLDS,
935 : : "mismatch between sequence size and num,ber of entries" );
936 : :
937 : : // build data source from data and label sequences
938 [ # # ]: 0 : uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aLDS( nNumLDS );
939 [ # # ]: 0 : uno::Reference< chart2::data::XLabeledDataSequence > *pLDS = aLDS.getArray();
940 [ # # ]: 0 : for (sal_Int32 i = 0; i < nNumLDS; ++i)
941 : : {
942 [ # # ]: 0 : SwChartLabeledDataSequence *pLabeledDtaSeq = new SwChartLabeledDataSequence;
943 [ # # ]: 0 : pLabeledDtaSeq->setLabel( pLabelSeqs[i] );
944 [ # # ]: 0 : pLabeledDtaSeq->setValues( pDataSeqs[i] );
945 [ # # ][ # # ]: 0 : pLDS[i] = pLabeledDtaSeq;
946 : : }
947 : :
948 : : // apply 'SequenceMapping' if it was provided
949 : 0 : sal_Int32 nSequenceMappingLen = aSequenceMapping.getLength();
950 [ # # ]: 0 : if (nSequenceMappingLen)
951 : : {
952 [ # # ]: 0 : sal_Int32 *pSequenceMapping = aSequenceMapping.getArray();
953 [ # # ]: 0 : uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aOld_LDS( aLDS );
954 [ # # ]: 0 : uno::Reference< chart2::data::XLabeledDataSequence > *pOld_LDS = aOld_LDS.getArray();
955 : :
956 : 0 : sal_Int32 nNewCnt = 0;
957 [ # # ]: 0 : for (sal_Int32 i = 0; i < nSequenceMappingLen; ++i)
958 : : {
959 : : // check that index to be used is valid
960 : : // and has not yet been used
961 : 0 : sal_Int32 nIdx = pSequenceMapping[i];
962 [ # # ][ # # ]: 0 : if (0 <= nIdx && nIdx < nNumLDS && pOld_LDS[nIdx].is())
[ # # ][ # # ]
963 : : {
964 [ # # ]: 0 : pLDS[nNewCnt++] = pOld_LDS[nIdx];
965 : :
966 : : // mark index as being used already (avoids duplicate entries)
967 : 0 : pOld_LDS[nIdx].clear();
968 : : }
969 : : }
970 : : // add not yet used 'old' sequences to new one
971 [ # # ]: 0 : for (sal_Int32 i = 0; i < nNumLDS; ++i)
972 : : {
973 : : #if OSL_DEBUG_LEVEL > 1
974 : : if (!pOld_LDS[i].is())
975 : : i = i;
976 : : #endif
977 [ # # ]: 0 : if (pOld_LDS[i].is())
978 [ # # ]: 0 : pLDS[nNewCnt++] = pOld_LDS[i];
979 : : }
980 [ # # ]: 0 : OSL_ENSURE( nNewCnt == nNumLDS, "unexpected size of resulting sequence" );
981 : : }
982 : :
983 [ # # ][ # # ]: 0 : xRes = new SwChartDataSource( aLDS );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
984 : : }
985 : : }
986 : :
987 [ # # ][ # # ]: 0 : return xRes;
[ # # ][ # # ]
988 : : }
989 : :
990 : 0 : sal_Bool SAL_CALL SwChartDataProvider::createDataSourcePossible(
991 : : const uno::Sequence< beans::PropertyValue >& rArguments )
992 : : throw (uno::RuntimeException)
993 : : {
994 [ # # ]: 0 : SolarMutexGuard aGuard;
995 : :
996 : 0 : sal_Bool bPossible = sal_True;
997 : : try
998 : : {
999 [ # # ]: 0 : Impl_createDataSource( rArguments, sal_True );
1000 : : }
1001 [ # # ]: 0 : catch (lang::IllegalArgumentException &)
1002 : : {
1003 : 0 : bPossible = sal_False;
1004 : : }
1005 : :
1006 [ # # ][ # # ]: 0 : return bPossible;
1007 : : }
1008 : :
1009 : 0 : uno::Reference< chart2::data::XDataSource > SAL_CALL SwChartDataProvider::createDataSource(
1010 : : const uno::Sequence< beans::PropertyValue >& rArguments )
1011 : : throw (lang::IllegalArgumentException, uno::RuntimeException)
1012 : : {
1013 [ # # ]: 0 : SolarMutexGuard aGuard;
1014 [ # # ][ # # ]: 0 : return Impl_createDataSource( rArguments );
1015 : : }
1016 : :
1017 : : ////////////////////////////////////////////////////////////
1018 : : // SwChartDataProvider::GetBrokenCellRangeForExport
1019 : : //
1020 : : // fix for #i79009
1021 : : // we need to return a property that has the same value as the property
1022 : : // 'CellRangeRepresentation' but for all rows which are increased by one.
1023 : : // E.g. Table1:A1:D5 -> Table1:A2:D6
1024 : : // Since the problem is only for old charts which did not support multiple
1025 : : // we do not need to provide that property/string if the 'CellRangeRepresentation'
1026 : : // contains multiple ranges.
1027 : 0 : OUString SwChartDataProvider::GetBrokenCellRangeForExport(
1028 : : const OUString &rCellRangeRepresentation )
1029 : : {
1030 : 0 : OUString aRes;
1031 : :
1032 : : // check that we do not have multiple ranges
1033 [ # # ]: 0 : if (-1 == rCellRangeRepresentation.indexOf( ';' ))
1034 : : {
1035 : : // get current cell and table names
1036 [ # # ][ # # ]: 0 : String aTblName, aStartCell, aEndCell;
[ # # ]
1037 : : GetTableAndCellsFromRangeRep( rCellRangeRepresentation,
1038 [ # # ]: 0 : aTblName, aStartCell, aEndCell, sal_False );
1039 : 0 : sal_Int32 nStartCol = -1, nStartRow = -1, nEndCol = -1, nEndRow = -1;
1040 [ # # ]: 0 : lcl_GetCellPosition( aStartCell, nStartCol, nStartRow );
1041 [ # # ]: 0 : lcl_GetCellPosition( aEndCell, nEndCol, nEndRow );
1042 : :
1043 : : // get new cell names
1044 : 0 : ++nStartRow;
1045 : 0 : ++nEndRow;
1046 [ # # ][ # # ]: 0 : aStartCell = lcl_GetCellName( nStartCol, nStartRow );
[ # # ]
1047 [ # # ][ # # ]: 0 : aEndCell = lcl_GetCellName( nEndCol, nEndRow );
[ # # ]
1048 : :
1049 : : aRes = GetRangeRepFromTableAndCells( aTblName,
1050 [ # # ][ # # ]: 0 : aStartCell, aEndCell, sal_False );
[ # # ][ # # ]
[ # # ][ # # ]
1051 : : }
1052 : :
1053 : 0 : return aRes;
1054 : : }
1055 : :
1056 : 0 : uno::Sequence< beans::PropertyValue > SAL_CALL SwChartDataProvider::detectArguments(
1057 : : const uno::Reference< chart2::data::XDataSource >& xDataSource )
1058 : : throw (uno::RuntimeException)
1059 : : {
1060 [ # # ]: 0 : SolarMutexGuard aGuard;
1061 [ # # ]: 0 : if (bDisposed)
1062 [ # # ]: 0 : throw lang::DisposedException();
1063 : :
1064 [ # # ]: 0 : uno::Sequence< beans::PropertyValue > aResult;
1065 [ # # ]: 0 : if (!xDataSource.is())
1066 : : return aResult;
1067 : :
1068 [ # # ][ # # ]: 0 : const uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aDS_LDS( xDataSource->getDataSequences() );
1069 : 0 : const uno::Reference< chart2::data::XLabeledDataSequence > *pDS_LDS = aDS_LDS.getConstArray();
1070 : 0 : sal_Int32 nNumDS_LDS = aDS_LDS.getLength();
1071 : :
1072 [ # # ]: 0 : if (nNumDS_LDS == 0)
1073 : : {
1074 : : OSL_FAIL( "XLabeledDataSequence in data source contains 0 entries" );
1075 : : return aResult;
1076 : : }
1077 : :
1078 : 0 : SwFrmFmt *pTableFmt = 0;
1079 : 0 : SwTable *pTable = 0;
1080 [ # # ]: 0 : String aTableName;
1081 : 0 : sal_Int32 nTableRows = 0;
1082 : 0 : sal_Int32 nTableCols = 0;
1083 : :
1084 : : // data used to build 'CellRangeRepresentation' from later on
1085 [ # # ]: 0 : std::vector< std::vector< sal_Char > > aMap;
1086 : :
1087 [ # # ]: 0 : uno::Sequence< sal_Int32 > aSequenceMapping( nNumDS_LDS );
1088 [ # # ]: 0 : sal_Int32 *pSequenceMapping = aSequenceMapping.getArray();
1089 : :
1090 [ # # ]: 0 : String aCellRanges;
1091 : 0 : sal_Int16 nDtaSrcIsColumns = -1;// -1: don't know yet, 0: false, 1: true -2: neither
1092 : 0 : sal_Int32 nLabelSeqLen = -1; // used to see if labels are always used or not and have
1093 : : // the expected size of 1 (i.e. if FirstCellAsLabel can
1094 : : // be determined)
1095 : : // -1: don't know yet, 0: not used, 1: always a single labe cell, ...
1096 : : // -2: neither/failed
1097 [ # # ]: 0 : for (sal_Int32 nDS1 = 0; nDS1 < nNumDS_LDS; ++nDS1)
1098 : : {
1099 : 0 : uno::Reference< chart2::data::XLabeledDataSequence > xLabeledDataSequence( pDS_LDS[nDS1] );
1100 [ # # ]: 0 : if( !xLabeledDataSequence.is() )
1101 : : {
1102 : : OSL_FAIL("got NULL for XLabeledDataSequence from Data source");
1103 : 0 : continue;
1104 : : }
1105 [ # # ][ # # ]: 0 : const uno::Reference< chart2::data::XDataSequence > xCurLabel( xLabeledDataSequence->getLabel(), uno::UNO_QUERY );
[ # # ]
1106 [ # # ][ # # ]: 0 : const uno::Reference< chart2::data::XDataSequence > xCurValues( xLabeledDataSequence->getValues(), uno::UNO_QUERY );
[ # # ]
1107 : :
1108 : : // get sequence lengths for label and values.
1109 : : // (0 length is Ok)
1110 : 0 : sal_Int32 nCurLabelSeqLen = -1;
1111 : 0 : sal_Int32 nCurValuesSeqLen = -1;
1112 [ # # ]: 0 : if (xCurLabel.is())
1113 [ # # ][ # # ]: 0 : nCurLabelSeqLen = xCurLabel->getData().getLength();
[ # # ]
1114 [ # # ]: 0 : if (xCurValues.is())
1115 [ # # ][ # # ]: 0 : nCurValuesSeqLen = xCurValues->getData().getLength();
[ # # ]
1116 : :
1117 : : // check for consistent use of 'first cell as label'
1118 [ # # ]: 0 : if (nLabelSeqLen == -1) // set initial value to compare with below further on
1119 : 0 : nLabelSeqLen = nCurLabelSeqLen;
1120 [ # # ]: 0 : if (nLabelSeqLen != nCurLabelSeqLen)
1121 : 0 : nLabelSeqLen = -2; // failed / no consistent use of label cells
1122 : :
1123 : : // get table and cell names for label and values data sequences
1124 : : // (start and end cell will be sorted, i.e. start cell <= end cell)
1125 [ # # ][ # # ]: 0 : String aLabelTblName, aLabelStartCell, aLabelEndCell;
[ # # ]
1126 [ # # ][ # # ]: 0 : String aValuesTblName, aValuesStartCell, aValuesEndCell;
[ # # ]
1127 [ # # ][ # # ]: 0 : String aLabelRange, aValuesRange;
1128 [ # # ]: 0 : if (xCurLabel.is())
1129 [ # # ][ # # ]: 0 : aLabelRange = xCurLabel->getSourceRangeRepresentation();
[ # # ]
1130 [ # # ]: 0 : if (xCurValues.is())
1131 [ # # ][ # # ]: 0 : aValuesRange = xCurValues->getSourceRangeRepresentation();
[ # # ]
1132 [ # # ][ # # ]: 0 : if ((aLabelRange.Len() && !GetTableAndCellsFromRangeRep( aLabelRange,
[ # # ][ # # ]
1133 [ # # ][ # # ]: 0 : aLabelTblName, aLabelStartCell, aLabelEndCell )) ||
[ # # ][ # # ]
1134 : : !GetTableAndCellsFromRangeRep( aValuesRange,
1135 [ # # ][ # # ]: 0 : aValuesTblName, aValuesStartCell, aValuesEndCell ))
[ # # ][ # # ]
1136 : : {
1137 : : return aResult; // failed -> return empty property sequence
1138 : : }
1139 : :
1140 : : // make sure all sequences use the same table
1141 [ # # ]: 0 : if (!aTableName.Len())
1142 [ # # ]: 0 : aTableName = aValuesTblName; // get initial value to compare with
1143 [ # # ]: 0 : if (!aTableName.Len() ||
[ # # # # ]
[ # # ][ # # ]
1144 [ # # ]: 0 : aTableName != aValuesTblName ||
1145 [ # # ]: 0 : (aLabelTblName.Len() && aTableName != aLabelTblName))
1146 : : {
1147 : : return aResult; // failed -> return empty property sequence
1148 : : }
1149 : :
1150 : :
1151 : : // try to get 'DataRowSource' value (ROWS or COLUMNS) from inspecting
1152 : : // first and last cell used in both sequences
1153 : : //
1154 : 0 : sal_Int32 nFirstCol = -1, nFirstRow = -1, nLastCol = -1, nLastRow = -1;
1155 [ # # ][ # # ]: 0 : String aCell( aLabelStartCell.Len() ? aLabelStartCell : aValuesStartCell );
1156 : : OSL_ENSURE( aCell.Len() , "start cell missing?" );
1157 [ # # ]: 0 : lcl_GetCellPosition( aCell, nFirstCol, nFirstRow);
1158 [ # # ]: 0 : lcl_GetCellPosition( aValuesEndCell, nLastCol, nLastRow);
1159 : : //
1160 : 0 : sal_Int16 nDirection = -1; // -1: not yet set, 0: columns, 1: rows, -2: failed
1161 [ # # ][ # # ]: 0 : if (nFirstCol == nLastCol && nFirstRow == nLastRow) // a single cell...
1162 : : {
1163 : : OSL_ENSURE( nCurLabelSeqLen == 0 && nCurValuesSeqLen == 1,
1164 : : "trying to determine 'DataRowSource': something's fishy... should have been a single cell");
1165 : : (void)nCurValuesSeqLen;
1166 : 0 : nDirection = 0; // default direction for a single cell should be 'columns'
1167 : : }
1168 : : else // more than one cell is availabale (in values and label together!)
1169 : : {
1170 [ # # ][ # # ]: 0 : if (nFirstCol == nLastCol && nFirstRow != nLastRow)
1171 : 0 : nDirection = 1;
1172 [ # # ][ # # ]: 0 : else if (nFirstCol != nLastCol && nFirstRow == nLastRow)
1173 : 0 : nDirection = 0;
1174 : : else
1175 : : {
1176 : : OSL_FAIL( "trying to determine 'DataRowSource': unexpected case found" );
1177 : 0 : nDirection = -2;
1178 : : }
1179 : : }
1180 : : // check for consistent direction of data source
1181 [ # # ]: 0 : if (nDtaSrcIsColumns == -1) // set initial value to compare with below
1182 : 0 : nDtaSrcIsColumns = nDirection;
1183 [ # # ]: 0 : if (nDtaSrcIsColumns != nDirection)
1184 : : {
1185 : 0 : nDtaSrcIsColumns = -2; // failed
1186 : : }
1187 : :
1188 : :
1189 [ # # ][ # # ]: 0 : if (nDtaSrcIsColumns == 0 || nDtaSrcIsColumns == 1)
1190 : : {
1191 : : // build data to obtain 'SequenceMapping' later on
1192 : : //
1193 : : OSL_ENSURE( nDtaSrcIsColumns == 0 || /* rows */
1194 : : nDtaSrcIsColumns == 1, /* columns */
1195 : : "unexpected value for 'nDtaSrcIsColumns'" );
1196 [ # # ]: 0 : pSequenceMapping[nDS1] = nDtaSrcIsColumns ? nFirstCol : nFirstRow;
1197 : :
1198 : :
1199 : : // build data used to determine 'CellRangeRepresentation' later on
1200 : : //
1201 [ # # ]: 0 : GetTableByName( *pDoc, aTableName, &pTableFmt, &pTable );
1202 [ # # ][ # # ]: 0 : if (!pTable || pTable->IsTblComplex())
[ # # ][ # # ]
1203 : : return aResult; // failed -> return empty property sequence
1204 : 0 : nTableRows = pTable->GetTabLines().size();
1205 [ # # ]: 0 : nTableCols = pTable->GetTabLines().front()->GetTabBoxes().size();
1206 [ # # ]: 0 : aMap.resize( nTableRows );
1207 [ # # ]: 0 : for (sal_Int32 i = 0; i < nTableRows; ++i)
1208 [ # # ][ # # ]: 0 : aMap[i].resize( nTableCols );
1209 : : //
1210 [ # # ][ # # ]: 0 : if (aLabelStartCell.Len() && aLabelEndCell.Len())
[ # # ]
1211 : : {
1212 : 0 : sal_Int32 nStartCol = -1, nStartRow = -1, nEndCol = -1, nEndRow = -1;
1213 [ # # ]: 0 : lcl_GetCellPosition( aLabelStartCell, nStartCol, nStartRow );
1214 [ # # ]: 0 : lcl_GetCellPosition( aLabelEndCell, nEndCol, nEndRow );
1215 [ # # ][ # # ]: 0 : if (nStartRow < 0 || nEndRow >= nTableRows ||
[ # # ][ # # ]
1216 : : nStartCol < 0 || nEndCol >= nTableCols)
1217 : : {
1218 : : return aResult; // failed -> return empty property sequence
1219 : : }
1220 [ # # ]: 0 : for (sal_Int32 i = nStartRow; i <= nEndRow; ++i)
1221 : : {
1222 [ # # ]: 0 : for (sal_Int32 k = nStartCol; k <= nEndCol; ++k)
1223 : : {
1224 [ # # ][ # # ]: 0 : sal_Char &rChar = aMap[i][k];
1225 [ # # ]: 0 : if (rChar == '\0') // check for overlapping values and/or labels
1226 : 0 : rChar = 'L';
1227 : : else
1228 : : return aResult; // failed -> return empty property sequence
1229 : : }
1230 : : }
1231 : : }
1232 [ # # ][ # # ]: 0 : if (aValuesStartCell.Len() && aValuesEndCell.Len())
[ # # ]
1233 : : {
1234 : 0 : sal_Int32 nStartCol = -1, nStartRow = -1, nEndCol = -1, nEndRow = -1;
1235 [ # # ]: 0 : lcl_GetCellPosition( aValuesStartCell, nStartCol, nStartRow );
1236 [ # # ]: 0 : lcl_GetCellPosition( aValuesEndCell, nEndCol, nEndRow );
1237 [ # # ][ # # ]: 0 : if (nStartRow < 0 || nEndRow >= nTableRows ||
[ # # ][ # # ]
1238 : : nStartCol < 0 || nEndCol >= nTableCols)
1239 : : {
1240 : : return aResult; // failed -> return empty property sequence
1241 : : }
1242 [ # # ]: 0 : for (sal_Int32 i = nStartRow; i <= nEndRow; ++i)
1243 : : {
1244 [ # # ]: 0 : for (sal_Int32 k = nStartCol; k <= nEndCol; ++k)
1245 : : {
1246 [ # # ][ # # ]: 0 : sal_Char &rChar = aMap[i][k];
1247 [ # # ]: 0 : if (rChar == '\0') // check for overlapping values and/or labels
1248 : 0 : rChar = 'x';
1249 : : else
1250 : : return aResult; // failed -> return empty property sequence
1251 : : }
1252 : : }
1253 : : }
1254 : : }
1255 : :
1256 : : #if OSL_DEBUG_LEVEL > 0
1257 : : // do some extra sanity checking that the length of the sequences
1258 : : // matches their range representation
1259 : : {
1260 : : sal_Int32 nStartRow = -1, nStartCol = -1, nEndRow = -1, nEndCol = -1;
1261 : : if (xCurLabel.is())
1262 : : {
1263 : : lcl_GetCellPosition( aLabelStartCell, nStartCol, nStartRow);
1264 : : lcl_GetCellPosition( aLabelEndCell, nEndCol, nEndRow);
1265 : : OSL_ENSURE( (nStartCol == nEndCol && (nEndRow - nStartRow + 1) == xCurLabel->getData().getLength()) ||
1266 : : (nStartRow == nEndRow && (nEndCol - nStartCol + 1) == xCurLabel->getData().getLength()),
1267 : : "label sequence length does not match range representation!" );
1268 : : }
1269 : : if (xCurValues.is())
1270 : : {
1271 : : lcl_GetCellPosition( aValuesStartCell, nStartCol, nStartRow);
1272 : : lcl_GetCellPosition( aValuesEndCell, nEndCol, nEndRow);
1273 : : OSL_ENSURE( (nStartCol == nEndCol && (nEndRow - nStartRow + 1) == xCurValues->getData().getLength()) ||
1274 : : (nStartRow == nEndRow && (nEndCol - nStartCol + 1) == xCurValues->getData().getLength()),
1275 : : "value sequence length does not match range representation!" );
1276 : : }
1277 : : }
1278 : : #endif
1279 [ # # ][ # # ]: 0 : } // for
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # ]
1280 : :
1281 : :
1282 : : // build value for 'CellRangeRepresentation'
1283 : : //
1284 [ # # ]: 0 : String aCellRangeBase( aTableName );
1285 [ # # ]: 0 : aCellRangeBase += '.';
1286 [ # # ]: 0 : String aCurRange;
1287 [ # # ]: 0 : for (sal_Int32 i = 0; i < nTableRows; ++i)
1288 : : {
1289 [ # # ]: 0 : for (sal_Int32 k = 0; k < nTableCols; ++k)
1290 : : {
1291 [ # # ][ # # ]: 0 : if (aMap[i][k] != '\0') // top-left cell of a sub-range found
[ # # ]
1292 : : {
1293 : : // find rectangular sub-range to use
1294 : 0 : sal_Int32 nRowIndex1 = i; // row index
1295 : 0 : sal_Int32 nColIndex1 = k; // column index
1296 : 0 : sal_Int32 nRowSubLen = 0;
1297 : 0 : sal_Int32 nColSubLen = 0;
1298 [ # # ][ # # ]: 0 : while (nRowIndex1 < nTableRows && aMap[nRowIndex1++][k] != '\0')
[ # # ][ # # ]
[ # # ]
1299 : 0 : ++nRowSubLen;
1300 : : // be aware of shifted sequences!
1301 : : // (according to the checks done prior the length should be ok)
1302 [ # # ][ # # ]: 0 : while (nColIndex1 < nTableCols && aMap[i][nColIndex1] != '\0'
[ # # ][ # # ]
[ # # ][ # # ]
1303 [ # # ][ # # ]: 0 : && aMap[i + nRowSubLen-1][nColIndex1] != '\0')
1304 : : {
1305 : 0 : ++nColIndex1;
1306 : 0 : ++nColSubLen;
1307 : : }
1308 [ # # ]: 0 : String aStartCell( lcl_GetCellName( k, i ) );
1309 [ # # ]: 0 : String aEndCell( lcl_GetCellName( k + nColSubLen - 1, i + nRowSubLen - 1) );
1310 [ # # ]: 0 : aCurRange = aCellRangeBase;
1311 [ # # ]: 0 : aCurRange += aStartCell;
1312 [ # # ]: 0 : aCurRange += ':';
1313 [ # # ]: 0 : aCurRange += aEndCell;
1314 [ # # ]: 0 : if (aCellRanges.Len())
1315 [ # # ]: 0 : aCellRanges += ';';
1316 [ # # ]: 0 : aCellRanges += aCurRange;
1317 : :
1318 : : // clear already found sub-range from map
1319 [ # # ]: 0 : for (sal_Int32 nRowIndex2 = 0; nRowIndex2 < nRowSubLen; ++nRowIndex2)
1320 [ # # ]: 0 : for (sal_Int32 nColumnIndex2 = 0; nColumnIndex2 < nColSubLen; ++nColumnIndex2)
1321 [ # # ][ # # ]: 0 : aMap[i + nRowIndex2][k + nColumnIndex2] = '\0';
[ # # ][ # # ]
1322 : : }
1323 : : }
1324 : : }
1325 : : // to be nice to the user we now sort the cell ranges according to
1326 : : // rows or columns depending on the direction used in the data source
1327 [ # # ]: 0 : uno::Sequence< OUString > aSortedRanges;
1328 [ # # ][ # # ]: 0 : GetSubranges( aCellRanges, aSortedRanges, sal_False /*sub ranges should already be normalized*/ );
1329 [ # # ]: 0 : SortSubranges( aSortedRanges, (nDtaSrcIsColumns == 1) );
1330 : 0 : sal_Int32 nSortedRanges = aSortedRanges.getLength();
1331 : 0 : const OUString *pSortedRanges = aSortedRanges.getConstArray();
1332 : 0 : OUString aSortedCellRanges;
1333 [ # # ]: 0 : for (sal_Int32 i = 0; i < nSortedRanges; ++i)
1334 : : {
1335 [ # # ]: 0 : if (!aSortedCellRanges.isEmpty())
1336 : 0 : aSortedCellRanges += OUString::valueOf( (sal_Unicode) ';');
1337 : 0 : aSortedCellRanges += pSortedRanges[i];
1338 : : }
1339 : :
1340 : :
1341 : : // build value for 'SequenceMapping'
1342 : : //
1343 [ # # ]: 0 : uno::Sequence< sal_Int32 > aSortedMapping( aSequenceMapping );
1344 [ # # ]: 0 : sal_Int32 *pSortedMapping = aSortedMapping.getArray();
1345 [ # # ]: 0 : std::sort( pSortedMapping, pSortedMapping + aSortedMapping.getLength() );
1346 : : OSL_ENSURE( aSortedMapping.getLength() == nNumDS_LDS, "unexpected size of sequence" );
1347 : 0 : sal_Bool bNeedSequenceMapping = sal_False;
1348 [ # # ]: 0 : for (sal_Int32 i = 0; i < nNumDS_LDS; ++i)
1349 : : {
1350 : : sal_Int32 *pIt = std::find( pSortedMapping, pSortedMapping + nNumDS_LDS,
1351 [ # # ]: 0 : pSequenceMapping[i] );
1352 : : OSL_ENSURE( pIt, "index not found" );
1353 [ # # ]: 0 : if (!pIt)
1354 : : return aResult; // failed -> return empty property sequence
1355 : 0 : pSequenceMapping[i] = pIt - pSortedMapping;
1356 : :
1357 [ # # ]: 0 : if (i != pSequenceMapping[i])
1358 : 0 : bNeedSequenceMapping = sal_True;
1359 : : }
1360 : :
1361 : : // check if 'SequenceMapping' is actually not required...
1362 : : // (don't write unnecessary properties to the XML file)
1363 [ # # ]: 0 : if (!bNeedSequenceMapping)
1364 [ # # ]: 0 : aSequenceMapping.realloc(0);
1365 : :
1366 : : //
1367 : : // build resulting properties
1368 : : //
1369 : : OSL_ENSURE(nLabelSeqLen >= 0 || nLabelSeqLen == -2 /*not used*/,
1370 : : "unexpected value for 'nLabelSeqLen'" );
1371 : 0 : sal_Bool bFirstCellIsLabel = sal_False; // default value if 'nLabelSeqLen' could not properly determined
1372 [ # # ]: 0 : if (nLabelSeqLen > 0) // == 0 means no label sequence in use
1373 : 0 : bFirstCellIsLabel = sal_True;
1374 : : //
1375 : : OSL_ENSURE( !aSortedCellRanges.isEmpty(), "CellRangeRepresentation missing" );
1376 [ # # ]: 0 : OUString aBrokenCellRangeForExport( GetBrokenCellRangeForExport( aSortedCellRanges ) );
1377 : : //
1378 [ # # ]: 0 : aResult.realloc(5);
1379 : 0 : sal_Int32 nProps = 0;
1380 [ # # ][ # # ]: 0 : aResult[nProps ].Name = C2U("FirstCellAsLabel");
1381 [ # # ][ # # ]: 0 : aResult[nProps++].Value <<= bFirstCellIsLabel;
1382 [ # # ][ # # ]: 0 : aResult[nProps ].Name = C2U("CellRangeRepresentation");
1383 [ # # ][ # # ]: 0 : aResult[nProps++].Value <<= aSortedCellRanges;
1384 [ # # ]: 0 : if (!aBrokenCellRangeForExport.isEmpty())
1385 : : {
1386 [ # # ][ # # ]: 0 : aResult[nProps ].Name = C2U("BrokenCellRangeForExport");
1387 [ # # ][ # # ]: 0 : aResult[nProps++].Value <<= aBrokenCellRangeForExport;
1388 : : }
1389 [ # # ][ # # ]: 0 : if (nDtaSrcIsColumns == 0 || nDtaSrcIsColumns == 1)
1390 : : {
1391 : : chart::ChartDataRowSource eDataRowSource = (nDtaSrcIsColumns == 1) ?
1392 [ # # ]: 0 : chart::ChartDataRowSource_COLUMNS : chart::ChartDataRowSource_ROWS;
1393 [ # # ][ # # ]: 0 : aResult[nProps ].Name = C2U("DataRowSource");
1394 [ # # ][ # # ]: 0 : aResult[nProps++].Value <<= eDataRowSource;
1395 : :
1396 [ # # ]: 0 : if (aSequenceMapping.getLength() != 0)
1397 : : {
1398 [ # # ][ # # ]: 0 : aResult[nProps ].Name = C2U("SequenceMapping");
1399 [ # # ][ # # ]: 0 : aResult[nProps++].Value <<= aSequenceMapping;
1400 : : }
1401 : : }
1402 [ # # ]: 0 : aResult.realloc( nProps );
1403 : :
1404 [ # # ][ # # ]: 0 : return aResult;
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1405 : : }
1406 : :
1407 : 0 : uno::Reference< chart2::data::XDataSequence > SwChartDataProvider::Impl_createDataSequenceByRangeRepresentation(
1408 : : const OUString& rRangeRepresentation, sal_Bool bTestOnly )
1409 : : throw (lang::IllegalArgumentException, uno::RuntimeException)
1410 : : {
1411 [ # # ]: 0 : if (bDisposed)
1412 [ # # ]: 0 : throw lang::DisposedException();
1413 : :
1414 : 0 : SwFrmFmt *pTblFmt = 0; // pointer to table format
1415 : 0 : SwUnoCrsr *pUnoCrsr = 0; // pointer to new created cursor spanning the cell range
1416 : : GetFormatAndCreateCursorFromRangeRep( pDoc, rRangeRepresentation,
1417 [ # # ]: 0 : &pTblFmt, &pUnoCrsr );
1418 [ # # ][ # # ]: 0 : if (!pTblFmt || !pUnoCrsr)
1419 [ # # ]: 0 : throw lang::IllegalArgumentException();
1420 : :
1421 : : // check that cursors point and mark are in a single row or column.
1422 [ # # ]: 0 : String aCellRange( GetCellRangeName( *pTblFmt, *pUnoCrsr ) );
1423 : : SwRangeDescriptor aDesc;
1424 [ # # ]: 0 : FillRangeDescriptor( aDesc, aCellRange );
1425 [ # # ][ # # ]: 0 : if (aDesc.nTop != aDesc.nBottom && aDesc.nLeft != aDesc.nRight)
1426 [ # # ]: 0 : throw lang::IllegalArgumentException();
1427 : :
1428 : : OSL_ENSURE( pTblFmt && pUnoCrsr, "table format or cursor missing" );
1429 : 0 : uno::Reference< chart2::data::XDataSequence > xDataSeq;
1430 [ # # ]: 0 : if (!bTestOnly)
1431 [ # # ][ # # ]: 0 : xDataSeq = new SwChartDataSequence( *this, *pTblFmt, pUnoCrsr );
[ # # ]
1432 : :
1433 [ # # ]: 0 : return xDataSeq;
1434 : : }
1435 : :
1436 : 0 : sal_Bool SAL_CALL SwChartDataProvider::createDataSequenceByRangeRepresentationPossible(
1437 : : const OUString& rRangeRepresentation )
1438 : : throw (uno::RuntimeException)
1439 : : {
1440 [ # # ]: 0 : SolarMutexGuard aGuard;
1441 : :
1442 : 0 : sal_Bool bPossible = sal_True;
1443 : : try
1444 : : {
1445 [ # # ]: 0 : Impl_createDataSequenceByRangeRepresentation( rRangeRepresentation, sal_True );
1446 : : }
1447 [ # # ]: 0 : catch (lang::IllegalArgumentException &)
1448 : : {
1449 : 0 : bPossible = sal_False;
1450 : : }
1451 : :
1452 [ # # ][ # # ]: 0 : return bPossible;
1453 : : }
1454 : :
1455 : 0 : uno::Reference< chart2::data::XDataSequence > SAL_CALL SwChartDataProvider::createDataSequenceByRangeRepresentation(
1456 : : const OUString& rRangeRepresentation )
1457 : : throw (lang::IllegalArgumentException, uno::RuntimeException)
1458 : : {
1459 [ # # ]: 0 : SolarMutexGuard aGuard;
1460 [ # # ][ # # ]: 0 : return Impl_createDataSequenceByRangeRepresentation( rRangeRepresentation );
1461 : : }
1462 : :
1463 : 0 : uno::Reference< sheet::XRangeSelection > SAL_CALL SwChartDataProvider::getRangeSelection( )
1464 : : throw (uno::RuntimeException)
1465 : : {
1466 : : // note: it is no error to return nothing here
1467 : 0 : return uno::Reference< sheet::XRangeSelection >();
1468 : : }
1469 : :
1470 : 0 : void SAL_CALL SwChartDataProvider::dispose( )
1471 : : throw (uno::RuntimeException)
1472 : : {
1473 : 0 : sal_Bool bMustDispose( sal_False );
1474 : : {
1475 [ # # ][ # # ]: 0 : osl::MutexGuard aGuard( GetChartMutex() );
1476 : 0 : bMustDispose = !bDisposed;
1477 [ # # ]: 0 : if (!bDisposed)
1478 [ # # ]: 0 : bDisposed = sal_True;
1479 : : }
1480 [ # # ]: 0 : if (bMustDispose)
1481 : : {
1482 : : // dispose all data-sequences
1483 : 0 : Map_Set_DataSequenceRef_t::iterator aIt( aDataSequences.begin() );
1484 [ # # ]: 0 : while (aIt != aDataSequences.end())
1485 : : {
1486 [ # # ]: 0 : DisposeAllDataSequences( (*aIt).first );
1487 : 0 : ++aIt;
1488 : : }
1489 : : // release all references to data-sequences
1490 : 0 : aDataSequences.clear();
1491 : :
1492 : : // require listeners to release references to this object
1493 [ # # ][ # # ]: 0 : lang::EventObject aEvtObj( dynamic_cast< chart2::data::XDataSequence * >(this) );
[ # # ]
1494 [ # # ][ # # ]: 0 : aEvtListeners.disposeAndClear( aEvtObj );
1495 : : }
1496 : 0 : }
1497 : :
1498 : 0 : void SAL_CALL SwChartDataProvider::addEventListener(
1499 : : const uno::Reference< lang::XEventListener >& rxListener )
1500 : : throw (uno::RuntimeException)
1501 : : {
1502 [ # # ][ # # ]: 0 : osl::MutexGuard aGuard( GetChartMutex() );
1503 [ # # ][ # # ]: 0 : if (!bDisposed && rxListener.is())
[ # # ]
1504 [ # # ][ # # ]: 0 : aEvtListeners.addInterface( rxListener );
1505 : 0 : }
1506 : :
1507 : 0 : void SAL_CALL SwChartDataProvider::removeEventListener(
1508 : : const uno::Reference< lang::XEventListener >& rxListener )
1509 : : throw (uno::RuntimeException)
1510 : : {
1511 [ # # ][ # # ]: 0 : osl::MutexGuard aGuard( GetChartMutex() );
1512 [ # # ][ # # ]: 0 : if (!bDisposed && rxListener.is())
[ # # ]
1513 [ # # ][ # # ]: 0 : aEvtListeners.removeInterface( rxListener );
1514 : 0 : }
1515 : :
1516 : 0 : OUString SAL_CALL SwChartDataProvider::getImplementationName( )
1517 : : throw (uno::RuntimeException)
1518 : : {
1519 : 0 : return C2U("SwChartDataProvider");
1520 : : }
1521 : :
1522 : 0 : sal_Bool SAL_CALL SwChartDataProvider::supportsService(
1523 : : const OUString& rServiceName )
1524 : : throw (uno::RuntimeException)
1525 : : {
1526 [ # # ]: 0 : SolarMutexGuard aGuard;
1527 [ # # ]: 0 : return rServiceName == SN_DATA_PROVIDER;
1528 : : }
1529 : :
1530 : 0 : uno::Sequence< OUString > SAL_CALL SwChartDataProvider::getSupportedServiceNames( )
1531 : : throw (uno::RuntimeException)
1532 : : {
1533 [ # # ]: 0 : SolarMutexGuard aGuard;
1534 [ # # ]: 0 : uno::Sequence< OUString > aRes(1);
1535 [ # # ][ # # ]: 0 : aRes.getArray()[0] = C2U( SN_DATA_PROVIDER );
1536 [ # # ]: 0 : return aRes;
1537 : : }
1538 : :
1539 : 0 : void SwChartDataProvider::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew)
1540 : : {
1541 : : // actually this function should be superfluous (need to check later)
1542 : 0 : ClientModify(this, pOld, pNew );
1543 : 0 : }
1544 : :
1545 : 0 : void SwChartDataProvider::AddDataSequence( const SwTable &rTable, uno::Reference< chart2::data::XDataSequence > &rxDataSequence )
1546 : : {
1547 [ # # ][ # # ]: 0 : aDataSequences[ &rTable ].insert( rxDataSequence );
1548 : 0 : }
1549 : :
1550 : 0 : void SwChartDataProvider::RemoveDataSequence( const SwTable &rTable, uno::Reference< chart2::data::XDataSequence > &rxDataSequence )
1551 : : {
1552 [ # # ][ # # ]: 0 : aDataSequences[ &rTable ].erase( rxDataSequence );
1553 : 0 : }
1554 : :
1555 : 0 : void SwChartDataProvider::InvalidateTable( const SwTable *pTable )
1556 : : {
1557 : : OSL_ENSURE( pTable, "table pointer is NULL" );
1558 [ # # ]: 0 : if (pTable)
1559 : : {
1560 [ # # ]: 0 : if (!bDisposed)
1561 [ # # ][ # # ]: 0 : pTable->GetFrmFmt()->GetDoc()->GetChartControllerHelper().StartOrContinueLocking();
1562 : :
1563 [ # # ]: 0 : const Set_DataSequenceRef_t &rSet = aDataSequences[ pTable ];
1564 : 0 : Set_DataSequenceRef_t::const_iterator aIt( rSet.begin() );
1565 [ # # ]: 0 : while (aIt != rSet.end())
1566 : : {
1567 [ # # ]: 0 : uno::Reference< chart2::data::XDataSequence > xTemp(*aIt); // temporary needed for g++ 3.3.5
1568 [ # # ]: 0 : uno::Reference< util::XModifiable > xRef( xTemp, uno::UNO_QUERY );
1569 [ # # ]: 0 : if (xRef.is())
1570 : : {
1571 : : // mark the sequence as 'dirty' and notify listeners
1572 [ # # ][ # # ]: 0 : xRef->setModified( sal_True );
1573 : : }
1574 : 0 : ++aIt;
1575 : 0 : }
1576 : : }
1577 : 0 : }
1578 : :
1579 : 0 : sal_Bool SwChartDataProvider::DeleteBox( const SwTable *pTable, const SwTableBox &rBox )
1580 : : {
1581 : 0 : sal_Bool bRes = sal_False;
1582 : : OSL_ENSURE( pTable, "table pointer is NULL" );
1583 [ # # ]: 0 : if (pTable)
1584 : : {
1585 [ # # ]: 0 : if (!bDisposed)
1586 [ # # ][ # # ]: 0 : pTable->GetFrmFmt()->GetDoc()->GetChartControllerHelper().StartOrContinueLocking();
1587 : :
1588 [ # # ]: 0 : Set_DataSequenceRef_t &rSet = aDataSequences[ pTable ];
1589 : :
1590 : : // iterate over all data-sequences for that table...
1591 : 0 : Set_DataSequenceRef_t::iterator aIt( rSet.begin() );
1592 : 0 : Set_DataSequenceRef_t::iterator aEndIt( rSet.end() );
1593 : 0 : Set_DataSequenceRef_t::iterator aDelIt; // iterator used for deletion when appropriate
1594 [ # # ]: 0 : while (aIt != aEndIt)
1595 : : {
1596 : 0 : SwChartDataSequence *pDataSeq = 0;
1597 : 0 : sal_Bool bNowEmpty = sal_False;
1598 : :
1599 : : // check if weak reference is still valid...
1600 [ # # ]: 0 : uno::Reference< chart2::data::XDataSequence > xTemp(*aIt); // temporary needed for g++ 3.3.5
1601 [ # # ]: 0 : uno::Reference< chart2::data::XDataSequence > xRef( xTemp, uno::UNO_QUERY );
1602 [ # # ]: 0 : if (xRef.is())
1603 : : {
1604 : : // then delete that table box (check if implementation cursor needs to be adjusted)
1605 [ # # ][ # # ]: 0 : pDataSeq = static_cast< SwChartDataSequence * >( xRef.get() );
1606 [ # # ]: 0 : if (pDataSeq)
1607 : : {
1608 : : #if OSL_DEBUG_LEVEL > 1
1609 : : OUString aRangeStr( pDataSeq->getSourceRangeRepresentation() );
1610 : : #endif
1611 [ # # ]: 0 : bNowEmpty = pDataSeq->DeleteBox( rBox );
1612 [ # # ]: 0 : if (bNowEmpty)
1613 : 0 : aDelIt = aIt;
1614 : : }
1615 : : }
1616 : 0 : ++aIt;
1617 : :
1618 [ # # ]: 0 : if (bNowEmpty)
1619 : : {
1620 [ # # ]: 0 : rSet.erase( aDelIt );
1621 [ # # ]: 0 : if (pDataSeq)
1622 [ # # ]: 0 : pDataSeq->dispose(); // the current way to tell chart that sth. got removed
1623 : : }
1624 : 0 : }
1625 : : }
1626 : 0 : return bRes;
1627 : : }
1628 : :
1629 : 0 : void SwChartDataProvider::DisposeAllDataSequences( const SwTable *pTable )
1630 : : {
1631 : : OSL_ENSURE( pTable, "table pointer is NULL" );
1632 [ # # ]: 0 : if (pTable)
1633 : : {
1634 [ # # ]: 0 : if (!bDisposed)
1635 [ # # ][ # # ]: 0 : pTable->GetFrmFmt()->GetDoc()->GetChartControllerHelper().StartOrContinueLocking();
1636 : :
1637 : : //! make a copy of the STL container!
1638 : : //! This is necessary since calling 'dispose' will implicitly remove an element
1639 : : //! of the original container, and thus any iterator in the original container
1640 : : //! would become invalid.
1641 [ # # ][ # # ]: 0 : const Set_DataSequenceRef_t aSet( aDataSequences[ pTable ] );
1642 : :
1643 : 0 : Set_DataSequenceRef_t::const_iterator aIt( aSet.begin() );
1644 : 0 : Set_DataSequenceRef_t::const_iterator aEndIt( aSet.end() );
1645 [ # # ]: 0 : while (aIt != aEndIt)
1646 : : {
1647 [ # # ]: 0 : uno::Reference< chart2::data::XDataSequence > xTemp(*aIt); // temporary needed for g++ 3.3.5
1648 [ # # ]: 0 : uno::Reference< lang::XComponent > xRef( xTemp, uno::UNO_QUERY );
1649 [ # # ]: 0 : if (xRef.is())
1650 : : {
1651 [ # # ][ # # ]: 0 : xRef->dispose();
1652 : : }
1653 : 0 : ++aIt;
1654 : 0 : }
1655 : : }
1656 : 0 : }
1657 : :
1658 : : ////////////////////////////////////////
1659 : : // SwChartDataProvider::AddRowCols tries to notify charts of added columns
1660 : : // or rows and extends the value sequence respectively (if possible).
1661 : : // If those can be added to the end of existing value data-sequences those
1662 : : // sequences get mofdified accordingly and will send a modification
1663 : : // notification (calling 'setModified').
1664 : : //
1665 : : // Since this function is a work-around for non existent Writer core functionality
1666 : : // (no arbitrary multi-selection in tables that can be used to define a
1667 : : // data-sequence) this function will be somewhat unreliable.
1668 : : // For example we will only try to adapt value sequences. For this we assume
1669 : : // that a sequence of length 1 is a label sequence and those with length >= 2
1670 : : // we presume to be value sequences. Also new cells can only be added in the
1671 : : // direction the value sequence is already pointing (rows / cols) and at the
1672 : : // start or end of the values data-sequence.
1673 : : // Nothing needs to be done if the new cells are in between the table cursors
1674 : : // point and mark since data-sequence are considered to consist of all cells
1675 : : // between those.
1676 : : // New rows/cols need to be added already to the table before calling
1677 : : // this function.
1678 : : //
1679 : 0 : void SwChartDataProvider::AddRowCols(
1680 : : const SwTable &rTable,
1681 : : const SwSelBoxes& rBoxes,
1682 : : sal_uInt16 nLines, sal_Bool bBehind )
1683 : : {
1684 [ # # ]: 0 : if (rTable.IsTblComplex())
1685 : 0 : return;
1686 : :
1687 : 0 : const sal_uInt16 nBoxes = rBoxes.size();
1688 [ # # ][ # # ]: 0 : if (nBoxes < 1 || nLines < 1)
1689 : 0 : return;
1690 : :
1691 : 0 : SwTableBox* pFirstBox = rBoxes[0];
1692 : 0 : SwTableBox* pLastBox = rBoxes.back();
1693 : :
1694 [ # # ][ # # ]: 0 : if (pFirstBox && pLastBox)
1695 : : {
1696 : 0 : sal_Int32 nFirstCol = -1, nFirstRow = -1, nLastCol = -1, nLastRow = -1;
1697 [ # # ][ # # ]: 0 : lcl_GetCellPosition( pFirstBox->GetName(), nFirstCol, nFirstRow );
[ # # ]
1698 [ # # ][ # # ]: 0 : lcl_GetCellPosition( pLastBox->GetName(), nLastCol, nLastRow );
[ # # ]
1699 : :
1700 : 0 : bool bAddCols = false; // default; also to be used if nBoxes == 1 :-/
1701 [ # # ][ # # ]: 0 : if (nFirstCol == nLastCol && nFirstRow != nLastRow)
1702 : 0 : bAddCols = true;
1703 [ # # ][ # # ]: 0 : if (nFirstCol == nLastCol || nFirstRow == nLastRow)
1704 : : {
1705 : : //get range of indices in col/rows for new cells
1706 : 0 : sal_Int32 nFirstNewCol = nFirstCol;
1707 [ # # ]: 0 : sal_Int32 nFirstNewRow = bBehind ? nFirstRow + 1 : nFirstRow - nLines;
1708 [ # # ]: 0 : if (bAddCols)
1709 : : {
1710 : : OSL_ENSURE( nFirstCol == nLastCol, "column indices seem broken" );
1711 [ # # ]: 0 : nFirstNewCol = bBehind ? nFirstCol + 1 : nFirstCol - nLines;
1712 : 0 : nFirstNewRow = nFirstRow;
1713 : : }
1714 : :
1715 : : // iterate over all data-sequences for the table
1716 [ # # ]: 0 : const Set_DataSequenceRef_t &rSet = aDataSequences[ &rTable ];
1717 : 0 : Set_DataSequenceRef_t::const_iterator aIt( rSet.begin() );
1718 [ # # ]: 0 : while (aIt != rSet.end())
1719 : : {
1720 [ # # ]: 0 : uno::Reference< chart2::data::XDataSequence > xTemp(*aIt); // temporary needed for g++ 3.3.5
1721 [ # # ]: 0 : uno::Reference< chart2::data::XTextualDataSequence > xRef( xTemp, uno::UNO_QUERY );
1722 [ # # ]: 0 : if (xRef.is())
1723 : : {
1724 [ # # ][ # # ]: 0 : const sal_Int32 nLen = xRef->getTextualData().getLength();
[ # # ]
1725 [ # # ]: 0 : if (nLen > 1) // value data-sequence ?
1726 : : {
1727 : 0 : SwChartDataSequence *pDataSeq = 0;
1728 [ # # ]: 0 : uno::Reference< lang::XUnoTunnel > xTunnel( xRef, uno::UNO_QUERY );
1729 [ # # ]: 0 : if(xTunnel.is())
1730 : : {
1731 : : pDataSeq = reinterpret_cast< SwChartDataSequence * >(
1732 [ # # ][ # # ]: 0 : sal::static_int_cast< sal_IntPtr >( xTunnel->getSomething( SwChartDataSequence::getUnoTunnelId() )));
[ # # ]
1733 : :
1734 [ # # ]: 0 : if (pDataSeq)
1735 : : {
1736 : : SwRangeDescriptor aDesc;
1737 [ # # ]: 0 : pDataSeq->FillRangeDesc( aDesc );
1738 : :
1739 : 0 : chart::ChartDataRowSource eDRSource = chart::ChartDataRowSource_COLUMNS;
1740 [ # # ][ # # ]: 0 : if (aDesc.nTop == aDesc.nBottom && aDesc.nLeft != aDesc.nRight)
1741 : 0 : eDRSource = chart::ChartDataRowSource_ROWS;
1742 : :
1743 [ # # ][ # # ]: 0 : if (!bAddCols && eDRSource == chart::ChartDataRowSource_COLUMNS)
1744 : : {
1745 : : // add rows: extend affected columns by newly added row cells
1746 [ # # ]: 0 : pDataSeq->ExtendTo( true, nFirstNewRow, nLines );
1747 : : }
1748 [ # # ][ # # ]: 0 : else if (bAddCols && eDRSource == chart::ChartDataRowSource_ROWS)
1749 : : {
1750 : : // add cols: extend affected rows by newly added column cells
1751 [ # # ]: 0 : pDataSeq->ExtendTo( false, nFirstNewCol, nLines );
1752 : : }
1753 : : }
1754 : 0 : }
1755 : : }
1756 : : }
1757 : 0 : ++aIt;
1758 : 0 : }
1759 : :
1760 : : }
1761 : : }
1762 : : }
1763 : :
1764 : : // XRangeXMLConversion ---------------------------------------------------
1765 : 0 : rtl::OUString SAL_CALL SwChartDataProvider::convertRangeToXML( const rtl::OUString& rRangeRepresentation )
1766 : : throw ( uno::RuntimeException, lang::IllegalArgumentException )
1767 : : {
1768 [ # # ]: 0 : SolarMutexGuard aGuard;
1769 [ # # ]: 0 : if (bDisposed)
1770 [ # # ]: 0 : throw lang::DisposedException();
1771 : :
1772 [ # # ]: 0 : String aRes;
1773 [ # # ]: 0 : String aRangeRepresentation( rRangeRepresentation );
1774 : :
1775 : : // multiple ranges are delimeted by a ';' like in
1776 : : // "Table1.A1:A4;Table1.C2:C5" the same table must be used in all ranges!
1777 [ # # ][ # # ]: 0 : xub_StrLen nNumRanges = comphelper::string::getTokenCount(aRangeRepresentation, ';');
1778 : 0 : SwTable* pFirstFoundTable = 0; // to check that only one table will be used
1779 [ # # ]: 0 : for (sal_uInt16 i = 0; i < nNumRanges; ++i)
1780 : : {
1781 [ # # ]: 0 : String aRange( aRangeRepresentation.GetToken(i, ';') );
1782 : 0 : SwFrmFmt *pTblFmt = 0; // pointer to table format
1783 [ # # ][ # # ]: 0 : GetFormatAndCreateCursorFromRangeRep( pDoc, aRange, &pTblFmt, NULL );
1784 [ # # ]: 0 : if (!pTblFmt)
1785 [ # # ]: 0 : throw lang::IllegalArgumentException();
1786 [ # # ]: 0 : SwTable* pTable = SwTable::FindTable( pTblFmt );
1787 [ # # ][ # # ]: 0 : if (pTable->IsTblComplex())
1788 [ # # ]: 0 : throw uno::RuntimeException();
1789 : :
1790 : : // check that there is only one table used in all ranges
1791 [ # # ]: 0 : if (!pFirstFoundTable)
1792 : 0 : pFirstFoundTable = pTable;
1793 [ # # ]: 0 : if (pTable != pFirstFoundTable)
1794 [ # # ]: 0 : throw lang::IllegalArgumentException();
1795 : :
1796 [ # # ]: 0 : String aTblName;
1797 [ # # ]: 0 : String aStartCell;
1798 [ # # ]: 0 : String aEndCell;
1799 [ # # ][ # # ]: 0 : if (!GetTableAndCellsFromRangeRep( aRange, aTblName, aStartCell, aEndCell ))
[ # # ]
1800 [ # # ]: 0 : throw lang::IllegalArgumentException();
1801 : :
1802 : : sal_Int32 nCol, nRow;
1803 [ # # ]: 0 : lcl_GetCellPosition( aStartCell, nCol, nRow );
1804 [ # # ][ # # ]: 0 : if (nCol < 0 || nRow < 0)
1805 [ # # ]: 0 : throw uno::RuntimeException();
1806 : :
1807 : : //!! following objects/functions are implemented in XMLRangeHelper.?xx
1808 : : //!! which is a copy of the respective file from chart2 !!
1809 : 0 : XMLRangeHelper::CellRange aCellRange;
1810 [ # # ]: 0 : aCellRange.aTableName = aTblName;
1811 : 0 : aCellRange.aUpperLeft.nColumn = nCol;
1812 : 0 : aCellRange.aUpperLeft.nRow = nRow;
1813 : 0 : aCellRange.aUpperLeft.bIsEmpty = false;
1814 [ # # ][ # # ]: 0 : if (aStartCell != aEndCell && aEndCell.Len() != 0)
[ # # ][ # # ]
1815 : : {
1816 [ # # ]: 0 : lcl_GetCellPosition( aEndCell, nCol, nRow );
1817 [ # # ][ # # ]: 0 : if (nCol < 0 || nRow < 0)
1818 [ # # ]: 0 : throw uno::RuntimeException();
1819 : :
1820 : 0 : aCellRange.aLowerRight.nColumn = nCol;
1821 : 0 : aCellRange.aLowerRight.nRow = nRow;
1822 : 0 : aCellRange.aLowerRight.bIsEmpty = false;
1823 : : }
1824 [ # # ][ # # ]: 0 : String aTmp( XMLRangeHelper::getXMLStringFromCellRange( aCellRange ) );
1825 [ # # ]: 0 : if (aRes.Len()) // in case of multiple ranges add delimeter
1826 [ # # ]: 0 : aRes.AppendAscii( " " );
1827 [ # # ]: 0 : aRes += aTmp;
1828 [ # # ][ # # ]: 0 : }
[ # # ][ # # ]
[ # # ]
1829 : :
1830 [ # # ][ # # ]: 0 : return aRes;
[ # # ][ # # ]
1831 : : }
1832 : :
1833 : 0 : rtl::OUString SAL_CALL SwChartDataProvider::convertRangeFromXML( const rtl::OUString& rXMLRange )
1834 : : throw ( uno::RuntimeException, lang::IllegalArgumentException )
1835 : : {
1836 [ # # ]: 0 : SolarMutexGuard aGuard;
1837 [ # # ]: 0 : if (bDisposed)
1838 [ # # ]: 0 : throw lang::DisposedException();
1839 : :
1840 [ # # ]: 0 : String aRes;
1841 [ # # ]: 0 : String aXMLRange( rXMLRange );
1842 : :
1843 : : // multiple ranges are delimeted by a ' ' like in
1844 : : // "Table1.$A$1:.$A$4 Table1.$C$2:.$C$5" the same table must be used in all ranges!
1845 [ # # ][ # # ]: 0 : xub_StrLen nNumRanges = comphelper::string::getTokenCount(aXMLRange, ' ');
1846 : 0 : rtl::OUString aFirstFoundTable; // to check that only one table will be used
1847 [ # # ]: 0 : for (sal_uInt16 i = 0; i < nNumRanges; ++i)
1848 : : {
1849 [ # # ]: 0 : String aRange( aXMLRange.GetToken(i, ' ') );
1850 : :
1851 : : //!! following objects and function are implemented in XMLRangeHelper.?xx
1852 : : //!! which is a copy of the respective file from chart2 !!
1853 [ # # ][ # # ]: 0 : XMLRangeHelper::CellRange aCellRange( XMLRangeHelper::getCellRangeFromXMLString( aRange ));
1854 : :
1855 : : // check that there is only one table used in all ranges
1856 [ # # ]: 0 : if (aFirstFoundTable.isEmpty())
1857 : 0 : aFirstFoundTable = aCellRange.aTableName;
1858 [ # # ]: 0 : if (aCellRange.aTableName != aFirstFoundTable)
1859 [ # # ]: 0 : throw lang::IllegalArgumentException();
1860 : :
1861 : 0 : OUString aTmp( aCellRange.aTableName );
1862 : 0 : aTmp += OUString::valueOf((sal_Unicode) '.');
1863 : : aTmp += lcl_GetCellName( aCellRange.aUpperLeft.nColumn,
1864 [ # # ][ # # ]: 0 : aCellRange.aUpperLeft.nRow );
[ # # ]
1865 : : // does cell range consist of more than a single cell?
1866 [ # # ]: 0 : if (!aCellRange.aLowerRight.bIsEmpty)
1867 : : {
1868 : 0 : aTmp += OUString::valueOf((sal_Unicode) ':');
1869 : : aTmp += lcl_GetCellName( aCellRange.aLowerRight.nColumn,
1870 [ # # ][ # # ]: 0 : aCellRange.aLowerRight.nRow );
[ # # ]
1871 : : }
1872 : :
1873 [ # # ]: 0 : if (aRes.Len()) // in case of multiple ranges add delimeter
1874 [ # # ]: 0 : aRes.AppendAscii( ";" );
1875 [ # # ][ # # ]: 0 : aRes += String(aTmp);
[ # # ]
1876 [ # # ]: 0 : }
1877 : :
1878 [ # # ][ # # ]: 0 : return aRes;
[ # # ][ # # ]
1879 : : }
1880 : :
1881 : 0 : SwChartDataSource::SwChartDataSource(
1882 : : const uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > &rLDS ) :
1883 [ # # ]: 0 : aLDS( rLDS )
1884 : : {
1885 : 0 : }
1886 : :
1887 [ # # ]: 0 : SwChartDataSource::~SwChartDataSource()
1888 : : {
1889 [ # # ]: 0 : }
1890 : :
1891 : 0 : uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > SAL_CALL SwChartDataSource::getDataSequences( )
1892 : : throw (uno::RuntimeException)
1893 : : {
1894 [ # # ]: 0 : SolarMutexGuard aGuard;
1895 [ # # ][ # # ]: 0 : return aLDS;
1896 : : }
1897 : :
1898 : 0 : OUString SAL_CALL SwChartDataSource::getImplementationName( )
1899 : : throw (uno::RuntimeException)
1900 : : {
1901 [ # # ]: 0 : SolarMutexGuard aGuard;
1902 [ # # ][ # # ]: 0 : return C2U("SwChartDataSource");
1903 : : }
1904 : :
1905 : 0 : sal_Bool SAL_CALL SwChartDataSource::supportsService(
1906 : : const OUString& rServiceName )
1907 : : throw (uno::RuntimeException)
1908 : : {
1909 [ # # ]: 0 : SolarMutexGuard aGuard;
1910 [ # # ]: 0 : return rServiceName == SN_DATA_SOURCE;
1911 : : }
1912 : :
1913 : 0 : uno::Sequence< OUString > SAL_CALL SwChartDataSource::getSupportedServiceNames( )
1914 : : throw (uno::RuntimeException)
1915 : : {
1916 [ # # ]: 0 : SolarMutexGuard aGuard;
1917 [ # # ]: 0 : uno::Sequence< OUString > aRes(1);
1918 [ # # ][ # # ]: 0 : aRes.getArray()[0] = C2U( SN_DATA_SOURCE );
1919 [ # # ]: 0 : return aRes;
1920 : : }
1921 : :
1922 : 0 : SwChartDataSequence::SwChartDataSequence(
1923 : : SwChartDataProvider &rProvider,
1924 : : SwFrmFmt &rTblFmt,
1925 : : SwUnoCrsr *pTableCursor ) :
1926 : : SwClient( &rTblFmt ),
1927 [ # # ]: 0 : aEvtListeners( GetChartMutex() ),
1928 [ # # ]: 0 : aModifyListeners( GetChartMutex() ),
1929 : : aRowLabelText( SW_RES( STR_CHART2_ROW_LABEL_TEXT ) ),
1930 : : aColLabelText( SW_RES( STR_CHART2_COL_LABEL_TEXT ) ),
1931 : : xDataProvider( &rProvider ),
1932 : : pDataProvider( &rProvider ),
1933 : : pTblCrsr( pTableCursor ),
1934 : : aCursorDepend( this, pTableCursor ),
1935 [ # # ][ # # ]: 0 : _pPropSet( aSwMapProvider.GetPropertySet( PROPERTY_MAP_CHART2_DATA_SEQUENCE ) )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
1936 : : {
1937 : 0 : bDisposed = sal_False;
1938 : :
1939 : 0 : acquire();
1940 : : try
1941 : : {
1942 [ # # ]: 0 : const SwTable* pTable = SwTable::FindTable( &rTblFmt );
1943 [ # # ]: 0 : if (pTable)
1944 : : {
1945 [ # # ]: 0 : uno::Reference< chart2::data::XDataSequence > xRef( dynamic_cast< chart2::data::XDataSequence * >(this), uno::UNO_QUERY );
1946 [ # # ]: 0 : pDataProvider->AddDataSequence( *pTable, xRef );
1947 [ # # ][ # # ]: 0 : pDataProvider->addEventListener( dynamic_cast< lang::XEventListener * >(this) );
1948 : : }
1949 : : else {
1950 : : OSL_FAIL( "table missing" );
1951 : : }
1952 : : }
1953 [ # # # ]: 0 : catch (uno::RuntimeException &)
1954 : : {
1955 : 0 : throw;
1956 : : }
1957 [ # # ]: 0 : catch (uno::Exception &)
1958 : : {
1959 : : }
1960 : 0 : release();
1961 : :
1962 : : #if OSL_DEBUG_LEVEL > 0
1963 : : OUString aRangeStr( getSourceRangeRepresentation() );
1964 : :
1965 : : // check if it can properly convert into a SwUnoTableCrsr
1966 : : // which is required for some functions
1967 : : SwUnoTableCrsr* pUnoTblCrsr = dynamic_cast<SwUnoTableCrsr*>(pTblCrsr);
1968 : : OSL_ENSURE(pUnoTblCrsr, "SwChartDataSequence: cursor not SwUnoTableCrsr");
1969 : : (void) pUnoTblCrsr;
1970 : : #endif
1971 : 0 : }
1972 : :
1973 : 0 : SwChartDataSequence::SwChartDataSequence( const SwChartDataSequence &rObj ) :
1974 : : SwChartDataSequenceBaseClass(),
1975 : 0 : SwClient( rObj.GetFrmFmt() ),
1976 [ # # ]: 0 : aEvtListeners( GetChartMutex() ),
1977 [ # # ]: 0 : aModifyListeners( GetChartMutex() ),
1978 : : aRole( rObj.aRole ),
1979 : : aRowLabelText( SW_RES(STR_CHART2_ROW_LABEL_TEXT) ),
1980 : : aColLabelText( SW_RES(STR_CHART2_COL_LABEL_TEXT) ),
1981 : : xDataProvider( rObj.pDataProvider ),
1982 : : pDataProvider( rObj.pDataProvider ),
1983 [ # # ]: 0 : pTblCrsr( rObj.pTblCrsr->Clone() ),
1984 : : aCursorDepend( this, pTblCrsr ),
1985 [ # # ][ # # ]: 0 : _pPropSet( rObj._pPropSet )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
1986 : : {
1987 : 0 : bDisposed = sal_False;
1988 : :
1989 : 0 : acquire();
1990 : : try
1991 : : {
1992 [ # # ]: 0 : const SwTable* pTable = SwTable::FindTable( GetFrmFmt() );
1993 [ # # ]: 0 : if (pTable)
1994 : : {
1995 [ # # ]: 0 : uno::Reference< chart2::data::XDataSequence > xRef( dynamic_cast< chart2::data::XDataSequence * >(this), uno::UNO_QUERY );
1996 [ # # ]: 0 : pDataProvider->AddDataSequence( *pTable, xRef );
1997 [ # # ][ # # ]: 0 : pDataProvider->addEventListener( dynamic_cast< lang::XEventListener * >(this) );
1998 : : }
1999 : : else {
2000 : : OSL_FAIL( "table missing" );
2001 : : }
2002 : : }
2003 [ # # # ]: 0 : catch (uno::RuntimeException &)
2004 : : {
2005 : 0 : throw;
2006 : : }
2007 [ # # ]: 0 : catch (uno::Exception &)
2008 : : {
2009 : : }
2010 : 0 : release();
2011 : :
2012 : : #if OSL_DEBUG_LEVEL > 0
2013 : : OUString aRangeStr( getSourceRangeRepresentation() );
2014 : :
2015 : : // check if it can properly convert into a SwUnoTableCrsr
2016 : : // which is required for some functions
2017 : : SwUnoTableCrsr* pUnoTblCrsr = dynamic_cast<SwUnoTableCrsr*>(pTblCrsr);
2018 : : OSL_ENSURE(pUnoTblCrsr, "SwChartDataSequence: cursor not SwUnoTableCrsr");
2019 : : (void) pUnoTblCrsr;
2020 : : #endif
2021 : 0 : }
2022 : :
2023 [ # # ][ # # ]: 0 : SwChartDataSequence::~SwChartDataSequence()
[ # # ][ # # ]
[ # # ][ # # ]
2024 : : {
2025 : : // since the data-provider holds only weak references to the data-sequence
2026 : : // there should be no need here to release them explicitly...
2027 : :
2028 [ # # ][ # # ]: 0 : delete pTblCrsr;
2029 [ # # ]: 0 : }
2030 : :
2031 : : namespace
2032 : : {
2033 : : class theSwChartDataSequenceUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwChartDataSequenceUnoTunnelId > {};
2034 : : }
2035 : :
2036 : 0 : const uno::Sequence< sal_Int8 > & SwChartDataSequence::getUnoTunnelId()
2037 : : {
2038 : 0 : return theSwChartDataSequenceUnoTunnelId::get().getSeq();
2039 : : }
2040 : :
2041 : 0 : sal_Int64 SAL_CALL SwChartDataSequence::getSomething( const uno::Sequence< sal_Int8 > &rId )
2042 : : throw(uno::RuntimeException)
2043 : : {
2044 [ # # # # ]: 0 : if( rId.getLength() == 16
[ # # ]
2045 : 0 : && 0 == memcmp( getUnoTunnelId().getConstArray(),
2046 : 0 : rId.getConstArray(), 16 ) )
2047 : : {
2048 : 0 : return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >(this) );
2049 : : }
2050 : 0 : return 0;
2051 : : }
2052 : :
2053 : 0 : uno::Sequence< uno::Any > SAL_CALL SwChartDataSequence::getData( )
2054 : : throw (uno::RuntimeException)
2055 : : {
2056 [ # # ]: 0 : SolarMutexGuard aGuard;
2057 [ # # ]: 0 : if (bDisposed)
2058 [ # # ]: 0 : throw lang::DisposedException();
2059 : :
2060 [ # # ]: 0 : uno::Sequence< uno::Any > aRes;
2061 : 0 : SwFrmFmt* pTblFmt = GetFrmFmt();
2062 [ # # ]: 0 : if(pTblFmt)
2063 : : {
2064 [ # # ]: 0 : SwTable* pTable = SwTable::FindTable( pTblFmt );
2065 [ # # ][ # # ]: 0 : if(!pTable->IsTblComplex())
2066 : : {
2067 : : SwRangeDescriptor aDesc;
2068 [ # # ][ # # ]: 0 : if (FillRangeDescriptor( aDesc, GetCellRangeName( *pTblFmt, *pTblCrsr ) ))
[ # # ][ # # ]
2069 : : {
2070 : : //!! make copy of pTblCrsr (SwUnoCrsr )
2071 : : // keep original cursor and make copy of it that gets handed
2072 : : // over to the SwXCellRange object which takes ownership and
2073 : : // thus will destroy the copy later.
2074 [ # # ][ # # ]: 0 : SwXCellRange aRange( pTblCrsr->Clone(), *pTblFmt, aDesc );
2075 [ # # ][ # # ]: 0 : aRange.GetDataSequence( &aRes, 0, 0 );
2076 : : }
2077 : : }
2078 : : }
2079 [ # # ]: 0 : return aRes;
2080 : : }
2081 : :
2082 : 0 : OUString SAL_CALL SwChartDataSequence::getSourceRangeRepresentation( )
2083 : : throw (uno::RuntimeException)
2084 : : {
2085 [ # # ]: 0 : SolarMutexGuard aGuard;
2086 [ # # ]: 0 : if (bDisposed)
2087 [ # # ]: 0 : throw lang::DisposedException();
2088 : :
2089 [ # # ]: 0 : String aRes;
2090 : 0 : SwFrmFmt* pTblFmt = GetFrmFmt();
2091 [ # # ]: 0 : if (pTblFmt)
2092 : : {
2093 [ # # ]: 0 : aRes = pTblFmt->GetName();
2094 [ # # ]: 0 : String aCellRange( GetCellRangeName( *pTblFmt, *pTblCrsr ) );
2095 : : OSL_ENSURE( aCellRange.Len() != 0, "failed to get cell range" );
2096 [ # # ]: 0 : aRes += (sal_Unicode) '.';
2097 [ # # ][ # # ]: 0 : aRes += aCellRange;
2098 : : }
2099 [ # # ][ # # ]: 0 : return aRes;
[ # # ]
2100 : : }
2101 : :
2102 : 0 : uno::Sequence< OUString > SAL_CALL SwChartDataSequence::generateLabel(
2103 : : chart2::data::LabelOrigin eLabelOrigin )
2104 : : throw (uno::RuntimeException)
2105 : : {
2106 [ # # ]: 0 : SolarMutexGuard aGuard;
2107 [ # # ]: 0 : if (bDisposed)
2108 [ # # ]: 0 : throw lang::DisposedException();
2109 : :
2110 [ # # ]: 0 : uno::Sequence< OUString > aLabels;
2111 : :
2112 : : {
2113 : : SwRangeDescriptor aDesc;
2114 : 0 : sal_Bool bOk sal_False;
2115 : 0 : SwFrmFmt* pTblFmt = GetFrmFmt();
2116 [ # # ][ # # ]: 0 : SwTable* pTable = pTblFmt ? SwTable::FindTable( pTblFmt ) : 0;
2117 [ # # ][ # # ]: 0 : if (!pTblFmt || !pTable || pTable->IsTblComplex())
[ # # ][ # # ]
[ # # ]
2118 [ # # ]: 0 : throw uno::RuntimeException();
2119 : : else
2120 : : {
2121 [ # # ]: 0 : String aCellRange( GetCellRangeName( *pTblFmt, *pTblCrsr ) );
2122 : : OSL_ENSURE( aCellRange.Len() != 0, "failed to get cell range" );
2123 [ # # ]: 0 : bOk = FillRangeDescriptor( aDesc, aCellRange );
2124 [ # # ]: 0 : OSL_ENSURE( bOk, "falied to get SwRangeDescriptor" );
2125 : : }
2126 [ # # ]: 0 : if (bOk)
2127 : : {
2128 [ # # ]: 0 : aDesc.Normalize();
2129 : 0 : sal_Int32 nColSpan = aDesc.nRight - aDesc.nLeft + 1;
2130 : 0 : sal_Int32 nRowSpan = aDesc.nBottom - aDesc.nTop + 1;
2131 : : OSL_ENSURE( nColSpan == 1 || nRowSpan == 1,
2132 : : "unexpected range of selected cells" );
2133 : :
2134 [ # # ]: 0 : String aTxt; // label text to be returned
2135 : 0 : sal_Bool bReturnEmptyTxt = sal_False;
2136 : 0 : sal_Bool bUseCol = sal_True;
2137 [ # # ]: 0 : if (eLabelOrigin == chart2::data::LabelOrigin_COLUMN)
2138 : 0 : bUseCol = sal_True;
2139 [ # # ]: 0 : else if (eLabelOrigin == chart2::data::LabelOrigin_ROW)
2140 : 0 : bUseCol = sal_False;
2141 [ # # ]: 0 : else if (eLabelOrigin == chart2::data::LabelOrigin_SHORT_SIDE)
2142 : : {
2143 : 0 : bUseCol = nColSpan < nRowSpan;
2144 : 0 : bReturnEmptyTxt = nColSpan == nRowSpan;
2145 : : }
2146 [ # # ]: 0 : else if (eLabelOrigin == chart2::data::LabelOrigin_LONG_SIDE)
2147 : : {
2148 : 0 : bUseCol = nColSpan > nRowSpan;
2149 : 0 : bReturnEmptyTxt = nColSpan == nRowSpan;
2150 : : }
2151 : : else {
2152 : : OSL_FAIL( "unexpected case" );
2153 : : }
2154 : :
2155 : : // build label sequence
2156 : : //
2157 [ # # ]: 0 : sal_Int32 nSeqLen = bUseCol ? nColSpan : nRowSpan;
2158 [ # # ]: 0 : aLabels.realloc( nSeqLen );
2159 [ # # ]: 0 : OUString *pLabels = aLabels.getArray();
2160 [ # # ]: 0 : for (sal_Int32 i = 0; i < nSeqLen; ++i)
2161 : : {
2162 [ # # ]: 0 : if (!bReturnEmptyTxt)
2163 : : {
2164 [ # # ][ # # ]: 0 : aTxt = bUseCol ? aColLabelText : aRowLabelText;
2165 : 0 : sal_Int32 nCol = aDesc.nLeft;
2166 : 0 : sal_Int32 nRow = aDesc.nTop;
2167 [ # # ]: 0 : if (bUseCol)
2168 : 0 : nCol = nCol + i;
2169 : : else
2170 : 0 : nRow = nRow + i;
2171 [ # # ]: 0 : String aCellName( lcl_GetCellName( nCol, nRow ) );
2172 : :
2173 : 0 : xub_StrLen nLen = aCellName.Len();
2174 [ # # ]: 0 : if (nLen)
2175 : : {
2176 : 0 : const sal_Unicode *pBuf = aCellName.GetBuffer();
2177 : 0 : const sal_Unicode *pEnd = pBuf + nLen;
2178 [ # # ][ # # ]: 0 : while (pBuf < pEnd && !('0' <= *pBuf && *pBuf <= '9'))
[ # # ][ # # ]
2179 : 0 : ++pBuf;
2180 : : // start of number found?
2181 [ # # ][ # # ]: 0 : if (pBuf < pEnd && ('0' <= *pBuf && *pBuf <= '9'))
[ # # ]
2182 : : {
2183 [ # # ]: 0 : String aRplc;
2184 [ # # ]: 0 : String aNew;
2185 [ # # ]: 0 : if (bUseCol)
2186 : : {
2187 [ # # ]: 0 : aRplc = rtl::OUString("%COLUMNLETTER");
2188 [ # # ]: 0 : aNew = rtl::OUString(aCellName.GetBuffer(), pBuf - aCellName.GetBuffer());
2189 : : }
2190 : : else
2191 : : {
2192 [ # # ]: 0 : aRplc = rtl::OUString("%ROWNUMBER");
2193 [ # # ]: 0 : aNew = rtl::OUString(pBuf, (aCellName.GetBuffer() + nLen) - pBuf);
2194 : : }
2195 [ # # ]: 0 : xub_StrLen nPos = aTxt.Search( aRplc );
2196 [ # # ]: 0 : if (nPos != STRING_NOTFOUND)
2197 [ # # ][ # # ]: 0 : aTxt = aTxt.Replace( nPos, aRplc.Len(), aNew );
[ # # ][ # # ]
2198 : : }
2199 [ # # ]: 0 : }
2200 : : }
2201 [ # # ]: 0 : pLabels[i] = aTxt;
2202 [ # # ]: 0 : }
2203 : : }
2204 : : }
2205 : :
2206 [ # # ]: 0 : return aLabels;
2207 : : }
2208 : :
2209 : 0 : ::sal_Int32 SAL_CALL SwChartDataSequence::getNumberFormatKeyByIndex(
2210 : : ::sal_Int32 /*nIndex*/ )
2211 : : throw (lang::IndexOutOfBoundsException,
2212 : : uno::RuntimeException)
2213 : : {
2214 : 0 : return 0;
2215 : : }
2216 : :
2217 : 0 : uno::Sequence< OUString > SAL_CALL SwChartDataSequence::getTextualData( )
2218 : : throw (uno::RuntimeException)
2219 : : {
2220 [ # # ]: 0 : SolarMutexGuard aGuard;
2221 [ # # ]: 0 : if (bDisposed)
2222 [ # # ]: 0 : throw lang::DisposedException();
2223 : :
2224 [ # # ]: 0 : uno::Sequence< OUString > aRes;
2225 : 0 : SwFrmFmt* pTblFmt = GetFrmFmt();
2226 [ # # ]: 0 : if(pTblFmt)
2227 : : {
2228 [ # # ]: 0 : SwTable* pTable = SwTable::FindTable( pTblFmt );
2229 [ # # ][ # # ]: 0 : if(!pTable->IsTblComplex())
2230 : : {
2231 : : SwRangeDescriptor aDesc;
2232 [ # # ][ # # ]: 0 : if (FillRangeDescriptor( aDesc, GetCellRangeName( *pTblFmt, *pTblCrsr ) ))
[ # # ][ # # ]
2233 : : {
2234 : : //!! make copy of pTblCrsr (SwUnoCrsr )
2235 : : // keep original cursor and make copy of it that gets handed
2236 : : // over to the SwXCellRange object which takes ownership and
2237 : : // thus will destroy the copy later.
2238 [ # # ][ # # ]: 0 : SwXCellRange aRange( pTblCrsr->Clone(), *pTblFmt, aDesc );
2239 [ # # ][ # # ]: 0 : aRange.GetDataSequence( 0, &aRes, 0 );
2240 : : }
2241 : : }
2242 : : }
2243 [ # # ]: 0 : return aRes;
2244 : : }
2245 : :
2246 : 0 : uno::Sequence< double > SAL_CALL SwChartDataSequence::getNumericalData( )
2247 : : throw (uno::RuntimeException)
2248 : : {
2249 [ # # ]: 0 : SolarMutexGuard aGuard;
2250 [ # # ]: 0 : if (bDisposed)
2251 [ # # ]: 0 : throw lang::DisposedException();
2252 : :
2253 [ # # ]: 0 : uno::Sequence< double > aRes;
2254 : 0 : SwFrmFmt* pTblFmt = GetFrmFmt();
2255 [ # # ]: 0 : if(pTblFmt)
2256 : : {
2257 [ # # ]: 0 : SwTable* pTable = SwTable::FindTable( pTblFmt );
2258 [ # # ][ # # ]: 0 : if(!pTable->IsTblComplex())
2259 : : {
2260 : : SwRangeDescriptor aDesc;
2261 [ # # ][ # # ]: 0 : if (FillRangeDescriptor( aDesc, GetCellRangeName( *pTblFmt, *pTblCrsr ) ))
[ # # ][ # # ]
2262 : : {
2263 : : //!! make copy of pTblCrsr (SwUnoCrsr )
2264 : : // keep original cursor and make copy of it that gets handed
2265 : : // over to the SwXCellRange object which takes ownership and
2266 : : // thus will destroy the copy later.
2267 [ # # ][ # # ]: 0 : SwXCellRange aRange( pTblCrsr->Clone(), *pTblFmt, aDesc );
2268 : :
2269 : : // get numerical values and make an effort to return the
2270 : : // numerical value for text formatted cells
2271 [ # # ][ # # ]: 0 : aRange.GetDataSequence( 0, 0, &aRes, sal_True );
2272 : : }
2273 : : }
2274 : : }
2275 [ # # ]: 0 : return aRes;
2276 : : }
2277 : :
2278 : 0 : uno::Reference< util::XCloneable > SAL_CALL SwChartDataSequence::createClone( )
2279 : : throw (uno::RuntimeException)
2280 : : {
2281 [ # # ]: 0 : SolarMutexGuard aGuard;
2282 [ # # ]: 0 : if (bDisposed)
2283 [ # # ]: 0 : throw lang::DisposedException();
2284 [ # # ][ # # ]: 0 : return new SwChartDataSequence( *this );
[ # # ][ # # ]
2285 : : }
2286 : :
2287 : 0 : uno::Reference< beans::XPropertySetInfo > SAL_CALL SwChartDataSequence::getPropertySetInfo( )
2288 : : throw (uno::RuntimeException)
2289 : : {
2290 [ # # ]: 0 : SolarMutexGuard aGuard;
2291 [ # # ]: 0 : if (bDisposed)
2292 [ # # ]: 0 : throw lang::DisposedException();
2293 : :
2294 [ # # ][ # # ]: 0 : static uno::Reference< beans::XPropertySetInfo > xRes = _pPropSet->getPropertySetInfo();
[ # # ][ # # ]
2295 [ # # ]: 0 : return xRes;
2296 : : }
2297 : :
2298 : 0 : void SAL_CALL SwChartDataSequence::setPropertyValue(
2299 : : const OUString& rPropertyName,
2300 : : const uno::Any& rValue )
2301 : : throw (beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
2302 : : {
2303 [ # # ]: 0 : SolarMutexGuard aGuard;
2304 [ # # ]: 0 : if (bDisposed)
2305 [ # # ]: 0 : throw lang::DisposedException();
2306 : :
2307 [ # # ][ # # ]: 0 : if (rPropertyName.equalsAscii( SW_PROP_NAME_STR( UNO_NAME_ROLE )))
2308 : : {
2309 [ # # ]: 0 : if ( !(rValue >>= aRole) )
2310 [ # # ]: 0 : throw lang::IllegalArgumentException();
2311 : : }
2312 : : else
2313 [ # # ][ # # ]: 0 : throw beans::UnknownPropertyException();
2314 : 0 : }
2315 : :
2316 : 0 : uno::Any SAL_CALL SwChartDataSequence::getPropertyValue(
2317 : : const OUString& rPropertyName )
2318 : : throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
2319 : : {
2320 [ # # ]: 0 : SolarMutexGuard aGuard;
2321 [ # # ]: 0 : if (bDisposed)
2322 [ # # ]: 0 : throw lang::DisposedException();
2323 : :
2324 : 0 : uno::Any aRes;
2325 [ # # ][ # # ]: 0 : if (rPropertyName.equalsAscii( SW_PROP_NAME_STR( UNO_NAME_ROLE )))
2326 [ # # ]: 0 : aRes <<= aRole;
2327 : : else
2328 [ # # ]: 0 : throw beans::UnknownPropertyException();
2329 : :
2330 [ # # ]: 0 : return aRes;
2331 : : }
2332 : :
2333 : 0 : void SAL_CALL SwChartDataSequence::addPropertyChangeListener(
2334 : : const OUString& /*rPropertyName*/,
2335 : : const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ )
2336 : : throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
2337 : : {
2338 : : OSL_FAIL( "not implemented" );
2339 : 0 : }
2340 : :
2341 : 0 : void SAL_CALL SwChartDataSequence::removePropertyChangeListener(
2342 : : const OUString& /*rPropertyName*/,
2343 : : const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ )
2344 : : throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
2345 : : {
2346 : : OSL_FAIL( "not implemented" );
2347 : 0 : }
2348 : :
2349 : 0 : void SAL_CALL SwChartDataSequence::addVetoableChangeListener(
2350 : : const OUString& /*rPropertyName*/,
2351 : : const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/ )
2352 : : throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
2353 : : {
2354 : : OSL_FAIL( "not implemented" );
2355 : 0 : }
2356 : :
2357 : 0 : void SAL_CALL SwChartDataSequence::removeVetoableChangeListener(
2358 : : const OUString& /*rPropertyName*/,
2359 : : const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/ )
2360 : : throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
2361 : : {
2362 : : OSL_FAIL( "not implemented" );
2363 : 0 : }
2364 : :
2365 : 0 : OUString SAL_CALL SwChartDataSequence::getImplementationName( )
2366 : : throw (uno::RuntimeException)
2367 : : {
2368 : 0 : return C2U("SwChartDataSequence");
2369 : : }
2370 : :
2371 : 0 : sal_Bool SAL_CALL SwChartDataSequence::supportsService(
2372 : : const OUString& rServiceName )
2373 : : throw (uno::RuntimeException)
2374 : : {
2375 : 0 : return rServiceName == SN_DATA_SEQUENCE;
2376 : : }
2377 : :
2378 : 0 : uno::Sequence< OUString > SAL_CALL SwChartDataSequence::getSupportedServiceNames( )
2379 : : throw (uno::RuntimeException)
2380 : : {
2381 [ # # ]: 0 : SolarMutexGuard aGuard;
2382 [ # # ]: 0 : uno::Sequence< OUString > aRes(1);
2383 [ # # ][ # # ]: 0 : aRes.getArray()[0] = C2U( SN_DATA_SEQUENCE );
2384 [ # # ]: 0 : return aRes;
2385 : : }
2386 : :
2387 : 0 : void SwChartDataSequence::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew)
2388 : : {
2389 : 0 : ClientModify(this, pOld, pNew );
2390 : :
2391 : : // table was deleted or cursor was deleted
2392 [ # # ][ # # ]: 0 : if(!GetRegisteredIn() || !aCursorDepend.GetRegisteredIn())
[ # # ]
2393 : : {
2394 : 0 : pTblCrsr = 0;
2395 : 0 : dispose();
2396 : : }
2397 : : else
2398 : : {
2399 : 0 : setModified( sal_True );
2400 : : }
2401 : 0 : }
2402 : :
2403 : 0 : sal_Bool SAL_CALL SwChartDataSequence::isModified( )
2404 : : throw (uno::RuntimeException)
2405 : : {
2406 [ # # ]: 0 : SolarMutexGuard aGuard;
2407 [ # # ]: 0 : if (bDisposed)
2408 [ # # ]: 0 : throw lang::DisposedException();
2409 : :
2410 [ # # ]: 0 : return sal_True;
2411 : : }
2412 : :
2413 : 0 : void SAL_CALL SwChartDataSequence::setModified(
2414 : : ::sal_Bool bModified )
2415 : : throw (beans::PropertyVetoException, uno::RuntimeException)
2416 : : {
2417 [ # # ]: 0 : SolarMutexGuard aGuard;
2418 [ # # ]: 0 : if (bDisposed)
2419 [ # # ]: 0 : throw lang::DisposedException();
2420 : :
2421 [ # # ]: 0 : if (bModified)
2422 [ # # ][ # # ]: 0 : LaunchModifiedEvent( aModifyListeners, dynamic_cast< XModifyBroadcaster * >(this) );
[ # # ]
2423 : 0 : }
2424 : :
2425 : 0 : void SAL_CALL SwChartDataSequence::addModifyListener(
2426 : : const uno::Reference< util::XModifyListener >& rxListener )
2427 : : throw (uno::RuntimeException)
2428 : : {
2429 [ # # ][ # # ]: 0 : osl::MutexGuard aGuard( GetChartMutex() );
2430 [ # # ][ # # ]: 0 : if (!bDisposed && rxListener.is())
[ # # ]
2431 [ # # ][ # # ]: 0 : aModifyListeners.addInterface( rxListener );
2432 : 0 : }
2433 : :
2434 : 0 : void SAL_CALL SwChartDataSequence::removeModifyListener(
2435 : : const uno::Reference< util::XModifyListener >& rxListener )
2436 : : throw (uno::RuntimeException)
2437 : : {
2438 [ # # ][ # # ]: 0 : osl::MutexGuard aGuard( GetChartMutex() );
2439 [ # # ][ # # ]: 0 : if (!bDisposed && rxListener.is())
[ # # ]
2440 [ # # ][ # # ]: 0 : aModifyListeners.removeInterface( rxListener );
2441 : 0 : }
2442 : :
2443 : 0 : void SAL_CALL SwChartDataSequence::disposing( const lang::EventObject& rSource )
2444 : : throw (uno::RuntimeException)
2445 : : {
2446 [ # # ]: 0 : if (bDisposed)
2447 [ # # ]: 0 : throw lang::DisposedException();
2448 [ # # ]: 0 : if (rSource.Source == xDataProvider)
2449 : : {
2450 : 0 : pDataProvider = 0;
2451 : 0 : xDataProvider.clear();
2452 : : }
2453 : 0 : }
2454 : :
2455 : 0 : void SAL_CALL SwChartDataSequence::dispose( )
2456 : : throw (uno::RuntimeException)
2457 : : {
2458 : 0 : sal_Bool bMustDispose( sal_False );
2459 : : {
2460 [ # # ][ # # ]: 0 : osl::MutexGuard aGuard( GetChartMutex() );
2461 : 0 : bMustDispose = !bDisposed;
2462 [ # # ]: 0 : if (!bDisposed)
2463 [ # # ]: 0 : bDisposed = sal_True;
2464 : : }
2465 [ # # ]: 0 : if (bMustDispose)
2466 : : {
2467 : 0 : bDisposed = sal_True;
2468 [ # # ]: 0 : if (pDataProvider)
2469 : : {
2470 [ # # ]: 0 : const SwTable* pTable = SwTable::FindTable( GetFrmFmt() );
2471 [ # # ]: 0 : if (pTable)
2472 : : {
2473 [ # # ]: 0 : uno::Reference< chart2::data::XDataSequence > xRef( dynamic_cast< chart2::data::XDataSequence * >(this), uno::UNO_QUERY );
2474 [ # # ]: 0 : pDataProvider->RemoveDataSequence( *pTable, xRef );
2475 : : }
2476 : : else {
2477 : : OSL_FAIL( "table missing" );
2478 : : }
2479 : : }
2480 : :
2481 : : // require listeners to release references to this object
2482 [ # # ][ # # ]: 0 : lang::EventObject aEvtObj( dynamic_cast< chart2::data::XDataSequence * >(this) );
2483 [ # # ]: 0 : aModifyListeners.disposeAndClear( aEvtObj );
2484 [ # # ][ # # ]: 0 : aEvtListeners.disposeAndClear( aEvtObj );
2485 : : }
2486 : 0 : }
2487 : :
2488 : 0 : void SAL_CALL SwChartDataSequence::addEventListener(
2489 : : const uno::Reference< lang::XEventListener >& rxListener )
2490 : : throw (uno::RuntimeException)
2491 : : {
2492 [ # # ][ # # ]: 0 : osl::MutexGuard aGuard( GetChartMutex() );
2493 [ # # ][ # # ]: 0 : if (!bDisposed && rxListener.is())
[ # # ]
2494 [ # # ][ # # ]: 0 : aEvtListeners.addInterface( rxListener );
2495 : 0 : }
2496 : :
2497 : 0 : void SAL_CALL SwChartDataSequence::removeEventListener(
2498 : : const uno::Reference< lang::XEventListener >& rxListener )
2499 : : throw (uno::RuntimeException)
2500 : : {
2501 [ # # ][ # # ]: 0 : osl::MutexGuard aGuard( GetChartMutex() );
2502 [ # # ][ # # ]: 0 : if (!bDisposed && rxListener.is())
[ # # ]
2503 [ # # ][ # # ]: 0 : aEvtListeners.removeInterface( rxListener );
2504 : 0 : }
2505 : :
2506 : 0 : sal_Bool SwChartDataSequence::DeleteBox( const SwTableBox &rBox )
2507 : : {
2508 : : #if OSL_DEBUG_LEVEL > 1
2509 : : String aBoxName( rBox.GetName() );
2510 : : #endif
2511 : :
2512 : : // to be set if the last box of the data-sequence was removed here
2513 : 0 : sal_Bool bNowEmpty = sal_False;
2514 : :
2515 : : // if the implementation cursor gets affected (i.e. thew box where it is located
2516 : : // in gets removed) we need to move it before that... (otherwise it does not need to change)
2517 : : //
2518 : 0 : const SwStartNode* pPointStartNode = pTblCrsr->GetPoint()->nNode.GetNode().FindTableBoxStartNode();
2519 : 0 : const SwStartNode* pMarkStartNode = pTblCrsr->GetMark()->nNode.GetNode().FindTableBoxStartNode();
2520 : : //
2521 [ # # ][ # # ]: 0 : if (!pTblCrsr->HasMark() || (pPointStartNode == rBox.GetSttNd() && pMarkStartNode == rBox.GetSttNd()))
[ # # ][ # # ]
2522 : : {
2523 : 0 : bNowEmpty = sal_True;
2524 : : }
2525 [ # # ][ # # ]: 0 : else if (pPointStartNode == rBox.GetSttNd() || pMarkStartNode == rBox.GetSttNd())
[ # # ]
2526 : : {
2527 : 0 : sal_Int32 nPointRow = -1, nPointCol = -1;
2528 : 0 : sal_Int32 nMarkRow = -1, nMarkCol = -1;
2529 [ # # ]: 0 : const SwTable* pTable = SwTable::FindTable( GetFrmFmt() );
2530 [ # # ][ # # ]: 0 : String aPointCellName( pTable->GetTblBox( pPointStartNode->GetIndex() )->GetName() );
2531 [ # # ][ # # ]: 0 : String aMarkCellName( pTable->GetTblBox( pMarkStartNode->GetIndex() )->GetName() );
2532 : :
2533 [ # # ]: 0 : lcl_GetCellPosition( aPointCellName, nPointCol, nPointRow );
2534 [ # # ]: 0 : lcl_GetCellPosition( aMarkCellName, nMarkCol, nMarkRow );
2535 : : OSL_ENSURE( nPointRow >= 0 && nPointCol >= 0, "invalid row and col" );
2536 : : OSL_ENSURE( nMarkRow >= 0 && nMarkCol >= 0, "invalid row and col" );
2537 : :
2538 : : // move vertical or horizontal?
2539 : : OSL_ENSURE( nPointRow == nMarkRow || nPointCol == nMarkCol,
2540 : : "row/col indices not matching" );
2541 : : OSL_ENSURE( nPointRow != nMarkRow || nPointCol != nMarkCol,
2542 : : "point and mark are identical" );
2543 : 0 : sal_Bool bMoveVertical = (nPointCol == nMarkCol);
2544 : 0 : sal_Bool bMoveHorizontal = (nPointRow == nMarkRow);
2545 : :
2546 : : // get movement direction
2547 : 0 : sal_Bool bMoveLeft = sal_False; // move left or right?
2548 : 0 : sal_Bool bMoveUp = sal_False; // move up or down?
2549 [ # # ]: 0 : if (bMoveVertical)
2550 : : {
2551 [ # # ]: 0 : if (pPointStartNode == rBox.GetSttNd()) // move point?
2552 : 0 : bMoveUp = nPointRow > nMarkRow;
2553 : : else // move mark
2554 : 0 : bMoveUp = nMarkRow > nPointRow;
2555 : : }
2556 [ # # ]: 0 : else if (bMoveHorizontal)
2557 : : {
2558 [ # # ]: 0 : if (pPointStartNode == rBox.GetSttNd()) // move point?
2559 : 0 : bMoveLeft = nPointCol > nMarkCol;
2560 : : else // move mark
2561 : 0 : bMoveLeft = nMarkCol > nPointCol;
2562 : : }
2563 : : else {
2564 : : OSL_FAIL( "neither vertical nor horizontal movement" );
2565 : : }
2566 : :
2567 : : // get new box (position) to use...
2568 [ # # ]: 0 : sal_Int32 nRow = (pPointStartNode == rBox.GetSttNd()) ? nPointRow : nMarkRow;
2569 [ # # ]: 0 : sal_Int32 nCol = (pPointStartNode == rBox.GetSttNd()) ? nPointCol : nMarkCol;
2570 [ # # ]: 0 : if (bMoveVertical)
2571 [ # # ]: 0 : nRow += bMoveUp ? -1 : +1;
2572 [ # # ]: 0 : if (bMoveHorizontal)
2573 [ # # ]: 0 : nCol += bMoveLeft ? -1 : +1;
2574 [ # # ]: 0 : String aNewCellName = lcl_GetCellName( nCol, nRow );
2575 [ # # ]: 0 : SwTableBox* pNewBox = (SwTableBox*) pTable->GetTblBox( aNewCellName );
2576 : :
2577 [ # # ]: 0 : if (pNewBox) // set new position (cell range) to use
2578 : : {
2579 : : // So erh lt man den ersten Inhaltsnode in einer gegebenen Zelle:
2580 : : // Zun chst einen SwNodeIndex auf den Node hinter dem SwStartNode der Box...
2581 [ # # ]: 0 : SwNodeIndex aIdx( *pNewBox->GetSttNd(), +1 );
2582 : : // Dies kann ein SwCntntNode sein, kann aber auch ein Tabellen oder Sectionnode sein,
2583 : : // deshalb das GoNext;
2584 : 0 : SwCntntNode *pCNd = aIdx.GetNode().GetCntntNode();
2585 [ # # ]: 0 : if (!pCNd)
2586 [ # # ][ # # ]: 0 : pCNd = GetFrmFmt()->GetDoc()->GetNodes().GoNext( &aIdx );
2587 : : //und damit kann man z.B. eine SwPosition erzeugen:
2588 [ # # ]: 0 : SwPosition aNewPos( *pCNd ); // new position to beused with cursor
2589 : :
2590 : : // if the mark is to be changed make sure there is one...
2591 [ # # ][ # # ]: 0 : if (pMarkStartNode == rBox.GetSttNd() && !pTblCrsr->HasMark())
[ # # ]
2592 [ # # ]: 0 : pTblCrsr->SetMark();
2593 : :
2594 : : // set cursor to new position...
2595 : 0 : SwPosition *pPos = (pPointStartNode == rBox.GetSttNd()) ?
2596 [ # # ]: 0 : pTblCrsr->GetPoint() : pTblCrsr->GetMark();
2597 [ # # ]: 0 : if (pPos)
2598 : : {
2599 [ # # ]: 0 : pPos->nNode = aNewPos.nNode;
2600 [ # # ]: 0 : pPos->nContent = aNewPos.nContent;
2601 : : }
2602 : : else {
2603 : : OSL_FAIL( "neither point nor mark available for change" );
2604 [ # # ][ # # ]: 0 : }
2605 : : }
2606 : : else {
2607 : : OSL_FAIL( "failed to get position" );
2608 [ # # ][ # # ]: 0 : }
[ # # ]
2609 : : }
2610 : :
2611 : 0 : return bNowEmpty;
2612 : : }
2613 : :
2614 : 0 : void SwChartDataSequence::FillRangeDesc( SwRangeDescriptor &rRangeDesc ) const
2615 : : {
2616 : 0 : SwFrmFmt* pTblFmt = GetFrmFmt();
2617 [ # # ]: 0 : if(pTblFmt)
2618 : : {
2619 : 0 : SwTable* pTable = SwTable::FindTable( pTblFmt );
2620 [ # # ]: 0 : if(!pTable->IsTblComplex())
2621 : : {
2622 [ # # ]: 0 : FillRangeDescriptor( rRangeDesc, GetCellRangeName( *pTblFmt, *pTblCrsr ) );
2623 : : }
2624 : : }
2625 : 0 : }
2626 : :
2627 : : /**
2628 : : SwChartDataSequence::ExtendTo
2629 : :
2630 : : extends the data-sequence by new cells added at the end of the direction
2631 : : the data-sequence points to.
2632 : : If the cells are already within the range of the sequence nothing needs
2633 : : to be done.
2634 : : If the cells are beyond the end of the sequence (are not adjacent to the
2635 : : current last cell) nothing can be done. Only if the cells are adjacent to
2636 : : the last cell they can be added.
2637 : :
2638 : : @returns true if the data-sequence was changed.
2639 : : @param bExtendCols
2640 : : specifies if columns or rows are to be extended
2641 : : @param nFirstNew
2642 : : index of first new row/col to be included in data-sequence
2643 : : @param nLastNew
2644 : : index of last new row/col to be included in data-sequence
2645 : : */
2646 : 0 : bool SwChartDataSequence::ExtendTo( bool bExtendCol,
2647 : : sal_Int32 nFirstNew, sal_Int32 nCount )
2648 : : {
2649 : 0 : bool bChanged = false;
2650 : :
2651 [ # # ]: 0 : SwUnoTableCrsr* pUnoTblCrsr = dynamic_cast<SwUnoTableCrsr*>(pTblCrsr);
2652 : : //pUnoTblCrsr->MakeBoxSels();
2653 : :
2654 : 0 : const SwStartNode *pStartNd = 0;
2655 : 0 : const SwTableBox *pStartBox = 0;
2656 : 0 : const SwTableBox *pEndBox = 0;
2657 : :
2658 [ # # ]: 0 : const SwTable* pTable = SwTable::FindTable( GetFrmFmt() );
2659 : : OSL_ENSURE( !pTable->IsTblComplex(), "table too complex" );
2660 [ # # ][ # # ]: 0 : if (nCount < 1 || nFirstNew < 0 || pTable->IsTblComplex())
[ # # ][ # # ]
[ # # ]
2661 : 0 : return false;
2662 : :
2663 : : //
2664 : : // get range descriptor (cell range) for current data-sequence
2665 : : //
2666 [ # # ]: 0 : pStartNd = pUnoTblCrsr->GetPoint()->nNode.GetNode().FindTableBoxStartNode();
2667 [ # # ]: 0 : pEndBox = pTable->GetTblBox( pStartNd->GetIndex() );
2668 [ # # ]: 0 : const String aEndBox( pEndBox->GetName() );
2669 : : //
2670 [ # # ]: 0 : pStartNd = pUnoTblCrsr->GetMark()->nNode.GetNode().FindTableBoxStartNode();
2671 [ # # ]: 0 : pStartBox = pTable->GetTblBox( pStartNd->GetIndex() );
2672 [ # # ]: 0 : const String aStartBox( pStartBox->GetName() );
2673 : : //
2674 [ # # ]: 0 : String aCellRange( aStartBox ); // note that cell range here takes the newly added rows/cols already into account
2675 [ # # ]: 0 : aCellRange.AppendAscii( ":" );
2676 [ # # ]: 0 : aCellRange += aEndBox;
2677 : : SwRangeDescriptor aDesc;
2678 [ # # ]: 0 : FillRangeDescriptor( aDesc, aCellRange );
2679 : :
2680 [ # # ]: 0 : String aNewStartCell;
2681 [ # # ]: 0 : String aNewEndCell;
2682 [ # # ][ # # ]: 0 : if (bExtendCol && aDesc.nBottom + 1 == nFirstNew)
2683 : : {
2684 : : // new column cells adjacent to the bottom of the
2685 : : // current data-sequence to be added...
2686 : : OSL_ENSURE( aDesc.nLeft == aDesc.nRight, "data-sequence is not a column" );
2687 [ # # ][ # # ]: 0 : aNewStartCell = lcl_GetCellName(aDesc.nLeft, aDesc.nTop);
[ # # ]
2688 [ # # ][ # # ]: 0 : aNewEndCell = lcl_GetCellName(aDesc.nRight, aDesc.nBottom + nCount);
[ # # ]
2689 : 0 : bChanged = true;
2690 : : }
2691 [ # # ][ # # ]: 0 : else if (bExtendCol && aDesc.nTop - nCount == nFirstNew)
2692 : : {
2693 : : // new column cells adjacent to the top of the
2694 : : // current data-sequence to be added...
2695 : : OSL_ENSURE( aDesc.nLeft == aDesc.nRight, "data-sequence is not a column" );
2696 [ # # ][ # # ]: 0 : aNewStartCell = lcl_GetCellName(aDesc.nLeft, aDesc.nTop - nCount);
[ # # ]
2697 [ # # ][ # # ]: 0 : aNewEndCell = lcl_GetCellName(aDesc.nRight, aDesc.nBottom);
[ # # ]
2698 : 0 : bChanged = true;
2699 : : }
2700 [ # # ][ # # ]: 0 : else if (!bExtendCol && aDesc.nRight + 1 == nFirstNew)
2701 : : {
2702 : : // new row cells adjacent to the right of the
2703 : : // current data-sequence to be added...
2704 : : OSL_ENSURE( aDesc.nTop == aDesc.nBottom, "data-sequence is not a row" );
2705 [ # # ][ # # ]: 0 : aNewStartCell = lcl_GetCellName(aDesc.nLeft, aDesc.nTop);
[ # # ]
2706 [ # # ][ # # ]: 0 : aNewEndCell = lcl_GetCellName(aDesc.nRight + nCount, aDesc.nBottom);
[ # # ]
2707 : 0 : bChanged = true;
2708 : : }
2709 [ # # ][ # # ]: 0 : else if (!bExtendCol && aDesc.nLeft - nCount == nFirstNew)
2710 : : {
2711 : : // new row cells adjacent to the left of the
2712 : : // current data-sequence to be added...
2713 : : OSL_ENSURE( aDesc.nTop == aDesc.nBottom, "data-sequence is not a row" );
2714 [ # # ][ # # ]: 0 : aNewStartCell = lcl_GetCellName(aDesc.nLeft - nCount, aDesc.nTop);
[ # # ]
2715 [ # # ][ # # ]: 0 : aNewEndCell = lcl_GetCellName(aDesc.nRight, aDesc.nBottom);
[ # # ]
2716 : 0 : bChanged = true;
2717 : : }
2718 : :
2719 [ # # ]: 0 : if (bChanged)
2720 : : {
2721 : : // move table cursor to new start and end of data-sequence
2722 [ # # ]: 0 : const SwTableBox *pNewStartBox = pTable->GetTblBox( aNewStartCell );
2723 [ # # ]: 0 : const SwTableBox *pNewEndBox = pTable->GetTblBox( aNewEndCell );
2724 [ # # ]: 0 : pUnoTblCrsr->SetMark();
2725 [ # # ]: 0 : pUnoTblCrsr->GetPoint()->nNode = *pNewEndBox->GetSttNd();
2726 [ # # ]: 0 : pUnoTblCrsr->GetMark()->nNode = *pNewStartBox->GetSttNd();
2727 [ # # ]: 0 : pUnoTblCrsr->Move( fnMoveForward, fnGoNode );
2728 [ # # ]: 0 : pUnoTblCrsr->MakeBoxSels();
2729 : : }
2730 : :
2731 [ # # ][ # # ]: 0 : return bChanged;
[ # # ][ # # ]
[ # # ]
2732 : : }
2733 : :
2734 : 0 : SwChartLabeledDataSequence::SwChartLabeledDataSequence() :
2735 [ # # ]: 0 : aEvtListeners( GetChartMutex() ),
2736 [ # # ][ # # ]: 0 : aModifyListeners( GetChartMutex() )
[ # # ]
2737 : : {
2738 : 0 : bDisposed = sal_False;
2739 : 0 : }
2740 : :
2741 [ # # ][ # # ]: 0 : SwChartLabeledDataSequence::~SwChartLabeledDataSequence()
2742 : : {
2743 [ # # ]: 0 : }
2744 : :
2745 : 0 : uno::Reference< chart2::data::XDataSequence > SAL_CALL SwChartLabeledDataSequence::getValues( )
2746 : : throw (uno::RuntimeException)
2747 : : {
2748 [ # # ]: 0 : SolarMutexGuard aGuard;
2749 [ # # ]: 0 : if (bDisposed)
2750 [ # # ]: 0 : throw lang::DisposedException();
2751 [ # # ]: 0 : return xData;
2752 : : }
2753 : :
2754 : 0 : void SwChartLabeledDataSequence::SetDataSequence(
2755 : : uno::Reference< chart2::data::XDataSequence >& rxDest,
2756 : : const uno::Reference< chart2::data::XDataSequence >& rxSource)
2757 : : {
2758 [ # # ]: 0 : uno::Reference< util::XModifyListener > xML( dynamic_cast< util::XModifyListener* >(this), uno::UNO_QUERY );
2759 [ # # ]: 0 : uno::Reference< lang::XEventListener > xEL( dynamic_cast< lang::XEventListener* >(this), uno::UNO_QUERY );
2760 : :
2761 : : // stop listening to old data-sequence
2762 [ # # ]: 0 : uno::Reference< util::XModifyBroadcaster > xMB( rxDest, uno::UNO_QUERY );
2763 [ # # ]: 0 : if (xMB.is())
2764 [ # # ][ # # ]: 0 : xMB->removeModifyListener( xML );
2765 [ # # ]: 0 : uno::Reference< lang::XComponent > xC( rxDest, uno::UNO_QUERY );
2766 [ # # ]: 0 : if (xC.is())
2767 [ # # ][ # # ]: 0 : xC->removeEventListener( xEL );
2768 : :
2769 [ # # ]: 0 : rxDest = rxSource;
2770 : :
2771 : : // start listening to new data-sequence
2772 [ # # ][ # # ]: 0 : xC = uno::Reference< lang::XComponent >( rxDest, uno::UNO_QUERY );
2773 [ # # ]: 0 : if (xC.is())
2774 [ # # ][ # # ]: 0 : xC->addEventListener( xEL );
2775 [ # # ][ # # ]: 0 : xMB = uno::Reference< util::XModifyBroadcaster >( rxDest, uno::UNO_QUERY );
2776 [ # # ]: 0 : if (xMB.is())
2777 [ # # ][ # # ]: 0 : xMB->addModifyListener( xML );
2778 : 0 : }
2779 : :
2780 : 0 : void SAL_CALL SwChartLabeledDataSequence::setValues(
2781 : : const uno::Reference< chart2::data::XDataSequence >& rxSequence )
2782 : : throw (uno::RuntimeException)
2783 : : {
2784 [ # # ]: 0 : SolarMutexGuard aGuard;
2785 [ # # ]: 0 : if (bDisposed)
2786 [ # # ]: 0 : throw lang::DisposedException();
2787 : :
2788 [ # # ][ # # ]: 0 : if (xData != rxSequence)
2789 : : {
2790 [ # # ]: 0 : SetDataSequence( xData, rxSequence );
2791 : : // inform listeners of changes
2792 [ # # ][ # # ]: 0 : LaunchModifiedEvent( aModifyListeners, dynamic_cast< XModifyBroadcaster * >(this) );
2793 [ # # ]: 0 : }
2794 : 0 : }
2795 : :
2796 : 0 : uno::Reference< chart2::data::XDataSequence > SAL_CALL SwChartLabeledDataSequence::getLabel( )
2797 : : throw (uno::RuntimeException)
2798 : : {
2799 [ # # ]: 0 : SolarMutexGuard aGuard;
2800 [ # # ]: 0 : if (bDisposed)
2801 [ # # ]: 0 : throw lang::DisposedException();
2802 [ # # ]: 0 : return xLabels;
2803 : : }
2804 : :
2805 : 0 : void SAL_CALL SwChartLabeledDataSequence::setLabel(
2806 : : const uno::Reference< chart2::data::XDataSequence >& rxSequence )
2807 : : throw (uno::RuntimeException)
2808 : : {
2809 [ # # ]: 0 : SolarMutexGuard aGuard;
2810 [ # # ]: 0 : if (bDisposed)
2811 [ # # ]: 0 : throw lang::DisposedException();
2812 : :
2813 [ # # ][ # # ]: 0 : if (xLabels != rxSequence)
2814 : : {
2815 [ # # ]: 0 : SetDataSequence( xLabels, rxSequence );
2816 : : // inform listeners of changes
2817 [ # # ][ # # ]: 0 : LaunchModifiedEvent( aModifyListeners, dynamic_cast< XModifyBroadcaster * >(this) );
2818 [ # # ]: 0 : }
2819 : 0 : }
2820 : :
2821 : 0 : uno::Reference< util::XCloneable > SAL_CALL SwChartLabeledDataSequence::createClone( )
2822 : : throw (uno::RuntimeException)
2823 : : {
2824 [ # # ]: 0 : SolarMutexGuard aGuard;
2825 [ # # ]: 0 : if (bDisposed)
2826 [ # # ]: 0 : throw lang::DisposedException();
2827 : :
2828 : 0 : uno::Reference< util::XCloneable > xRes;
2829 : :
2830 [ # # ]: 0 : uno::Reference< util::XCloneable > xDataCloneable( xData, uno::UNO_QUERY );
2831 [ # # ]: 0 : uno::Reference< util::XCloneable > xLabelsCloneable( xLabels, uno::UNO_QUERY );
2832 [ # # ]: 0 : SwChartLabeledDataSequence *pRes = new SwChartLabeledDataSequence();
2833 [ # # ]: 0 : if (xDataCloneable.is())
2834 : : {
2835 [ # # ][ # # ]: 0 : uno::Reference< chart2::data::XDataSequence > xDataClone( xDataCloneable->createClone(), uno::UNO_QUERY );
[ # # ]
2836 [ # # ]: 0 : pRes->setValues( xDataClone );
2837 : : }
2838 : :
2839 [ # # ]: 0 : if (xLabelsCloneable.is())
2840 : : {
2841 [ # # ][ # # ]: 0 : uno::Reference< chart2::data::XDataSequence > xLabelsClone( xLabelsCloneable->createClone(), uno::UNO_QUERY );
[ # # ]
2842 [ # # ]: 0 : pRes->setLabel( xLabelsClone );
2843 : : }
2844 [ # # ][ # # ]: 0 : xRes = pRes;
2845 [ # # ]: 0 : return xRes;
2846 : : }
2847 : :
2848 : 0 : OUString SAL_CALL SwChartLabeledDataSequence::getImplementationName( )
2849 : : throw (uno::RuntimeException)
2850 : : {
2851 : 0 : return C2U("SwChartLabeledDataSequence");
2852 : : }
2853 : :
2854 : 0 : sal_Bool SAL_CALL SwChartLabeledDataSequence::supportsService(
2855 : : const OUString& rServiceName )
2856 : : throw (uno::RuntimeException)
2857 : : {
2858 : 0 : return rServiceName == SN_LABELED_DATA_SEQUENCE;
2859 : : }
2860 : :
2861 : 0 : uno::Sequence< OUString > SAL_CALL SwChartLabeledDataSequence::getSupportedServiceNames( )
2862 : : throw (uno::RuntimeException)
2863 : : {
2864 [ # # ]: 0 : SolarMutexGuard aGuard;
2865 [ # # ]: 0 : uno::Sequence< OUString > aRes(1);
2866 [ # # ][ # # ]: 0 : aRes.getArray()[0] = C2U( SN_LABELED_DATA_SEQUENCE );
2867 [ # # ]: 0 : return aRes;
2868 : : }
2869 : :
2870 : 0 : void SAL_CALL SwChartLabeledDataSequence::disposing(
2871 : : const lang::EventObject& rSource )
2872 : : throw (uno::RuntimeException)
2873 : : {
2874 [ # # ][ # # ]: 0 : osl::MutexGuard aGuard( GetChartMutex() );
2875 : 0 : uno::Reference< uno::XInterface > xRef( rSource.Source );
2876 [ # # ][ # # ]: 0 : if (xRef == xData)
2877 : 0 : xData.clear();
2878 [ # # ][ # # ]: 0 : if (xRef == xLabels)
2879 : 0 : xLabels.clear();
2880 [ # # ][ # # ]: 0 : if (!xData.is() && !xLabels.is())
[ # # ]
2881 [ # # ][ # # ]: 0 : dispose();
2882 : 0 : }
2883 : :
2884 : 0 : void SAL_CALL SwChartLabeledDataSequence::modified(
2885 : : const lang::EventObject& rEvent )
2886 : : throw (uno::RuntimeException)
2887 : : {
2888 [ # # ][ # # ]: 0 : if (rEvent.Source == xData || rEvent.Source == xLabels)
[ # # ]
2889 : : {
2890 [ # # ]: 0 : LaunchModifiedEvent( aModifyListeners, dynamic_cast< XModifyBroadcaster * >(this) );
2891 : : }
2892 : 0 : }
2893 : :
2894 : 0 : void SAL_CALL SwChartLabeledDataSequence::addModifyListener(
2895 : : const uno::Reference< util::XModifyListener >& rxListener )
2896 : : throw (uno::RuntimeException)
2897 : : {
2898 [ # # ][ # # ]: 0 : osl::MutexGuard aGuard( GetChartMutex() );
2899 [ # # ][ # # ]: 0 : if (!bDisposed && rxListener.is())
[ # # ]
2900 [ # # ][ # # ]: 0 : aModifyListeners.addInterface( rxListener );
2901 : 0 : }
2902 : :
2903 : 0 : void SAL_CALL SwChartLabeledDataSequence::removeModifyListener(
2904 : : const uno::Reference< util::XModifyListener >& rxListener )
2905 : : throw (uno::RuntimeException)
2906 : : {
2907 [ # # ][ # # ]: 0 : osl::MutexGuard aGuard( GetChartMutex() );
2908 [ # # ][ # # ]: 0 : if (!bDisposed && rxListener.is())
[ # # ]
2909 [ # # ][ # # ]: 0 : aModifyListeners.removeInterface( rxListener );
2910 : 0 : }
2911 : :
2912 : 0 : void SAL_CALL SwChartLabeledDataSequence::dispose( )
2913 : : throw (uno::RuntimeException)
2914 : : {
2915 : 0 : sal_Bool bMustDispose( sal_False );
2916 : : {
2917 [ # # ][ # # ]: 0 : osl::MutexGuard aGuard( GetChartMutex() );
2918 : 0 : bMustDispose = !bDisposed;
2919 [ # # ]: 0 : if (!bDisposed)
2920 [ # # ]: 0 : bDisposed = sal_True;
2921 : : }
2922 [ # # ]: 0 : if (bMustDispose)
2923 : : {
2924 : 0 : bDisposed = sal_True;
2925 : :
2926 : : // require listeners to release references to this object
2927 [ # # ][ # # ]: 0 : lang::EventObject aEvtObj( dynamic_cast< chart2::data::XLabeledDataSequence * >(this) );
2928 [ # # ]: 0 : aModifyListeners.disposeAndClear( aEvtObj );
2929 [ # # ][ # # ]: 0 : aEvtListeners.disposeAndClear( aEvtObj );
2930 : : }
2931 : 0 : }
2932 : :
2933 : 0 : void SAL_CALL SwChartLabeledDataSequence::addEventListener(
2934 : : const uno::Reference< lang::XEventListener >& rxListener )
2935 : : throw (uno::RuntimeException)
2936 : : {
2937 [ # # ][ # # ]: 0 : osl::MutexGuard aGuard( GetChartMutex() );
2938 [ # # ][ # # ]: 0 : if (!bDisposed && rxListener.is())
[ # # ]
2939 [ # # ][ # # ]: 0 : aEvtListeners.addInterface( rxListener );
2940 : 0 : }
2941 : :
2942 : 0 : void SAL_CALL SwChartLabeledDataSequence::removeEventListener(
2943 : : const uno::Reference< lang::XEventListener >& rxListener )
2944 : : throw (uno::RuntimeException)
2945 : : {
2946 [ # # ][ # # ]: 0 : osl::MutexGuard aGuard( GetChartMutex() );
2947 [ # # ][ # # ]: 0 : if (!bDisposed && rxListener.is())
[ # # ]
2948 [ # # ][ # # ]: 0 : aEvtListeners.removeInterface( rxListener );
2949 : 0 : }
2950 : :
2951 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|