xref: /aoo42x/main/sc/source/filter/excel/xlroot.cxx (revision b77af630)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_scfilt.hxx"
26 #include "xlroot.hxx"
27 #include <com/sun/star/awt/XDevice.hpp>
28 #include <com/sun/star/frame/XFrame.hpp>
29 #include <com/sun/star/frame/XFramesSupplier.hpp>
30 #include <com/sun/star/i18n/ScriptType.hpp>
31 #include <comphelper/processfactory.hxx>
32 #include <vcl/svapp.hxx>
33 #include <svl/stritem.hxx>
34 #include <svl/languageoptions.hxx>
35 #include <sfx2/objsh.hxx>
36 #include <sfx2/printer.hxx>
37 #include <sfx2/docfile.hxx>
38 #include <vcl/font.hxx>
39 #include <editeng/editstat.hxx>
40 #include "scitems.hxx"
41 #include <editeng/eeitem.hxx>
42 #include "document.hxx"
43 #include "docpool.hxx"
44 #include "docuno.hxx"
45 #include "editutil.hxx"
46 #include "drwlayer.hxx"
47 #include "scextopt.hxx"
48 #include "patattr.hxx"
49 #include "fapihelper.hxx"
50 #include "xlconst.hxx"
51 #include "xlstyle.hxx"
52 #include "xlchart.hxx"
53 #include "xltracer.hxx"
54 #include <unotools/useroptions.hxx>
55 #include "root.hxx"
56 
57 namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
58 
59 using ::rtl::OUString;
60 using ::com::sun::star::uno::Exception;
61 using ::com::sun::star::uno::Reference;
62 using ::com::sun::star::uno::UNO_QUERY_THROW;
63 using ::com::sun::star::uno::UNO_SET_THROW;
64 using ::com::sun::star::awt::XDevice;
65 using ::com::sun::star::awt::DeviceInfo;
66 using ::com::sun::star::frame::XFrame;
67 using ::com::sun::star::frame::XFramesSupplier;
68 using ::com::sun::star::lang::XMultiServiceFactory;
69 
70 using namespace ::com::sun::star;
71 
72 // Global data ================================================================
73 
74 #ifdef DBG_UTIL
~XclDebugObjCounter()75 XclDebugObjCounter::~XclDebugObjCounter()
76 {
77     DBG_ASSERT( mnObjCnt == 0, "XclDebugObjCounter::~XclDebugObjCounter - wrong root object count" );
78 }
79 #endif
80 
81 // ----------------------------------------------------------------------------
82 
XclRootData(XclBiff eBiff,SfxMedium & rMedium,SotStorageRef xRootStrg,ScDocument & rDoc,rtl_TextEncoding eTextEnc,bool bExport)83 XclRootData::XclRootData( XclBiff eBiff, SfxMedium& rMedium,
84         SotStorageRef xRootStrg, ScDocument& rDoc, rtl_TextEncoding eTextEnc, bool bExport ) :
85     meBiff( eBiff ),
86     meOutput( EXC_OUTPUT_BINARY ),
87     mrMedium( rMedium ),
88     mxRootStrg( xRootStrg ),
89     mrDoc( rDoc ),
90     maDefPassword( CREATE_STRING( "VelvetSweatshop" ) ),
91     meTextEnc( eTextEnc ),
92     meSysLang( Application::GetSettings().GetLanguage() ),
93     meDocLang( Application::GetSettings().GetLanguage() ),
94     meUILang( Application::GetSettings().GetUILanguage() ),
95     mnDefApiScript( ApiScriptType::LATIN ),
96     maScMaxPos( MAXCOL, MAXROW, MAXTAB ),
97     maXclMaxPos( EXC_MAXCOL2, EXC_MAXROW2, EXC_MAXTAB2 ),
98     maMaxPos( EXC_MAXCOL2, EXC_MAXROW2, EXC_MAXTAB2 ),
99     mxFontPropSetHlp( new XclFontPropSetHelper ),
100     mxChPropSetHlp( new XclChPropSetHelper ),
101     mxRD( new RootData ),//!
102     mfScreenPixelX( 50.0 ),
103     mfScreenPixelY( 50.0 ),
104     mnCharWidth( 110 ),
105     mnScTab( 0 ),
106     mbExport( bExport )
107 {
108  maUserName = SvtUserOptions().GetLastName();
109     if( maUserName.Len() == 0 )
110         maUserName = CREATE_STRING( "Calc" );
111 
112     switch( ScGlobal::GetDefaultScriptType() )
113     {
114         case SCRIPTTYPE_LATIN:      mnDefApiScript = ApiScriptType::LATIN;      break;
115         case SCRIPTTYPE_ASIAN:      mnDefApiScript = ApiScriptType::ASIAN;      break;
116         case SCRIPTTYPE_COMPLEX:    mnDefApiScript = ApiScriptType::COMPLEX;    break;
117         default:    DBG_ERRORFILE( "XclRootData::XclRootData - unknown script type" );
118     }
119 
120     // maximum cell position
121     switch( meBiff )
122     {
123         case EXC_BIFF2: maXclMaxPos.Set( EXC_MAXCOL2, EXC_MAXROW2, EXC_MAXTAB2 );   break;
124         case EXC_BIFF3: maXclMaxPos.Set( EXC_MAXCOL3, EXC_MAXROW3, EXC_MAXTAB3 );   break;
125         case EXC_BIFF4: maXclMaxPos.Set( EXC_MAXCOL4, EXC_MAXROW4, EXC_MAXTAB4 );   break;
126         case EXC_BIFF5: maXclMaxPos.Set( EXC_MAXCOL5, EXC_MAXROW5, EXC_MAXTAB5 );   break;
127         case EXC_BIFF8: maXclMaxPos.Set( EXC_MAXCOL8, EXC_MAXROW8, EXC_MAXTAB8 );   break;
128         default:        DBG_ERROR_BIFF();
129     }
130     maMaxPos.SetCol( ::std::min( maScMaxPos.Col(), maXclMaxPos.Col() ) );
131     maMaxPos.SetRow( ::std::min( maScMaxPos.Row(), maXclMaxPos.Row() ) );
132     maMaxPos.SetTab( ::std::min( maScMaxPos.Tab(), maXclMaxPos.Tab() ) );
133 
134     // document URL and path
135     if( const SfxItemSet* pItemSet = mrMedium.GetItemSet() )
136         if( const SfxStringItem* pItem = static_cast< const SfxStringItem* >( pItemSet->GetItem( SID_FILE_NAME ) ) )
137             maDocUrl = pItem->GetValue();
138     maBasePath = maDocUrl.Copy( 0, maDocUrl.SearchBackward( '/' ) + 1 );
139 
140     // extended document options - always own object, try to copy existing data from document
141     if( const ScExtDocOptions* pOldDocOpt = mrDoc.GetExtDocOptions() )
142         mxExtDocOpt.reset( new ScExtDocOptions( *pOldDocOpt ) );
143     else
144         mxExtDocOpt.reset( new ScExtDocOptions );
145 
146     // screen pixel size
147     try
148     {
149         Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(), UNO_SET_THROW );
150         Reference< XFramesSupplier > xFramesSupp( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.frame.Desktop" ) ), UNO_QUERY_THROW );
151         Reference< XFrame > xFrame( xFramesSupp->getActiveFrame(), UNO_SET_THROW );
152         Reference< XDevice > xDevice( xFrame->getContainerWindow(), UNO_QUERY_THROW );
153         DeviceInfo aDeviceInfo = xDevice->getInfo();
154         mfScreenPixelX = (aDeviceInfo.PixelPerMeterX > 0) ? (100000.0 / aDeviceInfo.PixelPerMeterX) : 50.0;
155         mfScreenPixelY = (aDeviceInfo.PixelPerMeterY > 0) ? (100000.0 / aDeviceInfo.PixelPerMeterY) : 50.0;
156     }
157     catch( Exception& )
158     {
159         OSL_ENSURE( false, "XclRootData::XclRootData - cannot get output device info" );
160     }
161 }
162 
~XclRootData()163 XclRootData::~XclRootData()
164 {
165 }
166 
167 // ----------------------------------------------------------------------------
168 
XclRoot(XclRootData & rRootData)169 XclRoot::XclRoot( XclRootData& rRootData ) :
170     mrData( rRootData )
171 {
172 #ifdef DBG_UTIL
173     ++mrData.mnObjCnt;
174 #endif
175 
176     // filter tracer
177     // do not use CREATE_OUSTRING for conditional expression
178     mrData.mxTracer.reset( new XclTracer( GetDocUrl(), OUString::createFromAscii(
179         IsExport() ? "Office.Tracing/Export/Excel" : "Office.Tracing/Import/Excel" ) ) );
180 }
181 
XclRoot(const XclRoot & rRoot)182 XclRoot::XclRoot( const XclRoot& rRoot ) :
183     mrData( rRoot.mrData )
184 {
185 #ifdef DBG_UTIL
186     ++mrData.mnObjCnt;
187 #endif
188 }
189 
~XclRoot()190 XclRoot::~XclRoot()
191 {
192 #ifdef DBG_UTIL
193     --mrData.mnObjCnt;
194 #endif
195 }
196 
operator =(const XclRoot & rRoot)197 XclRoot& XclRoot::operator=( const XclRoot& rRoot )
198 {
199     (void)rRoot;    // avoid compiler warning
200     // allowed for assignment in derived classes - but test if the same root data is used
201     DBG_ASSERT( &mrData == &rRoot.mrData, "XclRoot::operator= - incompatible root data" );
202     return *this;
203 }
204 
SetTextEncoding(rtl_TextEncoding eTextEnc)205 void XclRoot::SetTextEncoding( rtl_TextEncoding eTextEnc )
206 {
207     if( eTextEnc != RTL_TEXTENCODING_DONTKNOW )
208         mrData.meTextEnc = eTextEnc;
209 }
210 
SetCharWidth(const XclFontData & rFontData)211 void XclRoot::SetCharWidth( const XclFontData& rFontData )
212 {
213     mrData.mnCharWidth = 0;
214     if( OutputDevice* pPrinter = GetPrinter() )
215     {
216         Font aFont( rFontData.maName, Size( 0, rFontData.mnHeight ) );
217         aFont.SetFamily( rFontData.GetScFamily( GetTextEncoding() ) );
218         aFont.SetCharSet( rFontData.GetFontEncoding() );
219         aFont.SetWeight( rFontData.GetScWeight() );
220         pPrinter->SetFont( aFont );
221         mrData.mnCharWidth = pPrinter->GetTextWidth( String( '0' ) );
222     }
223     if( mrData.mnCharWidth <= 0 )
224     {
225         // #i48717# Win98 with HP LaserJet returns 0
226         DBG_ERRORFILE( "XclRoot::SetCharWidth - invalid character width (no printer?)" );
227         mrData.mnCharWidth = 11 * rFontData.mnHeight / 20;
228     }
229 }
230 
GetHmmFromPixelX(double fPixelX) const231 sal_Int32 XclRoot::GetHmmFromPixelX( double fPixelX ) const
232 {
233     return static_cast< sal_Int32 >( fPixelX * mrData.mfScreenPixelX + 0.5 );
234 }
235 
GetHmmFromPixelY(double fPixelY) const236 sal_Int32 XclRoot::GetHmmFromPixelY( double fPixelY ) const
237 {
238     return static_cast< sal_Int32 >( fPixelY * mrData.mfScreenPixelY + 0.5 );
239 }
240 
RequestEncryptionData(::comphelper::IDocPasswordVerifier & rVerifier) const241 uno::Sequence< beans::NamedValue > XclRoot::RequestEncryptionData( ::comphelper::IDocPasswordVerifier& rVerifier ) const
242 {
243     ::std::vector< OUString > aDefaultPasswords;
244     aDefaultPasswords.push_back( mrData.maDefPassword );
245     return ScfApiHelper::QueryEncryptionDataForMedium( mrData.mrMedium, rVerifier, &aDefaultPasswords );
246 }
247 
HasVbaStorage() const248 bool XclRoot::HasVbaStorage() const
249 {
250     SotStorageRef xRootStrg = GetRootStorage();
251     return xRootStrg.Is() && xRootStrg->IsContained( EXC_STORAGE_VBA_PROJECT );
252 }
253 
OpenStorage(SotStorageRef xStrg,const String & rStrgName) const254 SotStorageRef XclRoot::OpenStorage( SotStorageRef xStrg, const String& rStrgName ) const
255 {
256     return mrData.mbExport ?
257         ScfTools::OpenStorageWrite( xStrg, rStrgName ) :
258         ScfTools::OpenStorageRead( xStrg, rStrgName );
259 }
260 
OpenStorage(const String & rStrgName) const261 SotStorageRef XclRoot::OpenStorage( const String& rStrgName ) const
262 {
263     return OpenStorage( GetRootStorage(), rStrgName );
264 }
265 
OpenStream(SotStorageRef xStrg,const String & rStrmName) const266 SotStorageStreamRef XclRoot::OpenStream( SotStorageRef xStrg, const String& rStrmName ) const
267 {
268     return mrData.mbExport ?
269         ScfTools::OpenStorageStreamWrite( xStrg, rStrmName ) :
270         ScfTools::OpenStorageStreamRead( xStrg, rStrmName );
271 }
272 
OpenStream(const String & rStrmName) const273 SotStorageStreamRef XclRoot::OpenStream( const String& rStrmName ) const
274 {
275     return OpenStream( GetRootStorage(), rStrmName );
276 }
277 
GetDocShell() const278 SfxObjectShell* XclRoot::GetDocShell() const
279 {
280     return GetDoc().GetDocumentShell();
281 }
282 
GetDocModelObj() const283 ScModelObj* XclRoot::GetDocModelObj() const
284 {
285     SfxObjectShell* pDocShell = GetDocShell();
286     return pDocShell ? ScModelObj::getImplementation( pDocShell->GetModel() ) : 0;
287 }
288 
GetPrinter() const289 OutputDevice* XclRoot::GetPrinter() const
290 {
291     return GetDoc().GetRefDevice();
292 }
293 
GetStyleSheetPool() const294 ScStyleSheetPool& XclRoot::GetStyleSheetPool() const
295 {
296     return *GetDoc().GetStyleSheetPool();
297 }
298 
GetNamedRanges() const299 ScRangeName& XclRoot::GetNamedRanges() const
300 {
301     return *GetDoc().GetRangeName();
302 }
303 
GetDatabaseRanges() const304 ScDBCollection& XclRoot::GetDatabaseRanges() const
305 {
306     return *GetDoc().GetDBCollection();
307 }
308 
GetSdrPage(SCTAB nScTab) const309 SdrPage* XclRoot::GetSdrPage( SCTAB nScTab ) const
310 {
311     return ((nScTab >= 0) && GetDoc().GetDrawLayer()) ?
312         GetDoc().GetDrawLayer()->GetPage( static_cast< sal_uInt16 >( nScTab ) ) : 0;
313 }
314 
GetFormatter() const315 SvNumberFormatter& XclRoot::GetFormatter() const
316 {
317     return *GetDoc().GetFormatTable();
318 }
319 
GetNullDate() const320 DateTime XclRoot::GetNullDate() const
321 {
322     return *GetFormatter().GetNullDate();
323 }
324 
GetBaseYear() const325 sal_uInt16 XclRoot::GetBaseYear() const
326 {
327     // return 1904 for 1904-01-01, and 1900 for 1899-12-30
328     return (GetNullDate().GetYear() == 1904) ? 1904 : 1900;
329 }
330 
GetDoubleFromDateTime(const DateTime & rDateTime) const331 double XclRoot::GetDoubleFromDateTime( const DateTime& rDateTime ) const
332 {
333     double fValue = rDateTime - GetNullDate();
334     // adjust dates before 1900-03-01 to get correct time values in the range [0.0,1.0)
335     if( rDateTime < DateTime( Date( 1, 3, 1900 ) ) )
336         fValue -= 1.0;
337     return fValue;
338 }
339 
GetDateTimeFromDouble(double fValue) const340 DateTime XclRoot::GetDateTimeFromDouble( double fValue ) const
341 {
342     DateTime aDateTime = GetNullDate() + fValue;
343     // adjust dates before 1900-03-01 to get correct time values
344     if( aDateTime < DateTime( Date( 1, 3, 1900 ) ) )
345         aDateTime += 1L;
346     return aDateTime;
347 }
348 
GetEditEngine() const349 ScEditEngineDefaulter& XclRoot::GetEditEngine() const
350 {
351     if( !mrData.mxEditEngine.get() )
352     {
353         mrData.mxEditEngine.reset( new ScEditEngineDefaulter( GetDoc().GetEnginePool() ) );
354         ScEditEngineDefaulter& rEE = *mrData.mxEditEngine;
355         rEE.SetRefMapMode( MAP_100TH_MM );
356         rEE.SetEditTextObjectPool( GetDoc().GetEditPool() );
357         rEE.SetUpdateMode( sal_False );
358         rEE.EnableUndo( sal_False );
359         rEE.SetControlWord( rEE.GetControlWord() & ~EE_CNTRL_ALLOWBIGOBJS );
360     }
361     return *mrData.mxEditEngine;
362 }
363 
GetHFEditEngine() const364 ScHeaderEditEngine& XclRoot::GetHFEditEngine() const
365 {
366     if( !mrData.mxHFEditEngine.get() )
367     {
368         mrData.mxHFEditEngine.reset( new ScHeaderEditEngine( EditEngine::CreatePool(), sal_True ) );
369         ScHeaderEditEngine& rEE = *mrData.mxHFEditEngine;
370         rEE.SetRefMapMode( MAP_TWIP );  // headers/footers use twips as default metric
371         rEE.SetUpdateMode( sal_False );
372         rEE.EnableUndo( sal_False );
373         rEE.SetControlWord( rEE.GetControlWord() & ~EE_CNTRL_ALLOWBIGOBJS );
374 
375         // set Calc header/footer defaults
376         SfxItemSet* pEditSet = new SfxItemSet( rEE.GetEmptyItemSet() );
377         SfxItemSet aItemSet( *GetDoc().GetPool(), ATTR_PATTERN_START, ATTR_PATTERN_END );
378         ScPatternAttr::FillToEditItemSet( *pEditSet, aItemSet );
379         // FillToEditItemSet() adjusts font height to 1/100th mm, we need twips
380         pEditSet->Put( aItemSet.Get( ATTR_FONT_HEIGHT ), EE_CHAR_FONTHEIGHT );
381         pEditSet->Put( aItemSet.Get( ATTR_CJK_FONT_HEIGHT ), EE_CHAR_FONTHEIGHT_CJK );
382         pEditSet->Put( aItemSet.Get( ATTR_CTL_FONT_HEIGHT ), EE_CHAR_FONTHEIGHT_CTL );
383         rEE.SetDefaults( pEditSet );    // takes ownership
384    }
385     return *mrData.mxHFEditEngine;
386 }
387 
GetDrawEditEngine() const388 EditEngine& XclRoot::GetDrawEditEngine() const
389 {
390     if( !mrData.mxDrawEditEng.get() )
391     {
392         mrData.mxDrawEditEng.reset( new EditEngine( &GetDoc().GetDrawLayer()->GetItemPool() ) );
393         EditEngine& rEE = *mrData.mxDrawEditEng;
394         rEE.SetRefMapMode( MAP_100TH_MM );
395         rEE.SetUpdateMode( sal_False );
396         rEE.EnableUndo( sal_False );
397         rEE.SetControlWord( rEE.GetControlWord() & ~EE_CNTRL_ALLOWBIGOBJS );
398     }
399     return *mrData.mxDrawEditEng;
400 }
401 
GetFontPropSetHelper() const402 XclFontPropSetHelper& XclRoot::GetFontPropSetHelper() const
403 {
404     return *mrData.mxFontPropSetHlp;
405 }
406 
GetChartPropSetHelper() const407 XclChPropSetHelper& XclRoot::GetChartPropSetHelper() const
408 {
409     return *mrData.mxChPropSetHlp;
410 }
411 
GetExtDocOptions() const412 ScExtDocOptions& XclRoot::GetExtDocOptions() const
413 {
414     return *mrData.mxExtDocOpt;
415 }
416 
GetTracer() const417 XclTracer& XclRoot::GetTracer() const
418 {
419     return *mrData.mxTracer;
420 }
421 
422 // ============================================================================
423 
424