xref: /AOO41X/main/sw/source/core/unocore/unochart.cxx (revision d3e0dd8eb215533c15e891ee35bd141abe9397ee)
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