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