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