xref: /AOO41X/main/sc/source/filter/excel/exctools.cxx (revision b3f79822e811ac3493b185030a72c3c5a51f32d8)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26 
27 
28 
29 //------------------------------------------------------------------------
30 
31 #include "scitems.hxx"
32 #include <editeng/eeitem.hxx>
33 
34 #include <editeng/editdata.hxx>
35 #include <editeng/editeng.hxx>
36 #include <editeng/editobj.hxx>
37 #include <editeng/editstat.hxx>
38 
39 #include "document.hxx"
40 #include "patattr.hxx"
41 #include "attrib.hxx"
42 #include "globstr.hrc"
43 #include "scextopt.hxx"
44 #include "progress.hxx"
45 #include "rangenam.hxx"
46 #include "editutil.hxx"
47 
48 #include "excrecds.hxx"
49 #include "root.hxx"
50 #include "imp_op.hxx"
51 #include "excimp8.hxx"
52 #include "otlnbuff.hxx"
53 #include "xcl97rec.hxx"
54 #include "formel.hxx"
55 #include "xilink.hxx"
56 #include "xecontent.hxx"
57 
58 // - ALLGEMEINE ----------------------------------------------------------
59 
RootData(void)60 RootData::RootData( void )
61 {
62     eDateiTyp = BiffX;
63     pExtSheetBuff = NULL;
64     pShrfmlaBuff = NULL;
65     pExtNameBuff = NULL;
66     pFmlaConverter = NULL;
67 
68     pAutoFilterBuffer = NULL;
69     pPrintRanges = new _ScRangeListTabs;
70     pPrintTitles = new _ScRangeListTabs;
71 
72     pTabId = NULL;
73     pUserBViewList = NULL;
74 
75     pIR = NULL;
76     pER = NULL;
77 }
78 
~RootData()79 RootData::~RootData()
80 {
81     delete pExtSheetBuff;
82     delete pShrfmlaBuff;
83     delete pExtNameBuff;
84     delete pAutoFilterBuffer;
85     delete pPrintRanges;
86     delete pPrintTitles;
87 }
88 
89 
90 
91 
XclImpOutlineBuffer(SCSIZE nNewSize)92 XclImpOutlineBuffer::XclImpOutlineBuffer( SCSIZE nNewSize )
93 {
94     DBG_ASSERT( nNewSize > 0, "-OutlineBuffer::Ctor: nNewSize == 0!" );
95 
96     nSize = nNewSize + 1;
97     pLevel = new sal_uInt8[ nSize ];
98     pOuted = new sal_Bool[ nSize ];
99     pHidden = new sal_Bool[ nSize ];
100     pOutlineArray = NULL;
101 
102     Reset();
103 }
104 
105 
~XclImpOutlineBuffer()106 XclImpOutlineBuffer::~XclImpOutlineBuffer()
107 {
108     delete[] pLevel;
109     delete[] pOuted;
110     delete[] pHidden;
111 }
112 
113 
SetLevel(SCSIZE nIndex,sal_uInt8 nVal,sal_Bool bOuted,sal_Bool bHidden)114 void XclImpOutlineBuffer::SetLevel( SCSIZE nIndex, sal_uInt8 nVal, sal_Bool bOuted, sal_Bool bHidden )
115 {
116     if( nIndex < nSize )
117     {
118         pLevel[ nIndex ] = nVal;
119         pOuted[ nIndex ] = bOuted;
120         pHidden[ nIndex ] = bHidden;
121 
122         if( nIndex > nLast )
123             nLast = nIndex;
124         if( nVal > nMaxLevel )
125             nMaxLevel = nVal;
126     }
127 }
128 
129 
SetOutlineArray(ScOutlineArray * pOArray)130 void XclImpOutlineBuffer::SetOutlineArray( ScOutlineArray* pOArray )
131 {
132     pOutlineArray = pOArray;
133 }
134 
135 
136 // transtorm xcl-outline into SC-outline
MakeScOutline(void)137 void XclImpOutlineBuffer::MakeScOutline( void )
138 {
139     if( !pOutlineArray || !HasOutline() )
140         return;
141 
142     const sal_uInt16    nNumLev         = 8;
143     sal_Bool            bPreOutedLevel  = sal_False;
144     sal_uInt8           nCurrLevel      = 0;
145     sal_Bool            bMakeHidden[ nNumLev ];
146     sal_Bool            bMakeVisible[ nNumLev + 1 ];
147 
148     sal_uInt16 nLevel;
149     for( nLevel = 0; nLevel < nNumLev; ++nLevel )
150         bMakeHidden[ nLevel ] = sal_False;
151     for( nLevel = 0; nLevel <= nNumLev; ++nLevel )
152         bMakeVisible[ nLevel ] = sal_True;
153     if( nLast < (nSize - 1) )
154         nLast++;
155 
156     // search for hidden attributes at end of level, move them to begin
157     if( bButtonNormal )
158     {
159         for( sal_uInt8 nWorkLevel = 1; nWorkLevel <= nMaxLevel; nWorkLevel++ )
160         {
161             sal_uInt16  nStartPos       = 0;
162             sal_uInt8    nCurrLevel2 = 0;
163             sal_uInt8   nPrevLevel  = 0;
164 
165             for( SCSIZE nC = 0 ; nC <= nLast ; nC++ )
166             {
167                 nPrevLevel = nCurrLevel2;
168                 nCurrLevel2 = pLevel[ nC ];
169                 if( (nPrevLevel < nWorkLevel) && (nCurrLevel2 >= nWorkLevel) )
170                     nStartPos = static_cast< sal_uInt16 >( nC );
171                 else if( (nPrevLevel >= nWorkLevel) && (nCurrLevel2 < nWorkLevel) )
172                 {
173                     if( pOuted[ nC ] && pHidden[ nStartPos ] )
174                     {
175                         if( nStartPos )
176                             pOuted[ nStartPos - 1 ] = sal_True;
177                         else
178                             bPreOutedLevel = sal_True;
179                         pOuted[ nC ] = sal_False;
180                     }
181                 }
182             }
183         }
184     }
185     else
186         bPreOutedLevel = pHidden[ 0 ];
187 
188     // generate SC outlines
189     sal_uInt16  nPrevC;
190     sal_uInt16  nStart[ nNumLev ];
191     sal_Bool    bDummy;
192     sal_Bool    bPrevOuted  = bPreOutedLevel;
193     sal_Bool    bCurrHidden = sal_False;
194     sal_Bool    bPrevHidden = sal_False;
195 
196     for( SCSIZE nC = 0; nC <= nLast; nC++ )
197     {
198         sal_uInt8 nWorkLevel = pLevel[ nC ];
199 
200         nPrevC      = static_cast< sal_uInt16 >( nC ? nC - 1 : 0 );
201         bPrevHidden = bCurrHidden;
202         bCurrHidden = pHidden[ nC ];
203 
204         // open new levels
205         while( nWorkLevel > nCurrLevel )
206         {
207             nCurrLevel++;
208             bMakeHidden[ nCurrLevel ] = bPrevOuted;
209             bMakeVisible[ nCurrLevel + 1 ] =
210                 bMakeVisible[ nCurrLevel ] && !bMakeHidden[ nCurrLevel ];
211             nStart[ nCurrLevel ] = static_cast< sal_uInt16 >( nC );
212         }
213         // close levels
214         while( nWorkLevel < nCurrLevel )
215         {
216             sal_Bool bLastLevel     = (nWorkLevel == (nCurrLevel - 1));
217             sal_Bool bRealHidden    = (bMakeHidden[ nCurrLevel ] && bPrevHidden );
218             sal_Bool bRealVisible   = (bMakeVisible[ nCurrLevel ] ||
219                                     (!bCurrHidden && bLastLevel));
220 
221             pOutlineArray->Insert( nStart[ nCurrLevel ], nPrevC , bDummy,
222                 bRealHidden, bRealVisible );
223             nCurrLevel--;
224         }
225 
226         bPrevOuted = pOuted[ nC ];
227     }
228 }
229 
230 
SetLevelRange(SCSIZE nF,SCSIZE nL,sal_uInt8 nVal,sal_Bool bOuted,sal_Bool bHidden)231 void XclImpOutlineBuffer::SetLevelRange( SCSIZE nF, SCSIZE nL, sal_uInt8 nVal,
232                                     sal_Bool bOuted, sal_Bool bHidden )
233 {
234     DBG_ASSERT( nF <= nL, "+OutlineBuffer::SetLevelRange(): Last < First!" );
235 
236     if( nL < nSize )
237     {
238         if( nL > nLast )
239             nLast = nL;
240 
241         sal_uInt8*  pLevelCount;
242         sal_uInt8*  pLast;
243         sal_Bool*   pOutedCount;
244         sal_Bool*   pHiddenCount;
245 
246         pLevelCount = &pLevel[ nF ];
247         pLast = &pLevel[ nL ];
248         pOutedCount = &pOuted[ nF ];
249         pHiddenCount = &pHidden[ nF ];
250 
251         while( pLevelCount <= pLast )
252         {
253             *( pLevelCount++ ) = nVal;
254             *( pOutedCount++ ) = bOuted;
255             *( pHiddenCount++ ) = bHidden;
256         }
257 
258         if( nVal > nMaxLevel )
259             nMaxLevel = nVal;
260     }
261 }
262 
263 
Reset(void)264 void XclImpOutlineBuffer::Reset( void )
265 {
266     for( SCSIZE nC = 0 ; nC < nSize ; nC++  )
267     {
268         pLevel[ nC ] = 0;
269         pOuted[ nC ] = pHidden[ nC ] = sal_False;
270     }
271     nLast = 0;
272     nMaxLevel = 0;
273 }
274 
275 
276 //___________________________________________________________________
277 
278 
ExcScenarioCell(const sal_uInt16 nC,const sal_uInt16 nR)279 ExcScenarioCell::ExcScenarioCell( const sal_uInt16 nC, const sal_uInt16 nR ) : nCol( nC ), nRow( nR )
280 {
281 }
282 
283 
SetValue(const String & r)284 void ExcScenarioCell::SetValue( const String& r )
285 {
286     aValue = r;
287 }
288 
289 
290 
291 
292 #define EXCSCAPPEND(EXCSCCELL)  (List::Insert(EXCSCCELL,LIST_APPEND))
293 #define EXCSCFIRST()            ((ExcScenarioCell*)List::First())
294 #define EXCSCNEXT()             ((ExcScenarioCell*)List::Next())
295 
296 
ExcScenario(XclImpStream & rIn,const RootData & rR)297 ExcScenario::ExcScenario( XclImpStream& rIn, const RootData& rR ) : nTab( rR.pIR->GetCurrScTab() )
298 {
299     sal_uInt16          nCref;
300     sal_uInt8           nName, nComment;
301 
302     rIn >> nCref;
303     rIn >> nProtected;
304     rIn.Ignore( 1 );                // Hide
305     rIn >> nName >> nComment;
306     rIn.Ignore( 1 );       // statt nUser!
307 
308     if( nName )
309         pName = new String( rIn.ReadUniString( nName ) );
310     else
311     {
312         pName = new String( RTL_CONSTASCII_USTRINGPARAM( "Scenery" ) );
313         rIn.Ignore( 1 );
314     }
315 
316     pUserName = new String( rIn.ReadUniString() );
317 
318     if( nComment )
319         pComment = new String( rIn.ReadUniString() );
320     else
321         pComment = new String;
322 
323     sal_uInt16          n = nCref;
324     sal_uInt16          nC, nR;
325     while( n )
326     {
327         rIn >> nR >> nC;
328 
329         EXCSCAPPEND( new ExcScenarioCell( nC, nR ) );
330 
331         n--;
332     }
333 
334     n = nCref;
335     ExcScenarioCell*    p = EXCSCFIRST();
336     while( p )
337     {
338         p->SetValue( rIn.ReadUniString() );
339 
340         p = EXCSCNEXT();
341     }
342 }
343 
344 
~ExcScenario()345 ExcScenario::~ExcScenario()
346 {
347     ExcScenarioCell*    p = EXCSCFIRST();
348 
349     while( p )
350     {
351         delete p;
352         p = EXCSCNEXT();
353     }
354 
355     if( pName )
356         delete pName;
357     if( pComment )
358         delete pComment;
359     if( pUserName )
360         delete pUserName;
361 }
362 
363 
Apply(const XclImpRoot & rRoot,const sal_Bool bLast)364 void ExcScenario::Apply( const XclImpRoot& rRoot, const sal_Bool bLast )
365 {
366     ScDocument&         r = rRoot.GetDoc();
367     ExcScenarioCell*    p = EXCSCFIRST();
368     String              aSzenName( *pName );
369     sal_uInt16              nNewTab = nTab + 1;
370 
371     if( !r.InsertTab( nNewTab, aSzenName ) )
372         return;
373 
374     r.SetScenario( nNewTab, sal_True );
375     // #112621# do not show scenario frames
376     r.SetScenarioData( nNewTab, *pComment, COL_LIGHTGRAY, /*SC_SCENARIO_SHOWFRAME|*/SC_SCENARIO_COPYALL|(nProtected ? SC_SCENARIO_PROTECT : 0) );
377 
378     while( p )
379     {
380         sal_uInt16          nCol = p->nCol;
381         sal_uInt16          nRow = p->nRow;
382         String          aVal = p->GetValue();
383 
384         r.ApplyFlagsTab( nCol, nRow, nCol, nRow, nNewTab, SC_MF_SCENARIO );
385 
386         r.SetString( nCol, nRow, nNewTab, aVal );
387 
388         p = EXCSCNEXT();
389     }
390 
391     if( bLast )
392         r.SetActiveScenario( nNewTab, sal_True );
393 
394     // #111896# modify what the Active tab is set to if the new
395     // scenario tab occurs before the active tab.
396     ScExtDocSettings& rDocSett = rRoot.GetExtDocOptions().GetDocSettings();
397     if( (static_cast< SCCOL >( nTab ) < rDocSett.mnDisplTab) && (rDocSett.mnDisplTab < MAXTAB) )
398         ++rDocSett.mnDisplTab;
399     rRoot.GetTabInfo().InsertScTab( nNewTab );
400 }
401 
402 
403 
404 
~ExcScenarioList()405 ExcScenarioList::~ExcScenarioList()
406 {
407     ExcScenario*    p = _First();
408 
409     while( p )
410     {
411         delete p;
412         p = _Next();
413     }
414 }
415 
416 
Apply(const XclImpRoot & rRoot)417 void ExcScenarioList::Apply( const XclImpRoot& rRoot )
418 {
419     ExcScenario*    p = _Last();
420     sal_uInt16          n = ( sal_uInt16 ) Count();
421 
422     while( p )
423     {
424         n--;
425         p->Apply( rRoot, ( sal_Bool ) ( n == nLastScenario ) );
426         p = _Prev();
427     }
428 }
429 
430 
431