xref: /trunk/main/sc/source/filter/excel/exctools.cxx (revision b77af630)
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_scfilt.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