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