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