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_sc.hxx"
26*b1cdbd2cSJim Jagielski #include "xicontent.hxx"
27*b1cdbd2cSJim Jagielski #include <sfx2/objsh.hxx>
28*b1cdbd2cSJim Jagielski #include <sfx2/docfile.hxx>
29*b1cdbd2cSJim Jagielski #include <tools/urlobj.hxx>
30*b1cdbd2cSJim Jagielski #include <editeng/editeng.hxx>
31*b1cdbd2cSJim Jagielski #include <editeng/editobj.hxx>
32*b1cdbd2cSJim Jagielski #include <sfx2/linkmgr.hxx>
33*b1cdbd2cSJim Jagielski #include <svl/itemset.hxx>
34*b1cdbd2cSJim Jagielski #include "scitems.hxx"
35*b1cdbd2cSJim Jagielski #include <editeng/eeitem.hxx>
36*b1cdbd2cSJim Jagielski #include <svl/intitem.hxx>
37*b1cdbd2cSJim Jagielski #include <svl/stritem.hxx>
38*b1cdbd2cSJim Jagielski #include <editeng/flditem.hxx>
39*b1cdbd2cSJim Jagielski #include <editeng/fhgtitem.hxx>
40*b1cdbd2cSJim Jagielski #include <editeng/wghtitem.hxx>
41*b1cdbd2cSJim Jagielski #include <editeng/udlnitem.hxx>
42*b1cdbd2cSJim Jagielski #include <editeng/postitem.hxx>
43*b1cdbd2cSJim Jagielski #include <editeng/colritem.hxx>
44*b1cdbd2cSJim Jagielski #include <editeng/crsditem.hxx>
45*b1cdbd2cSJim Jagielski #include "document.hxx"
46*b1cdbd2cSJim Jagielski #include "editutil.hxx"
47*b1cdbd2cSJim Jagielski #include "cell.hxx"
48*b1cdbd2cSJim Jagielski #include "validat.hxx"
49*b1cdbd2cSJim Jagielski #include "patattr.hxx"
50*b1cdbd2cSJim Jagielski #include "docpool.hxx"
51*b1cdbd2cSJim Jagielski #include "rangenam.hxx"
52*b1cdbd2cSJim Jagielski #include "arealink.hxx"
53*b1cdbd2cSJim Jagielski #include "stlsheet.hxx"
54*b1cdbd2cSJim Jagielski #include "scextopt.hxx"
55*b1cdbd2cSJim Jagielski #include "xlformula.hxx"
56*b1cdbd2cSJim Jagielski #include "xltracer.hxx"
57*b1cdbd2cSJim Jagielski #include "xistream.hxx"
58*b1cdbd2cSJim Jagielski #include "xihelper.hxx"
59*b1cdbd2cSJim Jagielski #include "xistyle.hxx"
60*b1cdbd2cSJim Jagielski #include "xiescher.hxx"
61*b1cdbd2cSJim Jagielski #include "xiname.hxx"
62*b1cdbd2cSJim Jagielski 
63*b1cdbd2cSJim Jagielski #include "excform.hxx"
64*b1cdbd2cSJim Jagielski #include "tabprotection.hxx"
65*b1cdbd2cSJim Jagielski 
66*b1cdbd2cSJim Jagielski #include <memory>
67*b1cdbd2cSJim Jagielski 
68*b1cdbd2cSJim Jagielski using ::com::sun::star::uno::Sequence;
69*b1cdbd2cSJim Jagielski using ::std::auto_ptr;
70*b1cdbd2cSJim Jagielski 
71*b1cdbd2cSJim Jagielski // Shared string table ========================================================
72*b1cdbd2cSJim Jagielski 
XclImpSst(const XclImpRoot & rRoot)73*b1cdbd2cSJim Jagielski XclImpSst::XclImpSst( const XclImpRoot& rRoot ) :
74*b1cdbd2cSJim Jagielski     XclImpRoot( rRoot )
75*b1cdbd2cSJim Jagielski {
76*b1cdbd2cSJim Jagielski }
77*b1cdbd2cSJim Jagielski 
ReadSst(XclImpStream & rStrm)78*b1cdbd2cSJim Jagielski void XclImpSst::ReadSst( XclImpStream& rStrm )
79*b1cdbd2cSJim Jagielski {
80*b1cdbd2cSJim Jagielski     sal_uInt32 nStrCount;
81*b1cdbd2cSJim Jagielski     rStrm.Ignore( 4 );
82*b1cdbd2cSJim Jagielski     rStrm >> nStrCount;
83*b1cdbd2cSJim Jagielski     maStrings.clear();
84*b1cdbd2cSJim Jagielski     maStrings.reserve( static_cast< size_t >( nStrCount ) );
85*b1cdbd2cSJim Jagielski     while( (nStrCount > 0) && rStrm.IsValid() )
86*b1cdbd2cSJim Jagielski     {
87*b1cdbd2cSJim Jagielski         XclImpString aString;
88*b1cdbd2cSJim Jagielski         aString.Read( rStrm );
89*b1cdbd2cSJim Jagielski         maStrings.push_back( aString );
90*b1cdbd2cSJim Jagielski         --nStrCount;
91*b1cdbd2cSJim Jagielski     }
92*b1cdbd2cSJim Jagielski }
93*b1cdbd2cSJim Jagielski 
GetString(sal_uInt32 nSstIndex) const94*b1cdbd2cSJim Jagielski const XclImpString* XclImpSst::GetString( sal_uInt32 nSstIndex ) const
95*b1cdbd2cSJim Jagielski {
96*b1cdbd2cSJim Jagielski     return (nSstIndex < maStrings.size()) ? &maStrings[ nSstIndex ] : 0;
97*b1cdbd2cSJim Jagielski }
98*b1cdbd2cSJim Jagielski 
CreateCell(sal_uInt32 nSstIndex,sal_uInt16 nXFIndex) const99*b1cdbd2cSJim Jagielski ScBaseCell* XclImpSst::CreateCell( sal_uInt32 nSstIndex, sal_uInt16 nXFIndex ) const
100*b1cdbd2cSJim Jagielski {
101*b1cdbd2cSJim Jagielski     ScBaseCell* pCell = 0;
102*b1cdbd2cSJim Jagielski     if( const XclImpString* pString = GetString( nSstIndex ) )
103*b1cdbd2cSJim Jagielski         pCell = XclImpStringHelper::CreateCell( *this, *pString, nXFIndex );
104*b1cdbd2cSJim Jagielski     return pCell;
105*b1cdbd2cSJim Jagielski }
106*b1cdbd2cSJim Jagielski 
107*b1cdbd2cSJim Jagielski // Hyperlinks =================================================================
108*b1cdbd2cSJim Jagielski 
109*b1cdbd2cSJim Jagielski namespace {
110*b1cdbd2cSJim Jagielski 
111*b1cdbd2cSJim Jagielski /** Reads character array and stores it into rString.
112*b1cdbd2cSJim Jagielski     @param nChars  Number of following characters (not byte count!).
113*b1cdbd2cSJim Jagielski     @param b16Bit  true = 16-bit characters, false = 8-bit characters. */
lclAppendString32(String & rString,XclImpStream & rStrm,sal_uInt32 nChars,bool b16Bit)114*b1cdbd2cSJim Jagielski void lclAppendString32( String& rString, XclImpStream& rStrm, sal_uInt32 nChars, bool b16Bit )
115*b1cdbd2cSJim Jagielski {
116*b1cdbd2cSJim Jagielski     sal_uInt16 nReadChars = ulimit_cast< sal_uInt16 >( nChars );
117*b1cdbd2cSJim Jagielski     rString.Append( rStrm.ReadRawUniString( nReadChars, b16Bit ) );
118*b1cdbd2cSJim Jagielski     // ignore remaining chars
119*b1cdbd2cSJim Jagielski     sal_Size nIgnore = nChars - nReadChars;
120*b1cdbd2cSJim Jagielski     if( b16Bit )
121*b1cdbd2cSJim Jagielski         nIgnore *= 2;
122*b1cdbd2cSJim Jagielski     rStrm.Ignore( nIgnore );
123*b1cdbd2cSJim Jagielski }
124*b1cdbd2cSJim Jagielski 
125*b1cdbd2cSJim Jagielski /** Reads 32-bit string length and the character array and stores it into rString.
126*b1cdbd2cSJim Jagielski     @param b16Bit  true = 16-bit characters, false = 8-bit characters. */
lclAppendString32(String & rString,XclImpStream & rStrm,bool b16Bit)127*b1cdbd2cSJim Jagielski void lclAppendString32( String& rString, XclImpStream& rStrm, bool b16Bit )
128*b1cdbd2cSJim Jagielski {
129*b1cdbd2cSJim Jagielski     lclAppendString32( rString, rStrm, rStrm.ReaduInt32(), b16Bit );
130*b1cdbd2cSJim Jagielski }
131*b1cdbd2cSJim Jagielski 
132*b1cdbd2cSJim Jagielski /** Reads 32-bit string length and ignores following character array.
133*b1cdbd2cSJim Jagielski     @param b16Bit  true = 16-bit characters, false = 8-bit characters. */
lclIgnoreString32(XclImpStream & rStrm,bool b16Bit)134*b1cdbd2cSJim Jagielski void lclIgnoreString32( XclImpStream& rStrm, bool b16Bit )
135*b1cdbd2cSJim Jagielski {
136*b1cdbd2cSJim Jagielski     sal_uInt32 nChars;
137*b1cdbd2cSJim Jagielski     rStrm >> nChars;
138*b1cdbd2cSJim Jagielski     if( b16Bit )
139*b1cdbd2cSJim Jagielski         nChars *= 2;
140*b1cdbd2cSJim Jagielski     rStrm.Ignore( nChars );
141*b1cdbd2cSJim Jagielski }
142*b1cdbd2cSJim Jagielski 
143*b1cdbd2cSJim Jagielski /** Converts a path to an absolute path.
144*b1cdbd2cSJim Jagielski     @param rPath  The source path. The resulting path is returned here.
145*b1cdbd2cSJim Jagielski     @param nLevel  Number of parent directories to add in front of the path. */
lclGetAbsPath(String & rPath,sal_uInt16 nLevel,SfxObjectShell * pDocShell)146*b1cdbd2cSJim Jagielski void lclGetAbsPath( String& rPath, sal_uInt16 nLevel, SfxObjectShell* pDocShell )
147*b1cdbd2cSJim Jagielski {
148*b1cdbd2cSJim Jagielski     String aTmpStr;
149*b1cdbd2cSJim Jagielski     while( nLevel )
150*b1cdbd2cSJim Jagielski     {
151*b1cdbd2cSJim Jagielski         aTmpStr.AppendAscii( "../" );
152*b1cdbd2cSJim Jagielski         --nLevel;
153*b1cdbd2cSJim Jagielski     }
154*b1cdbd2cSJim Jagielski     aTmpStr += rPath;
155*b1cdbd2cSJim Jagielski 
156*b1cdbd2cSJim Jagielski     if( pDocShell )
157*b1cdbd2cSJim Jagielski     {
158*b1cdbd2cSJim Jagielski         bool bWasAbs = false;
159*b1cdbd2cSJim Jagielski         rPath = pDocShell->GetMedium()->GetURLObject().smartRel2Abs( aTmpStr, bWasAbs ).GetMainURL( INetURLObject::NO_DECODE );
160*b1cdbd2cSJim Jagielski         // full path as stored in SvxURLField must be encoded
161*b1cdbd2cSJim Jagielski     }
162*b1cdbd2cSJim Jagielski     else
163*b1cdbd2cSJim Jagielski         rPath = aTmpStr;
164*b1cdbd2cSJim Jagielski }
165*b1cdbd2cSJim Jagielski 
166*b1cdbd2cSJim Jagielski /** Inserts the URL into a text cell. Does not modify value or formula cells. */
lclInsertUrl(const XclImpRoot & rRoot,const String & rUrl,SCCOL nScCol,SCROW nScRow,SCTAB nScTab)167*b1cdbd2cSJim Jagielski void lclInsertUrl( const XclImpRoot& rRoot, const String& rUrl, SCCOL nScCol, SCROW nScRow, SCTAB nScTab )
168*b1cdbd2cSJim Jagielski {
169*b1cdbd2cSJim Jagielski     ScDocument& rDoc = rRoot.GetDoc();
170*b1cdbd2cSJim Jagielski     ScAddress aScPos( nScCol, nScRow, nScTab );
171*b1cdbd2cSJim Jagielski     CellType eCellType = rDoc.GetCellType( aScPos );
172*b1cdbd2cSJim Jagielski     switch( eCellType )
173*b1cdbd2cSJim Jagielski     {
174*b1cdbd2cSJim Jagielski         // #i54261# hyperlinks in string cells
175*b1cdbd2cSJim Jagielski         case CELLTYPE_STRING:
176*b1cdbd2cSJim Jagielski         case CELLTYPE_EDIT:
177*b1cdbd2cSJim Jagielski         {
178*b1cdbd2cSJim Jagielski             String aDisplText;
179*b1cdbd2cSJim Jagielski             rDoc.GetString( nScCol, nScRow, nScTab, aDisplText );
180*b1cdbd2cSJim Jagielski             if( !aDisplText.Len() )
181*b1cdbd2cSJim Jagielski                 aDisplText = rUrl;
182*b1cdbd2cSJim Jagielski 
183*b1cdbd2cSJim Jagielski             ScEditEngineDefaulter& rEE = rRoot.GetEditEngine();
184*b1cdbd2cSJim Jagielski             SvxURLField aUrlField( rUrl, aDisplText, SVXURLFORMAT_APPDEFAULT );
185*b1cdbd2cSJim Jagielski 
186*b1cdbd2cSJim Jagielski             const ScEditCell* pEditCell = (eCellType == CELLTYPE_EDIT) ? static_cast< const ScEditCell* >( rDoc.GetCell( aScPos ) ) : 0;
187*b1cdbd2cSJim Jagielski             const EditTextObject* pEditObj = pEditCell ? pEditCell->GetData() : 0;
188*b1cdbd2cSJim Jagielski             if( pEditObj )
189*b1cdbd2cSJim Jagielski             {
190*b1cdbd2cSJim Jagielski                 rEE.SetText( *pEditObj );
191*b1cdbd2cSJim Jagielski                 rEE.QuickInsertField( SvxFieldItem( aUrlField, EE_FEATURE_FIELD ), ESelection( 0, 0, 0xFFFF, 0 ) );
192*b1cdbd2cSJim Jagielski             }
193*b1cdbd2cSJim Jagielski             else
194*b1cdbd2cSJim Jagielski             {
195*b1cdbd2cSJim Jagielski                 rEE.SetText( EMPTY_STRING );
196*b1cdbd2cSJim Jagielski                 rEE.QuickInsertField( SvxFieldItem( aUrlField, EE_FEATURE_FIELD ), ESelection() );
197*b1cdbd2cSJim Jagielski                 if( const ScPatternAttr* pPattern = rDoc.GetPattern( aScPos.Col(), aScPos.Row(), nScTab ) )
198*b1cdbd2cSJim Jagielski                 {
199*b1cdbd2cSJim Jagielski                     SfxItemSet aItemSet( rEE.GetEmptyItemSet() );
200*b1cdbd2cSJim Jagielski                     pPattern->FillEditItemSet( &aItemSet );
201*b1cdbd2cSJim Jagielski                     rEE.QuickSetAttribs( aItemSet, ESelection( 0, 0, 0xFFFF, 0 ) );
202*b1cdbd2cSJim Jagielski                 }
203*b1cdbd2cSJim Jagielski             }
204*b1cdbd2cSJim Jagielski             ::std::auto_ptr< EditTextObject > xTextObj( rEE.CreateTextObject() );
205*b1cdbd2cSJim Jagielski 
206*b1cdbd2cSJim Jagielski             ScEditCell* pCell = new ScEditCell( xTextObj.get(), &rDoc, rEE.GetEditTextObjectPool() );
207*b1cdbd2cSJim Jagielski             rDoc.PutCell( aScPos, pCell );
208*b1cdbd2cSJim Jagielski         }
209*b1cdbd2cSJim Jagielski         break;
210*b1cdbd2cSJim Jagielski 
211*b1cdbd2cSJim Jagielski         // fix for #i31050# disabled, HYPERLINK is not able to return numeric value (#i91351#)
212*b1cdbd2cSJim Jagielski #if 0
213*b1cdbd2cSJim Jagielski         case CELLTYPE_VALUE:
214*b1cdbd2cSJim Jagielski         {
215*b1cdbd2cSJim Jagielski             // #i31050# replace number with HYPERLINK function
216*b1cdbd2cSJim Jagielski             ScTokenArray aTokenArray;
217*b1cdbd2cSJim Jagielski             aTokenArray.AddOpCode( ocHyperLink );
218*b1cdbd2cSJim Jagielski             aTokenArray.AddOpCode( ocOpen );
219*b1cdbd2cSJim Jagielski             aTokenArray.AddString( rUrl );
220*b1cdbd2cSJim Jagielski             aTokenArray.AddOpCode( ocSep );
221*b1cdbd2cSJim Jagielski             aTokenArray.AddDouble( rDoc.GetValue( aScPos ) );
222*b1cdbd2cSJim Jagielski             aTokenArray.AddOpCode( ocClose );
223*b1cdbd2cSJim Jagielski             rDoc.PutCell( aScPos, new ScFormulaCell( &rDoc, aScPos, &aTokenArray ) );
224*b1cdbd2cSJim Jagielski         }
225*b1cdbd2cSJim Jagielski         break;
226*b1cdbd2cSJim Jagielski #endif
227*b1cdbd2cSJim Jagielski 
228*b1cdbd2cSJim Jagielski         default:;
229*b1cdbd2cSJim Jagielski     }
230*b1cdbd2cSJim Jagielski }
231*b1cdbd2cSJim Jagielski 
232*b1cdbd2cSJim Jagielski } // namespace
233*b1cdbd2cSJim Jagielski 
234*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
235*b1cdbd2cSJim Jagielski 
ReadHlink(XclImpStream & rStrm)236*b1cdbd2cSJim Jagielski void XclImpHyperlink::ReadHlink( XclImpStream& rStrm )
237*b1cdbd2cSJim Jagielski {
238*b1cdbd2cSJim Jagielski     XclRange aXclRange( ScAddress::UNINITIALIZED );
239*b1cdbd2cSJim Jagielski     rStrm >> aXclRange;
240*b1cdbd2cSJim Jagielski     // #i80006# Excel silently ignores invalid hi-byte of column index (TODO: everywhere?)
241*b1cdbd2cSJim Jagielski     aXclRange.maFirst.mnCol &= 0xFF;
242*b1cdbd2cSJim Jagielski     aXclRange.maLast.mnCol &= 0xFF;
243*b1cdbd2cSJim Jagielski     String aString = ReadEmbeddedData( rStrm );
244*b1cdbd2cSJim Jagielski     if ( aString.Len() > 0 )
245*b1cdbd2cSJim Jagielski         rStrm.GetRoot().GetXFRangeBuffer().SetHyperlink( aXclRange, aString );
246*b1cdbd2cSJim Jagielski }
247*b1cdbd2cSJim Jagielski 
ReadEmbeddedData(XclImpStream & rStrm)248*b1cdbd2cSJim Jagielski String XclImpHyperlink::ReadEmbeddedData( XclImpStream& rStrm )
249*b1cdbd2cSJim Jagielski {
250*b1cdbd2cSJim Jagielski     const XclImpRoot& rRoot = rStrm.GetRoot();
251*b1cdbd2cSJim Jagielski     SfxObjectShell* pDocShell = rRoot.GetDocShell();
252*b1cdbd2cSJim Jagielski 
253*b1cdbd2cSJim Jagielski     DBG_ASSERT_BIFF( rRoot.GetBiff() == EXC_BIFF8 );
254*b1cdbd2cSJim Jagielski 
255*b1cdbd2cSJim Jagielski     sal_uInt32 nFlags;
256*b1cdbd2cSJim Jagielski     XclGuid aGuid;
257*b1cdbd2cSJim Jagielski     rStrm >> aGuid;
258*b1cdbd2cSJim Jagielski     rStrm.Ignore( 4 );
259*b1cdbd2cSJim Jagielski     rStrm >> nFlags;
260*b1cdbd2cSJim Jagielski 
261*b1cdbd2cSJim Jagielski     DBG_ASSERT( aGuid == XclTools::maGuidStdLink, "XclImpHyperlink::ReadEmbeddedData - unknown header GUID" );
262*b1cdbd2cSJim Jagielski 
263*b1cdbd2cSJim Jagielski     sal_uInt16 nLevel = 0;                  // counter for level to climb down in path
264*b1cdbd2cSJim Jagielski     ::std::auto_ptr< String > xLongName;    // link / file name
265*b1cdbd2cSJim Jagielski     ::std::auto_ptr< String > xShortName;   // 8.3-representation of file name
266*b1cdbd2cSJim Jagielski     ::std::auto_ptr< String > xTextMark;    // text mark
267*b1cdbd2cSJim Jagielski 
268*b1cdbd2cSJim Jagielski     // description (ignore)
269*b1cdbd2cSJim Jagielski     if( ::get_flag( nFlags, EXC_HLINK_DESCR ) )
270*b1cdbd2cSJim Jagielski         lclIgnoreString32( rStrm, true );
271*b1cdbd2cSJim Jagielski     // target frame (ignore) !! DESCR/FRAME - is this the right order? (never seen them together)
272*b1cdbd2cSJim Jagielski     if( ::get_flag( nFlags, EXC_HLINK_FRAME ) )
273*b1cdbd2cSJim Jagielski         lclIgnoreString32( rStrm, true );
274*b1cdbd2cSJim Jagielski 
275*b1cdbd2cSJim Jagielski     // URL fields are zero-terminated - do not let the stream replace them
276*b1cdbd2cSJim Jagielski     // in the lclAppendString32() with the '?' character.
277*b1cdbd2cSJim Jagielski     rStrm.SetNulSubstChar( '\0' );
278*b1cdbd2cSJim Jagielski 
279*b1cdbd2cSJim Jagielski     // UNC path
280*b1cdbd2cSJim Jagielski     if( ::get_flag( nFlags, EXC_HLINK_UNC ) )
281*b1cdbd2cSJim Jagielski     {
282*b1cdbd2cSJim Jagielski         xLongName.reset( new String );
283*b1cdbd2cSJim Jagielski         lclAppendString32( *xLongName, rStrm, true );
284*b1cdbd2cSJim Jagielski         lclGetAbsPath( *xLongName, 0, pDocShell );
285*b1cdbd2cSJim Jagielski     }
286*b1cdbd2cSJim Jagielski     // file link or URL
287*b1cdbd2cSJim Jagielski     else if( ::get_flag( nFlags, EXC_HLINK_BODY ) )
288*b1cdbd2cSJim Jagielski     {
289*b1cdbd2cSJim Jagielski         rStrm >> aGuid;
290*b1cdbd2cSJim Jagielski 
291*b1cdbd2cSJim Jagielski         if( aGuid == XclTools::maGuidFileMoniker )
292*b1cdbd2cSJim Jagielski         {
293*b1cdbd2cSJim Jagielski             rStrm >> nLevel;
294*b1cdbd2cSJim Jagielski             xShortName.reset( new String );
295*b1cdbd2cSJim Jagielski             lclAppendString32( *xShortName, rStrm, false );
296*b1cdbd2cSJim Jagielski             rStrm.Ignore( 24 );
297*b1cdbd2cSJim Jagielski 
298*b1cdbd2cSJim Jagielski             sal_uInt32 nStrLen;
299*b1cdbd2cSJim Jagielski             rStrm >> nStrLen;
300*b1cdbd2cSJim Jagielski             if( nStrLen )
301*b1cdbd2cSJim Jagielski             {
302*b1cdbd2cSJim Jagielski                 rStrm >> nStrLen;
303*b1cdbd2cSJim Jagielski                 nStrLen /= 2;       // it's byte count here...
304*b1cdbd2cSJim Jagielski                 rStrm.Ignore( 2 );
305*b1cdbd2cSJim Jagielski                 xLongName.reset( new String );
306*b1cdbd2cSJim Jagielski                 lclAppendString32( *xLongName, rStrm, nStrLen, true );
307*b1cdbd2cSJim Jagielski                 lclGetAbsPath( *xLongName, nLevel, pDocShell );
308*b1cdbd2cSJim Jagielski             }
309*b1cdbd2cSJim Jagielski             else
310*b1cdbd2cSJim Jagielski                 lclGetAbsPath( *xShortName, nLevel, pDocShell );
311*b1cdbd2cSJim Jagielski         }
312*b1cdbd2cSJim Jagielski         else if( aGuid == XclTools::maGuidUrlMoniker )
313*b1cdbd2cSJim Jagielski         {
314*b1cdbd2cSJim Jagielski             sal_uInt32 nStrLen;
315*b1cdbd2cSJim Jagielski             rStrm >> nStrLen;
316*b1cdbd2cSJim Jagielski             nStrLen /= 2;       // it's byte count here...
317*b1cdbd2cSJim Jagielski             xLongName.reset( new String );
318*b1cdbd2cSJim Jagielski             lclAppendString32( *xLongName, rStrm, nStrLen, true );
319*b1cdbd2cSJim Jagielski             if( !::get_flag( nFlags, EXC_HLINK_ABS ) )
320*b1cdbd2cSJim Jagielski                 lclGetAbsPath( *xLongName, 0, pDocShell );
321*b1cdbd2cSJim Jagielski         }
322*b1cdbd2cSJim Jagielski         else
323*b1cdbd2cSJim Jagielski         {
324*b1cdbd2cSJim Jagielski             DBG_ERRORFILE( "XclImpHyperlink::ReadEmbeddedData - unknown content GUID" );
325*b1cdbd2cSJim Jagielski         }
326*b1cdbd2cSJim Jagielski     }
327*b1cdbd2cSJim Jagielski 
328*b1cdbd2cSJim Jagielski     // text mark
329*b1cdbd2cSJim Jagielski     if( ::get_flag( nFlags, EXC_HLINK_MARK ) )
330*b1cdbd2cSJim Jagielski     {
331*b1cdbd2cSJim Jagielski         xTextMark.reset( new String );
332*b1cdbd2cSJim Jagielski         lclAppendString32( *xTextMark, rStrm, true );
333*b1cdbd2cSJim Jagielski     }
334*b1cdbd2cSJim Jagielski 
335*b1cdbd2cSJim Jagielski     rStrm.SetNulSubstChar();    // back to default
336*b1cdbd2cSJim Jagielski 
337*b1cdbd2cSJim Jagielski     DBG_ASSERT( rStrm.GetRecLeft() == 0, "XclImpHyperlink::ReadEmbeddedData - record size mismatch" );
338*b1cdbd2cSJim Jagielski 
339*b1cdbd2cSJim Jagielski     if( !xLongName.get() && xShortName.get() )
340*b1cdbd2cSJim Jagielski         xLongName = xShortName;
341*b1cdbd2cSJim Jagielski     else if( !xLongName.get() && xTextMark.get() )
342*b1cdbd2cSJim Jagielski         xLongName.reset( new String );
343*b1cdbd2cSJim Jagielski 
344*b1cdbd2cSJim Jagielski     if( xLongName.get() )
345*b1cdbd2cSJim Jagielski     {
346*b1cdbd2cSJim Jagielski         if( xTextMark.get() )
347*b1cdbd2cSJim Jagielski         {
348*b1cdbd2cSJim Jagielski             if( xLongName->Len() == 0 )
349*b1cdbd2cSJim Jagielski                 xTextMark->SearchAndReplaceAll( '!', '.' );
350*b1cdbd2cSJim Jagielski             xLongName->Append( '#' );
351*b1cdbd2cSJim Jagielski             xLongName->Append( *xTextMark );
352*b1cdbd2cSJim Jagielski         }
353*b1cdbd2cSJim Jagielski         return *xLongName;
354*b1cdbd2cSJim Jagielski     }
355*b1cdbd2cSJim Jagielski     return String::EmptyString();
356*b1cdbd2cSJim Jagielski }
357*b1cdbd2cSJim Jagielski 
ConvertToValidTabName(String & rUrl)358*b1cdbd2cSJim Jagielski void XclImpHyperlink::ConvertToValidTabName(String& rUrl)
359*b1cdbd2cSJim Jagielski {
360*b1cdbd2cSJim Jagielski     xub_StrLen n = rUrl.Len();
361*b1cdbd2cSJim Jagielski     if (n < 4)
362*b1cdbd2cSJim Jagielski         // Needs at least 4 characters.
363*b1cdbd2cSJim Jagielski         return;
364*b1cdbd2cSJim Jagielski 
365*b1cdbd2cSJim Jagielski     sal_Unicode c = rUrl.GetChar(0);
366*b1cdbd2cSJim Jagielski     if (c != sal_Unicode('#'))
367*b1cdbd2cSJim Jagielski         // the 1st character must be '#'.
368*b1cdbd2cSJim Jagielski         return;
369*b1cdbd2cSJim Jagielski 
370*b1cdbd2cSJim Jagielski     String aNewUrl(sal_Unicode('#')), aTabName;
371*b1cdbd2cSJim Jagielski 
372*b1cdbd2cSJim Jagielski     bool bInQuote = false;
373*b1cdbd2cSJim Jagielski     bool bQuoteTabName = false;
374*b1cdbd2cSJim Jagielski     for (xub_StrLen i = 1; i < n; ++i)
375*b1cdbd2cSJim Jagielski     {
376*b1cdbd2cSJim Jagielski         c = rUrl.GetChar(i);
377*b1cdbd2cSJim Jagielski         if (c == sal_Unicode('\''))
378*b1cdbd2cSJim Jagielski         {
379*b1cdbd2cSJim Jagielski             if (bInQuote && i+1 < n && rUrl.GetChar(i+1) == sal_Unicode('\''))
380*b1cdbd2cSJim Jagielski             {
381*b1cdbd2cSJim Jagielski                 // Two consecutive single quotes ('') signify a single literal
382*b1cdbd2cSJim Jagielski                 // quite.  When this occurs, the whole table name needs to be
383*b1cdbd2cSJim Jagielski                 // quoted.
384*b1cdbd2cSJim Jagielski                 bQuoteTabName = true;
385*b1cdbd2cSJim Jagielski                 aTabName.Append(c);
386*b1cdbd2cSJim Jagielski                 aTabName.Append(c);
387*b1cdbd2cSJim Jagielski                 ++i;
388*b1cdbd2cSJim Jagielski                 continue;
389*b1cdbd2cSJim Jagielski             }
390*b1cdbd2cSJim Jagielski 
391*b1cdbd2cSJim Jagielski             bInQuote = !bInQuote;
392*b1cdbd2cSJim Jagielski             if (!bInQuote && aTabName.Len() > 0)
393*b1cdbd2cSJim Jagielski             {
394*b1cdbd2cSJim Jagielski                 if (bQuoteTabName)
395*b1cdbd2cSJim Jagielski                     aNewUrl.Append(sal_Unicode('\''));
396*b1cdbd2cSJim Jagielski                 aNewUrl.Append(aTabName);
397*b1cdbd2cSJim Jagielski                 if (bQuoteTabName)
398*b1cdbd2cSJim Jagielski                     aNewUrl.Append(sal_Unicode('\''));
399*b1cdbd2cSJim Jagielski             }
400*b1cdbd2cSJim Jagielski         }
401*b1cdbd2cSJim Jagielski         else if (bInQuote)
402*b1cdbd2cSJim Jagielski             aTabName.Append(c);
403*b1cdbd2cSJim Jagielski         else
404*b1cdbd2cSJim Jagielski             aNewUrl.Append(c);
405*b1cdbd2cSJim Jagielski     }
406*b1cdbd2cSJim Jagielski 
407*b1cdbd2cSJim Jagielski     if (bInQuote)
408*b1cdbd2cSJim Jagielski         // It should be outside the quotes!
409*b1cdbd2cSJim Jagielski         return;
410*b1cdbd2cSJim Jagielski 
411*b1cdbd2cSJim Jagielski     // All is good.  Pass the new URL.
412*b1cdbd2cSJim Jagielski     rUrl = aNewUrl;
413*b1cdbd2cSJim Jagielski }
414*b1cdbd2cSJim Jagielski 
InsertUrl(const XclImpRoot & rRoot,const XclRange & rXclRange,const String & rUrl)415*b1cdbd2cSJim Jagielski void XclImpHyperlink::InsertUrl( const XclImpRoot& rRoot, const XclRange& rXclRange, const String& rUrl )
416*b1cdbd2cSJim Jagielski {
417*b1cdbd2cSJim Jagielski     String aUrl(rUrl);
418*b1cdbd2cSJim Jagielski     ConvertToValidTabName(aUrl);
419*b1cdbd2cSJim Jagielski 
420*b1cdbd2cSJim Jagielski     SCTAB nScTab = rRoot.GetCurrScTab();
421*b1cdbd2cSJim Jagielski     ScRange aScRange( ScAddress::UNINITIALIZED );
422*b1cdbd2cSJim Jagielski     if( rRoot.GetAddressConverter().ConvertRange( aScRange, rXclRange, nScTab, nScTab, true ) )
423*b1cdbd2cSJim Jagielski     {
424*b1cdbd2cSJim Jagielski         SCCOL nScCol1, nScCol2;
425*b1cdbd2cSJim Jagielski         SCROW nScRow1, nScRow2;
426*b1cdbd2cSJim Jagielski         aScRange.GetVars( nScCol1, nScRow1, nScTab, nScCol2, nScRow2, nScTab );
427*b1cdbd2cSJim Jagielski         for( SCCOL nScCol = nScCol1; nScCol <= nScCol2; ++nScCol )
428*b1cdbd2cSJim Jagielski             for( SCROW nScRow = nScRow1; nScRow <= nScRow2; ++nScRow )
429*b1cdbd2cSJim Jagielski                 lclInsertUrl( rRoot, aUrl, nScCol, nScRow, nScTab );
430*b1cdbd2cSJim Jagielski     }
431*b1cdbd2cSJim Jagielski }
432*b1cdbd2cSJim Jagielski 
433*b1cdbd2cSJim Jagielski // Label ranges ===============================================================
434*b1cdbd2cSJim Jagielski 
ReadLabelranges(XclImpStream & rStrm)435*b1cdbd2cSJim Jagielski void XclImpLabelranges::ReadLabelranges( XclImpStream& rStrm )
436*b1cdbd2cSJim Jagielski {
437*b1cdbd2cSJim Jagielski     const XclImpRoot& rRoot = rStrm.GetRoot();
438*b1cdbd2cSJim Jagielski     DBG_ASSERT_BIFF( rRoot.GetBiff() == EXC_BIFF8 );
439*b1cdbd2cSJim Jagielski 
440*b1cdbd2cSJim Jagielski     ScDocument& rDoc = rRoot.GetDoc();
441*b1cdbd2cSJim Jagielski     SCTAB nScTab = rRoot.GetCurrScTab();
442*b1cdbd2cSJim Jagielski     XclImpAddressConverter& rAddrConv = rRoot.GetAddressConverter();
443*b1cdbd2cSJim Jagielski     ScRangePairListRef xLabelRangesRef;
444*b1cdbd2cSJim Jagielski     const ScRange* pScRange = 0;
445*b1cdbd2cSJim Jagielski 
446*b1cdbd2cSJim Jagielski     XclRangeList aRowXclRanges, aColXclRanges;
447*b1cdbd2cSJim Jagielski     rStrm >> aRowXclRanges >> aColXclRanges;
448*b1cdbd2cSJim Jagielski 
449*b1cdbd2cSJim Jagielski     // row label ranges
450*b1cdbd2cSJim Jagielski     ScRangeList aRowScRanges;
451*b1cdbd2cSJim Jagielski     rAddrConv.ConvertRangeList( aRowScRanges, aRowXclRanges, nScTab, false );
452*b1cdbd2cSJim Jagielski     xLabelRangesRef = rDoc.GetRowNameRangesRef();
453*b1cdbd2cSJim Jagielski     for( pScRange = aRowScRanges.First(); pScRange; pScRange = aRowScRanges.Next() )
454*b1cdbd2cSJim Jagielski     {
455*b1cdbd2cSJim Jagielski         ScRange aDataRange( *pScRange );
456*b1cdbd2cSJim Jagielski         if( aDataRange.aEnd.Col() < MAXCOL )
457*b1cdbd2cSJim Jagielski         {
458*b1cdbd2cSJim Jagielski             aDataRange.aStart.SetCol( aDataRange.aEnd.Col() + 1 );
459*b1cdbd2cSJim Jagielski             aDataRange.aEnd.SetCol( MAXCOL );
460*b1cdbd2cSJim Jagielski         }
461*b1cdbd2cSJim Jagielski         else if( aDataRange.aStart.Col() > 0 )
462*b1cdbd2cSJim Jagielski         {
463*b1cdbd2cSJim Jagielski             aDataRange.aEnd.SetCol( aDataRange.aStart.Col() - 1 );
464*b1cdbd2cSJim Jagielski             aDataRange.aStart.SetCol( 0 );
465*b1cdbd2cSJim Jagielski         }
466*b1cdbd2cSJim Jagielski         xLabelRangesRef->Append( ScRangePair( *pScRange, aDataRange ) );
467*b1cdbd2cSJim Jagielski     }
468*b1cdbd2cSJim Jagielski 
469*b1cdbd2cSJim Jagielski     // column label ranges
470*b1cdbd2cSJim Jagielski     ScRangeList aColScRanges;
471*b1cdbd2cSJim Jagielski     rAddrConv.ConvertRangeList( aColScRanges, aColXclRanges, nScTab, false );
472*b1cdbd2cSJim Jagielski     xLabelRangesRef = rDoc.GetColNameRangesRef();
473*b1cdbd2cSJim Jagielski     for( pScRange = aColScRanges.First(); pScRange; pScRange = aColScRanges.Next() )
474*b1cdbd2cSJim Jagielski     {
475*b1cdbd2cSJim Jagielski         ScRange aDataRange( *pScRange );
476*b1cdbd2cSJim Jagielski         if( aDataRange.aEnd.Row() < MAXROW )
477*b1cdbd2cSJim Jagielski         {
478*b1cdbd2cSJim Jagielski             aDataRange.aStart.SetRow( aDataRange.aEnd.Row() + 1 );
479*b1cdbd2cSJim Jagielski             aDataRange.aEnd.SetRow( MAXROW );
480*b1cdbd2cSJim Jagielski         }
481*b1cdbd2cSJim Jagielski         else if( aDataRange.aStart.Row() > 0 )
482*b1cdbd2cSJim Jagielski         {
483*b1cdbd2cSJim Jagielski             aDataRange.aEnd.SetRow( aDataRange.aStart.Row() - 1 );
484*b1cdbd2cSJim Jagielski             aDataRange.aStart.SetRow( 0 );
485*b1cdbd2cSJim Jagielski         }
486*b1cdbd2cSJim Jagielski         xLabelRangesRef->Append( ScRangePair( *pScRange, aDataRange ) );
487*b1cdbd2cSJim Jagielski     }
488*b1cdbd2cSJim Jagielski }
489*b1cdbd2cSJim Jagielski 
490*b1cdbd2cSJim Jagielski // Conditional formatting =====================================================
491*b1cdbd2cSJim Jagielski 
XclImpCondFormat(const XclImpRoot & rRoot,sal_uInt32 nFormatIndex)492*b1cdbd2cSJim Jagielski XclImpCondFormat::XclImpCondFormat( const XclImpRoot& rRoot, sal_uInt32 nFormatIndex ) :
493*b1cdbd2cSJim Jagielski     XclImpRoot( rRoot ),
494*b1cdbd2cSJim Jagielski     mnFormatIndex( nFormatIndex ),
495*b1cdbd2cSJim Jagielski     mnCondCount( 0 ),
496*b1cdbd2cSJim Jagielski     mnCondIndex( 0 )
497*b1cdbd2cSJim Jagielski {
498*b1cdbd2cSJim Jagielski }
499*b1cdbd2cSJim Jagielski 
~XclImpCondFormat()500*b1cdbd2cSJim Jagielski XclImpCondFormat::~XclImpCondFormat()
501*b1cdbd2cSJim Jagielski {
502*b1cdbd2cSJim Jagielski }
503*b1cdbd2cSJim Jagielski 
ReadCondfmt(XclImpStream & rStrm)504*b1cdbd2cSJim Jagielski void XclImpCondFormat::ReadCondfmt( XclImpStream& rStrm )
505*b1cdbd2cSJim Jagielski {
506*b1cdbd2cSJim Jagielski     DBG_ASSERT( !mnCondCount, "XclImpCondFormat::ReadCondfmt - already initialized" );
507*b1cdbd2cSJim Jagielski     XclRangeList aXclRanges;
508*b1cdbd2cSJim Jagielski     rStrm >> mnCondCount;
509*b1cdbd2cSJim Jagielski     rStrm.Ignore( 10 );
510*b1cdbd2cSJim Jagielski     rStrm >> aXclRanges;
511*b1cdbd2cSJim Jagielski     GetAddressConverter().ConvertRangeList( maRanges, aXclRanges, GetCurrScTab(), true );
512*b1cdbd2cSJim Jagielski }
513*b1cdbd2cSJim Jagielski 
ReadCF(XclImpStream & rStrm)514*b1cdbd2cSJim Jagielski void XclImpCondFormat::ReadCF( XclImpStream& rStrm )
515*b1cdbd2cSJim Jagielski {
516*b1cdbd2cSJim Jagielski     if( mnCondIndex >= mnCondCount )
517*b1cdbd2cSJim Jagielski     {
518*b1cdbd2cSJim Jagielski         DBG_ERRORFILE( "XclImpCondFormat::ReadCF - CF without leading CONDFMT" );
519*b1cdbd2cSJim Jagielski         return;
520*b1cdbd2cSJim Jagielski     }
521*b1cdbd2cSJim Jagielski 
522*b1cdbd2cSJim Jagielski     // entire conditional format outside of valid range?
523*b1cdbd2cSJim Jagielski     if( !maRanges.Count() )
524*b1cdbd2cSJim Jagielski         return;
525*b1cdbd2cSJim Jagielski 
526*b1cdbd2cSJim Jagielski     sal_uInt8 nType, nOperator;
527*b1cdbd2cSJim Jagielski     sal_uInt16 nFmlaSize1, nFmlaSize2;
528*b1cdbd2cSJim Jagielski     sal_uInt32 nFlags;
529*b1cdbd2cSJim Jagielski 
530*b1cdbd2cSJim Jagielski     rStrm >> nType >> nOperator >> nFmlaSize1 >> nFmlaSize2 >> nFlags;
531*b1cdbd2cSJim Jagielski     rStrm.Ignore( 2 );
532*b1cdbd2cSJim Jagielski 
533*b1cdbd2cSJim Jagielski     // *** mode and comparison operator ***
534*b1cdbd2cSJim Jagielski 
535*b1cdbd2cSJim Jagielski     ScConditionMode eMode = SC_COND_NONE;
536*b1cdbd2cSJim Jagielski     switch( nType )
537*b1cdbd2cSJim Jagielski     {
538*b1cdbd2cSJim Jagielski         case EXC_CF_TYPE_CELL:
539*b1cdbd2cSJim Jagielski         {
540*b1cdbd2cSJim Jagielski             switch( nOperator )
541*b1cdbd2cSJim Jagielski             {
542*b1cdbd2cSJim Jagielski                 case EXC_CF_CMP_BETWEEN:        eMode = SC_COND_BETWEEN;    break;
543*b1cdbd2cSJim Jagielski                 case EXC_CF_CMP_NOT_BETWEEN:    eMode = SC_COND_NOTBETWEEN; break;
544*b1cdbd2cSJim Jagielski                 case EXC_CF_CMP_EQUAL:          eMode = SC_COND_EQUAL;      break;
545*b1cdbd2cSJim Jagielski                 case EXC_CF_CMP_NOT_EQUAL:      eMode = SC_COND_NOTEQUAL;   break;
546*b1cdbd2cSJim Jagielski                 case EXC_CF_CMP_GREATER:        eMode = SC_COND_GREATER;    break;
547*b1cdbd2cSJim Jagielski                 case EXC_CF_CMP_LESS:           eMode = SC_COND_LESS;       break;
548*b1cdbd2cSJim Jagielski                 case EXC_CF_CMP_GREATER_EQUAL:  eMode = SC_COND_EQGREATER;  break;
549*b1cdbd2cSJim Jagielski                 case EXC_CF_CMP_LESS_EQUAL:     eMode = SC_COND_EQLESS;     break;
550*b1cdbd2cSJim Jagielski                 default:
551*b1cdbd2cSJim Jagielski                     DBG_ERROR1( "XclImpCondFormat::ReadCF - unknown CF comparison 0x%02hX", nOperator );
552*b1cdbd2cSJim Jagielski             }
553*b1cdbd2cSJim Jagielski         }
554*b1cdbd2cSJim Jagielski         break;
555*b1cdbd2cSJim Jagielski 
556*b1cdbd2cSJim Jagielski         case EXC_CF_TYPE_FMLA:
557*b1cdbd2cSJim Jagielski             eMode = SC_COND_DIRECT;
558*b1cdbd2cSJim Jagielski         break;
559*b1cdbd2cSJim Jagielski 
560*b1cdbd2cSJim Jagielski         default:
561*b1cdbd2cSJim Jagielski             DBG_ERROR1( "XclImpCondFormat::ReadCF - unknown CF mode 0x%02hX", nType );
562*b1cdbd2cSJim Jagielski             return;
563*b1cdbd2cSJim Jagielski     }
564*b1cdbd2cSJim Jagielski 
565*b1cdbd2cSJim Jagielski     // *** create style sheet ***
566*b1cdbd2cSJim Jagielski 
567*b1cdbd2cSJim Jagielski     String aStyleName( XclTools::GetCondFormatStyleName( GetCurrScTab(), mnFormatIndex, mnCondIndex ) );
568*b1cdbd2cSJim Jagielski     SfxItemSet& rStyleItemSet = ScfTools::MakeCellStyleSheet( GetStyleSheetPool(), aStyleName, true ).GetItemSet();
569*b1cdbd2cSJim Jagielski 
570*b1cdbd2cSJim Jagielski     const XclImpPalette& rPalette = GetPalette();
571*b1cdbd2cSJim Jagielski 
572*b1cdbd2cSJim Jagielski     // *** font block ***
573*b1cdbd2cSJim Jagielski 
574*b1cdbd2cSJim Jagielski     if( ::get_flag( nFlags, EXC_CF_BLOCK_FONT ) )
575*b1cdbd2cSJim Jagielski     {
576*b1cdbd2cSJim Jagielski         XclImpFont aFont( GetRoot() );
577*b1cdbd2cSJim Jagielski         aFont.ReadCFFontBlock( rStrm );
578*b1cdbd2cSJim Jagielski         aFont.FillToItemSet( rStyleItemSet, EXC_FONTITEM_CELL );
579*b1cdbd2cSJim Jagielski     }
580*b1cdbd2cSJim Jagielski 
581*b1cdbd2cSJim Jagielski     // *** border block ***
582*b1cdbd2cSJim Jagielski 
583*b1cdbd2cSJim Jagielski     if( ::get_flag( nFlags, EXC_CF_BLOCK_BORDER ) )
584*b1cdbd2cSJim Jagielski     {
585*b1cdbd2cSJim Jagielski         sal_uInt16 nLineStyle;
586*b1cdbd2cSJim Jagielski         sal_uInt32 nLineColor;
587*b1cdbd2cSJim Jagielski         rStrm >> nLineStyle >> nLineColor;
588*b1cdbd2cSJim Jagielski         rStrm.Ignore( 2 );
589*b1cdbd2cSJim Jagielski 
590*b1cdbd2cSJim Jagielski         XclImpCellBorder aBorder;
591*b1cdbd2cSJim Jagielski         aBorder.FillFromCF8( nLineStyle, nLineColor, nFlags );
592*b1cdbd2cSJim Jagielski         aBorder.FillToItemSet( rStyleItemSet, rPalette );
593*b1cdbd2cSJim Jagielski     }
594*b1cdbd2cSJim Jagielski 
595*b1cdbd2cSJim Jagielski     // *** pattern block ***
596*b1cdbd2cSJim Jagielski 
597*b1cdbd2cSJim Jagielski     if( ::get_flag( nFlags, EXC_CF_BLOCK_AREA ) )
598*b1cdbd2cSJim Jagielski     {
599*b1cdbd2cSJim Jagielski         sal_uInt16 nPattern, nColor;
600*b1cdbd2cSJim Jagielski         rStrm >> nPattern >> nColor;
601*b1cdbd2cSJim Jagielski 
602*b1cdbd2cSJim Jagielski         XclImpCellArea aArea;
603*b1cdbd2cSJim Jagielski         aArea.FillFromCF8( nPattern, nColor, nFlags );
604*b1cdbd2cSJim Jagielski         aArea.FillToItemSet( rStyleItemSet, rPalette );
605*b1cdbd2cSJim Jagielski     }
606*b1cdbd2cSJim Jagielski 
607*b1cdbd2cSJim Jagielski     // *** formulas ***
608*b1cdbd2cSJim Jagielski 
609*b1cdbd2cSJim Jagielski     const ScAddress& rPos = maRanges.GetObject( 0 )->aStart;    // assured above that maRanges is not empty
610*b1cdbd2cSJim Jagielski     ExcelToSc& rFmlaConv = GetOldFmlaConverter();
611*b1cdbd2cSJim Jagielski 
612*b1cdbd2cSJim Jagielski     ::std::auto_ptr< ScTokenArray > xTokArr1;
613*b1cdbd2cSJim Jagielski     if( nFmlaSize1 > 0 )
614*b1cdbd2cSJim Jagielski     {
615*b1cdbd2cSJim Jagielski         const ScTokenArray* pTokArr = 0;
616*b1cdbd2cSJim Jagielski         rFmlaConv.Reset( rPos );
617*b1cdbd2cSJim Jagielski         rFmlaConv.Convert( pTokArr, rStrm, nFmlaSize1, false, FT_Conditional );
618*b1cdbd2cSJim Jagielski         // formula converter owns pTokArr -> create a copy of the token array
619*b1cdbd2cSJim Jagielski         if( pTokArr )
620*b1cdbd2cSJim Jagielski             xTokArr1.reset( pTokArr->Clone() );
621*b1cdbd2cSJim Jagielski     }
622*b1cdbd2cSJim Jagielski 
623*b1cdbd2cSJim Jagielski     ::std::auto_ptr< ScTokenArray > pTokArr2;
624*b1cdbd2cSJim Jagielski     if( nFmlaSize2 > 0 )
625*b1cdbd2cSJim Jagielski     {
626*b1cdbd2cSJim Jagielski         const ScTokenArray* pTokArr = 0;
627*b1cdbd2cSJim Jagielski         rFmlaConv.Reset( rPos );
628*b1cdbd2cSJim Jagielski         rFmlaConv.Convert( pTokArr, rStrm, nFmlaSize2, false, FT_Conditional );
629*b1cdbd2cSJim Jagielski         // formula converter owns pTokArr -> create a copy of the token array
630*b1cdbd2cSJim Jagielski         if( pTokArr )
631*b1cdbd2cSJim Jagielski             pTokArr2.reset( pTokArr->Clone() );
632*b1cdbd2cSJim Jagielski     }
633*b1cdbd2cSJim Jagielski 
634*b1cdbd2cSJim Jagielski     // *** create the Calc conditional formatting ***
635*b1cdbd2cSJim Jagielski 
636*b1cdbd2cSJim Jagielski     if( !mxScCondFmt.get() )
637*b1cdbd2cSJim Jagielski     {
638*b1cdbd2cSJim Jagielski         sal_uLong nKey = 0;
639*b1cdbd2cSJim Jagielski         mxScCondFmt.reset( new ScConditionalFormat( nKey, GetDocPtr() ) );
640*b1cdbd2cSJim Jagielski     }
641*b1cdbd2cSJim Jagielski 
642*b1cdbd2cSJim Jagielski     ScCondFormatEntry aEntry( eMode, xTokArr1.get(), pTokArr2.get(), GetDocPtr(), rPos, aStyleName );
643*b1cdbd2cSJim Jagielski     mxScCondFmt->AddEntry( aEntry );
644*b1cdbd2cSJim Jagielski     ++mnCondIndex;
645*b1cdbd2cSJim Jagielski }
646*b1cdbd2cSJim Jagielski 
Apply()647*b1cdbd2cSJim Jagielski void XclImpCondFormat::Apply()
648*b1cdbd2cSJim Jagielski {
649*b1cdbd2cSJim Jagielski     if( mxScCondFmt.get() )
650*b1cdbd2cSJim Jagielski     {
651*b1cdbd2cSJim Jagielski         ScDocument& rDoc = GetDoc();
652*b1cdbd2cSJim Jagielski 
653*b1cdbd2cSJim Jagielski         sal_uLong nKey = rDoc.AddCondFormat( *mxScCondFmt );
654*b1cdbd2cSJim Jagielski         ScPatternAttr aPattern( rDoc.GetPool() );
655*b1cdbd2cSJim Jagielski         aPattern.GetItemSet().Put( SfxUInt32Item( ATTR_CONDITIONAL, nKey ) );
656*b1cdbd2cSJim Jagielski 
657*b1cdbd2cSJim Jagielski         // maRanges contains only valid cell ranges
658*b1cdbd2cSJim Jagielski         for( const ScRange* pScRange = maRanges.First(); pScRange; pScRange = maRanges.Next() )
659*b1cdbd2cSJim Jagielski         {
660*b1cdbd2cSJim Jagielski             rDoc.ApplyPatternAreaTab(
661*b1cdbd2cSJim Jagielski                 pScRange->aStart.Col(), pScRange->aStart.Row(),
662*b1cdbd2cSJim Jagielski                 pScRange->aEnd.Col(), pScRange->aEnd.Row(),
663*b1cdbd2cSJim Jagielski                 pScRange->aStart.Tab(), aPattern );
664*b1cdbd2cSJim Jagielski         }
665*b1cdbd2cSJim Jagielski     }
666*b1cdbd2cSJim Jagielski }
667*b1cdbd2cSJim Jagielski 
668*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
669*b1cdbd2cSJim Jagielski 
XclImpCondFormatManager(const XclImpRoot & rRoot)670*b1cdbd2cSJim Jagielski XclImpCondFormatManager::XclImpCondFormatManager( const XclImpRoot& rRoot ) :
671*b1cdbd2cSJim Jagielski     XclImpRoot( rRoot )
672*b1cdbd2cSJim Jagielski {
673*b1cdbd2cSJim Jagielski }
674*b1cdbd2cSJim Jagielski 
ReadCondfmt(XclImpStream & rStrm)675*b1cdbd2cSJim Jagielski void XclImpCondFormatManager::ReadCondfmt( XclImpStream& rStrm )
676*b1cdbd2cSJim Jagielski {
677*b1cdbd2cSJim Jagielski     XclImpCondFormat* pFmt = new XclImpCondFormat( GetRoot(), maCondFmtList.Count() );
678*b1cdbd2cSJim Jagielski     pFmt->ReadCondfmt( rStrm );
679*b1cdbd2cSJim Jagielski     maCondFmtList.Append( pFmt );
680*b1cdbd2cSJim Jagielski }
681*b1cdbd2cSJim Jagielski 
ReadCF(XclImpStream & rStrm)682*b1cdbd2cSJim Jagielski void XclImpCondFormatManager::ReadCF( XclImpStream& rStrm )
683*b1cdbd2cSJim Jagielski {
684*b1cdbd2cSJim Jagielski     DBG_ASSERT( !maCondFmtList.Empty(), "XclImpCondFormatManager::ReadCF - CF without leading CONDFMT" );
685*b1cdbd2cSJim Jagielski     if( !maCondFmtList.Empty() )
686*b1cdbd2cSJim Jagielski         maCondFmtList.GetObject( maCondFmtList.Count() - 1 )->ReadCF( rStrm );
687*b1cdbd2cSJim Jagielski }
688*b1cdbd2cSJim Jagielski 
Apply()689*b1cdbd2cSJim Jagielski void XclImpCondFormatManager::Apply()
690*b1cdbd2cSJim Jagielski {
691*b1cdbd2cSJim Jagielski     for( XclImpCondFormat* pFmt = maCondFmtList.First(); pFmt; pFmt = maCondFmtList.Next() )
692*b1cdbd2cSJim Jagielski         pFmt->Apply();
693*b1cdbd2cSJim Jagielski     maCondFmtList.Clear();
694*b1cdbd2cSJim Jagielski }
695*b1cdbd2cSJim Jagielski 
696*b1cdbd2cSJim Jagielski // Data Validation ============================================================
697*b1cdbd2cSJim Jagielski 
ReadDval(XclImpStream & rStrm)698*b1cdbd2cSJim Jagielski void XclImpValidation::ReadDval( XclImpStream& rStrm )
699*b1cdbd2cSJim Jagielski {
700*b1cdbd2cSJim Jagielski     const XclImpRoot& rRoot = rStrm.GetRoot();
701*b1cdbd2cSJim Jagielski     DBG_ASSERT_BIFF( rRoot.GetBiff() == EXC_BIFF8 );
702*b1cdbd2cSJim Jagielski 
703*b1cdbd2cSJim Jagielski     sal_uInt32 nObjId;
704*b1cdbd2cSJim Jagielski     rStrm.Ignore( 10 );
705*b1cdbd2cSJim Jagielski     rStrm >> nObjId;
706*b1cdbd2cSJim Jagielski     if( nObjId != EXC_DVAL_NOOBJ )
707*b1cdbd2cSJim Jagielski     {
708*b1cdbd2cSJim Jagielski         DBG_ASSERT( nObjId <= 0xFFFF, "XclImpValidation::ReadDval - invalid object ID" );
709*b1cdbd2cSJim Jagielski         rRoot.GetCurrSheetDrawing().SetSkipObj( static_cast< sal_uInt16 >( nObjId ) );
710*b1cdbd2cSJim Jagielski     }
711*b1cdbd2cSJim Jagielski }
712*b1cdbd2cSJim Jagielski 
ReadDV(XclImpStream & rStrm)713*b1cdbd2cSJim Jagielski void XclImpValidation::ReadDV( XclImpStream& rStrm )
714*b1cdbd2cSJim Jagielski {
715*b1cdbd2cSJim Jagielski     const XclImpRoot& rRoot = rStrm.GetRoot();
716*b1cdbd2cSJim Jagielski     DBG_ASSERT_BIFF( rRoot.GetBiff() == EXC_BIFF8 );
717*b1cdbd2cSJim Jagielski 
718*b1cdbd2cSJim Jagielski     ScDocument& rDoc = rRoot.GetDoc();
719*b1cdbd2cSJim Jagielski     SCTAB nScTab = rRoot.GetCurrScTab();
720*b1cdbd2cSJim Jagielski     ExcelToSc& rFmlaConv = rRoot.GetOldFmlaConverter();
721*b1cdbd2cSJim Jagielski 
722*b1cdbd2cSJim Jagielski     // flags
723*b1cdbd2cSJim Jagielski     sal_uInt32 nFlags;
724*b1cdbd2cSJim Jagielski     rStrm >> nFlags;
725*b1cdbd2cSJim Jagielski 
726*b1cdbd2cSJim Jagielski     // message strings
727*b1cdbd2cSJim Jagielski     /*  Empty strings are single NUL characters in Excel (string length is 1).
728*b1cdbd2cSJim Jagielski         -> Do not let the stream replace them with '?' characters. */
729*b1cdbd2cSJim Jagielski     rStrm.SetNulSubstChar( '\0' );
730*b1cdbd2cSJim Jagielski     String aPromptTitle(   rStrm.ReadUniString() );
731*b1cdbd2cSJim Jagielski     String aErrorTitle(    rStrm.ReadUniString() );
732*b1cdbd2cSJim Jagielski     String aPromptMessage( rStrm.ReadUniString() );
733*b1cdbd2cSJim Jagielski     String aErrorMessage(  rStrm.ReadUniString() );
734*b1cdbd2cSJim Jagielski     rStrm.SetNulSubstChar();    // back to default
735*b1cdbd2cSJim Jagielski 
736*b1cdbd2cSJim Jagielski     // formula(s)
737*b1cdbd2cSJim Jagielski     if( rStrm.GetRecLeft() > 8 )
738*b1cdbd2cSJim Jagielski     {
739*b1cdbd2cSJim Jagielski         sal_uInt16 nLen;
740*b1cdbd2cSJim Jagielski 
741*b1cdbd2cSJim Jagielski         // first formula
742*b1cdbd2cSJim Jagielski         // string list is single tStr token with NUL separators -> replace them with LF
743*b1cdbd2cSJim Jagielski         rStrm.SetNulSubstChar( '\n' );
744*b1cdbd2cSJim Jagielski         ::std::auto_ptr< ScTokenArray > xTokArr1;
745*b1cdbd2cSJim Jagielski         rStrm >> nLen;
746*b1cdbd2cSJim Jagielski         rStrm.Ignore( 2 );
747*b1cdbd2cSJim Jagielski         if( nLen > 0 )
748*b1cdbd2cSJim Jagielski         {
749*b1cdbd2cSJim Jagielski             const ScTokenArray* pTokArr = 0;
750*b1cdbd2cSJim Jagielski             rFmlaConv.Reset();
751*b1cdbd2cSJim Jagielski             rFmlaConv.Convert( pTokArr, rStrm, nLen, false, FT_Conditional );
752*b1cdbd2cSJim Jagielski             // formula converter owns pTokArr -> create a copy of the token array
753*b1cdbd2cSJim Jagielski             if( pTokArr )
754*b1cdbd2cSJim Jagielski                 xTokArr1.reset( pTokArr->Clone() );
755*b1cdbd2cSJim Jagielski         }
756*b1cdbd2cSJim Jagielski         rStrm.SetNulSubstChar();    // back to default
757*b1cdbd2cSJim Jagielski 
758*b1cdbd2cSJim Jagielski         // second formula
759*b1cdbd2cSJim Jagielski         ::std::auto_ptr< ScTokenArray > xTokArr2;
760*b1cdbd2cSJim Jagielski         rStrm >> nLen;
761*b1cdbd2cSJim Jagielski         rStrm.Ignore( 2 );
762*b1cdbd2cSJim Jagielski         if( nLen > 0 )
763*b1cdbd2cSJim Jagielski         {
764*b1cdbd2cSJim Jagielski             const ScTokenArray* pTokArr = 0;
765*b1cdbd2cSJim Jagielski             rFmlaConv.Reset();
766*b1cdbd2cSJim Jagielski             rFmlaConv.Convert( pTokArr, rStrm, nLen, false, FT_Conditional );
767*b1cdbd2cSJim Jagielski             // formula converter owns pTokArr -> create a copy of the token array
768*b1cdbd2cSJim Jagielski             if( pTokArr )
769*b1cdbd2cSJim Jagielski                 xTokArr2.reset( pTokArr->Clone() );
770*b1cdbd2cSJim Jagielski         }
771*b1cdbd2cSJim Jagielski 
772*b1cdbd2cSJim Jagielski         // read all cell ranges
773*b1cdbd2cSJim Jagielski         XclRangeList aXclRanges;
774*b1cdbd2cSJim Jagielski         rStrm >> aXclRanges;
775*b1cdbd2cSJim Jagielski 
776*b1cdbd2cSJim Jagielski         // convert to Calc range list
777*b1cdbd2cSJim Jagielski         ScRangeList aScRanges;
778*b1cdbd2cSJim Jagielski         rRoot.GetAddressConverter().ConvertRangeList( aScRanges, aXclRanges, nScTab, true );
779*b1cdbd2cSJim Jagielski 
780*b1cdbd2cSJim Jagielski         // only continue if there are valid ranges
781*b1cdbd2cSJim Jagielski         if( aScRanges.Count() )
782*b1cdbd2cSJim Jagielski         {
783*b1cdbd2cSJim Jagielski             bool bIsValid = true;   // valid settings in flags field
784*b1cdbd2cSJim Jagielski 
785*b1cdbd2cSJim Jagielski             ScValidationMode eValMode = SC_VALID_ANY;
786*b1cdbd2cSJim Jagielski             switch( nFlags & EXC_DV_MODE_MASK )
787*b1cdbd2cSJim Jagielski             {
788*b1cdbd2cSJim Jagielski                 case EXC_DV_MODE_ANY:       eValMode = SC_VALID_ANY;        break;
789*b1cdbd2cSJim Jagielski                 case EXC_DV_MODE_WHOLE:     eValMode = SC_VALID_WHOLE;      break;
790*b1cdbd2cSJim Jagielski                 case EXC_DV_MODE_DECIMAL:   eValMode = SC_VALID_DECIMAL;    break;
791*b1cdbd2cSJim Jagielski                 case EXC_DV_MODE_LIST:      eValMode = SC_VALID_LIST;       break;
792*b1cdbd2cSJim Jagielski                 case EXC_DV_MODE_DATE:      eValMode = SC_VALID_DATE;       break;
793*b1cdbd2cSJim Jagielski                 case EXC_DV_MODE_TIME:      eValMode = SC_VALID_TIME;       break;
794*b1cdbd2cSJim Jagielski                 case EXC_DV_MODE_TEXTLEN:   eValMode = SC_VALID_TEXTLEN;    break;
795*b1cdbd2cSJim Jagielski                 case EXC_DV_MODE_CUSTOM:    eValMode = SC_VALID_CUSTOM;     break;
796*b1cdbd2cSJim Jagielski                 default:                    bIsValid = false;
797*b1cdbd2cSJim Jagielski             }
798*b1cdbd2cSJim Jagielski             rRoot.GetTracer().TraceDVType(eValMode == SC_VALID_CUSTOM);
799*b1cdbd2cSJim Jagielski 
800*b1cdbd2cSJim Jagielski             ScConditionMode eCondMode = SC_COND_BETWEEN;
801*b1cdbd2cSJim Jagielski             switch( nFlags & EXC_DV_COND_MASK )
802*b1cdbd2cSJim Jagielski             {
803*b1cdbd2cSJim Jagielski                 case EXC_DV_COND_BETWEEN:   eCondMode = SC_COND_BETWEEN;    break;
804*b1cdbd2cSJim Jagielski                 case EXC_DV_COND_NOTBETWEEN:eCondMode = SC_COND_NOTBETWEEN; break;
805*b1cdbd2cSJim Jagielski                 case EXC_DV_COND_EQUAL:     eCondMode = SC_COND_EQUAL;      break;
806*b1cdbd2cSJim Jagielski                 case EXC_DV_COND_NOTEQUAL:  eCondMode = SC_COND_NOTEQUAL;   break;
807*b1cdbd2cSJim Jagielski                 case EXC_DV_COND_GREATER:   eCondMode = SC_COND_GREATER;    break;
808*b1cdbd2cSJim Jagielski                 case EXC_DV_COND_LESS:      eCondMode = SC_COND_LESS;       break;
809*b1cdbd2cSJim Jagielski                 case EXC_DV_COND_EQGREATER: eCondMode = SC_COND_EQGREATER;  break;
810*b1cdbd2cSJim Jagielski                 case EXC_DV_COND_EQLESS:    eCondMode = SC_COND_EQLESS;     break;
811*b1cdbd2cSJim Jagielski                 default:                    bIsValid = false;
812*b1cdbd2cSJim Jagielski             }
813*b1cdbd2cSJim Jagielski 
814*b1cdbd2cSJim Jagielski             if( bIsValid )
815*b1cdbd2cSJim Jagielski             {
816*b1cdbd2cSJim Jagielski                 // first range for base address for relative references
817*b1cdbd2cSJim Jagielski                 const ScRange& rScRange = *aScRanges.GetObject( 0 );    // aScRanges is not empty
818*b1cdbd2cSJim Jagielski 
819*b1cdbd2cSJim Jagielski                 // process string list of a list validity (convert to list of string tokens)
820*b1cdbd2cSJim Jagielski                 if( xTokArr1.get() && (eValMode == SC_VALID_LIST) && ::get_flag( nFlags, EXC_DV_STRINGLIST ) )
821*b1cdbd2cSJim Jagielski                     XclTokenArrayHelper::ConvertStringToList( *xTokArr1, '\n', true );
822*b1cdbd2cSJim Jagielski 
823*b1cdbd2cSJim Jagielski                 ScValidationData aValidData( eValMode, eCondMode, xTokArr1.get(), xTokArr2.get(), &rDoc, rScRange.aStart );
824*b1cdbd2cSJim Jagielski 
825*b1cdbd2cSJim Jagielski                 aValidData.SetIgnoreBlank( ::get_flag( nFlags, EXC_DV_IGNOREBLANK ) );
826*b1cdbd2cSJim Jagielski                 aValidData.SetListType( ::get_flagvalue( nFlags, EXC_DV_SUPPRESSDROPDOWN, ValidListType::INVISIBLE, ValidListType::UNSORTED ) );
827*b1cdbd2cSJim Jagielski 
828*b1cdbd2cSJim Jagielski                 // *** prompt box ***
829*b1cdbd2cSJim Jagielski                 if( aPromptTitle.Len() || aPromptMessage.Len() )
830*b1cdbd2cSJim Jagielski                 {
831*b1cdbd2cSJim Jagielski                     // set any text stored in the record
832*b1cdbd2cSJim Jagielski                     aValidData.SetInput( aPromptTitle, aPromptMessage );
833*b1cdbd2cSJim Jagielski                     if( !::get_flag( nFlags, EXC_DV_SHOWPROMPT ) )
834*b1cdbd2cSJim Jagielski                         aValidData.ResetInput();
835*b1cdbd2cSJim Jagielski                 }
836*b1cdbd2cSJim Jagielski 
837*b1cdbd2cSJim Jagielski                 // *** error box ***
838*b1cdbd2cSJim Jagielski                 ScValidErrorStyle eErrStyle = SC_VALERR_STOP;
839*b1cdbd2cSJim Jagielski                 switch( nFlags & EXC_DV_ERROR_MASK )
840*b1cdbd2cSJim Jagielski                 {
841*b1cdbd2cSJim Jagielski                     case EXC_DV_ERROR_WARNING:  eErrStyle = SC_VALERR_WARNING;  break;
842*b1cdbd2cSJim Jagielski                     case EXC_DV_ERROR_INFO:     eErrStyle = SC_VALERR_INFO;     break;
843*b1cdbd2cSJim Jagielski                 }
844*b1cdbd2cSJim Jagielski                 // set texts and error style
845*b1cdbd2cSJim Jagielski                 aValidData.SetError( aErrorTitle, aErrorMessage, eErrStyle );
846*b1cdbd2cSJim Jagielski                 if( !::get_flag( nFlags, EXC_DV_SHOWERROR ) )
847*b1cdbd2cSJim Jagielski                     aValidData.ResetError();
848*b1cdbd2cSJim Jagielski 
849*b1cdbd2cSJim Jagielski                 // set the handle ID
850*b1cdbd2cSJim Jagielski                 sal_uLong nHandle = rDoc.AddValidationEntry( aValidData );
851*b1cdbd2cSJim Jagielski                 ScPatternAttr aPattern( rDoc.GetPool() );
852*b1cdbd2cSJim Jagielski                 aPattern.GetItemSet().Put( SfxUInt32Item( ATTR_VALIDDATA, nHandle ) );
853*b1cdbd2cSJim Jagielski 
854*b1cdbd2cSJim Jagielski                 // apply all ranges
855*b1cdbd2cSJim Jagielski                 for( const ScRange* pScRange = aScRanges.First(); pScRange; pScRange = aScRanges.Next() )
856*b1cdbd2cSJim Jagielski                     rDoc.ApplyPatternAreaTab( pScRange->aStart.Col(), pScRange->aStart.Row(),
857*b1cdbd2cSJim Jagielski                         pScRange->aEnd.Col(), pScRange->aEnd.Row(), nScTab, aPattern );
858*b1cdbd2cSJim Jagielski             }
859*b1cdbd2cSJim Jagielski         }
860*b1cdbd2cSJim Jagielski     }
861*b1cdbd2cSJim Jagielski }
862*b1cdbd2cSJim Jagielski 
863*b1cdbd2cSJim Jagielski // Web queries ================================================================
864*b1cdbd2cSJim Jagielski 
XclImpWebQuery(const ScRange & rDestRange)865*b1cdbd2cSJim Jagielski XclImpWebQuery::XclImpWebQuery( const ScRange& rDestRange ) :
866*b1cdbd2cSJim Jagielski     maDestRange( rDestRange ),
867*b1cdbd2cSJim Jagielski     meMode( xlWQUnknown ),
868*b1cdbd2cSJim Jagielski     mnRefresh( 0 )
869*b1cdbd2cSJim Jagielski {
870*b1cdbd2cSJim Jagielski }
871*b1cdbd2cSJim Jagielski 
ReadParamqry(XclImpStream & rStrm)872*b1cdbd2cSJim Jagielski void XclImpWebQuery::ReadParamqry( XclImpStream& rStrm )
873*b1cdbd2cSJim Jagielski {
874*b1cdbd2cSJim Jagielski     sal_uInt16 nFlags = rStrm.ReaduInt16();
875*b1cdbd2cSJim Jagielski     sal_uInt16 nType = ::extract_value< sal_uInt16 >( nFlags, 0, 3 );
876*b1cdbd2cSJim Jagielski     if( (nType == EXC_PQRYTYPE_WEBQUERY) && ::get_flag( nFlags, EXC_PQRY_WEBQUERY ) )
877*b1cdbd2cSJim Jagielski     {
878*b1cdbd2cSJim Jagielski         if( ::get_flag( nFlags, EXC_PQRY_TABLES ) )
879*b1cdbd2cSJim Jagielski         {
880*b1cdbd2cSJim Jagielski             meMode = xlWQAllTables;
881*b1cdbd2cSJim Jagielski             maTables = ScfTools::GetHTMLTablesName();
882*b1cdbd2cSJim Jagielski         }
883*b1cdbd2cSJim Jagielski         else
884*b1cdbd2cSJim Jagielski         {
885*b1cdbd2cSJim Jagielski             meMode = xlWQDocument;
886*b1cdbd2cSJim Jagielski             maTables = ScfTools::GetHTMLDocName();
887*b1cdbd2cSJim Jagielski         }
888*b1cdbd2cSJim Jagielski     }
889*b1cdbd2cSJim Jagielski }
890*b1cdbd2cSJim Jagielski 
ReadWqstring(XclImpStream & rStrm)891*b1cdbd2cSJim Jagielski void XclImpWebQuery::ReadWqstring( XclImpStream& rStrm )
892*b1cdbd2cSJim Jagielski {
893*b1cdbd2cSJim Jagielski     maURL = rStrm.ReadUniString();
894*b1cdbd2cSJim Jagielski }
895*b1cdbd2cSJim Jagielski 
ReadWqsettings(XclImpStream & rStrm)896*b1cdbd2cSJim Jagielski void XclImpWebQuery::ReadWqsettings( XclImpStream& rStrm )
897*b1cdbd2cSJim Jagielski {
898*b1cdbd2cSJim Jagielski     sal_uInt16 nFlags;
899*b1cdbd2cSJim Jagielski     rStrm.Ignore( 10 );
900*b1cdbd2cSJim Jagielski     rStrm >> nFlags;
901*b1cdbd2cSJim Jagielski     rStrm.Ignore( 10 );
902*b1cdbd2cSJim Jagielski     rStrm >> mnRefresh;
903*b1cdbd2cSJim Jagielski 
904*b1cdbd2cSJim Jagielski     if( ::get_flag( nFlags, EXC_WQSETT_SPECTABLES ) && (meMode == xlWQAllTables) )
905*b1cdbd2cSJim Jagielski         meMode = xlWQSpecTables;
906*b1cdbd2cSJim Jagielski }
907*b1cdbd2cSJim Jagielski 
ReadWqtables(XclImpStream & rStrm)908*b1cdbd2cSJim Jagielski void XclImpWebQuery::ReadWqtables( XclImpStream& rStrm )
909*b1cdbd2cSJim Jagielski {
910*b1cdbd2cSJim Jagielski     if( meMode == xlWQSpecTables )
911*b1cdbd2cSJim Jagielski 	{
912*b1cdbd2cSJim Jagielski         rStrm.Ignore( 4 );
913*b1cdbd2cSJim Jagielski         String aTables( rStrm.ReadUniString() );
914*b1cdbd2cSJim Jagielski 
915*b1cdbd2cSJim Jagielski         const sal_Unicode cSep = ';';
916*b1cdbd2cSJim Jagielski         String aQuotedPairs( RTL_CONSTASCII_USTRINGPARAM( "\"\"" ) );
917*b1cdbd2cSJim Jagielski         xub_StrLen nTokenCnt = aTables.GetQuotedTokenCount( aQuotedPairs, ',' );
918*b1cdbd2cSJim Jagielski         maTables.Erase();
919*b1cdbd2cSJim Jagielski         xub_StrLen nStringIx = 0;
920*b1cdbd2cSJim Jagielski         for( xub_StrLen nToken = 0; nToken < nTokenCnt; ++nToken )
921*b1cdbd2cSJim Jagielski         {
922*b1cdbd2cSJim Jagielski             String aToken( aTables.GetQuotedToken( 0, aQuotedPairs, ',', nStringIx ) );
923*b1cdbd2cSJim Jagielski             sal_Int32 nTabNum = CharClass::isAsciiNumeric( aToken ) ? aToken.ToInt32() : 0;
924*b1cdbd2cSJim Jagielski             if( nTabNum > 0 )
925*b1cdbd2cSJim Jagielski                 ScGlobal::AddToken( maTables, ScfTools::GetNameFromHTMLIndex( static_cast< sal_uInt32 >( nTabNum ) ), cSep );
926*b1cdbd2cSJim Jagielski             else
927*b1cdbd2cSJim Jagielski             {
928*b1cdbd2cSJim Jagielski                 ScGlobal::EraseQuotes( aToken, '"', false );
929*b1cdbd2cSJim Jagielski                 if( aToken.Len() )
930*b1cdbd2cSJim Jagielski                     ScGlobal::AddToken( maTables, ScfTools::GetNameFromHTMLName( aToken ), cSep );
931*b1cdbd2cSJim Jagielski             }
932*b1cdbd2cSJim Jagielski         }
933*b1cdbd2cSJim Jagielski     }
934*b1cdbd2cSJim Jagielski }
935*b1cdbd2cSJim Jagielski 
Apply(ScDocument & rDoc,const String & rFilterName)936*b1cdbd2cSJim Jagielski void XclImpWebQuery::Apply( ScDocument& rDoc, const String& rFilterName )
937*b1cdbd2cSJim Jagielski {
938*b1cdbd2cSJim Jagielski     if( maURL.Len() && (meMode != xlWQUnknown) && rDoc.GetDocumentShell() )
939*b1cdbd2cSJim Jagielski     {
940*b1cdbd2cSJim Jagielski         ScAreaLink* pLink = new ScAreaLink( rDoc.GetDocumentShell(),
941*b1cdbd2cSJim Jagielski             maURL, rFilterName, EMPTY_STRING, maTables, maDestRange, mnRefresh * 60UL );
942*b1cdbd2cSJim Jagielski         rDoc.GetLinkManager()->InsertFileLink( *pLink, OBJECT_CLIENT_FILE,
943*b1cdbd2cSJim Jagielski             maURL, &rFilterName, &maTables );
944*b1cdbd2cSJim Jagielski     }
945*b1cdbd2cSJim Jagielski }
946*b1cdbd2cSJim Jagielski 
947*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
948*b1cdbd2cSJim Jagielski 
XclImpWebQueryBuffer(const XclImpRoot & rRoot)949*b1cdbd2cSJim Jagielski XclImpWebQueryBuffer::XclImpWebQueryBuffer( const XclImpRoot& rRoot ) :
950*b1cdbd2cSJim Jagielski     XclImpRoot( rRoot )
951*b1cdbd2cSJim Jagielski {
952*b1cdbd2cSJim Jagielski }
953*b1cdbd2cSJim Jagielski 
ReadQsi(XclImpStream & rStrm)954*b1cdbd2cSJim Jagielski void XclImpWebQueryBuffer::ReadQsi( XclImpStream& rStrm )
955*b1cdbd2cSJim Jagielski {
956*b1cdbd2cSJim Jagielski     if( GetBiff() == EXC_BIFF8 )
957*b1cdbd2cSJim Jagielski     {
958*b1cdbd2cSJim Jagielski         rStrm.Ignore( 10 );
959*b1cdbd2cSJim Jagielski         String aXclName( rStrm.ReadUniString() );
960*b1cdbd2cSJim Jagielski 
961*b1cdbd2cSJim Jagielski         // #i64794# Excel replaces spaces with underscores
962*b1cdbd2cSJim Jagielski         aXclName.SearchAndReplaceAll( ' ', '_' );
963*b1cdbd2cSJim Jagielski 
964*b1cdbd2cSJim Jagielski         // #101529# find the defined name used in Calc
965*b1cdbd2cSJim Jagielski         if( const XclImpName* pName = GetNameManager().FindName( aXclName, GetCurrScTab() ) )
966*b1cdbd2cSJim Jagielski         {
967*b1cdbd2cSJim Jagielski             if( const ScRangeData* pRangeData = pName->GetScRangeData() )
968*b1cdbd2cSJim Jagielski             {
969*b1cdbd2cSJim Jagielski                 ScRange aRange;
970*b1cdbd2cSJim Jagielski                 if( pRangeData->IsReference( aRange ) )
971*b1cdbd2cSJim Jagielski                     maWQList.Append( new XclImpWebQuery( aRange ) );
972*b1cdbd2cSJim Jagielski             }
973*b1cdbd2cSJim Jagielski         }
974*b1cdbd2cSJim Jagielski     }
975*b1cdbd2cSJim Jagielski     else
976*b1cdbd2cSJim Jagielski     {
977*b1cdbd2cSJim Jagielski         DBG_ERROR_BIFF();
978*b1cdbd2cSJim Jagielski     }
979*b1cdbd2cSJim Jagielski }
980*b1cdbd2cSJim Jagielski 
ReadParamqry(XclImpStream & rStrm)981*b1cdbd2cSJim Jagielski void XclImpWebQueryBuffer::ReadParamqry( XclImpStream& rStrm )
982*b1cdbd2cSJim Jagielski {
983*b1cdbd2cSJim Jagielski     if( XclImpWebQuery* pQuery = maWQList.Last() )
984*b1cdbd2cSJim Jagielski         pQuery->ReadParamqry( rStrm );
985*b1cdbd2cSJim Jagielski }
986*b1cdbd2cSJim Jagielski 
ReadWqstring(XclImpStream & rStrm)987*b1cdbd2cSJim Jagielski void XclImpWebQueryBuffer::ReadWqstring( XclImpStream& rStrm )
988*b1cdbd2cSJim Jagielski {
989*b1cdbd2cSJim Jagielski     if( XclImpWebQuery* pQuery = maWQList.Last() )
990*b1cdbd2cSJim Jagielski         pQuery->ReadWqstring( rStrm );
991*b1cdbd2cSJim Jagielski }
992*b1cdbd2cSJim Jagielski 
ReadWqsettings(XclImpStream & rStrm)993*b1cdbd2cSJim Jagielski void XclImpWebQueryBuffer::ReadWqsettings( XclImpStream& rStrm )
994*b1cdbd2cSJim Jagielski {
995*b1cdbd2cSJim Jagielski     if( XclImpWebQuery* pQuery = maWQList.Last() )
996*b1cdbd2cSJim Jagielski         pQuery->ReadWqsettings( rStrm );
997*b1cdbd2cSJim Jagielski }
998*b1cdbd2cSJim Jagielski 
ReadWqtables(XclImpStream & rStrm)999*b1cdbd2cSJim Jagielski void XclImpWebQueryBuffer::ReadWqtables( XclImpStream& rStrm )
1000*b1cdbd2cSJim Jagielski {
1001*b1cdbd2cSJim Jagielski     if( XclImpWebQuery* pQuery = maWQList.Last() )
1002*b1cdbd2cSJim Jagielski         pQuery->ReadWqtables( rStrm );
1003*b1cdbd2cSJim Jagielski }
1004*b1cdbd2cSJim Jagielski 
Apply()1005*b1cdbd2cSJim Jagielski void XclImpWebQueryBuffer::Apply()
1006*b1cdbd2cSJim Jagielski {
1007*b1cdbd2cSJim Jagielski     ScDocument& rDoc = GetDoc();
1008*b1cdbd2cSJim Jagielski     String aFilterName( RTL_CONSTASCII_USTRINGPARAM( EXC_WEBQRY_FILTER ) );
1009*b1cdbd2cSJim Jagielski     for( XclImpWebQuery* pQuery = maWQList.First(); pQuery; pQuery = maWQList.Next() )
1010*b1cdbd2cSJim Jagielski         pQuery->Apply( rDoc, aFilterName );
1011*b1cdbd2cSJim Jagielski }
1012*b1cdbd2cSJim Jagielski 
1013*b1cdbd2cSJim Jagielski // Decryption =================================================================
1014*b1cdbd2cSJim Jagielski 
1015*b1cdbd2cSJim Jagielski namespace {
1016*b1cdbd2cSJim Jagielski 
lclReadFilepass5(XclImpStream & rStrm)1017*b1cdbd2cSJim Jagielski XclImpDecrypterRef lclReadFilepass5( XclImpStream& rStrm )
1018*b1cdbd2cSJim Jagielski {
1019*b1cdbd2cSJim Jagielski     XclImpDecrypterRef xDecr;
1020*b1cdbd2cSJim Jagielski     DBG_ASSERT( rStrm.GetRecLeft() == 4, "lclReadFilepass5 - wrong record size" );
1021*b1cdbd2cSJim Jagielski     if( rStrm.GetRecLeft() == 4 )
1022*b1cdbd2cSJim Jagielski     {
1023*b1cdbd2cSJim Jagielski         sal_uInt16 nKey, nHash;
1024*b1cdbd2cSJim Jagielski         rStrm >> nKey >> nHash;
1025*b1cdbd2cSJim Jagielski         xDecr.reset( new XclImpBiff5Decrypter( nKey, nHash ) );
1026*b1cdbd2cSJim Jagielski     }
1027*b1cdbd2cSJim Jagielski     return xDecr;
1028*b1cdbd2cSJim Jagielski }
1029*b1cdbd2cSJim Jagielski 
lclReadFilepass8_Standard(XclImpStream & rStrm)1030*b1cdbd2cSJim Jagielski XclImpDecrypterRef lclReadFilepass8_Standard( XclImpStream& rStrm )
1031*b1cdbd2cSJim Jagielski {
1032*b1cdbd2cSJim Jagielski     XclImpDecrypterRef xDecr;
1033*b1cdbd2cSJim Jagielski     DBG_ASSERT( rStrm.GetRecLeft() == 48, "lclReadFilepass8 - wrong record size" );
1034*b1cdbd2cSJim Jagielski     if( rStrm.GetRecLeft() == 48 )
1035*b1cdbd2cSJim Jagielski     {
1036*b1cdbd2cSJim Jagielski         sal_uInt8 pnSalt[ 16 ];
1037*b1cdbd2cSJim Jagielski         sal_uInt8 pnVerifier[ 16 ];
1038*b1cdbd2cSJim Jagielski         sal_uInt8 pnVerifierHash[ 16 ];
1039*b1cdbd2cSJim Jagielski         rStrm.Read( pnSalt, 16 );
1040*b1cdbd2cSJim Jagielski         rStrm.Read( pnVerifier, 16 );
1041*b1cdbd2cSJim Jagielski         rStrm.Read( pnVerifierHash, 16 );
1042*b1cdbd2cSJim Jagielski         xDecr.reset( new XclImpBiff8Decrypter( pnSalt, pnVerifier, pnVerifierHash ) );
1043*b1cdbd2cSJim Jagielski     }
1044*b1cdbd2cSJim Jagielski     return xDecr;
1045*b1cdbd2cSJim Jagielski }
1046*b1cdbd2cSJim Jagielski 
lclReadFilepass8_Strong(XclImpStream &)1047*b1cdbd2cSJim Jagielski XclImpDecrypterRef lclReadFilepass8_Strong( XclImpStream& /*rStrm*/ )
1048*b1cdbd2cSJim Jagielski {
1049*b1cdbd2cSJim Jagielski     // not supported
1050*b1cdbd2cSJim Jagielski     return XclImpDecrypterRef();
1051*b1cdbd2cSJim Jagielski }
1052*b1cdbd2cSJim Jagielski 
lclReadFilepass8(XclImpStream & rStrm)1053*b1cdbd2cSJim Jagielski XclImpDecrypterRef lclReadFilepass8( XclImpStream& rStrm )
1054*b1cdbd2cSJim Jagielski {
1055*b1cdbd2cSJim Jagielski     XclImpDecrypterRef xDecr;
1056*b1cdbd2cSJim Jagielski 
1057*b1cdbd2cSJim Jagielski     sal_uInt16 nMode;
1058*b1cdbd2cSJim Jagielski     rStrm >> nMode;
1059*b1cdbd2cSJim Jagielski     switch( nMode )
1060*b1cdbd2cSJim Jagielski     {
1061*b1cdbd2cSJim Jagielski         case EXC_FILEPASS_BIFF5:
1062*b1cdbd2cSJim Jagielski             xDecr = lclReadFilepass5( rStrm );
1063*b1cdbd2cSJim Jagielski         break;
1064*b1cdbd2cSJim Jagielski 
1065*b1cdbd2cSJim Jagielski         case EXC_FILEPASS_BIFF8:
1066*b1cdbd2cSJim Jagielski         {
1067*b1cdbd2cSJim Jagielski             rStrm.Ignore( 2 );
1068*b1cdbd2cSJim Jagielski             sal_uInt16 nSubMode;
1069*b1cdbd2cSJim Jagielski             rStrm >> nSubMode;
1070*b1cdbd2cSJim Jagielski             switch( nSubMode )
1071*b1cdbd2cSJim Jagielski             {
1072*b1cdbd2cSJim Jagielski                 case EXC_FILEPASS_BIFF8_STD:
1073*b1cdbd2cSJim Jagielski                     xDecr = lclReadFilepass8_Standard( rStrm );
1074*b1cdbd2cSJim Jagielski                 break;
1075*b1cdbd2cSJim Jagielski                 case EXC_FILEPASS_BIFF8_STRONG:
1076*b1cdbd2cSJim Jagielski                     xDecr = lclReadFilepass8_Strong( rStrm );
1077*b1cdbd2cSJim Jagielski                 break;
1078*b1cdbd2cSJim Jagielski                 default:
1079*b1cdbd2cSJim Jagielski                     DBG_ERRORFILE( "lclReadFilepass8 - unknown BIFF8 encryption sub mode" );
1080*b1cdbd2cSJim Jagielski             }
1081*b1cdbd2cSJim Jagielski         }
1082*b1cdbd2cSJim Jagielski         break;
1083*b1cdbd2cSJim Jagielski 
1084*b1cdbd2cSJim Jagielski         default:
1085*b1cdbd2cSJim Jagielski             DBG_ERRORFILE( "lclReadFilepass8 - unknown encryption mode" );
1086*b1cdbd2cSJim Jagielski     }
1087*b1cdbd2cSJim Jagielski 
1088*b1cdbd2cSJim Jagielski     return xDecr;
1089*b1cdbd2cSJim Jagielski }
1090*b1cdbd2cSJim Jagielski 
1091*b1cdbd2cSJim Jagielski } // namespace
1092*b1cdbd2cSJim Jagielski 
1093*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
1094*b1cdbd2cSJim Jagielski 
ReadFilepass(XclImpStream & rStrm)1095*b1cdbd2cSJim Jagielski ErrCode XclImpDecryptHelper::ReadFilepass( XclImpStream& rStrm )
1096*b1cdbd2cSJim Jagielski {
1097*b1cdbd2cSJim Jagielski     XclImpDecrypterRef xDecr;
1098*b1cdbd2cSJim Jagielski     rStrm.DisableDecryption();
1099*b1cdbd2cSJim Jagielski 
1100*b1cdbd2cSJim Jagielski     // read the FILEPASS record and create a new decrypter object
1101*b1cdbd2cSJim Jagielski     switch( rStrm.GetRoot().GetBiff() )
1102*b1cdbd2cSJim Jagielski     {
1103*b1cdbd2cSJim Jagielski         case EXC_BIFF2:
1104*b1cdbd2cSJim Jagielski         case EXC_BIFF3:
1105*b1cdbd2cSJim Jagielski         case EXC_BIFF4:
1106*b1cdbd2cSJim Jagielski         case EXC_BIFF5: xDecr = lclReadFilepass5( rStrm );  break;
1107*b1cdbd2cSJim Jagielski         case EXC_BIFF8: xDecr = lclReadFilepass8( rStrm );  break;
1108*b1cdbd2cSJim Jagielski         default:        DBG_ERROR_BIFF();
1109*b1cdbd2cSJim Jagielski     };
1110*b1cdbd2cSJim Jagielski 
1111*b1cdbd2cSJim Jagielski     // set decrypter at import stream
1112*b1cdbd2cSJim Jagielski     rStrm.SetDecrypter( xDecr );
1113*b1cdbd2cSJim Jagielski 
1114*b1cdbd2cSJim Jagielski     // request and verify a password (decrypter implements IDocPasswordVerifier)
1115*b1cdbd2cSJim Jagielski     if( xDecr.is() )
1116*b1cdbd2cSJim Jagielski         rStrm.GetRoot().RequestEncryptionData( *xDecr );
1117*b1cdbd2cSJim Jagielski 
1118*b1cdbd2cSJim Jagielski     // return error code (success, wrong password, etc.)
1119*b1cdbd2cSJim Jagielski     return xDecr.is() ? xDecr->GetError() : EXC_ENCR_ERROR_UNSUPP_CRYPT;
1120*b1cdbd2cSJim Jagielski }
1121*b1cdbd2cSJim Jagielski 
1122*b1cdbd2cSJim Jagielski // Document protection ========================================================
1123*b1cdbd2cSJim Jagielski 
XclImpDocProtectBuffer(const XclImpRoot & rRoot)1124*b1cdbd2cSJim Jagielski XclImpDocProtectBuffer::XclImpDocProtectBuffer( const XclImpRoot& rRoot ) :
1125*b1cdbd2cSJim Jagielski     XclImpRoot( rRoot ),
1126*b1cdbd2cSJim Jagielski     mnPassHash(0x0000),
1127*b1cdbd2cSJim Jagielski     mbDocProtect(false),
1128*b1cdbd2cSJim Jagielski     mbWinProtect(false)
1129*b1cdbd2cSJim Jagielski {
1130*b1cdbd2cSJim Jagielski }
1131*b1cdbd2cSJim Jagielski 
ReadDocProtect(XclImpStream & rStrm)1132*b1cdbd2cSJim Jagielski void XclImpDocProtectBuffer::ReadDocProtect( XclImpStream& rStrm )
1133*b1cdbd2cSJim Jagielski {
1134*b1cdbd2cSJim Jagielski     mbDocProtect = rStrm.ReaduInt16() ? true : false;
1135*b1cdbd2cSJim Jagielski }
1136*b1cdbd2cSJim Jagielski 
ReadWinProtect(XclImpStream & rStrm)1137*b1cdbd2cSJim Jagielski void XclImpDocProtectBuffer::ReadWinProtect( XclImpStream& rStrm )
1138*b1cdbd2cSJim Jagielski {
1139*b1cdbd2cSJim Jagielski     mbWinProtect = rStrm.ReaduInt16() ? true : false;
1140*b1cdbd2cSJim Jagielski }
1141*b1cdbd2cSJim Jagielski 
ReadPasswordHash(XclImpStream & rStrm)1142*b1cdbd2cSJim Jagielski void XclImpDocProtectBuffer::ReadPasswordHash( XclImpStream& rStrm )
1143*b1cdbd2cSJim Jagielski {
1144*b1cdbd2cSJim Jagielski     rStrm.EnableDecryption();
1145*b1cdbd2cSJim Jagielski     mnPassHash = rStrm.ReaduInt16();
1146*b1cdbd2cSJim Jagielski }
1147*b1cdbd2cSJim Jagielski 
Apply() const1148*b1cdbd2cSJim Jagielski void XclImpDocProtectBuffer::Apply() const
1149*b1cdbd2cSJim Jagielski {
1150*b1cdbd2cSJim Jagielski     if (!mbDocProtect && !mbWinProtect)
1151*b1cdbd2cSJim Jagielski         // Excel requires either the structure or windows protection is set.
1152*b1cdbd2cSJim Jagielski         // If neither is set then the document is not protected at all.
1153*b1cdbd2cSJim Jagielski         return;
1154*b1cdbd2cSJim Jagielski 
1155*b1cdbd2cSJim Jagielski     auto_ptr<ScDocProtection> pProtect(new ScDocProtection);
1156*b1cdbd2cSJim Jagielski     pProtect->setProtected(true);
1157*b1cdbd2cSJim Jagielski 
1158*b1cdbd2cSJim Jagielski #if ENABLE_SHEET_PROTECTION
1159*b1cdbd2cSJim Jagielski     if (mnPassHash)
1160*b1cdbd2cSJim Jagielski     {
1161*b1cdbd2cSJim Jagielski         // 16-bit password pash.
1162*b1cdbd2cSJim Jagielski         Sequence<sal_Int8> aPass(2);
1163*b1cdbd2cSJim Jagielski         aPass[0] = (mnPassHash >> 8) & 0xFF;
1164*b1cdbd2cSJim Jagielski         aPass[1] = mnPassHash & 0xFF;
1165*b1cdbd2cSJim Jagielski         pProtect->setPasswordHash(aPass, PASSHASH_XL);
1166*b1cdbd2cSJim Jagielski     }
1167*b1cdbd2cSJim Jagielski #endif
1168*b1cdbd2cSJim Jagielski 
1169*b1cdbd2cSJim Jagielski     // document protection options
1170*b1cdbd2cSJim Jagielski     pProtect->setOption(ScDocProtection::STRUCTURE, mbDocProtect);
1171*b1cdbd2cSJim Jagielski     pProtect->setOption(ScDocProtection::WINDOWS,   mbWinProtect);
1172*b1cdbd2cSJim Jagielski 
1173*b1cdbd2cSJim Jagielski     GetDoc().SetDocProtection(pProtect.get());
1174*b1cdbd2cSJim Jagielski }
1175*b1cdbd2cSJim Jagielski 
1176*b1cdbd2cSJim Jagielski // Sheet Protection ===========================================================
1177*b1cdbd2cSJim Jagielski 
Sheet()1178*b1cdbd2cSJim Jagielski XclImpSheetProtectBuffer::Sheet::Sheet() :
1179*b1cdbd2cSJim Jagielski     mbProtected(false),
1180*b1cdbd2cSJim Jagielski     mnPasswordHash(0x0000),
1181*b1cdbd2cSJim Jagielski     mnOptions(0x4400)
1182*b1cdbd2cSJim Jagielski {
1183*b1cdbd2cSJim Jagielski }
1184*b1cdbd2cSJim Jagielski 
1185*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
1186*b1cdbd2cSJim Jagielski 
Sheet(const Sheet & r)1187*b1cdbd2cSJim Jagielski XclImpSheetProtectBuffer::Sheet::Sheet(const Sheet& r) :
1188*b1cdbd2cSJim Jagielski     mbProtected(r.mbProtected),
1189*b1cdbd2cSJim Jagielski     mnPasswordHash(r.mnPasswordHash),
1190*b1cdbd2cSJim Jagielski     mnOptions(r.mnOptions)
1191*b1cdbd2cSJim Jagielski {
1192*b1cdbd2cSJim Jagielski }
1193*b1cdbd2cSJim Jagielski 
XclImpSheetProtectBuffer(const XclImpRoot & rRoot)1194*b1cdbd2cSJim Jagielski XclImpSheetProtectBuffer::XclImpSheetProtectBuffer( const XclImpRoot& rRoot ) :
1195*b1cdbd2cSJim Jagielski     XclImpRoot( rRoot )
1196*b1cdbd2cSJim Jagielski {
1197*b1cdbd2cSJim Jagielski }
1198*b1cdbd2cSJim Jagielski 
ReadProtect(XclImpStream & rStrm,SCTAB nTab)1199*b1cdbd2cSJim Jagielski void XclImpSheetProtectBuffer::ReadProtect( XclImpStream& rStrm, SCTAB nTab )
1200*b1cdbd2cSJim Jagielski {
1201*b1cdbd2cSJim Jagielski     if ( rStrm.ReaduInt16() )
1202*b1cdbd2cSJim Jagielski     {
1203*b1cdbd2cSJim Jagielski         Sheet* pSheet = GetSheetItem(nTab);
1204*b1cdbd2cSJim Jagielski         if (pSheet)
1205*b1cdbd2cSJim Jagielski             pSheet->mbProtected = true;
1206*b1cdbd2cSJim Jagielski     }
1207*b1cdbd2cSJim Jagielski }
1208*b1cdbd2cSJim Jagielski 
ReadOptions(XclImpStream & rStrm,SCTAB nTab)1209*b1cdbd2cSJim Jagielski void XclImpSheetProtectBuffer::ReadOptions( XclImpStream& rStrm, SCTAB nTab )
1210*b1cdbd2cSJim Jagielski {
1211*b1cdbd2cSJim Jagielski     rStrm.Ignore(12);
1212*b1cdbd2cSJim Jagielski 
1213*b1cdbd2cSJim Jagielski     // feature type can be either 2 or 4.  If 2, this record stores flag for
1214*b1cdbd2cSJim Jagielski     // enhanced protection, whereas if 4 it stores flag for smart tag.
1215*b1cdbd2cSJim Jagielski     sal_uInt16 nFeatureType;
1216*b1cdbd2cSJim Jagielski     rStrm >> nFeatureType;
1217*b1cdbd2cSJim Jagielski     if (nFeatureType != 2)
1218*b1cdbd2cSJim Jagielski         // We currently only support import of enhanced protection data.
1219*b1cdbd2cSJim Jagielski         return;
1220*b1cdbd2cSJim Jagielski 
1221*b1cdbd2cSJim Jagielski     rStrm.Ignore(1); // always 1
1222*b1cdbd2cSJim Jagielski 
1223*b1cdbd2cSJim Jagielski     // The flag size specifies the size of bytes that follows that stores
1224*b1cdbd2cSJim Jagielski     // feature data.  If -1 it depends on the feature type imported earlier.
1225*b1cdbd2cSJim Jagielski     // For enhanced protection data, the size is always 4.  For the most xls
1226*b1cdbd2cSJim Jagielski     // documents out there this value is almost always -1.
1227*b1cdbd2cSJim Jagielski     sal_Int32 nFlagSize;
1228*b1cdbd2cSJim Jagielski     rStrm >> nFlagSize;
1229*b1cdbd2cSJim Jagielski     if (nFlagSize != -1)
1230*b1cdbd2cSJim Jagielski         return;
1231*b1cdbd2cSJim Jagielski 
1232*b1cdbd2cSJim Jagielski     // There are actually 4 bytes to read, but the upper 2 bytes currently
1233*b1cdbd2cSJim Jagielski     // don't store any bits.
1234*b1cdbd2cSJim Jagielski     sal_uInt16 nOptions;
1235*b1cdbd2cSJim Jagielski     rStrm >> nOptions;
1236*b1cdbd2cSJim Jagielski 
1237*b1cdbd2cSJim Jagielski     Sheet* pSheet = GetSheetItem(nTab);
1238*b1cdbd2cSJim Jagielski     if (pSheet)
1239*b1cdbd2cSJim Jagielski         pSheet->mnOptions = nOptions;
1240*b1cdbd2cSJim Jagielski }
1241*b1cdbd2cSJim Jagielski 
ReadPasswordHash(XclImpStream & rStrm,SCTAB nTab)1242*b1cdbd2cSJim Jagielski void XclImpSheetProtectBuffer::ReadPasswordHash( XclImpStream& rStrm, SCTAB nTab )
1243*b1cdbd2cSJim Jagielski {
1244*b1cdbd2cSJim Jagielski     sal_uInt16 nHash;
1245*b1cdbd2cSJim Jagielski     rStrm >> nHash;
1246*b1cdbd2cSJim Jagielski     Sheet* pSheet = GetSheetItem(nTab);
1247*b1cdbd2cSJim Jagielski     if (pSheet)
1248*b1cdbd2cSJim Jagielski         pSheet->mnPasswordHash = nHash;
1249*b1cdbd2cSJim Jagielski }
1250*b1cdbd2cSJim Jagielski 
Apply() const1251*b1cdbd2cSJim Jagielski void XclImpSheetProtectBuffer::Apply() const
1252*b1cdbd2cSJim Jagielski {
1253*b1cdbd2cSJim Jagielski     for (ProtectedSheetMap::const_iterator itr = maProtectedSheets.begin(), itrEnd = maProtectedSheets.end();
1254*b1cdbd2cSJim Jagielski          itr != itrEnd; ++itr)
1255*b1cdbd2cSJim Jagielski     {
1256*b1cdbd2cSJim Jagielski         if (!itr->second.mbProtected)
1257*b1cdbd2cSJim Jagielski             // This sheet is (for whatever reason) not protected.
1258*b1cdbd2cSJim Jagielski             continue;
1259*b1cdbd2cSJim Jagielski 
1260*b1cdbd2cSJim Jagielski         auto_ptr<ScTableProtection> pProtect(new ScTableProtection);
1261*b1cdbd2cSJim Jagielski         pProtect->setProtected(true);
1262*b1cdbd2cSJim Jagielski 
1263*b1cdbd2cSJim Jagielski #if ENABLE_SHEET_PROTECTION
1264*b1cdbd2cSJim Jagielski         // 16-bit hash password
1265*b1cdbd2cSJim Jagielski         const sal_uInt16 nHash = itr->second.mnPasswordHash;
1266*b1cdbd2cSJim Jagielski         if (nHash)
1267*b1cdbd2cSJim Jagielski         {
1268*b1cdbd2cSJim Jagielski             Sequence<sal_Int8> aPass(2);
1269*b1cdbd2cSJim Jagielski             aPass[0] = (nHash >> 8) & 0xFF;
1270*b1cdbd2cSJim Jagielski             aPass[1] = nHash & 0xFF;
1271*b1cdbd2cSJim Jagielski             pProtect->setPasswordHash(aPass, PASSHASH_XL);
1272*b1cdbd2cSJim Jagielski         }
1273*b1cdbd2cSJim Jagielski #endif
1274*b1cdbd2cSJim Jagielski 
1275*b1cdbd2cSJim Jagielski         // sheet protection options
1276*b1cdbd2cSJim Jagielski         const sal_uInt16 nOptions = itr->second.mnOptions;
1277*b1cdbd2cSJim Jagielski         pProtect->setOption( ScTableProtection::OBJECTS,               (nOptions & 0x0001) );
1278*b1cdbd2cSJim Jagielski         pProtect->setOption( ScTableProtection::SCENARIOS,             (nOptions & 0x0002) );
1279*b1cdbd2cSJim Jagielski         pProtect->setOption( ScTableProtection::FORMAT_CELLS,          (nOptions & 0x0004) );
1280*b1cdbd2cSJim Jagielski         pProtect->setOption( ScTableProtection::FORMAT_COLUMNS,        (nOptions & 0x0008) );
1281*b1cdbd2cSJim Jagielski         pProtect->setOption( ScTableProtection::FORMAT_ROWS,           (nOptions & 0x0010) );
1282*b1cdbd2cSJim Jagielski         pProtect->setOption( ScTableProtection::INSERT_COLUMNS,        (nOptions & 0x0020) );
1283*b1cdbd2cSJim Jagielski         pProtect->setOption( ScTableProtection::INSERT_ROWS,           (nOptions & 0x0040) );
1284*b1cdbd2cSJim Jagielski         pProtect->setOption( ScTableProtection::INSERT_HYPERLINKS,     (nOptions & 0x0080) );
1285*b1cdbd2cSJim Jagielski         pProtect->setOption( ScTableProtection::DELETE_COLUMNS,        (nOptions & 0x0100) );
1286*b1cdbd2cSJim Jagielski         pProtect->setOption( ScTableProtection::DELETE_ROWS,           (nOptions & 0x0200) );
1287*b1cdbd2cSJim Jagielski         pProtect->setOption( ScTableProtection::SELECT_LOCKED_CELLS,   (nOptions & 0x0400) );
1288*b1cdbd2cSJim Jagielski         pProtect->setOption( ScTableProtection::SORT,                  (nOptions & 0x0800) );
1289*b1cdbd2cSJim Jagielski         pProtect->setOption( ScTableProtection::AUTOFILTER,            (nOptions & 0x1000) );
1290*b1cdbd2cSJim Jagielski         pProtect->setOption( ScTableProtection::PIVOT_TABLES,          (nOptions & 0x2000) );
1291*b1cdbd2cSJim Jagielski         pProtect->setOption( ScTableProtection::SELECT_UNLOCKED_CELLS, (nOptions & 0x4000) );
1292*b1cdbd2cSJim Jagielski 
1293*b1cdbd2cSJim Jagielski         // all done.  now commit.
1294*b1cdbd2cSJim Jagielski         GetDoc().SetTabProtection(itr->first, pProtect.get());
1295*b1cdbd2cSJim Jagielski     }
1296*b1cdbd2cSJim Jagielski }
1297*b1cdbd2cSJim Jagielski 
GetSheetItem(SCTAB nTab)1298*b1cdbd2cSJim Jagielski XclImpSheetProtectBuffer::Sheet* XclImpSheetProtectBuffer::GetSheetItem( SCTAB nTab )
1299*b1cdbd2cSJim Jagielski {
1300*b1cdbd2cSJim Jagielski     ProtectedSheetMap::iterator itr = maProtectedSheets.find(nTab);
1301*b1cdbd2cSJim Jagielski     if (itr == maProtectedSheets.end())
1302*b1cdbd2cSJim Jagielski     {
1303*b1cdbd2cSJim Jagielski         // new sheet
1304*b1cdbd2cSJim Jagielski         if ( !maProtectedSheets.insert( ProtectedSheetMap::value_type(nTab, Sheet()) ).second )
1305*b1cdbd2cSJim Jagielski             return NULL;
1306*b1cdbd2cSJim Jagielski 
1307*b1cdbd2cSJim Jagielski         itr = maProtectedSheets.find(nTab);
1308*b1cdbd2cSJim Jagielski     }
1309*b1cdbd2cSJim Jagielski 
1310*b1cdbd2cSJim Jagielski     return &itr->second;
1311*b1cdbd2cSJim Jagielski }
1312*b1cdbd2cSJim Jagielski 
1313*b1cdbd2cSJim Jagielski // ============================================================================
1314*b1cdbd2cSJim Jagielski 
1315