xref: /aoo42x/main/sc/source/ui/unoobj/docuno.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
30 
31 #include "scitems.hxx"
32 #include <svx/fmdpage.hxx>
33 #include <svx/fmview.hxx>
34 #include <svx/svditer.hxx>
35 #include <svx/svdpage.hxx>
36 #include <svx/svxids.hrc>
37 #include <svx/unoshape.hxx>
38 
39 #include <svl/numuno.hxx>
40 #include <svl/smplhint.hxx>
41 #include <unotools/undoopt.hxx>
42 #include <unotools/moduleoptions.hxx>
43 #include <sfx2/printer.hxx>
44 #include <sfx2/bindings.hxx>
45 #include <vcl/pdfextoutdevdata.hxx>
46 #include <vcl/waitobj.hxx>
47 #include <unotools/charclass.hxx>
48 #include <tools/multisel.hxx>
49 #include <tools/resary.hxx>
50 #include <toolkit/awt/vclxdevice.hxx>
51 
52 #include <ctype.h>
53 #include <float.h>	// DBL_MAX
54 
55 #include <com/sun/star/util/Date.hpp>
56 #include <com/sun/star/sheet/XNamedRanges.hpp>
57 #include <com/sun/star/sheet/XLabelRanges.hpp>
58 #include <com/sun/star/i18n/XForbiddenCharacters.hpp>
59 #include <com/sun/star/script/XLibraryContainer.hpp>
60 #include <com/sun/star/lang/XInitialization.hpp>
61 #include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
62 #include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
63 #include <com/sun/star/script/XInvocation.hpp>
64 #include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
65 #include <com/sun/star/reflection/XIdlClassProvider.hpp>
66 #include <comphelper/processfactory.hxx>
67 
68 #include "docuno.hxx"
69 #include "cellsuno.hxx"
70 #include "nameuno.hxx"
71 #include "datauno.hxx"
72 #include "miscuno.hxx"
73 #include "notesuno.hxx"
74 #include "styleuno.hxx"
75 #include "linkuno.hxx"
76 #include "servuno.hxx"
77 #include "targuno.hxx"
78 #include "convuno.hxx"
79 #include "optuno.hxx"
80 #include "forbiuno.hxx"
81 #include "docsh.hxx"
82 #include "hints.hxx"
83 #include "docfunc.hxx"
84 #include "dociter.hxx"
85 #include "cell.hxx"
86 #include "drwlayer.hxx"
87 #include "rangeutl.hxx"
88 #include "markdata.hxx"
89 #include "docoptio.hxx"
90 #include "scextopt.hxx"
91 #include "unoguard.hxx"
92 #include "unonames.hxx"
93 #include "shapeuno.hxx"
94 #include "viewuno.hxx"
95 #include "tabvwsh.hxx"
96 #include "printfun.hxx"
97 #include "pfuncache.hxx"
98 #include "scmod.hxx"
99 #include "rangeutl.hxx"
100 #include "ViewSettingsSequenceDefines.hxx"
101 #include "sheetevents.hxx"
102 #include "sc.hrc"
103 #include "scresid.hxx"
104 
105 using namespace com::sun::star;
106 
107 // #i111553# provides the name of the VBA constant for this document type (e.g. 'ThisExcelDoc' for Calc)
108 #define SC_UNO_VBAGLOBNAME "VBAGlobalConstantName"
109 
110 //------------------------------------------------------------------------
111 
112 //	alles ohne Which-ID, Map nur fuer PropertySetInfo
113 
114 //!	umbenennen, sind nicht mehr nur Options
115 const SfxItemPropertyMapEntry* lcl_GetDocOptPropertyMap()
116 {
117     static SfxItemPropertyMapEntry aDocOptPropertyMap_Impl[] =
118 	{
119         {MAP_CHAR_LEN(SC_UNO_APPLYFMDES),        0, &getBooleanCppuType(),									  0, 0},
120         {MAP_CHAR_LEN(SC_UNO_AREALINKS),         0, &getCppuType((uno::Reference<sheet::XAreaLinks>*)0),      0, 0},
121         {MAP_CHAR_LEN(SC_UNO_AUTOCONTFOC),       0, &getBooleanCppuType(),                                    0, 0},
122         {MAP_CHAR_LEN(SC_UNO_BASICLIBRARIES),    0, &getCppuType((uno::Reference< script::XLibraryContainer >*)0), beans::PropertyAttribute::READONLY, 0},
123         {MAP_CHAR_LEN(SC_UNO_DIALOGLIBRARIES),   0, &getCppuType((uno::Reference< script::XLibraryContainer >*)0), beans::PropertyAttribute::READONLY, 0},
124         {MAP_CHAR_LEN(SC_UNO_VBAGLOBNAME),       0, &getCppuType(static_cast< const rtl::OUString * >(0)),    beans::PropertyAttribute::READONLY, 0},
125         {MAP_CHAR_LEN(SC_UNO_CALCASSHOWN),       PROP_UNO_CALCASSHOWN, &getBooleanCppuType(),                                    0, 0},
126         {MAP_CHAR_LEN(SC_UNONAME_CLOCAL),        0, &getCppuType((lang::Locale*)0),                           0, 0},
127         {MAP_CHAR_LEN(SC_UNO_CJK_CLOCAL),        0, &getCppuType((lang::Locale*)0),                           0, 0},
128         {MAP_CHAR_LEN(SC_UNO_CTL_CLOCAL),        0, &getCppuType((lang::Locale*)0),                           0, 0},
129         {MAP_CHAR_LEN(SC_UNO_COLLABELRNG),       0, &getCppuType((uno::Reference<sheet::XLabelRanges>*)0),    0, 0},
130         {MAP_CHAR_LEN(SC_UNO_DDELINKS),          0, &getCppuType((uno::Reference<container::XNameAccess>*)0), 0, 0},
131         {MAP_CHAR_LEN(SC_UNO_DEFTABSTOP),        PROP_UNO_DEFTABSTOP, &getCppuType((sal_Int16*)0),                              0, 0},
132         {MAP_CHAR_LEN(SC_UNO_EXTERNALDOCLINKS),  0, &getCppuType((uno::Reference<sheet::XExternalDocLinks>*)0), 0, 0},
133         {MAP_CHAR_LEN(SC_UNO_FORBIDDEN),         0, &getCppuType((uno::Reference<i18n::XForbiddenCharacters>*)0), beans::PropertyAttribute::READONLY, 0},
134         {MAP_CHAR_LEN(SC_UNO_HASDRAWPAGES),      0, &getBooleanCppuType(),                                    beans::PropertyAttribute::READONLY, 0},
135         {MAP_CHAR_LEN(SC_UNO_IGNORECASE),        PROP_UNO_IGNORECASE, &getBooleanCppuType(),                                    0, 0},
136         {MAP_CHAR_LEN(SC_UNO_ITERENABLED),       PROP_UNO_ITERENABLED, &getBooleanCppuType(),                                    0, 0},
137         {MAP_CHAR_LEN(SC_UNO_ITERCOUNT),         PROP_UNO_ITERCOUNT, &getCppuType((sal_Int32*)0),                              0, 0},
138         {MAP_CHAR_LEN(SC_UNO_ITEREPSILON),       PROP_UNO_ITEREPSILON, &getCppuType((double*)0),                                 0, 0},
139         {MAP_CHAR_LEN(SC_UNO_LOOKUPLABELS),      PROP_UNO_LOOKUPLABELS, &getBooleanCppuType(),                                    0, 0},
140         {MAP_CHAR_LEN(SC_UNO_MATCHWHOLE),        PROP_UNO_MATCHWHOLE, &getBooleanCppuType(),                                    0, 0},
141         {MAP_CHAR_LEN(SC_UNO_NAMEDRANGES),       0, &getCppuType((uno::Reference<sheet::XNamedRanges>*)0),    0, 0},
142         {MAP_CHAR_LEN(SC_UNO_DATABASERNG),       0, &getCppuType((uno::Reference<sheet::XDatabaseRanges>*)0), 0, 0},
143         {MAP_CHAR_LEN(SC_UNO_NULLDATE),          PROP_UNO_NULLDATE, &getCppuType((util::Date*)0),                             0, 0},
144         {MAP_CHAR_LEN(SC_UNO_ROWLABELRNG),       0, &getCppuType((uno::Reference<sheet::XLabelRanges>*)0),    0, 0},
145         {MAP_CHAR_LEN(SC_UNO_SHEETLINKS),        0, &getCppuType((uno::Reference<container::XNameAccess>*)0), 0, 0},
146         {MAP_CHAR_LEN(SC_UNO_SPELLONLINE),       PROP_UNO_SPELLONLINE, &getBooleanCppuType(),                                    0, 0},
147         {MAP_CHAR_LEN(SC_UNO_STANDARDDEC),       PROP_UNO_STANDARDDEC, &getCppuType((sal_Int16*)0),                              0, 0},
148         {MAP_CHAR_LEN(SC_UNO_REGEXENABLED),      PROP_UNO_REGEXENABLED, &getBooleanCppuType(),                                    0, 0},
149         {MAP_CHAR_LEN(SC_UNO_RUNTIMEUID),        0, &getCppuType(static_cast< const rtl::OUString * >(0)),    beans::PropertyAttribute::READONLY, 0},
150         {MAP_CHAR_LEN(SC_UNO_HASVALIDSIGNATURES),0, &getBooleanCppuType(),                                    beans::PropertyAttribute::READONLY, 0},
151         {MAP_CHAR_LEN(SC_UNO_ISLOADED),          0, &getBooleanCppuType(),                                    0, 0},
152         {MAP_CHAR_LEN(SC_UNO_ISUNDOENABLED),     0, &getBooleanCppuType(),                                    0, 0},
153         {MAP_CHAR_LEN(SC_UNO_ISADJUSTHEIGHTENABLED), 0, &getBooleanCppuType(),                                0, 0},
154         {MAP_CHAR_LEN(SC_UNO_ISEXECUTELINKENABLED), 0, &getBooleanCppuType(),                                 0, 0},
155         {MAP_CHAR_LEN(SC_UNO_ISCHANGEREADONLYENABLED), 0, &getBooleanCppuType(),                              0, 0},
156         {MAP_CHAR_LEN(SC_UNO_REFERENCEDEVICE),   0, &getCppuType((uno::Reference<awt::XDevice>*)0),           beans::PropertyAttribute::READONLY, 0},
157         {MAP_CHAR_LEN("BuildId"),                0, &::getCppuType(static_cast< const rtl::OUString * >(0)), 0, 0},
158         {MAP_CHAR_LEN(SC_UNO_CODENAME),        0, &getCppuType(static_cast< const rtl::OUString * >(0)),    0, 0},
159 
160         {0,0,0,0,0,0}
161 	};
162 	return aDocOptPropertyMap_Impl;
163 }
164 
165 //!	StandardDecimals als Property und vom NumberFormatter ????????
166 
167 const SfxItemPropertyMapEntry* lcl_GetColumnsPropertyMap()
168 {
169     static SfxItemPropertyMapEntry aColumnsPropertyMap_Impl[] =
170 	{
171 		{MAP_CHAR_LEN(SC_UNONAME_MANPAGE),	0,	&getBooleanCppuType(),			0, 0 },
172 		{MAP_CHAR_LEN(SC_UNONAME_NEWPAGE),	0,	&getBooleanCppuType(),			0, 0 },
173 		{MAP_CHAR_LEN(SC_UNONAME_CELLVIS),	0,	&getBooleanCppuType(),			0, 0 },
174 		{MAP_CHAR_LEN(SC_UNONAME_OWIDTH),	0,	&getBooleanCppuType(),			0, 0 },
175 		{MAP_CHAR_LEN(SC_UNONAME_CELLWID),	0,	&getCppuType((sal_Int32*)0),	0, 0 },
176         {0,0,0,0,0,0}
177 	};
178 	return aColumnsPropertyMap_Impl;
179 }
180 
181 const SfxItemPropertyMapEntry* lcl_GetRowsPropertyMap()
182 {
183     static SfxItemPropertyMapEntry aRowsPropertyMap_Impl[] =
184 	{
185 		{MAP_CHAR_LEN(SC_UNONAME_CELLHGT),	0,	&getCppuType((sal_Int32*)0),	0, 0 },
186 		{MAP_CHAR_LEN(SC_UNONAME_CELLFILT),	0,	&getBooleanCppuType(),			0, 0 },
187 		{MAP_CHAR_LEN(SC_UNONAME_OHEIGHT),	0,	&getBooleanCppuType(),			0, 0 },
188 		{MAP_CHAR_LEN(SC_UNONAME_MANPAGE),	0,	&getBooleanCppuType(),			0, 0 },
189 		{MAP_CHAR_LEN(SC_UNONAME_NEWPAGE),	0,	&getBooleanCppuType(),			0, 0 },
190 		{MAP_CHAR_LEN(SC_UNONAME_CELLVIS),	0,	&getBooleanCppuType(),			0, 0 },
191         {MAP_CHAR_LEN(SC_UNONAME_CELLBACK), ATTR_BACKGROUND, &::getCppuType((const sal_Int32*)0), 0, MID_BACK_COLOR },
192         {MAP_CHAR_LEN(SC_UNONAME_CELLTRAN), ATTR_BACKGROUND, &::getBooleanCppuType(), 0, MID_GRAPHIC_TRANSPARENT },
193         // not sorted, not used with SfxItemPropertyMapEntry::GetByName
194         {0,0,0,0,0,0}
195 	};
196 	return aRowsPropertyMap_Impl;
197 }
198 
199 //!	move these functions to a header file
200 inline long TwipsToHMM(long nTwips)	{ return (nTwips * 127 + 36) / 72; }
201 inline long HMMToTwips(long nHMM)	{ return (nHMM * 72 + 63) / 127; }
202 
203 //------------------------------------------------------------------------
204 
205 #define SCMODELOBJ_SERVICE			"com.sun.star.sheet.SpreadsheetDocument"
206 #define SCDOCSETTINGS_SERVICE		"com.sun.star.sheet.SpreadsheetDocumentSettings"
207 #define SCDOC_SERVICE				"com.sun.star.document.OfficeDocument"
208 
209 SC_SIMPLE_SERVICE_INFO( ScAnnotationsObj, "ScAnnotationsObj", "com.sun.star.sheet.CellAnnotations" )
210 SC_SIMPLE_SERVICE_INFO( ScDrawPagesObj, "ScDrawPagesObj", "com.sun.star.drawing.DrawPages" )
211 SC_SIMPLE_SERVICE_INFO( ScScenariosObj, "ScScenariosObj", "com.sun.star.sheet.Scenarios" )
212 SC_SIMPLE_SERVICE_INFO( ScSpreadsheetSettingsObj, "ScSpreadsheetSettingsObj", "com.sun.star.sheet.SpreadsheetDocumentSettings" )
213 SC_SIMPLE_SERVICE_INFO( ScTableColumnsObj, "ScTableColumnsObj", "com.sun.star.table.TableColumns" )
214 SC_SIMPLE_SERVICE_INFO( ScTableRowsObj, "ScTableRowsObj", "com.sun.star.table.TableRows" )
215 SC_SIMPLE_SERVICE_INFO( ScTableSheetsObj, "ScTableSheetsObj", "com.sun.star.sheet.Spreadsheets" )
216 
217 //------------------------------------------------------------------------
218 
219 class ScPrintUIOptions : public vcl::PrinterOptionsHelper
220 {
221 public:
222     ScPrintUIOptions();
223     void SetDefaults();
224 };
225 
226 ScPrintUIOptions::ScPrintUIOptions()
227 {
228     const ScPrintOptions& rPrintOpt = SC_MOD()->GetPrintOptions();
229     sal_Int32 nContent = rPrintOpt.GetAllSheets() ? 0 : 1;
230     sal_Bool bSuppress = rPrintOpt.GetSkipEmpty();
231 
232     ResStringArray aStrings( ScResId( SCSTR_PRINT_OPTIONS ) );
233     DBG_ASSERT( aStrings.Count() >= 10, "resource incomplete" );
234     if( aStrings.Count() < 10 ) // bad resource ?
235         return;
236 
237     m_aUIProperties.realloc( 8 );
238 
239     // create Section for spreadsheet (results in an extra tab page in dialog)
240     SvtModuleOptions aOpt;
241     String aAppGroupname( aStrings.GetString( 9 ) );
242     aAppGroupname.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "%s" ) ),
243                                     aOpt.GetModuleName( SvtModuleOptions::E_SCALC ) );
244     m_aUIProperties[0].Value = getGroupControlOpt( aAppGroupname, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:TabPage:AppPage" ) ) );
245 
246     // create subgroup for pages
247     m_aUIProperties[1].Value = getSubgroupControlOpt( rtl::OUString( aStrings.GetString( 0 ) ), rtl::OUString() );
248 
249     // create a bool option for empty pages
250     m_aUIProperties[2].Value = getBoolControlOpt( rtl::OUString( aStrings.GetString( 1 ) ),
251                                                   rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:IsIncludeEmptyPages:CheckBox" ) ),
252                                                   rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsIncludeEmptyPages" ) ),
253                                                   ! bSuppress
254                                                   );
255     // create Subgroup for print content
256     vcl::PrinterOptionsHelper::UIControlOptions aPrintRangeOpt;
257     aPrintRangeOpt.maGroupHint = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintRange" ) );
258     m_aUIProperties[3].Value = getSubgroupControlOpt( rtl::OUString( aStrings.GetString( 2 ) ),
259                                                       rtl::OUString(),
260                                                       aPrintRangeOpt
261                                                       );
262 
263     // create a choice for the content to create
264     uno::Sequence< rtl::OUString > aChoices( 3 ), aHelpIds( 3 );
265     aChoices[0] = aStrings.GetString( 3 );
266     aHelpIds[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:PrintContent:RadioButton:0" ) );
267     aChoices[1] = aStrings.GetString( 4 );
268     aHelpIds[1] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:PrintContent:RadioButton:1" ) );
269     aChoices[2] = aStrings.GetString( 5 );
270     aHelpIds[2] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:PrintContent:RadioButton:2" ) );
271     m_aUIProperties[4].Value = getChoiceControlOpt( rtl::OUString(),
272                                                     aHelpIds,
273                                                     rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintContent" ) ),
274                                                     aChoices,
275                                                     nContent );
276 
277     // create Subgroup for print range
278     aPrintRangeOpt.mbInternalOnly = sal_True;
279     m_aUIProperties[5].Value = getSubgroupControlOpt( rtl::OUString( aStrings.GetString( 6 ) ),
280                                                       rtl::OUString(),
281                                                       aPrintRangeOpt
282                                                       );
283 
284     // create a choice for the range to print
285     rtl::OUString aPrintRangeName( RTL_CONSTASCII_USTRINGPARAM( "PrintRange" ) );
286     aChoices.realloc( 2 );
287     aHelpIds.realloc( 2 );
288     aChoices[0] = aStrings.GetString( 7 );
289     aHelpIds[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:PrintRange:RadioButton:0" ) );
290     aChoices[1] = aStrings.GetString( 8 );
291     aHelpIds[1] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:PrintRange:RadioButton:1" ) );
292     m_aUIProperties[6].Value = getChoiceControlOpt( rtl::OUString(),
293                                                     aHelpIds,
294                                                     aPrintRangeName,
295                                                     aChoices,
296                                                     0 );
297 
298     // create a an Edit dependent on "Pages" selected
299     vcl::PrinterOptionsHelper::UIControlOptions aPageRangeOpt( aPrintRangeName, 1, sal_True );
300     m_aUIProperties[7].Value = getEditControlOpt( rtl::OUString(),
301                                                   rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:PageRange:Edit" ) ),
302                                                   rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PageRange" ) ),
303                                                   rtl::OUString(),
304                                                   aPageRangeOpt
305                                                   );
306 }
307 
308 void ScPrintUIOptions::SetDefaults()
309 {
310     // re-initialize the default values from print options
311 
312     const ScPrintOptions& rPrintOpt = SC_MOD()->GetPrintOptions();
313     sal_Int32 nContent = rPrintOpt.GetAllSheets() ? 0 : 1;
314     sal_Bool bSuppress = rPrintOpt.GetSkipEmpty();
315 
316     for (sal_Int32 nUIPos=0; nUIPos<m_aUIProperties.getLength(); ++nUIPos)
317     {
318         uno::Sequence<beans::PropertyValue> aUIProp;
319         if ( m_aUIProperties[nUIPos].Value >>= aUIProp )
320         {
321             for (sal_Int32 nPropPos=0; nPropPos<aUIProp.getLength(); ++nPropPos)
322             {
323                 rtl::OUString aName = aUIProp[nPropPos].Name;
324                 if ( aName.equalsAscii("Property") )
325                 {
326                     beans::PropertyValue aPropertyValue;
327                     if ( aUIProp[nPropPos].Value >>= aPropertyValue )
328                     {
329                         if ( aPropertyValue.Name.equalsAscii( "PrintContent" ) )
330                         {
331                             aPropertyValue.Value <<= nContent;
332                             aUIProp[nPropPos].Value <<= aPropertyValue;
333                         }
334                         else if ( aPropertyValue.Name.equalsAscii( "IsIncludeEmptyPages" ) )
335                         {
336                             ScUnoHelpFunctions::SetBoolInAny( aPropertyValue.Value, ! bSuppress );
337                             aUIProp[nPropPos].Value <<= aPropertyValue;
338                         }
339                     }
340                 }
341             }
342             m_aUIProperties[nUIPos].Value <<= aUIProp;
343         }
344     }
345 }
346 
347 // static
348 void ScModelObj::CreateAndSet(ScDocShell* pDocSh)
349 {
350 	if (pDocSh)
351 		pDocSh->SetBaseModel( new ScModelObj(pDocSh) );
352 }
353 
354 ScModelObj::ScModelObj( ScDocShell* pDocSh ) :
355 	SfxBaseModel( pDocSh ),
356 	aPropSet( lcl_GetDocOptPropertyMap() ),
357 	pDocShell( pDocSh ),
358     pPrintFuncCache( NULL ),
359     pPrinterOptions( NULL ),
360     maChangesListeners( m_aMutex )
361 {
362 	// pDocShell may be NULL if this is the base of a ScDocOptionsObj
363 	if ( pDocShell )
364 	{
365 		pDocShell->GetDocument()->AddUnoObject(*this);		// SfxModel is derived from SfxListener
366 	}
367 }
368 
369 ScModelObj::~ScModelObj()
370 {
371 	if (pDocShell)
372 		pDocShell->GetDocument()->RemoveUnoObject(*this);
373 
374 	if (xNumberAgg.is())
375 		xNumberAgg->setDelegator(uno::Reference<uno::XInterface>());
376 
377 	delete pPrintFuncCache;
378     delete pPrinterOptions;
379 }
380 
381 uno::Reference< uno::XAggregation> ScModelObj::GetFormatter()
382 {
383     // pDocShell may be NULL if this is the base of a ScDocOptionsObj
384     if ( !xNumberAgg.is() && pDocShell )
385     {
386         // setDelegator veraendert den RefCount, darum eine Referenz selber halten
387 		// (direkt am m_refCount, um sich beim release nicht selbst zu loeschen)
388 		comphelper::increment( m_refCount );
389         // waehrend des queryInterface braucht man ein Ref auf das
390 		// SvNumberFormatsSupplierObj, sonst wird es geloescht.
391 		uno::Reference<util::XNumberFormatsSupplier> xFormatter(new SvNumberFormatsSupplierObj(pDocShell->GetDocument()->GetFormatTable() ));
392 		{
393 			xNumberAgg.set(uno::Reference<uno::XAggregation>( xFormatter, uno::UNO_QUERY ));
394 			// extra block to force deletion of the temporary before setDelegator
395 		}
396 
397 		// beim setDelegator darf die zusaetzliche Ref nicht mehr existieren
398 		xFormatter = NULL;
399 
400 		if (xNumberAgg.is())
401 			xNumberAgg->setDelegator( (cppu::OWeakObject*)this );
402         comphelper::decrement( m_refCount );
403     } // if ( !xNumberAgg.is() )
404     return xNumberAgg;
405 }
406 
407 ScDocument* ScModelObj::GetDocument() const
408 {
409 	if (pDocShell)
410 		return pDocShell->GetDocument();
411 	return NULL;
412 }
413 
414 SfxObjectShell* ScModelObj::GetEmbeddedObject() const
415 {
416 	return pDocShell;
417 }
418 
419 void ScModelObj::UpdateAllRowHeights(const ScMarkData* pTabMark, bool bCalcOutputFactor)
420 {
421     if (pDocShell)
422     {
423         if (bCalcOutputFactor)
424             pDocShell->CalcOutputFactor();
425         pDocShell->UpdateAllRowHeights(pTabMark);
426     }
427 }
428 
429 void ScModelObj::BeforeXMLLoading()
430 {
431 	if (pDocShell)
432 		pDocShell->BeforeXMLLoading();
433 }
434 
435 void ScModelObj::AfterXMLLoading(sal_Bool bRet)
436 {
437 	if (pDocShell)
438 		pDocShell->AfterXMLLoading(bRet);
439 }
440 
441 ScSheetSaveData* ScModelObj::GetSheetSaveData()
442 {
443     if (pDocShell)
444         return pDocShell->GetSheetSaveData();
445     return NULL;
446 }
447 
448 void ScModelObj::RepaintRange( const ScRange& rRange )
449 {
450     if (pDocShell)
451         pDocShell->PostPaint( rRange, PAINT_GRID );
452 }
453 
454 uno::Any SAL_CALL ScModelObj::queryInterface( const uno::Type& rType )
455 												throw(uno::RuntimeException)
456 {
457 	SC_QUERYINTERFACE( sheet::XSpreadsheetDocument )
458 	SC_QUERYINTERFACE( document::XActionLockable )
459 	SC_QUERYINTERFACE( sheet::XCalculatable )
460 	SC_QUERYINTERFACE( util::XProtectable )
461 	SC_QUERYINTERFACE( drawing::XDrawPagesSupplier )
462 	SC_QUERYINTERFACE( sheet::XGoalSeek )
463 	SC_QUERYINTERFACE( sheet::XConsolidatable )
464 	SC_QUERYINTERFACE( sheet::XDocumentAuditing )
465 	SC_QUERYINTERFACE( style::XStyleFamiliesSupplier )
466 	SC_QUERYINTERFACE( view::XRenderable )
467 	SC_QUERYINTERFACE( document::XLinkTargetSupplier )
468 	SC_QUERYINTERFACE( beans::XPropertySet )
469 	SC_QUERYINTERFACE( lang::XMultiServiceFactory )
470 	SC_QUERYINTERFACE( lang::XServiceInfo )
471     SC_QUERYINTERFACE( util::XChangesNotifier )
472 
473 	uno::Any aRet(SfxBaseModel::queryInterface( rType ));
474     if ( !aRet.hasValue()
475         && rType != ::getCppuType((uno::Reference< com::sun::star::document::XDocumentEventBroadcaster>*)0)
476         && rType != ::getCppuType((uno::Reference< com::sun::star::frame::XController>*)0)
477         && rType != ::getCppuType((uno::Reference< com::sun::star::frame::XFrame>*)0)
478         && rType != ::getCppuType((uno::Reference< com::sun::star::script::XInvocation>*)0)
479         && rType != ::getCppuType((uno::Reference< com::sun::star::reflection::XIdlClassProvider>*)0)
480         && rType != ::getCppuType((uno::Reference< com::sun::star::beans::XFastPropertySet>*)0)
481         && rType != ::getCppuType((uno::Reference< com::sun::star::awt::XWindow>*)0))
482     {
483         GetFormatter();
484 	    if ( xNumberAgg.is() )
485 		    aRet = xNumberAgg->queryAggregation( rType );
486     }
487 
488 	return aRet;
489 }
490 
491 void SAL_CALL ScModelObj::acquire() throw()
492 {
493 	SfxBaseModel::acquire();
494 }
495 
496 void SAL_CALL ScModelObj::release() throw()
497 {
498 	SfxBaseModel::release();
499 }
500 
501 uno::Sequence<uno::Type> SAL_CALL ScModelObj::getTypes() throw(uno::RuntimeException)
502 {
503 	static uno::Sequence<uno::Type> aTypes;
504 	if ( aTypes.getLength() == 0 )
505 	{
506 		uno::Sequence<uno::Type> aParentTypes(SfxBaseModel::getTypes());
507 		long nParentLen = aParentTypes.getLength();
508 		const uno::Type* pParentPtr = aParentTypes.getConstArray();
509 
510 		uno::Sequence<uno::Type> aAggTypes;
511 		if ( GetFormatter().is() )
512 		{
513 			const uno::Type& rProvType = ::getCppuType((uno::Reference<lang::XTypeProvider>*) 0);
514 			uno::Any aNumProv(xNumberAgg->queryAggregation(rProvType));
515 			if(aNumProv.getValueType() == rProvType)
516 			{
517 				uno::Reference<lang::XTypeProvider> xNumProv(
518 					*(uno::Reference<lang::XTypeProvider>*)aNumProv.getValue());
519 				aAggTypes = xNumProv->getTypes();
520 			}
521 		}
522 		long nAggLen = aAggTypes.getLength();
523 		const uno::Type* pAggPtr = aAggTypes.getConstArray();
524 
525         const long nThisLen = 15;
526 		aTypes.realloc( nParentLen + nAggLen + nThisLen );
527 		uno::Type* pPtr = aTypes.getArray();
528 		pPtr[nParentLen + 0] = getCppuType((const uno::Reference<sheet::XSpreadsheetDocument>*)0);
529 		pPtr[nParentLen + 1] = getCppuType((const uno::Reference<document::XActionLockable>*)0);
530 		pPtr[nParentLen + 2] = getCppuType((const uno::Reference<sheet::XCalculatable>*)0);
531 		pPtr[nParentLen + 3] = getCppuType((const uno::Reference<util::XProtectable>*)0);
532 		pPtr[nParentLen + 4] = getCppuType((const uno::Reference<drawing::XDrawPagesSupplier>*)0);
533 		pPtr[nParentLen + 5] = getCppuType((const uno::Reference<sheet::XGoalSeek>*)0);
534 		pPtr[nParentLen + 6] = getCppuType((const uno::Reference<sheet::XConsolidatable>*)0);
535 		pPtr[nParentLen + 7] = getCppuType((const uno::Reference<sheet::XDocumentAuditing>*)0);
536 		pPtr[nParentLen + 8] = getCppuType((const uno::Reference<style::XStyleFamiliesSupplier>*)0);
537 		pPtr[nParentLen + 9] = getCppuType((const uno::Reference<view::XRenderable>*)0);
538 		pPtr[nParentLen +10] = getCppuType((const uno::Reference<document::XLinkTargetSupplier>*)0);
539 		pPtr[nParentLen +11] = getCppuType((const uno::Reference<beans::XPropertySet>*)0);
540 		pPtr[nParentLen +12] = getCppuType((const uno::Reference<lang::XMultiServiceFactory>*)0);
541 		pPtr[nParentLen +13] = getCppuType((const uno::Reference<lang::XServiceInfo>*)0);
542         pPtr[nParentLen +14] = getCppuType((const uno::Reference<util::XChangesNotifier>*)0);
543 
544 		long i;
545 		for (i=0; i<nParentLen; i++)
546 			pPtr[i] = pParentPtr[i];					// parent types first
547 
548 		for (i=0; i<nAggLen; i++)
549 			pPtr[nParentLen+nThisLen+i] = pAggPtr[i];	// aggregated types last
550 	}
551 	return aTypes;
552 }
553 
554 uno::Sequence<sal_Int8> SAL_CALL ScModelObj::getImplementationId()
555 													throw(uno::RuntimeException)
556 {
557 	static uno::Sequence< sal_Int8 > aId;
558 	if( aId.getLength() == 0 )
559 	{
560 		aId.realloc( 16 );
561 		rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
562 	}
563 	return aId;
564 }
565 
566 void ScModelObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
567 {
568 	//	Not interested in reference update hints here
569 
570 	if ( rHint.ISA( SfxSimpleHint ) )
571 	{
572 		sal_uLong nId = ((const SfxSimpleHint&)rHint).GetId();
573 		if ( nId == SFX_HINT_DYING )
574 		{
575 			pDocShell = NULL;		// has become invalid
576 			if (xNumberAgg.is())
577 			{
578 				SvNumberFormatsSupplierObj* pNumFmt =
579 					SvNumberFormatsSupplierObj::getImplementation(
580 						uno::Reference<util::XNumberFormatsSupplier>(xNumberAgg, uno::UNO_QUERY) );
581 				if ( pNumFmt )
582 					pNumFmt->SetNumberFormatter( NULL );
583 			}
584 
585 			DELETEZ( pPrintFuncCache );		// must be deleted because it has a pointer to the DocShell
586 		}
587 		else if ( nId == SFX_HINT_DATACHANGED )
588 		{
589 			//	cached data for rendering become invalid when contents change
590 			//	(if a broadcast is added to SetDrawModified, is has to be tested here, too)
591 
592 			DELETEZ( pPrintFuncCache );
593 
594             // handle "OnCalculate" sheet events (search also for VBA event handlers)
595             if ( pDocShell )
596             {
597                 ScDocument* pDoc = pDocShell->GetDocument();
598                 if ( pDoc->GetVbaEventProcessor().is() )
599                 {
600                     // If the VBA event processor is set, HasAnyCalcNotification is much faster than HasAnySheetEventScript
601                     if ( pDoc->HasAnyCalcNotification() && pDoc->HasAnySheetEventScript( SC_SHEETEVENT_CALCULATE, true ) )
602                         HandleCalculateEvents();
603                 }
604                 else
605                 {
606                     if ( pDoc->HasAnySheetEventScript( SC_SHEETEVENT_CALCULATE ) )
607                         HandleCalculateEvents();
608                 }
609             }
610 		}
611 	}
612 	else if ( rHint.ISA( ScPointerChangedHint ) )
613 	{
614 		sal_uInt16 nFlags = ((const ScPointerChangedHint&)rHint).GetFlags();
615 		if (nFlags & SC_POINTERCHANGED_NUMFMT)
616 		{
617 			//	NumberFormatter-Pointer am Uno-Objekt neu setzen
618 
619 			if (GetFormatter().is())
620 			{
621 				SvNumberFormatsSupplierObj* pNumFmt =
622 					SvNumberFormatsSupplierObj::getImplementation(
623 						uno::Reference<util::XNumberFormatsSupplier>(xNumberAgg, uno::UNO_QUERY) );
624 				if ( pNumFmt && pDocShell )
625 					pNumFmt->SetNumberFormatter( pDocShell->GetDocument()->GetFormatTable() );
626 			}
627 		}
628 	}
629 
630     // always call parent - SfxBaseModel might need to handle the same hints again
631     SfxBaseModel::Notify( rBC, rHint );     // SfxBaseModel is derived from SfxListener
632 }
633 
634 // XSpreadsheetDocument
635 
636 uno::Reference<sheet::XSpreadsheets> SAL_CALL ScModelObj::getSheets() throw(uno::RuntimeException)
637 {
638 	ScUnoGuard aGuard;
639 	if (pDocShell)
640 		return new ScTableSheetsObj(pDocShell);
641 	return NULL;
642 }
643 
644 // XStyleFamiliesSupplier
645 
646 uno::Reference<container::XNameAccess> SAL_CALL ScModelObj::getStyleFamilies()
647 												throw(uno::RuntimeException)
648 {
649 	ScUnoGuard aGuard;
650 	if (pDocShell)
651 		return new ScStyleFamiliesObj(pDocShell);
652 	return NULL;
653 }
654 
655 // XRenderable
656 
657 OutputDevice* lcl_GetRenderDevice( const uno::Sequence<beans::PropertyValue>& rOptions )
658 {
659 	OutputDevice* pRet = NULL;
660 	const beans::PropertyValue* pPropArray = rOptions.getConstArray();
661 	long nPropCount = rOptions.getLength();
662 	for (long i = 0; i < nPropCount; i++)
663 	{
664 		const beans::PropertyValue& rProp = pPropArray[i];
665 		String aPropName(rProp.Name);
666 
667 		if (aPropName.EqualsAscii( SC_UNONAME_RENDERDEV ))
668 		{
669             uno::Reference<awt::XDevice> xRenderDevice(rProp.Value, uno::UNO_QUERY);
670 			if ( xRenderDevice.is() )
671 			{
672 				VCLXDevice* pDevice = VCLXDevice::GetImplementation( xRenderDevice );
673 				if ( pDevice )
674 				{
675 					pRet = pDevice->GetOutputDevice();
676 					pRet->SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
677 				}
678 			}
679 		}
680 	}
681 	return pRet;
682 }
683 
684 bool lcl_ParseTarget( const String& rTarget, ScRange& rTargetRange, Rectangle& rTargetRect,
685                         bool& rIsSheet, ScDocument* pDoc, SCTAB nSourceTab )
686 {
687     // test in same order as in SID_CURRENTCELL execute
688 
689     ScAddress aAddress;
690     ScRangeUtil aRangeUtil;
691     SCTAB nNameTab;
692     sal_Int32 nNumeric = 0;
693 
694     bool bRangeValid = false;
695     bool bRectValid = false;
696 
697     if ( rTargetRange.Parse( rTarget, pDoc ) & SCA_VALID )
698     {
699         bRangeValid = true;             // range reference
700     }
701     else if ( aAddress.Parse( rTarget, pDoc ) & SCA_VALID )
702     {
703         rTargetRange = aAddress;
704         bRangeValid = true;             // cell reference
705     }
706     else if ( aRangeUtil.MakeRangeFromName( rTarget, pDoc, nSourceTab, rTargetRange, RUTL_NAMES ) ||
707               aRangeUtil.MakeRangeFromName( rTarget, pDoc, nSourceTab, rTargetRange, RUTL_DBASE ) )
708     {
709         bRangeValid = true;             // named range or database range
710     }
711     else if ( ByteString( rTarget, RTL_TEXTENCODING_ASCII_US ).IsNumericAscii() &&
712               ( nNumeric = rTarget.ToInt32() ) > 0 && nNumeric <= MAXROW+1 )
713     {
714         // row number is always mapped to cell A(row) on the same sheet
715         rTargetRange = ScAddress( 0, (SCROW)(nNumeric-1), nSourceTab );     // target row number is 1-based
716         bRangeValid = true;             // row number
717     }
718     else if ( pDoc->GetTable( rTarget, nNameTab ) )
719     {
720         rTargetRange = ScAddress(0,0,nNameTab);
721         bRangeValid = true;             // sheet name
722         rIsSheet = true;                // needs special handling (first page of the sheet)
723     }
724     else
725     {
726         // look for named drawing object
727 
728         ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
729         if ( pDrawLayer )
730         {
731             SCTAB nTabCount = pDoc->GetTableCount();
732             for (SCTAB i=0; i<nTabCount && !bRangeValid; i++)
733             {
734                 SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(i));
735                 DBG_ASSERT(pPage,"Page ?");
736                 if (pPage)
737                 {
738                     SdrObjListIter aIter( *pPage, IM_DEEPWITHGROUPS );
739                     SdrObject* pObject = aIter.Next();
740                     while (pObject && !bRangeValid)
741                     {
742                         if ( ScDrawLayer::GetVisibleName( pObject ) == rTarget )
743                         {
744                             rTargetRect = pObject->GetLogicRect();              // 1/100th mm
745                             rTargetRange = pDoc->GetRange( i, rTargetRect );    // underlying cells
746                             bRangeValid = bRectValid = true;                    // rectangle is valid
747                         }
748                         pObject = aIter.Next();
749                     }
750                 }
751             }
752         }
753     }
754     if ( bRangeValid && !bRectValid )
755     {
756         //  get rectangle for cell range
757         rTargetRect = pDoc->GetMMRect( rTargetRange.aStart.Col(), rTargetRange.aStart.Row(),
758                                        rTargetRange.aEnd.Col(),   rTargetRange.aEnd.Row(),
759                                        rTargetRange.aStart.Tab() );
760     }
761 
762     return bRangeValid;
763 }
764 
765 sal_Bool ScModelObj::FillRenderMarkData( const uno::Any& aSelection,
766                                      const uno::Sequence< beans::PropertyValue >& rOptions,
767                                      ScMarkData& rMark,
768                                      ScPrintSelectionStatus& rStatus, String& rPagesStr ) const
769 {
770 	DBG_ASSERT( !rMark.IsMarked() && !rMark.IsMultiMarked(), "FillRenderMarkData: MarkData must be empty" );
771 	DBG_ASSERT( pDocShell, "FillRenderMarkData: DocShell must be set" );
772 
773 	sal_Bool bDone = sal_False;
774 
775     uno::Reference<frame::XController> xView;
776 
777     // defaults when no options are passed: all sheets, include empty pages
778     sal_Bool bSelectedSheetsOnly = sal_False;
779     sal_Bool bIncludeEmptyPages = sal_True;
780 
781     bool bHasPrintContent = false;
782     sal_Int32 nPrintContent = 0;        // all sheets / selected sheets / selected cells
783     sal_Int32 nPrintRange = 0;          // all pages / pages
784     rtl::OUString aPageRange;           // "pages" edit value
785 
786     for( sal_Int32 i = 0, nLen = rOptions.getLength(); i < nLen; i++ )
787     {
788         if( rOptions[i].Name.equalsAscii( "IsOnlySelectedSheets" ) )
789         {
790             rOptions[i].Value >>= bSelectedSheetsOnly;
791         }
792         else if( rOptions[i].Name.equalsAscii( "IsIncludeEmptyPages" ) )
793         {
794             rOptions[i].Value >>= bIncludeEmptyPages;
795         }
796         else if( rOptions[i].Name.equalsAscii( "PageRange" ) )
797         {
798             rOptions[i].Value >>= aPageRange;
799         }
800         else if( rOptions[i].Name.equalsAscii( "PrintRange" ) )
801         {
802             rOptions[i].Value >>= nPrintRange;
803         }
804         else if( rOptions[i].Name.equalsAscii( "PrintContent" ) )
805         {
806             bHasPrintContent = true;
807             rOptions[i].Value >>= nPrintContent;
808         }
809         else if( rOptions[i].Name.equalsAscii( "View" ) )
810         {
811             rOptions[i].Value >>= xView;
812         }
813     }
814 
815     // "Print Content" selection wins over "Selected Sheets" option
816     if ( bHasPrintContent )
817         bSelectedSheetsOnly = ( nPrintContent != 0 );
818 
819     uno::Reference<uno::XInterface> xInterface(aSelection, uno::UNO_QUERY);
820 	if ( xInterface.is() )
821 	{
822 		ScCellRangesBase* pSelObj = ScCellRangesBase::getImplementation( xInterface );
823         uno::Reference< drawing::XShapes > xShapes( xInterface, uno::UNO_QUERY );
824         if ( pSelObj && pSelObj->GetDocShell() == pDocShell )
825 		{
826 			sal_Bool bSheet = ( ScTableSheetObj::getImplementation( xInterface ) != NULL );
827 			sal_Bool bCursor = pSelObj->IsCursorOnly();
828 			const ScRangeList& rRanges = pSelObj->GetRangeList();
829 
830 			rMark.MarkFromRangeList( rRanges, sal_False );
831 			rMark.MarkToSimple();
832 
833             if ( rMark.IsMultiMarked() )
834             {
835                 // #i115266# copy behavior of old printing:
836                 // treat multiple selection like a single selection with the enclosing range
837                 ScRange aMultiMarkArea;
838                 rMark.GetMultiMarkArea( aMultiMarkArea );
839                 rMark.ResetMark();
840                 rMark.SetMarkArea( aMultiMarkArea );
841             }
842 
843 			if ( rMark.IsMarked() && !rMark.IsMultiMarked() )
844 			{
845 				// a sheet object is treated like an empty selection: print the used area of the sheet
846 
847 				if ( bCursor || bSheet )				// nothing selected -> use whole tables
848 				{
849 					rMark.ResetMark();		// doesn't change table selection
850 					rStatus.SetMode( SC_PRINTSEL_CURSOR );
851 				}
852 				else
853 					rStatus.SetMode( SC_PRINTSEL_RANGE );
854 
855 				rStatus.SetRanges( rRanges );
856 				bDone = sal_True;
857 			}
858 			// multi selection isn't supported
859 		}
860         else if( xShapes.is() )
861         {
862             //print a selected ole object
863             uno::Reference< container::XIndexAccess > xIndexAccess( xShapes, uno::UNO_QUERY );
864             if( xIndexAccess.is() )
865             {
866                 // multi selection isn't supported yet
867                 uno::Reference< drawing::XShape > xShape( xIndexAccess->getByIndex(0), uno::UNO_QUERY );
868                 SvxShape* pShape = SvxShape::getImplementation( xShape );
869                 if( pShape )
870                 {
871                     SdrObject *pSdrObj = pShape->GetSdrObject();
872                     if( pDocShell )
873                     {
874                         ScDocument* pDoc = pDocShell->GetDocument();
875                         if( pDoc && pSdrObj )
876                         {
877                             Rectangle aObjRect = pSdrObj->GetCurrentBoundRect();
878                             SCTAB nCurrentTab = ScDocShell::GetCurTab();
879                             ScRange aRange = pDoc->GetRange( nCurrentTab, aObjRect );
880                             rMark.SetMarkArea( aRange );
881 
882                             if( rMark.IsMarked() && !rMark.IsMultiMarked() )
883                             {
884                                 rStatus.SetMode( SC_PRINTSEL_RANGE_EXCLUSIVELY_OLE_AND_DRAW_OBJECTS );
885                                 bDone = sal_True;
886                             }
887                         }
888                     }
889                 }
890             }
891         }
892 		else if ( ScModelObj::getImplementation( xInterface ) == this )
893 		{
894 			//	render the whole document
895 			//	-> no selection, all sheets
896 
897 			SCTAB nTabCount = pDocShell->GetDocument()->GetTableCount();
898 			for (SCTAB nTab = 0; nTab < nTabCount; nTab++)
899 				rMark.SelectTable( nTab, sal_True );
900 			rStatus.SetMode( SC_PRINTSEL_DOCUMENT );
901 			bDone = sal_True;
902 		}
903 		// other selection types aren't supported
904 	}
905 
906     // restrict to selected sheets if a view is available
907     if ( bSelectedSheetsOnly && xView.is() )
908     {
909         ScTabViewObj* pViewObj = ScTabViewObj::getImplementation( xView );
910         if (pViewObj)
911         {
912             ScTabViewShell* pViewSh = pViewObj->GetViewShell();
913             if (pViewSh)
914             {
915                 // #i95280# when printing from the shell, the view is never activated,
916                 // so Excel view settings must also be evaluated here.
917                 ScExtDocOptions* pExtOpt = pDocShell->GetDocument()->GetExtDocOptions();
918                 if ( pExtOpt && pExtOpt->IsChanged() )
919                 {
920                     pViewSh->GetViewData()->ReadExtOptions(*pExtOpt);        // Excel view settings
921                     pViewSh->SetTabNo( pViewSh->GetViewData()->GetTabNo(), sal_True );
922                     pExtOpt->SetChanged( false );
923                 }
924 
925                 const ScMarkData& rViewMark = pViewSh->GetViewData()->GetMarkData();
926                 SCTAB nTabCount = pDocShell->GetDocument()->GetTableCount();
927                 for (SCTAB nTab = 0; nTab < nTabCount; nTab++)
928                     if (!rViewMark.GetTableSelect(nTab))
929                         rMark.SelectTable( nTab, sal_False );
930             }
931         }
932     }
933 
934     ScPrintOptions aNewOptions;
935     aNewOptions.SetSkipEmpty( !bIncludeEmptyPages );
936     aNewOptions.SetAllSheets( !bSelectedSheetsOnly );
937     rStatus.SetOptions( aNewOptions );
938 
939     // "PrintRange" enables (1) or disables (0) the "PageRange" edit
940     if ( nPrintRange == 1 )
941         rPagesStr = aPageRange;
942     else
943         rPagesStr.Erase();
944 
945 	return bDone;
946 }
947 
948 
949 sal_Int32 SAL_CALL ScModelObj::getRendererCount( const uno::Any& aSelection,
950                                     const uno::Sequence<beans::PropertyValue>& rOptions )
951 								throw (lang::IllegalArgumentException, uno::RuntimeException)
952 {
953 	ScUnoGuard aGuard;
954 	if (!pDocShell)
955 		throw uno::RuntimeException();
956 
957 	ScMarkData aMark;
958 	ScPrintSelectionStatus aStatus;
959     String aPagesStr;
960     if ( !FillRenderMarkData( aSelection, rOptions, aMark, aStatus, aPagesStr ) )
961 		return 0;
962 
963 	//	The same ScPrintFuncCache object in pPrintFuncCache is used as long as
964 	//	the same selection is used (aStatus) and the document isn't changed
965 	//	(pPrintFuncCache is cleared in Notify handler)
966 
967 	if ( !pPrintFuncCache || !pPrintFuncCache->IsSameSelection( aStatus ) )
968 	{
969 		delete pPrintFuncCache;
970 		pPrintFuncCache = new ScPrintFuncCache( pDocShell, aMark, aStatus );
971 	}
972     sal_Int32 nPages = pPrintFuncCache->GetPageCount();
973 
974     sal_Int32 nSelectCount = nPages;
975     if ( aPagesStr.Len() )
976     {
977         MultiSelection aPageRanges( aPagesStr );
978         aPageRanges.SetTotalRange( Range( 1, nPages ) );
979         nSelectCount = aPageRanges.GetSelectCount();
980     }
981     return nSelectCount;
982 }
983 
984 sal_Int32 lcl_GetRendererNum( sal_Int32 nSelRenderer, const String& rPagesStr, sal_Int32 nTotalPages )
985 {
986     if ( !rPagesStr.Len() )
987         return nSelRenderer;
988 
989     MultiSelection aPageRanges( rPagesStr );
990     aPageRanges.SetTotalRange( Range( 1, nTotalPages ) );
991 
992     sal_Int32 nSelected = aPageRanges.FirstSelected();
993     while ( nSelRenderer > 0 )
994     {
995         nSelected = aPageRanges.NextSelected();
996         --nSelRenderer;
997     }
998     return nSelected - 1;       // selection is 1-based
999 }
1000 
1001 uno::Sequence<beans::PropertyValue> SAL_CALL ScModelObj::getRenderer( sal_Int32 nSelRenderer,
1002                                     const uno::Any& aSelection, const uno::Sequence<beans::PropertyValue>& rOptions  )
1003 								throw (lang::IllegalArgumentException, uno::RuntimeException)
1004 {
1005 	ScUnoGuard aGuard;
1006 	if (!pDocShell)
1007 		throw uno::RuntimeException();
1008 
1009 	ScMarkData aMark;
1010 	ScPrintSelectionStatus aStatus;
1011     String aPagesStr;
1012     // #i115266# if FillRenderMarkData fails, keep nTotalPages at 0, but still handle getRenderer(0) below
1013     long nTotalPages = 0;
1014     if ( FillRenderMarkData( aSelection, rOptions, aMark, aStatus, aPagesStr ) )
1015     {
1016         if ( !pPrintFuncCache || !pPrintFuncCache->IsSameSelection( aStatus ) )
1017         {
1018             delete pPrintFuncCache;
1019             pPrintFuncCache = new ScPrintFuncCache( pDocShell, aMark, aStatus );
1020         }
1021         nTotalPages = pPrintFuncCache->GetPageCount();
1022     }
1023     sal_Int32 nRenderer = lcl_GetRendererNum( nSelRenderer, aPagesStr, nTotalPages );
1024 	if ( nRenderer >= nTotalPages )
1025     {
1026         if ( nSelRenderer == 0 )
1027         {
1028             // getRenderer(0) is used to query the settings, so it must always return something
1029 
1030             SCTAB nCurTab = 0;      //! use current sheet from view?
1031             ScPrintFunc aDefaultFunc( pDocShell, pDocShell->GetPrinter(), nCurTab );
1032             Size aTwips = aDefaultFunc.GetPageSize();
1033             awt::Size aPageSize( TwipsToHMM( aTwips.Width() ), TwipsToHMM( aTwips.Height() ) );
1034 
1035             uno::Sequence<beans::PropertyValue> aSequence(1);
1036             beans::PropertyValue* pArray = aSequence.getArray();
1037             pArray[0].Name = rtl::OUString::createFromAscii( SC_UNONAME_PAGESIZE );
1038             pArray[0].Value <<= aPageSize;
1039 
1040             if( ! pPrinterOptions )
1041                 pPrinterOptions = new ScPrintUIOptions;
1042             else
1043                 pPrinterOptions->SetDefaults();
1044             pPrinterOptions->appendPrintUIOptions( aSequence );
1045             return aSequence;
1046         }
1047         else
1048             throw lang::IllegalArgumentException();
1049     }
1050 
1051 	//	printer is used as device (just for page layout), draw view is not needed
1052 
1053 	SCTAB nTab = pPrintFuncCache->GetTabForPage( nRenderer );
1054 
1055 	ScRange aRange;
1056 	const ScRange* pSelRange = NULL;
1057 	if ( aMark.IsMarked() )
1058 	{
1059 		aMark.GetMarkArea( aRange );
1060 		pSelRange = &aRange;
1061 	}
1062 	ScPrintFunc aFunc( pDocShell, pDocShell->GetPrinter(), nTab,
1063 						pPrintFuncCache->GetFirstAttr(nTab), nTotalPages, pSelRange, &aStatus.GetOptions() );
1064 	aFunc.SetRenderFlag( sal_True );
1065 
1066 	Range aPageRange( nRenderer+1, nRenderer+1 );
1067 	MultiSelection aPage( aPageRange );
1068 	aPage.SetTotalRange( Range(0,RANGE_MAX) );
1069 	aPage.Select( aPageRange );
1070 
1071 	long nDisplayStart = pPrintFuncCache->GetDisplayStart( nTab );
1072 	long nTabStart = pPrintFuncCache->GetTabStart( nTab );
1073 
1074     (void)aFunc.DoPrint( aPage, nTabStart, nDisplayStart, sal_False, NULL );
1075 
1076 	ScRange aCellRange;
1077 	sal_Bool bWasCellRange = aFunc.GetLastSourceRange( aCellRange );
1078 	Size aTwips = aFunc.GetPageSize();
1079 	awt::Size aPageSize( TwipsToHMM( aTwips.Width() ), TwipsToHMM( aTwips.Height() ) );
1080 
1081     long nPropCount = bWasCellRange ? 3 : 2;
1082 	uno::Sequence<beans::PropertyValue> aSequence(nPropCount);
1083 	beans::PropertyValue* pArray = aSequence.getArray();
1084 	pArray[0].Name = rtl::OUString::createFromAscii( SC_UNONAME_PAGESIZE );
1085 	pArray[0].Value <<= aPageSize;
1086     // #i111158# all positions are relative to the whole page, including non-printable area
1087     pArray[1].Name = rtl::OUString::createFromAscii( SC_UNONAME_INC_NP_AREA );
1088     pArray[1].Value = uno::makeAny( sal_True );
1089 	if ( bWasCellRange )
1090 	{
1091 		table::CellRangeAddress aRangeAddress( nTab,
1092 						aCellRange.aStart.Col(), aCellRange.aStart.Row(),
1093 						aCellRange.aEnd.Col(), aCellRange.aEnd.Row() );
1094         pArray[2].Name = rtl::OUString::createFromAscii( SC_UNONAME_SOURCERANGE );
1095         pArray[2].Value <<= aRangeAddress;
1096 	}
1097 
1098     if( ! pPrinterOptions )
1099         pPrinterOptions = new ScPrintUIOptions;
1100     else
1101         pPrinterOptions->SetDefaults();
1102     pPrinterOptions->appendPrintUIOptions( aSequence );
1103 	return aSequence;
1104 }
1105 
1106 void SAL_CALL ScModelObj::render( sal_Int32 nSelRenderer, const uno::Any& aSelection,
1107 									const uno::Sequence<beans::PropertyValue>& rOptions )
1108 								throw(lang::IllegalArgumentException, uno::RuntimeException)
1109 {
1110 	ScUnoGuard aGuard;
1111 	if (!pDocShell)
1112 		throw uno::RuntimeException();
1113 
1114 	ScMarkData aMark;
1115 	ScPrintSelectionStatus aStatus;
1116     String aPagesStr;
1117     if ( !FillRenderMarkData( aSelection, rOptions, aMark, aStatus, aPagesStr ) )
1118 		throw lang::IllegalArgumentException();
1119 
1120 	if ( !pPrintFuncCache || !pPrintFuncCache->IsSameSelection( aStatus ) )
1121 	{
1122 		delete pPrintFuncCache;
1123 		pPrintFuncCache = new ScPrintFuncCache( pDocShell, aMark, aStatus );
1124 	}
1125 	long nTotalPages = pPrintFuncCache->GetPageCount();
1126     sal_Int32 nRenderer = lcl_GetRendererNum( nSelRenderer, aPagesStr, nTotalPages );
1127 	if ( nRenderer >= nTotalPages )
1128 		throw lang::IllegalArgumentException();
1129 
1130 	OutputDevice* pDev = lcl_GetRenderDevice( rOptions );
1131 	if ( !pDev )
1132 		throw lang::IllegalArgumentException();
1133 
1134 	SCTAB nTab = pPrintFuncCache->GetTabForPage( nRenderer );
1135 	ScDocument* pDoc = pDocShell->GetDocument();
1136 
1137 	FmFormView* pDrawView = NULL;
1138 	Rectangle aFull( 0, 0, LONG_MAX, LONG_MAX );
1139 
1140 	// #114135#
1141 	ScDrawLayer* pModel = pDoc->GetDrawLayer();
1142 
1143 	if( pModel )
1144 	{
1145 		pDrawView = new FmFormView( pModel, pDev );
1146 		pDrawView->ShowSdrPage(pDrawView->GetModel()->GetPage(nTab));
1147 		pDrawView->SetPrintPreview( sal_True );
1148 	}
1149 
1150 	ScRange aRange;
1151 	const ScRange* pSelRange = NULL;
1152 	if ( aMark.IsMarked() )
1153 	{
1154 		aMark.GetMarkArea( aRange );
1155 		pSelRange = &aRange;
1156 	}
1157 
1158 	//	to increase performance, ScPrintState might be used here for subsequent
1159 	//	pages of the same sheet
1160 
1161 	ScPrintFunc aFunc( pDev, pDocShell, nTab, pPrintFuncCache->GetFirstAttr(nTab), nTotalPages, pSelRange, &aStatus.GetOptions() );
1162 	aFunc.SetDrawView( pDrawView );
1163 	aFunc.SetRenderFlag( sal_True );
1164     if( aStatus.GetMode() == SC_PRINTSEL_RANGE_EXCLUSIVELY_OLE_AND_DRAW_OBJECTS )
1165         aFunc.SetExclusivelyDrawOleAndDrawObjects();
1166 
1167 	Range aPageRange( nRenderer+1, nRenderer+1 );
1168 	MultiSelection aPage( aPageRange );
1169 	aPage.SetTotalRange( Range(0,RANGE_MAX) );
1170 	aPage.Select( aPageRange );
1171 
1172 	long nDisplayStart = pPrintFuncCache->GetDisplayStart( nTab );
1173 	long nTabStart = pPrintFuncCache->GetTabStart( nTab );
1174 
1175     vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
1176     if ( nRenderer == nTabStart )
1177     {
1178         // first page of a sheet: add outline item for the sheet name
1179 
1180         if ( pPDFData && pPDFData->GetIsExportBookmarks() )
1181         {
1182             // the sheet starts at the top of the page
1183             Rectangle aArea( pDev->PixelToLogic( Rectangle( 0,0,0,0 ) ) );
1184             sal_Int32 nDestID = pPDFData->CreateDest( aArea );
1185             String aTabName;
1186             pDoc->GetName( nTab, aTabName );
1187             sal_Int32 nParent = -1;     // top-level
1188             pPDFData->CreateOutlineItem( nParent, aTabName, nDestID );
1189         }
1190         //--->i56629
1191         // add the named destination stuff
1192         if( pPDFData && pPDFData->GetIsExportNamedDestinations() )
1193         {
1194             Rectangle aArea( pDev->PixelToLogic( Rectangle( 0,0,0,0 ) ) );
1195             String aTabName;
1196             pDoc->GetName( nTab, aTabName );
1197 //need the PDF page number here
1198             pPDFData->CreateNamedDest( aTabName, aArea );
1199         }
1200         //<---i56629
1201     }
1202 
1203     (void)aFunc.DoPrint( aPage, nTabStart, nDisplayStart, sal_True, NULL );
1204 
1205     //  resolve the hyperlinks for PDF export
1206 
1207     if ( pPDFData )
1208     {
1209         //  iterate over the hyperlinks that were output for this page
1210 
1211         std::vector< vcl::PDFExtOutDevBookmarkEntry >& rBookmarks = pPDFData->GetBookmarks();
1212         std::vector< vcl::PDFExtOutDevBookmarkEntry >::iterator aIter = rBookmarks.begin();
1213         std::vector< vcl::PDFExtOutDevBookmarkEntry >::iterator aIEnd = rBookmarks.end();
1214         while ( aIter != aIEnd )
1215         {
1216             rtl::OUString aBookmark = aIter->aBookmark;
1217             if ( aBookmark.toChar() == (sal_Unicode) '#' )
1218             {
1219                 //  try to resolve internal link
1220 
1221                 String aTarget( aBookmark.copy( 1 ) );
1222 
1223                 ScRange aTargetRange;
1224                 Rectangle aTargetRect;      // 1/100th mm
1225                 bool bIsSheet = false;
1226                 bool bValid = lcl_ParseTarget( aTarget, aTargetRange, aTargetRect, bIsSheet, pDoc, nTab );
1227 
1228                 if ( bValid )
1229                 {
1230                     sal_Int32 nPage = -1;
1231                     Rectangle aArea;
1232                     if ( bIsSheet )
1233                     {
1234                         //  Get first page for sheet (if nothing from that sheet is printed,
1235                         //  this page can show a different sheet)
1236                         nPage = pPrintFuncCache->GetTabStart( aTargetRange.aStart.Tab() );
1237                         aArea = pDev->PixelToLogic( Rectangle( 0,0,0,0 ) );
1238                     }
1239                     else
1240                     {
1241                         pPrintFuncCache->InitLocations( aMark, pDev );      // does nothing if already initialized
1242 
1243                         ScPrintPageLocation aLocation;
1244                         if ( pPrintFuncCache->FindLocation( aTargetRange.aStart, aLocation ) )
1245                         {
1246                             nPage = aLocation.nPage;
1247 
1248                             // get the rectangle of the page's cell range in 1/100th mm
1249                             ScRange aLocRange = aLocation.aCellRange;
1250                             Rectangle aLocationMM = pDoc->GetMMRect(
1251                                        aLocRange.aStart.Col(), aLocRange.aStart.Row(),
1252                                        aLocRange.aEnd.Col(),   aLocRange.aEnd.Row(),
1253                                        aLocRange.aStart.Tab() );
1254                             Rectangle aLocationPixel = aLocation.aRectangle;
1255 
1256                             // Scale and move the target rectangle from aLocationMM to aLocationPixel,
1257                             // to get the target rectangle in pixels.
1258 
1259                             Fraction aScaleX( aLocationPixel.GetWidth(), aLocationMM.GetWidth() );
1260                             Fraction aScaleY( aLocationPixel.GetHeight(), aLocationMM.GetHeight() );
1261 
1262                             long nX1 = aLocationPixel.Left() + (long)
1263                                 ( Fraction( aTargetRect.Left() - aLocationMM.Left(), 1 ) * aScaleX );
1264                             long nX2 = aLocationPixel.Left() + (long)
1265                                 ( Fraction( aTargetRect.Right() - aLocationMM.Left(), 1 ) * aScaleX );
1266                             long nY1 = aLocationPixel.Top() + (long)
1267                                 ( Fraction( aTargetRect.Top() - aLocationMM.Top(), 1 ) * aScaleY );
1268                             long nY2 = aLocationPixel.Top() + (long)
1269                                 ( Fraction( aTargetRect.Bottom() - aLocationMM.Top(), 1 ) * aScaleY );
1270 
1271                             if ( nX1 > aLocationPixel.Right() ) nX1 = aLocationPixel.Right();
1272                             if ( nX2 > aLocationPixel.Right() ) nX2 = aLocationPixel.Right();
1273                             if ( nY1 > aLocationPixel.Bottom() ) nY1 = aLocationPixel.Bottom();
1274                             if ( nY2 > aLocationPixel.Bottom() ) nY2 = aLocationPixel.Bottom();
1275 
1276                             // The link target area is interpreted using the device's MapMode at
1277                             // the time of the CreateDest call, so PixelToLogic can be used here,
1278                             // regardless of the MapMode that is actually selected.
1279 
1280                             aArea = pDev->PixelToLogic( Rectangle( nX1, nY1, nX2, nY2 ) );
1281                         }
1282                     }
1283 
1284                     if ( nPage >= 0 )
1285                     {
1286                         if ( aIter->nLinkId != -1 )
1287                             pPDFData->SetLinkDest( aIter->nLinkId, pPDFData->CreateDest( aArea, nPage ) );
1288                         else
1289                             pPDFData->DescribeRegisteredDest( aIter->nDestId, aArea, nPage );
1290                     }
1291                 }
1292             }
1293             else
1294             {
1295                 //  external link, use as-is
1296                 pPDFData->SetLinkURL( aIter->nLinkId, aBookmark );
1297             }
1298             aIter++;
1299         }
1300         rBookmarks.clear();
1301     }
1302 
1303 	if ( pDrawView )
1304 		pDrawView->HideSdrPage();
1305 	delete pDrawView;
1306 }
1307 
1308 // XLinkTargetSupplier
1309 
1310 uno::Reference<container::XNameAccess> SAL_CALL ScModelObj::getLinks() throw(uno::RuntimeException)
1311 {
1312 	ScUnoGuard aGuard;
1313 	if (pDocShell)
1314 		return new ScLinkTargetTypesObj(pDocShell);
1315 	return NULL;
1316 }
1317 
1318 // XActionLockable
1319 
1320 sal_Bool SAL_CALL ScModelObj::isActionLocked() throw(uno::RuntimeException)
1321 {
1322 	ScUnoGuard aGuard;
1323 	sal_Bool bLocked = sal_False;
1324 	if (pDocShell)
1325 		bLocked = ( pDocShell->GetLockCount() != 0 );
1326 	return bLocked;
1327 }
1328 
1329 void SAL_CALL ScModelObj::addActionLock() throw(uno::RuntimeException)
1330 {
1331 	ScUnoGuard aGuard;
1332 	if (pDocShell)
1333 		pDocShell->LockDocument();
1334 }
1335 
1336 void SAL_CALL ScModelObj::removeActionLock() throw(uno::RuntimeException)
1337 {
1338 	ScUnoGuard aGuard;
1339 	if (pDocShell)
1340 		pDocShell->UnlockDocument();
1341 }
1342 
1343 void SAL_CALL ScModelObj::setActionLocks( sal_Int16 nLock ) throw(uno::RuntimeException)
1344 {
1345 	ScUnoGuard aGuard;
1346 	if (pDocShell)
1347 		pDocShell->SetLockCount(nLock);
1348 }
1349 
1350 sal_Int16 SAL_CALL ScModelObj::resetActionLocks() throw(uno::RuntimeException)
1351 {
1352 	ScUnoGuard aGuard;
1353 	sal_uInt16 nRet = 0;
1354 	if (pDocShell)
1355 	{
1356 		nRet = pDocShell->GetLockCount();
1357 		pDocShell->SetLockCount(0);
1358 	}
1359 	return nRet;
1360 }
1361 
1362 void SAL_CALL ScModelObj::lockControllers() throw (::com::sun::star::uno::RuntimeException)
1363 {
1364 	ScUnoGuard aGuard;
1365 	SfxBaseModel::lockControllers();
1366 	if (pDocShell)
1367 		pDocShell->LockPaint();
1368 }
1369 
1370 void SAL_CALL ScModelObj::unlockControllers() throw (::com::sun::star::uno::RuntimeException)
1371 {
1372 	ScUnoGuard aGuard;
1373 	if (hasControllersLocked())
1374 	{
1375 		SfxBaseModel::unlockControllers();
1376 		if (pDocShell)
1377 			pDocShell->UnlockPaint();
1378 	}
1379 }
1380 
1381 // XCalculate
1382 
1383 void SAL_CALL ScModelObj::calculate() throw(uno::RuntimeException)
1384 {
1385 	ScUnoGuard aGuard;
1386 	if (pDocShell)
1387 		pDocShell->DoRecalc(sal_True);
1388 	else
1389 	{
1390 		DBG_ERROR("keine DocShell");		//! Exception oder so?
1391 	}
1392 }
1393 
1394 void SAL_CALL ScModelObj::calculateAll() throw(uno::RuntimeException)
1395 {
1396 	ScUnoGuard aGuard;
1397 	if (pDocShell)
1398 		pDocShell->DoHardRecalc(sal_True);
1399 	else
1400 	{
1401 		DBG_ERROR("keine DocShell");		//! Exception oder so?
1402 	}
1403 }
1404 
1405 sal_Bool SAL_CALL ScModelObj::isAutomaticCalculationEnabled() throw(uno::RuntimeException)
1406 {
1407 	ScUnoGuard aGuard;
1408 	if (pDocShell)
1409 		return pDocShell->GetDocument()->GetAutoCalc();
1410 
1411 	DBG_ERROR("keine DocShell");		//! Exception oder so?
1412 	return sal_False;
1413 }
1414 
1415 void SAL_CALL ScModelObj::enableAutomaticCalculation( sal_Bool bEnabled )
1416 												throw(uno::RuntimeException)
1417 {
1418 	ScUnoGuard aGuard;
1419 	if (pDocShell)
1420 	{
1421 		ScDocument* pDoc = pDocShell->GetDocument();
1422 		if ( pDoc->GetAutoCalc() != bEnabled )
1423 		{
1424 			pDoc->SetAutoCalc( bEnabled );
1425 			pDocShell->SetDocumentModified();
1426 		}
1427 	}
1428 	else
1429 	{
1430 		DBG_ERROR("keine DocShell");		//! Exception oder so?
1431 	}
1432 }
1433 
1434 // XProtectable
1435 
1436 void SAL_CALL ScModelObj::protect( const rtl::OUString& aPassword ) throw(uno::RuntimeException)
1437 {
1438 	ScUnoGuard aGuard;
1439     // #i108245# if already protected, don't change anything
1440     if ( pDocShell && !pDocShell->GetDocument()->IsDocProtected() )
1441 	{
1442 		String aString(aPassword);
1443 
1444 		ScDocFunc aFunc(*pDocShell);
1445 		aFunc.Protect( TABLEID_DOC, aString, sal_True );
1446 	}
1447 }
1448 
1449 void SAL_CALL ScModelObj::unprotect( const rtl::OUString& aPassword )
1450 						throw(lang::IllegalArgumentException, uno::RuntimeException)
1451 {
1452 	ScUnoGuard aGuard;
1453 	if (pDocShell)
1454 	{
1455 		String aString(aPassword);
1456 
1457 		ScDocFunc aFunc(*pDocShell);
1458         sal_Bool bDone = aFunc.Unprotect( TABLEID_DOC, aString, sal_True );
1459         if (!bDone)
1460             throw lang::IllegalArgumentException();
1461 	}
1462 }
1463 
1464 sal_Bool SAL_CALL ScModelObj::isProtected() throw(uno::RuntimeException)
1465 {
1466 	ScUnoGuard aGuard;
1467 	if (pDocShell)
1468 		return pDocShell->GetDocument()->IsDocProtected();
1469 
1470 	DBG_ERROR("keine DocShell");		//! Exception oder so?
1471 	return sal_False;
1472 }
1473 
1474 // XDrawPagesSupplier
1475 
1476 uno::Reference<drawing::XDrawPages> SAL_CALL ScModelObj::getDrawPages() throw(uno::RuntimeException)
1477 {
1478 	ScUnoGuard aGuard;
1479 	if (pDocShell)
1480 		return new ScDrawPagesObj(pDocShell);
1481 
1482 	DBG_ERROR("keine DocShell");		//! Exception oder so?
1483 	return NULL;
1484 }
1485 
1486 #if 0
1487 // XPrintable
1488 
1489 rtl::OUString ScModelObj::getPrinterName(void) const
1490 {
1491 	ScUnoGuard aGuard;
1492 	if (pDocShell)
1493 	{
1494 		SfxPrinter* pPrinter = pDocShell->GetPrinter();
1495 		if (pPrinter)
1496 			return pPrinter->GetName();
1497 	}
1498 
1499 	DBG_ERROR("getPrinterName: keine DocShell oder kein Printer");
1500 	return rtl::OUString();
1501 }
1502 
1503 void ScModelObj::setPrinterName(const rtl::OUString& PrinterName)
1504 {
1505 	ScUnoGuard aGuard;
1506 	//	Drucker setzen - wie in SfxViewShell::ExecPrint_Impl
1507 
1508 	if (pDocShell)
1509 	{
1510 		SfxPrinter* pPrinter = pDocShell->GetPrinter();
1511 		if (pPrinter)
1512 		{
1513 			String aString(PrinterName);
1514 			SfxPrinter* pNewPrinter = new SfxPrinter( pPrinter->GetOptions().Clone(), aString );
1515 			if (pNewPrinter->IsKnown())
1516 				pDocShell->SetPrinter( pNewPrinter, SFX_PRINTER_PRINTER );
1517 			else
1518 				delete pNewPrinter;
1519 		}
1520 	}
1521 }
1522 
1523 XPropertySetRef ScModelObj::createPrintOptions(void)
1524 {
1525 	ScUnoGuard aGuard;
1526 	return new ScPrintSettingsObj;		//! ScPrintSettingsObj implementieren!
1527 }
1528 
1529 void ScModelObj::print(const XPropertySetRef& xOptions)
1530 {
1531 	ScUnoGuard aGuard;
1532 	if (pDocShell)
1533 	{
1534 		//!	xOptions auswerten (wie denn?)
1535 
1536 		//!	muss noch
1537 	}
1538 }
1539 #endif
1540 
1541 // XGoalSeek
1542 
1543 sheet::GoalResult SAL_CALL ScModelObj::seekGoal(
1544 								const table::CellAddress& aFormulaPosition,
1545 								const table::CellAddress& aVariablePosition,
1546 								const ::rtl::OUString& aGoalValue )
1547 									throw(uno::RuntimeException)
1548 {
1549 	ScUnoGuard aGuard;
1550 	sheet::GoalResult aResult;
1551 	aResult.Divergence = DBL_MAX;		// nichts gefunden
1552 	if (pDocShell)
1553 	{
1554 		WaitObject aWait( pDocShell->GetActiveDialogParent() );
1555 		String aGoalString(aGoalValue);
1556 		ScDocument* pDoc = pDocShell->GetDocument();
1557 		double fValue = 0.0;
1558 		sal_Bool bFound = pDoc->Solver(
1559 					(SCCOL)aFormulaPosition.Column, (SCROW)aFormulaPosition.Row, aFormulaPosition.Sheet,
1560 					(SCCOL)aVariablePosition.Column, (SCROW)aVariablePosition.Row, aVariablePosition.Sheet,
1561 					aGoalString, fValue );
1562 		aResult.Result = fValue;
1563 		if (bFound)
1564 			aResult.Divergence = 0.0;	//! das ist gelogen
1565 	}
1566 	return aResult;
1567 }
1568 
1569 // XConsolidatable
1570 
1571 uno::Reference<sheet::XConsolidationDescriptor> SAL_CALL ScModelObj::createConsolidationDescriptor(
1572 								sal_Bool bEmpty ) throw(uno::RuntimeException)
1573 {
1574 	ScUnoGuard aGuard;
1575 	ScConsolidationDescriptor* pNew = new ScConsolidationDescriptor;
1576 	if ( pDocShell && !bEmpty )
1577 	{
1578 		ScDocument* pDoc = pDocShell->GetDocument();
1579 		const ScConsolidateParam* pParam = pDoc->GetConsolidateDlgData();
1580 		if (pParam)
1581 			pNew->SetParam( *pParam );
1582 	}
1583 	return pNew;
1584 }
1585 
1586 void SAL_CALL ScModelObj::consolidate(
1587 		const uno::Reference<sheet::XConsolidationDescriptor>& xDescriptor )
1588 												throw(uno::RuntimeException)
1589 {
1590 	ScUnoGuard aGuard;
1591 	//	das koennte theoretisch ein fremdes Objekt sein, also nur das
1592 	//	oeffentliche XConsolidationDescriptor Interface benutzen, um
1593 	//	die Daten in ein ScConsolidationDescriptor Objekt zu kopieren:
1594 	//!	wenn es schon ein ScConsolidationDescriptor ist, direkt per getImplementation?
1595 
1596 	ScConsolidationDescriptor aImpl;
1597 	aImpl.setFunction( xDescriptor->getFunction() );
1598 	aImpl.setSources( xDescriptor->getSources() );
1599 	aImpl.setStartOutputPosition( xDescriptor->getStartOutputPosition() );
1600 	aImpl.setUseColumnHeaders( xDescriptor->getUseColumnHeaders() );
1601 	aImpl.setUseRowHeaders( xDescriptor->getUseRowHeaders() );
1602 	aImpl.setInsertLinks( xDescriptor->getInsertLinks() );
1603 
1604 	if (pDocShell)
1605 	{
1606 		const ScConsolidateParam& rParam = aImpl.GetParam();
1607 		pDocShell->DoConsolidate( rParam, sal_True );
1608 		pDocShell->GetDocument()->SetConsolidateDlgData( &rParam );
1609 	}
1610 }
1611 
1612 // XDocumentAuditing
1613 
1614 void SAL_CALL ScModelObj::refreshArrows() throw(uno::RuntimeException)
1615 {
1616 	ScUnoGuard aGuard;
1617 	if (pDocShell)
1618 	{
1619 		ScDocFunc aFunc(*pDocShell);
1620 		aFunc.DetectiveRefresh();
1621 	}
1622 }
1623 
1624 // XViewDataSupplier
1625 uno::Reference< container::XIndexAccess > SAL_CALL ScModelObj::getViewData(  )
1626     throw (uno::RuntimeException)
1627 {
1628     uno::Reference < container::XIndexAccess > xRet( SfxBaseModel::getViewData() );
1629 
1630     if( !xRet.is() )
1631     {
1632         ScUnoGuard aGuard;
1633         if (pDocShell && pDocShell->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED)
1634         {
1635             xRet.set(uno::Reference < container::XIndexAccess >::query(::comphelper::getProcessServiceFactory()->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.document.IndexedPropertyValues")))));
1636 
1637             uno::Reference < container::XIndexContainer > xCont( xRet, uno::UNO_QUERY );
1638             DBG_ASSERT( xCont.is(), "ScModelObj::getViewData() failed for OLE object" );
1639             if( xCont.is() )
1640             {
1641                 uno::Sequence< beans::PropertyValue > aSeq;
1642                 aSeq.realloc(1);
1643                 String sName;
1644                 pDocShell->GetDocument()->GetName( pDocShell->GetDocument()->GetVisibleTab(), sName );
1645                 rtl::OUString sOUName(sName);
1646                 aSeq[0].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ACTIVETABLE));
1647                 aSeq[0].Value <<= sOUName;
1648                 xCont->insertByIndex( 0, uno::makeAny( aSeq ) );
1649             }
1650         }
1651     }
1652 
1653     return xRet;
1654 }
1655 
1656 //	XPropertySet (Doc-Optionen)
1657 //!	auch an der Applikation anbieten?
1658 
1659 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScModelObj::getPropertySetInfo()
1660 														throw(uno::RuntimeException)
1661 {
1662 	ScUnoGuard aGuard;
1663 	static uno::Reference<beans::XPropertySetInfo> aRef(
1664 		new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
1665 	return aRef;
1666 }
1667 
1668 void SAL_CALL ScModelObj::setPropertyValue(
1669 						const rtl::OUString& aPropertyName, const uno::Any& aValue )
1670 				throw(beans::UnknownPropertyException, beans::PropertyVetoException,
1671 						lang::IllegalArgumentException, lang::WrappedTargetException,
1672 						uno::RuntimeException)
1673 {
1674 	ScUnoGuard aGuard;
1675 	String aString(aPropertyName);
1676 
1677 	if (pDocShell)
1678 	{
1679 		ScDocument* pDoc = pDocShell->GetDocument();
1680 		const ScDocOptions& rOldOpt = pDoc->GetDocOptions();
1681 		ScDocOptions aNewOpt = rOldOpt;
1682 
1683         sal_Bool bOpt = ScDocOptionsHelper::setPropertyValue( aNewOpt, *aPropSet.getPropertyMap(), aPropertyName, aValue );
1684 		if (bOpt)
1685 		{
1686 			// done...
1687 		}
1688 		else if ( aString.EqualsAscii( SC_UNONAME_CLOCAL ) )
1689 		{
1690 			lang::Locale aLocale;
1691 			if ( aValue >>= aLocale )
1692 			{
1693 				LanguageType eLatin, eCjk, eCtl;
1694 				pDoc->GetLanguage( eLatin, eCjk, eCtl );
1695 				eLatin = ScUnoConversion::GetLanguage(aLocale);
1696 				pDoc->SetLanguage( eLatin, eCjk, eCtl );
1697 			}
1698 		}
1699         else if ( aString.EqualsAscii( SC_UNO_CODENAME ) )
1700         {
1701             rtl::OUString sCodeName;
1702             if ( aValue >>= sCodeName )
1703                 pDoc->SetCodeName( sCodeName );
1704         }
1705 		else if ( aString.EqualsAscii( SC_UNO_CJK_CLOCAL ) )
1706 		{
1707 			lang::Locale aLocale;
1708 			if ( aValue >>= aLocale )
1709 			{
1710 				LanguageType eLatin, eCjk, eCtl;
1711 				pDoc->GetLanguage( eLatin, eCjk, eCtl );
1712 				eCjk = ScUnoConversion::GetLanguage(aLocale);
1713 				pDoc->SetLanguage( eLatin, eCjk, eCtl );
1714 			}
1715 		}
1716 		else if ( aString.EqualsAscii( SC_UNO_CTL_CLOCAL ) )
1717 		{
1718 			lang::Locale aLocale;
1719 			if ( aValue >>= aLocale )
1720 			{
1721 				LanguageType eLatin, eCjk, eCtl;
1722 				pDoc->GetLanguage( eLatin, eCjk, eCtl );
1723 				eCtl = ScUnoConversion::GetLanguage(aLocale);
1724 				pDoc->SetLanguage( eLatin, eCjk, eCtl );
1725 			}
1726 		}
1727 		else if ( aString.EqualsAscii( SC_UNO_APPLYFMDES ) )
1728 		{
1729 			//	model is created if not there
1730 			ScDrawLayer* pModel = pDocShell->MakeDrawLayer();
1731 			pModel->SetOpenInDesignMode( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1732 
1733 			SfxBindings* pBindings = pDocShell->GetViewBindings();
1734 			if (pBindings)
1735 				pBindings->Invalidate( SID_FM_OPEN_READONLY );
1736 		}
1737 		else if ( aString.EqualsAscii( SC_UNO_AUTOCONTFOC ) )
1738 		{
1739 			//	model is created if not there
1740 			ScDrawLayer* pModel = pDocShell->MakeDrawLayer();
1741 			pModel->SetAutoControlFocus( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1742 
1743 			SfxBindings* pBindings = pDocShell->GetViewBindings();
1744 			if (pBindings)
1745 				pBindings->Invalidate( SID_FM_AUTOCONTROLFOCUS );
1746 		}
1747         else if ( aString.EqualsAscii( SC_UNO_ISLOADED ) )
1748         {
1749             pDocShell->SetEmpty( !ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1750         }
1751         else if ( aString.EqualsAscii( SC_UNO_ISUNDOENABLED ) )
1752         {
1753             sal_Bool bUndoEnabled = ScUnoHelpFunctions::GetBoolFromAny( aValue );
1754             pDoc->EnableUndo( bUndoEnabled );
1755             sal_uInt16 nCount = ( bUndoEnabled ?
1756                 static_cast< sal_uInt16 >( SvtUndoOptions().GetUndoCount() ) : 0 );
1757             pDocShell->GetUndoManager()->SetMaxUndoActionCount( nCount );
1758         }
1759         else if ( aString.EqualsAscii( SC_UNO_ISADJUSTHEIGHTENABLED ) )
1760         {
1761             bool bOldAdjustHeightEnabled = pDoc->IsAdjustHeightEnabled();
1762             bool bAdjustHeightEnabled = ScUnoHelpFunctions::GetBoolFromAny( aValue );
1763             if( bOldAdjustHeightEnabled != bAdjustHeightEnabled )
1764             {
1765                 pDoc->EnableAdjustHeight( bAdjustHeightEnabled );
1766                 if( bAdjustHeightEnabled )
1767                     pDocShell->UpdateAllRowHeights();
1768             }
1769         }
1770         else if ( aString.EqualsAscii( SC_UNO_ISEXECUTELINKENABLED ) )
1771         {
1772             pDoc->EnableExecuteLink( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1773         }
1774         else if ( aString.EqualsAscii( SC_UNO_ISCHANGEREADONLYENABLED ) )
1775         {
1776             pDoc->EnableChangeReadOnly( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1777         }
1778 		else if ( aString.EqualsAscii( "BuildId" ) )
1779 		{
1780 			aValue >>= maBuildId;
1781 		}
1782         else if ( aString.EqualsAscii( "SavedObject" ) )    // set from chart after saving
1783         {
1784             rtl::OUString aObjName;
1785             aValue >>= aObjName;
1786             if ( aObjName.getLength() )
1787                 pDoc->RestoreChartListener( aObjName );
1788         }
1789 
1790 		if ( aNewOpt != rOldOpt )
1791 		{
1792 			pDoc->SetDocOptions( aNewOpt );
1793             //  Don't recalculate while loading XML, when the formula text is stored.
1794             //  Recalculation after loading is handled separately.
1795             //! Recalc only for options that need it?
1796             if ( !pDoc->IsImportingXML() )
1797                 pDocShell->DoHardRecalc( sal_True );
1798 			pDocShell->SetDocumentModified();
1799 		}
1800 	}
1801 }
1802 
1803 uno::Any SAL_CALL ScModelObj::getPropertyValue( const rtl::OUString& aPropertyName )
1804 				throw(beans::UnknownPropertyException, lang::WrappedTargetException,
1805 						uno::RuntimeException)
1806 {
1807 	ScUnoGuard aGuard;
1808 	String aString(aPropertyName);
1809 	uno::Any aRet;
1810 
1811 	if (pDocShell)
1812 	{
1813 		ScDocument* pDoc = pDocShell->GetDocument();
1814 		const ScDocOptions& rOpt = pDoc->GetDocOptions();
1815         aRet = ScDocOptionsHelper::getPropertyValue( rOpt, *aPropSet.getPropertyMap(), aPropertyName );
1816 		if ( aRet.hasValue() )
1817 		{
1818 			// done...
1819 		}
1820 		else if ( aString.EqualsAscii( SC_UNONAME_CLOCAL ) )
1821 		{
1822 			LanguageType eLatin, eCjk, eCtl;
1823 			pDoc->GetLanguage( eLatin, eCjk, eCtl );
1824 
1825 			lang::Locale aLocale;
1826 			ScUnoConversion::FillLocale( aLocale, eLatin );
1827 			aRet <<= aLocale;
1828 		}
1829         else if ( aString.EqualsAscii( SC_UNO_CODENAME ) )
1830         {
1831             rtl::OUString sCodeName = pDoc->GetCodeName();
1832             aRet <<= sCodeName;
1833         }
1834 
1835 		else if ( aString.EqualsAscii( SC_UNO_CJK_CLOCAL ) )
1836 		{
1837 			LanguageType eLatin, eCjk, eCtl;
1838 			pDoc->GetLanguage( eLatin, eCjk, eCtl );
1839 
1840 			lang::Locale aLocale;
1841 			ScUnoConversion::FillLocale( aLocale, eCjk );
1842 			aRet <<= aLocale;
1843 		}
1844 		else if ( aString.EqualsAscii( SC_UNO_CTL_CLOCAL ) )
1845 		{
1846 			LanguageType eLatin, eCjk, eCtl;
1847 			pDoc->GetLanguage( eLatin, eCjk, eCtl );
1848 
1849 			lang::Locale aLocale;
1850 			ScUnoConversion::FillLocale( aLocale, eCtl );
1851 			aRet <<= aLocale;
1852 		}
1853 		else if ( aString.EqualsAscii( SC_UNO_NAMEDRANGES ) )
1854 		{
1855 			aRet <<= uno::Reference<sheet::XNamedRanges>(new ScNamedRangesObj( pDocShell ));
1856 		}
1857 		else if ( aString.EqualsAscii( SC_UNO_DATABASERNG ) )
1858 		{
1859 			aRet <<= uno::Reference<sheet::XDatabaseRanges>(new ScDatabaseRangesObj( pDocShell ));
1860 		}
1861 		else if ( aString.EqualsAscii( SC_UNO_COLLABELRNG ) )
1862 		{
1863 			aRet <<= uno::Reference<sheet::XLabelRanges>(new ScLabelRangesObj( pDocShell, sal_True ));
1864 		}
1865 		else if ( aString.EqualsAscii( SC_UNO_ROWLABELRNG ) )
1866 		{
1867 			aRet <<= uno::Reference<sheet::XLabelRanges>(new ScLabelRangesObj( pDocShell, sal_False ));
1868 		}
1869 		else if ( aString.EqualsAscii( SC_UNO_AREALINKS ) )
1870 		{
1871 			aRet <<= uno::Reference<sheet::XAreaLinks>(new ScAreaLinksObj( pDocShell ));
1872 		}
1873 		else if ( aString.EqualsAscii( SC_UNO_DDELINKS ) )
1874 		{
1875 			aRet <<= uno::Reference<container::XNameAccess>(new ScDDELinksObj( pDocShell ));
1876 		}
1877         else if ( aString.EqualsAscii( SC_UNO_EXTERNALDOCLINKS ) )
1878         {
1879             aRet <<= uno::Reference<sheet::XExternalDocLinks>(new ScExternalDocLinksObj(pDocShell));
1880         }
1881 		else if ( aString.EqualsAscii( SC_UNO_SHEETLINKS ) )
1882 		{
1883 			aRet <<= uno::Reference<container::XNameAccess>(new ScSheetLinksObj( pDocShell ));
1884 		}
1885 		else if ( aString.EqualsAscii( SC_UNO_APPLYFMDES ) )
1886 		{
1887 			// default for no model is TRUE
1888 			ScDrawLayer* pModel = pDoc->GetDrawLayer();
1889 			sal_Bool bOpenInDesign = pModel ? pModel->GetOpenInDesignMode() : sal_True;
1890 			ScUnoHelpFunctions::SetBoolInAny( aRet, bOpenInDesign );
1891 		}
1892 		else if ( aString.EqualsAscii( SC_UNO_AUTOCONTFOC ) )
1893 		{
1894 			// default for no model is FALSE
1895 			ScDrawLayer* pModel = pDoc->GetDrawLayer();
1896 			sal_Bool bAutoControlFocus = pModel ? pModel->GetAutoControlFocus() : sal_False;
1897 			ScUnoHelpFunctions::SetBoolInAny( aRet, bAutoControlFocus );
1898 		}
1899 		else if ( aString.EqualsAscii( SC_UNO_FORBIDDEN ) )
1900 		{
1901 			aRet <<= uno::Reference<i18n::XForbiddenCharacters>(new ScForbiddenCharsObj( pDocShell ));
1902 		}
1903 		else if ( aString.EqualsAscii( SC_UNO_HASDRAWPAGES ) )
1904 		{
1905 			ScUnoHelpFunctions::SetBoolInAny( aRet, (pDocShell->GetDocument()->GetDrawLayer() != 0) );
1906         }
1907         else if ( aString.EqualsAscii( SC_UNO_BASICLIBRARIES ) )
1908         {
1909             aRet <<= pDocShell->GetBasicContainer();
1910 		}
1911         else if ( aString.EqualsAscii( SC_UNO_DIALOGLIBRARIES ) )
1912         {
1913             aRet <<= pDocShell->GetDialogContainer();
1914         }
1915         else if ( aString.EqualsAscii( SC_UNO_VBAGLOBNAME ) )
1916         {
1917             /*  #i111553# This property provides the name of the constant that
1918                 will be used to store this model in the global Basic manager.
1919                 That constant will be equivelant to 'ThisComponent' but for
1920                 each application, so e.g. a 'ThisExcelDoc' and a 'ThisWordDoc'
1921                 constant can co-exist, as required by VBA. */
1922             aRet <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ThisExcelDoc" ) );
1923         }
1924         else if ( aString.EqualsAscii( SC_UNO_RUNTIMEUID ) )
1925         {
1926             aRet <<= getRuntimeUID();
1927         }
1928         else if ( aString.EqualsAscii( SC_UNO_HASVALIDSIGNATURES ) )
1929         {
1930             aRet <<= hasValidSignatures();
1931         }
1932         else if ( aString.EqualsAscii( SC_UNO_ISLOADED ) )
1933         {
1934             ScUnoHelpFunctions::SetBoolInAny( aRet, !pDocShell->IsEmpty() );
1935         }
1936         else if ( aString.EqualsAscii( SC_UNO_ISUNDOENABLED ) )
1937         {
1938             ScUnoHelpFunctions::SetBoolInAny( aRet, pDoc->IsUndoEnabled() );
1939         }
1940         else if ( aString.EqualsAscii( SC_UNO_ISADJUSTHEIGHTENABLED ) )
1941         {
1942             ScUnoHelpFunctions::SetBoolInAny( aRet, pDoc->IsAdjustHeightEnabled() );
1943         }
1944         else if ( aString.EqualsAscii( SC_UNO_ISEXECUTELINKENABLED ) )
1945         {
1946             ScUnoHelpFunctions::SetBoolInAny( aRet, pDoc->IsExecuteLinkEnabled() );
1947         }
1948         else if ( aString.EqualsAscii( SC_UNO_ISCHANGEREADONLYENABLED ) )
1949         {
1950             ScUnoHelpFunctions::SetBoolInAny( aRet, pDoc->IsChangeReadOnlyEnabled() );
1951         }
1952         else if ( aString.EqualsAscii( SC_UNO_REFERENCEDEVICE ) )
1953         {
1954             VCLXDevice* pXDev = new VCLXDevice();
1955             pXDev->SetOutputDevice( pDoc->GetRefDevice() );
1956             aRet <<= uno::Reference< awt::XDevice >( pXDev );
1957         }
1958         else if ( aString.EqualsAscii( "BuildId" ) )
1959 		{
1960 			aRet <<= maBuildId;
1961 		}
1962         else if ( aString.EqualsAscii( "InternalDocument" ) )
1963         {
1964             ScUnoHelpFunctions::SetBoolInAny( aRet, (pDocShell->GetCreateMode() == SFX_CREATE_MODE_INTERNAL) );
1965         }
1966 	}
1967 
1968 	return aRet;
1969 }
1970 
1971 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScModelObj )
1972 
1973 // XMultiServiceFactory
1974 
1975 uno::Reference<uno::XInterface> SAL_CALL ScModelObj::createInstance(
1976 								const rtl::OUString& aServiceSpecifier )
1977 								throw(uno::Exception, uno::RuntimeException)
1978 {
1979 	ScUnoGuard aGuard;
1980 	uno::Reference<uno::XInterface> xRet;
1981 	String aNameStr(aServiceSpecifier);
1982 	sal_uInt16 nType = ScServiceProvider::GetProviderType(aNameStr);
1983 	if ( nType != SC_SERVICE_INVALID )
1984 	{
1985 		//	drawing layer tables must be kept as long as the model is alive
1986 		//	return stored instance if already set
1987 		switch ( nType )
1988 		{
1989 			case SC_SERVICE_GRADTAB:	xRet.set(xDrawGradTab);	    break;
1990 			case SC_SERVICE_HATCHTAB:	xRet.set(xDrawHatchTab);	break;
1991 			case SC_SERVICE_BITMAPTAB:	xRet.set(xDrawBitmapTab);	break;
1992 			case SC_SERVICE_TRGRADTAB:	xRet.set(xDrawTrGradTab);	break;
1993 			case SC_SERVICE_MARKERTAB:	xRet.set(xDrawMarkerTab);	break;
1994 			case SC_SERVICE_DASHTAB:	xRet.set(xDrawDashTab); 	break;
1995             case SC_SERVICE_CHDATAPROV: xRet.set(xChartDataProv);   break;
1996             case SC_SERVICE_VBAOBJECTPROVIDER: xRet.set(xObjProvider); break;
1997 		}
1998 
1999         // #i64497# If a chart is in a temporary document during clipoard paste,
2000         // there should be no data provider, so that own data is used
2001         bool bCreate =
2002             ! ( nType == SC_SERVICE_CHDATAPROV &&
2003                 ( pDocShell->GetCreateMode() == SFX_CREATE_MODE_INTERNAL ));
2004         // this should never happen, i.e. the temporary document should never be
2005         // loaded, becuase this unlinks the data
2006         OSL_ASSERT( bCreate );
2007 
2008 		if ( !xRet.is() && bCreate )
2009 		{
2010 			xRet.set(ScServiceProvider::MakeInstance( nType, pDocShell ));
2011 
2012 			//	store created instance
2013 			switch ( nType )
2014 			{
2015 				case SC_SERVICE_GRADTAB:	xDrawGradTab.set(xRet); 	break;
2016 				case SC_SERVICE_HATCHTAB:	xDrawHatchTab.set(xRet);	break;
2017 				case SC_SERVICE_BITMAPTAB:	xDrawBitmapTab.set(xRet);	break;
2018 				case SC_SERVICE_TRGRADTAB:	xDrawTrGradTab.set(xRet);	break;
2019 				case SC_SERVICE_MARKERTAB:	xDrawMarkerTab.set(xRet);	break;
2020 				case SC_SERVICE_DASHTAB:	xDrawDashTab.set(xRet); 	break;
2021                 case SC_SERVICE_CHDATAPROV: xChartDataProv.set(xRet);   break;
2022                 case SC_SERVICE_VBAOBJECTPROVIDER: xObjProvider.set(xRet); break;
2023 			}
2024 		}
2025 	}
2026 	else
2027 	{
2028 		//	alles was ich nicht kenn, werf ich der SvxFmMSFactory an den Hals,
2029 		//	da wird dann 'ne Exception geworfen, wenn's nicht passt...
2030 
2031         try
2032 		{
2033 			xRet.set(SvxFmMSFactory::createInstance(aServiceSpecifier));
2034 			// extra block to force deletion of the temporary before ScShapeObj ctor (setDelegator)
2035 		}
2036         catch ( lang::ServiceNotRegisteredException & )
2037         {
2038         }
2039 
2040 		//	#96117# if the drawing factory created a shape, a ScShapeObj has to be used
2041 		//	to support own properties like ImageMap:
2042 
2043 		uno::Reference<drawing::XShape> xShape( xRet, uno::UNO_QUERY );
2044 		if ( xShape.is() )
2045 		{
2046 			xRet.clear();				// for aggregation, xShape must be the object's only ref
2047 			new ScShapeObj( xShape );	// aggregates object and modifies xShape
2048 			xRet.set(xShape);
2049 		}
2050 	}
2051 	return xRet;
2052 }
2053 
2054 uno::Reference<uno::XInterface> SAL_CALL ScModelObj::createInstanceWithArguments(
2055 								const rtl::OUString& ServiceSpecifier,
2056 								const uno::Sequence<uno::Any>& aArgs )
2057 								throw(uno::Exception, uno::RuntimeException)
2058 {
2059 	//!	unterscheiden zwischen eigenen Services und denen vom Drawing-Layer?
2060 
2061 	ScUnoGuard aGuard;
2062 	uno::Reference<uno::XInterface> xInt(createInstance(ServiceSpecifier));
2063 
2064 	if ( aArgs.getLength() )
2065 	{
2066 		//	used only for cell value binding so far - it can be initialized after creating
2067 
2068 		uno::Reference<lang::XInitialization> xInit( xInt, uno::UNO_QUERY );
2069 		if ( xInit.is() )
2070             xInit->initialize( aArgs );
2071 	}
2072 
2073 	return xInt;
2074 }
2075 
2076 uno::Sequence<rtl::OUString> SAL_CALL ScModelObj::getAvailableServiceNames()
2077 												throw(uno::RuntimeException)
2078 {
2079 	ScUnoGuard aGuard;
2080 
2081 	//!	warum sind die Parameter bei concatServiceNames nicht const ???
2082 	//!	return concatServiceNames( ScServiceProvider::GetAllServiceNames(),
2083 	//!							   SvxFmMSFactory::getAvailableServiceNames() );
2084 
2085 	uno::Sequence<rtl::OUString> aMyServices(ScServiceProvider::GetAllServiceNames());
2086 	uno::Sequence<rtl::OUString> aDrawServices(SvxFmMSFactory::getAvailableServiceNames());
2087 
2088 	return concatServiceNames( aMyServices, aDrawServices );
2089 }
2090 
2091 // XServiceInfo
2092 
2093 rtl::OUString SAL_CALL ScModelObj::getImplementationName() throw(uno::RuntimeException)
2094 {
2095 	return rtl::OUString::createFromAscii( "ScModelObj" );
2096 }
2097 
2098 sal_Bool SAL_CALL ScModelObj::supportsService( const rtl::OUString& rServiceName )
2099 													throw(uno::RuntimeException)
2100 {
2101 	String aServiceStr(rServiceName);
2102 	return aServiceStr.EqualsAscii( SCMODELOBJ_SERVICE ) ||
2103 		   aServiceStr.EqualsAscii( SCDOCSETTINGS_SERVICE ) ||
2104 		   aServiceStr.EqualsAscii( SCDOC_SERVICE );
2105 }
2106 
2107 uno::Sequence<rtl::OUString> SAL_CALL ScModelObj::getSupportedServiceNames()
2108 													throw(uno::RuntimeException)
2109 {
2110     uno::Sequence<rtl::OUString> aRet(2);
2111 	rtl::OUString* pArray = aRet.getArray();
2112 	pArray[0] = rtl::OUString::createFromAscii( SCMODELOBJ_SERVICE );
2113 	pArray[1] = rtl::OUString::createFromAscii( SCDOCSETTINGS_SERVICE );
2114 	return aRet;
2115 }
2116 
2117 // XUnoTunnel
2118 
2119 sal_Int64 SAL_CALL ScModelObj::getSomething(
2120 				const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
2121 {
2122 	if ( rId.getLength() == 16 &&
2123           0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
2124 									rId.getConstArray(), 16 ) )
2125 	{
2126         return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
2127 	}
2128 
2129     if ( rId.getLength() == 16 &&
2130         0 == rtl_compareMemory( SfxObjectShell::getUnoTunnelId().getConstArray(),
2131                                     rId.getConstArray(), 16 ) )
2132     {
2133         return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(pDocShell ));
2134     }
2135 
2136 	//	aggregated number formats supplier has XUnoTunnel, too
2137 	//	interface from aggregated object must be obtained via queryAggregation
2138 
2139 	sal_Int64 nRet = SfxBaseModel::getSomething( rId );
2140 	if ( nRet )
2141 		return nRet;
2142 
2143 	if ( GetFormatter().is() )
2144 	{
2145 		const uno::Type& rTunnelType = ::getCppuType((uno::Reference<lang::XUnoTunnel>*) 0);
2146 		uno::Any aNumTunnel(xNumberAgg->queryAggregation(rTunnelType));
2147 		if(aNumTunnel.getValueType() == rTunnelType)
2148 		{
2149 			uno::Reference<lang::XUnoTunnel> xTunnelAgg(
2150 				*(uno::Reference<lang::XUnoTunnel>*)aNumTunnel.getValue());
2151 			return xTunnelAgg->getSomething( rId );
2152 		}
2153 	}
2154 
2155 	return 0;
2156 }
2157 
2158 // static
2159 const uno::Sequence<sal_Int8>& ScModelObj::getUnoTunnelId()
2160 {
2161 	static uno::Sequence<sal_Int8> * pSeq = 0;
2162 	if( !pSeq )
2163 	{
2164 		osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
2165 		if( !pSeq )
2166 		{
2167 			static uno::Sequence< sal_Int8 > aSeq( 16 );
2168 			rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
2169 			pSeq = &aSeq;
2170 		}
2171 	}
2172 	return *pSeq;
2173 }
2174 
2175 // static
2176 ScModelObj* ScModelObj::getImplementation( const uno::Reference<uno::XInterface> xObj )
2177 {
2178 	ScModelObj* pRet = NULL;
2179 	uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
2180 	if (xUT.is())
2181         pRet = reinterpret_cast<ScModelObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
2182 	return pRet;
2183 }
2184 
2185 // XChangesNotifier
2186 
2187 void ScModelObj::addChangesListener( const uno::Reference< util::XChangesListener >& aListener )
2188     throw (uno::RuntimeException)
2189 {
2190     ScUnoGuard aGuard;
2191     maChangesListeners.addInterface( aListener );
2192 }
2193 
2194 void ScModelObj::removeChangesListener( const uno::Reference< util::XChangesListener >& aListener )
2195     throw (uno::RuntimeException)
2196 {
2197     ScUnoGuard aGuard;
2198     maChangesListeners.removeInterface( aListener );
2199 }
2200 
2201 bool ScModelObj::HasChangesListeners() const
2202 {
2203     if ( maChangesListeners.getLength() > 0 )
2204         return true;
2205 
2206     // "change" event set in any sheet?
2207     return pDocShell && pDocShell->GetDocument()->HasAnySheetEventScript(SC_SHEETEVENT_CHANGE);
2208 }
2209 
2210 void ScModelObj::NotifyChanges( const ::rtl::OUString& rOperation, const ScRangeList& rRanges,
2211     const uno::Sequence< beans::PropertyValue >& rProperties )
2212 {
2213     if ( pDocShell && HasChangesListeners() )
2214     {
2215         util::ChangesEvent aEvent;
2216         aEvent.Source.set( static_cast< cppu::OWeakObject* >( this ) );
2217         aEvent.Base <<= aEvent.Source;
2218 
2219         sal_uLong nRangeCount = rRanges.Count();
2220         aEvent.Changes.realloc( static_cast< sal_Int32 >( nRangeCount ) );
2221         for ( sal_uLong nIndex = 0; nIndex < nRangeCount; ++nIndex )
2222         {
2223             uno::Reference< table::XCellRange > xRangeObj;
2224 
2225             ScRange aRange( *rRanges.GetObject( nIndex ) );
2226             if ( aRange.aStart == aRange.aEnd )
2227             {
2228                 xRangeObj.set( new ScCellObj( pDocShell, aRange.aStart ) );
2229             }
2230             else
2231             {
2232                 xRangeObj.set( new ScCellRangeObj( pDocShell, aRange ) );
2233             }
2234 
2235             util::ElementChange& rChange = aEvent.Changes[ static_cast< sal_Int32 >( nIndex ) ];
2236             rChange.Accessor <<= rOperation;
2237             rChange.Element <<= rProperties;
2238             rChange.ReplacedElement <<= xRangeObj;
2239         }
2240 
2241         ::cppu::OInterfaceIteratorHelper aIter( maChangesListeners );
2242         while ( aIter.hasMoreElements() )
2243         {
2244             try
2245             {
2246         		static_cast< util::XChangesListener* >( aIter.next() )->changesOccurred( aEvent );
2247             }
2248             catch( uno::Exception& )
2249             {
2250             }
2251         }
2252     }
2253 
2254     // handle sheet events
2255     //! separate method with ScMarkData? Then change HasChangesListeners back.
2256     if ( rOperation.compareToAscii("cell-change") == 0 && pDocShell )
2257     {
2258         ScMarkData aMarkData;
2259         aMarkData.MarkFromRangeList( rRanges, sal_False );
2260         ScDocument* pDoc = pDocShell->GetDocument();
2261         SCTAB nTabCount = pDoc->GetTableCount();
2262         for (SCTAB nTab = 0; nTab < nTabCount; nTab++)
2263             if (aMarkData.GetTableSelect(nTab))
2264             {
2265                 const ScSheetEvents* pEvents = pDoc->GetSheetEvents(nTab);
2266                 if (pEvents)
2267                 {
2268                     const rtl::OUString* pScript = pEvents->GetScript(SC_SHEETEVENT_CHANGE);
2269                     if (pScript)
2270                     {
2271                         ScRangeList aTabRanges;     // collect ranges on this sheet
2272                         sal_uLong nRangeCount = rRanges.Count();
2273                         for ( sal_uLong nIndex = 0; nIndex < nRangeCount; ++nIndex )
2274                         {
2275                             ScRange aRange( *rRanges.GetObject( nIndex ) );
2276                             if ( aRange.aStart.Tab() == nTab )
2277                                 aTabRanges.Append( aRange );
2278                         }
2279                         sal_uLong nTabRangeCount = aTabRanges.Count();
2280                         if ( nTabRangeCount > 0 )
2281                         {
2282                             uno::Reference<uno::XInterface> xTarget;
2283                             if ( nTabRangeCount == 1 )
2284                             {
2285                                 ScRange aRange( *aTabRanges.GetObject( 0 ) );
2286                                 if ( aRange.aStart == aRange.aEnd )
2287                                     xTarget.set( static_cast<cppu::OWeakObject*>( new ScCellObj( pDocShell, aRange.aStart ) ) );
2288                                 else
2289                                     xTarget.set( static_cast<cppu::OWeakObject*>( new ScCellRangeObj( pDocShell, aRange ) ) );
2290                             }
2291                             else
2292                                 xTarget.set( static_cast<cppu::OWeakObject*>( new ScCellRangesObj( pDocShell, aTabRanges ) ) );
2293 
2294                             uno::Sequence<uno::Any> aParams(1);
2295                             aParams[0] <<= xTarget;
2296 
2297                             uno::Any aRet;
2298                             uno::Sequence<sal_Int16> aOutArgsIndex;
2299                             uno::Sequence<uno::Any> aOutArgs;
2300 
2301                             /*ErrCode eRet =*/ pDocShell->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs );
2302                         }
2303                     }
2304                 }
2305             }
2306     }
2307 }
2308 
2309 void ScModelObj::HandleCalculateEvents()
2310 {
2311     if (pDocShell)
2312     {
2313         ScDocument* pDoc = pDocShell->GetDocument();
2314         // don't call events before the document is visible
2315         // (might also set a flag on SFX_EVENT_LOADFINISHED and only disable while loading)
2316         if ( pDoc->IsDocVisible() )
2317         {
2318             SCTAB nTabCount = pDoc->GetTableCount();
2319             for (SCTAB nTab = 0; nTab < nTabCount; nTab++)
2320             {
2321                 if (pDoc->HasCalcNotification(nTab))
2322                 {
2323                     if (const ScSheetEvents* pEvents = pDoc->GetSheetEvents( nTab ))
2324                     {
2325                         if (const rtl::OUString* pScript = pEvents->GetScript(SC_SHEETEVENT_CALCULATE))
2326                         {
2327                             uno::Any aRet;
2328                             uno::Sequence<uno::Any> aParams;
2329                             uno::Sequence<sal_Int16> aOutArgsIndex;
2330                             uno::Sequence<uno::Any> aOutArgs;
2331                             pDocShell->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs );
2332                         }
2333                     }
2334 
2335                     try
2336                     {
2337                         uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( pDoc->GetVbaEventProcessor(), uno::UNO_SET_THROW );
2338                         uno::Sequence< uno::Any > aArgs( 1 );
2339                         aArgs[ 0 ] <<= nTab;
2340                         xVbaEvents->processVbaEvent( ScSheetEvents::GetVbaSheetEventId( SC_SHEETEVENT_CALCULATE ), aArgs );
2341                     }
2342                     catch( uno::Exception& )
2343                     {
2344                     }
2345                 }
2346             }
2347         }
2348         pDoc->ResetCalcNotifications();
2349     }
2350 }
2351 
2352 //------------------------------------------------------------------------
2353 
2354 ScDrawPagesObj::ScDrawPagesObj(ScDocShell* pDocSh) :
2355 	pDocShell( pDocSh )
2356 {
2357 	pDocShell->GetDocument()->AddUnoObject(*this);
2358 }
2359 
2360 ScDrawPagesObj::~ScDrawPagesObj()
2361 {
2362 	if (pDocShell)
2363 		pDocShell->GetDocument()->RemoveUnoObject(*this);
2364 }
2365 
2366 void ScDrawPagesObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
2367 {
2368 	//	Referenz-Update interessiert hier nicht
2369 
2370 	if ( rHint.ISA( SfxSimpleHint ) &&
2371 			((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
2372 	{
2373 		pDocShell = NULL;		// ungueltig geworden
2374 	}
2375 }
2376 
2377 uno::Reference<drawing::XDrawPage> ScDrawPagesObj::GetObjectByIndex_Impl(sal_Int32 nIndex) const
2378 {
2379 	if (pDocShell)
2380 	{
2381 		ScDrawLayer* pDrawLayer = pDocShell->MakeDrawLayer();
2382 		DBG_ASSERT(pDrawLayer,"kann Draw-Layer nicht anlegen");
2383 		if ( pDrawLayer && nIndex >= 0 && nIndex < pDocShell->GetDocument()->GetTableCount() )
2384 		{
2385 			SdrPage* pPage = pDrawLayer->GetPage((sal_uInt16)nIndex);
2386 			DBG_ASSERT(pPage,"Draw-Page nicht gefunden");
2387 			if (pPage)
2388 			{
2389 				return uno::Reference<drawing::XDrawPage> (pPage->getUnoPage(), uno::UNO_QUERY);
2390 			}
2391 		}
2392 	}
2393 	return NULL;
2394 }
2395 
2396 // XDrawPages
2397 
2398 uno::Reference<drawing::XDrawPage> SAL_CALL ScDrawPagesObj::insertNewByIndex( sal_Int32 nPos )
2399 											throw(uno::RuntimeException)
2400 {
2401 	ScUnoGuard aGuard;
2402 	uno::Reference<drawing::XDrawPage> xRet;
2403 	if (pDocShell)
2404 	{
2405 		String aNewName;
2406 		pDocShell->GetDocument()->CreateValidTabName(aNewName);
2407 		ScDocFunc aFunc(*pDocShell);
2408 		if ( aFunc.InsertTable( (SCTAB)nPos, aNewName, sal_True, sal_True ) )
2409 			xRet.set(GetObjectByIndex_Impl( nPos ));
2410 	}
2411 	return xRet;
2412 }
2413 
2414 void SAL_CALL ScDrawPagesObj::remove( const uno::Reference<drawing::XDrawPage>& xPage )
2415 											throw(uno::RuntimeException)
2416 {
2417 	ScUnoGuard aGuard;
2418 	SvxDrawPage* pImp = SvxDrawPage::getImplementation( xPage );
2419 	if ( pDocShell && pImp )
2420 	{
2421 		SdrPage* pPage = pImp->GetSdrPage();
2422 		if (pPage)
2423 		{
2424 			SCTAB nPageNum = static_cast<SCTAB>(pPage->GetPageNum());
2425 			ScDocFunc aFunc(*pDocShell);
2426 			aFunc.DeleteTable( nPageNum, sal_True, sal_True );
2427 		}
2428 	}
2429 }
2430 
2431 // XIndexAccess
2432 
2433 sal_Int32 SAL_CALL ScDrawPagesObj::getCount() throw(uno::RuntimeException)
2434 {
2435 	ScUnoGuard aGuard;
2436 	if (pDocShell)
2437 		return pDocShell->GetDocument()->GetTableCount();
2438 	return 0;
2439 }
2440 
2441 uno::Any SAL_CALL ScDrawPagesObj::getByIndex( sal_Int32 nIndex )
2442 							throw(lang::IndexOutOfBoundsException,
2443 									lang::WrappedTargetException, uno::RuntimeException)
2444 {
2445 	ScUnoGuard aGuard;
2446 	uno::Reference<drawing::XDrawPage> xPage(GetObjectByIndex_Impl(nIndex));
2447 	if (xPage.is())
2448         return uno::makeAny(xPage);
2449 	else
2450 		throw lang::IndexOutOfBoundsException();
2451 //    return uno::Any();
2452 }
2453 
2454 uno::Type SAL_CALL ScDrawPagesObj::getElementType() throw(uno::RuntimeException)
2455 {
2456 	ScUnoGuard aGuard;
2457 	return getCppuType((uno::Reference<drawing::XDrawPage>*)0);
2458 }
2459 
2460 sal_Bool SAL_CALL ScDrawPagesObj::hasElements() throw(uno::RuntimeException)
2461 {
2462 	ScUnoGuard aGuard;
2463 	return ( getCount() != 0 );
2464 }
2465 
2466 //------------------------------------------------------------------------
2467 
2468 ScTableSheetsObj::ScTableSheetsObj(ScDocShell* pDocSh) :
2469 	pDocShell( pDocSh )
2470 {
2471 	pDocShell->GetDocument()->AddUnoObject(*this);
2472 }
2473 
2474 ScTableSheetsObj::~ScTableSheetsObj()
2475 {
2476 	if (pDocShell)
2477 		pDocShell->GetDocument()->RemoveUnoObject(*this);
2478 }
2479 
2480 void ScTableSheetsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
2481 {
2482 	//	Referenz-Update interessiert hier nicht
2483 
2484 	if ( rHint.ISA( SfxSimpleHint ) &&
2485 			((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
2486 	{
2487 		pDocShell = NULL;		// ungueltig geworden
2488 	}
2489 }
2490 
2491 // XSpreadsheets
2492 
2493 ScTableSheetObj* ScTableSheetsObj::GetObjectByIndex_Impl(sal_Int32 nIndex) const
2494 {
2495 	if ( pDocShell && nIndex >= 0 && nIndex < pDocShell->GetDocument()->GetTableCount() )
2496 		return new ScTableSheetObj( pDocShell, static_cast<SCTAB>(nIndex) );
2497 
2498 	return NULL;
2499 }
2500 
2501 ScTableSheetObj* ScTableSheetsObj::GetObjectByName_Impl(const rtl::OUString& aName) const
2502 {
2503 	if (pDocShell)
2504 	{
2505 		SCTAB nIndex;
2506 		String aString(aName);
2507 		if ( pDocShell->GetDocument()->GetTable( aString, nIndex ) )
2508 			return new ScTableSheetObj( pDocShell, nIndex );
2509 	}
2510 	return NULL;
2511 }
2512 
2513 void SAL_CALL ScTableSheetsObj::insertNewByName( const rtl::OUString& aName, sal_Int16 nPosition )
2514 												throw(uno::RuntimeException)
2515 {
2516 	ScUnoGuard aGuard;
2517 	sal_Bool bDone = sal_False;
2518 	if (pDocShell)
2519 	{
2520 		String aNamStr(aName);
2521 		ScDocFunc aFunc(*pDocShell);
2522 		bDone = aFunc.InsertTable( nPosition, aNamStr, sal_True, sal_True );
2523 	}
2524 	if (!bDone)
2525 		throw uno::RuntimeException();		// no other exceptions specified
2526 }
2527 
2528 void SAL_CALL ScTableSheetsObj::moveByName( const rtl::OUString& aName, sal_Int16 nDestination )
2529 											throw(uno::RuntimeException)
2530 {
2531 	ScUnoGuard aGuard;
2532 	sal_Bool bDone = sal_False;
2533 	if (pDocShell)
2534 	{
2535 		String aNamStr(aName);
2536 		SCTAB nSource;
2537 		if ( pDocShell->GetDocument()->GetTable( aNamStr, nSource ) )
2538 			bDone = pDocShell->MoveTable( nSource, nDestination, sal_False, sal_True );
2539 	}
2540 	if (!bDone)
2541 		throw uno::RuntimeException();		// no other exceptions specified
2542 }
2543 
2544 void SAL_CALL ScTableSheetsObj::copyByName( const rtl::OUString& aName,
2545 								const rtl::OUString& aCopy, sal_Int16 nDestination )
2546 												throw(uno::RuntimeException)
2547 {
2548 	ScUnoGuard aGuard;
2549 	sal_Bool bDone = sal_False;
2550 	if (pDocShell)
2551 	{
2552 		String aNamStr(aName);
2553 		String aNewStr(aCopy);
2554 		SCTAB nSource;
2555 		if ( pDocShell->GetDocument()->GetTable( aNamStr, nSource ) )
2556 		{
2557 			bDone = pDocShell->MoveTable( nSource, nDestination, sal_True, sal_True );
2558 			if (bDone)
2559 			{
2560                 // #i92477# any index past the last sheet means "append" in MoveTable
2561                 SCTAB nResultTab = static_cast<SCTAB>(nDestination);
2562                 SCTAB nTabCount = pDocShell->GetDocument()->GetTableCount();    // count after copying
2563                 if (nResultTab >= nTabCount)
2564                     nResultTab = nTabCount - 1;
2565 
2566                 ScDocFunc aFunc(*pDocShell);
2567                 bDone = aFunc.RenameTable( nResultTab, aNewStr, sal_True, sal_True );
2568 			}
2569 		}
2570 	}
2571 	if (!bDone)
2572 		throw uno::RuntimeException();		// no other exceptions specified
2573 }
2574 
2575 void SAL_CALL ScTableSheetsObj::insertByName( const rtl::OUString& aName, const uno::Any& aElement )
2576 							throw(lang::IllegalArgumentException, container::ElementExistException,
2577 									lang::WrappedTargetException, uno::RuntimeException)
2578 {
2579 	ScUnoGuard aGuard;
2580 	sal_Bool bDone = sal_False;
2581 	sal_Bool bIllArg = sal_False;
2582 
2583 	//!	Type of aElement can be some specific interface instead of XInterface
2584 
2585 	if ( pDocShell )
2586 	{
2587         uno::Reference<uno::XInterface> xInterface(aElement, uno::UNO_QUERY);
2588 		if ( xInterface.is() )
2589 		{
2590 			ScTableSheetObj* pSheetObj = ScTableSheetObj::getImplementation( xInterface );
2591 			if ( pSheetObj && !pSheetObj->GetDocShell() )	// noch nicht eingefuegt?
2592 			{
2593 				ScDocument* pDoc = pDocShell->GetDocument();
2594 				String aNamStr(aName);
2595 				SCTAB nDummy;
2596 				if ( pDoc->GetTable( aNamStr, nDummy ) )
2597 				{
2598 					//	name already exists
2599 					throw container::ElementExistException();
2600 				}
2601 				else
2602 				{
2603 					SCTAB nPosition = pDoc->GetTableCount();
2604 					ScDocFunc aFunc(*pDocShell);
2605 					bDone = aFunc.InsertTable( nPosition, aNamStr, sal_True, sal_True );
2606 					if (bDone)
2607 						pSheetObj->InitInsertSheet( pDocShell, nPosition );
2608 					//	Dokument und neuen Range am Objekt setzen
2609 				}
2610 			}
2611 			else
2612 				bIllArg = sal_True;
2613 		}
2614 		else
2615 			bIllArg = sal_True;
2616 	}
2617 
2618 	if (!bDone)
2619 	{
2620 		if (bIllArg)
2621 			throw lang::IllegalArgumentException();
2622 		else
2623 			throw uno::RuntimeException();		// ElementExistException is handled above
2624 	}
2625 }
2626 
2627 void SAL_CALL ScTableSheetsObj::replaceByName( const rtl::OUString& aName, const uno::Any& aElement )
2628 							throw(lang::IllegalArgumentException, container::NoSuchElementException,
2629 									lang::WrappedTargetException, uno::RuntimeException)
2630 {
2631 	ScUnoGuard aGuard;
2632 	sal_Bool bDone = sal_False;
2633 	sal_Bool bIllArg = sal_False;
2634 
2635 	//!	Type of aElement can be some specific interface instead of XInterface
2636 
2637 	if ( pDocShell )
2638 	{
2639         uno::Reference<uno::XInterface> xInterface(aElement, uno::UNO_QUERY);
2640 		if ( xInterface.is() )
2641 		{
2642 			ScTableSheetObj* pSheetObj = ScTableSheetObj::getImplementation( xInterface );
2643 			if ( pSheetObj && !pSheetObj->GetDocShell() )	// noch nicht eingefuegt?
2644 			{
2645 				String aNamStr(aName);
2646 				SCTAB nPosition;
2647 				if ( pDocShell->GetDocument()->GetTable( aNamStr, nPosition ) )
2648 				{
2649 					ScDocFunc aFunc(*pDocShell);
2650 					if ( aFunc.DeleteTable( nPosition, sal_True, sal_True ) )
2651 					{
2652 						//	InsertTable kann jetzt eigentlich nicht schiefgehen...
2653 						bDone = aFunc.InsertTable( nPosition, aNamStr, sal_True, sal_True );
2654 						if (bDone)
2655 							pSheetObj->InitInsertSheet( pDocShell, nPosition );
2656 					}
2657 				}
2658 				else
2659 				{
2660 					//	not found
2661 					throw container::NoSuchElementException();
2662 				}
2663 			}
2664 			else
2665 				bIllArg = sal_True;
2666 		}
2667 		else
2668 			bIllArg = sal_True;
2669 	}
2670 
2671 	if (!bDone)
2672 	{
2673 		if (bIllArg)
2674 			throw lang::IllegalArgumentException();
2675 		else
2676 			throw uno::RuntimeException();		// NoSuchElementException is handled above
2677 	}
2678 }
2679 
2680 void SAL_CALL ScTableSheetsObj::removeByName( const rtl::OUString& aName )
2681 								throw(container::NoSuchElementException,
2682 									lang::WrappedTargetException, uno::RuntimeException)
2683 {
2684 	ScUnoGuard aGuard;
2685 	sal_Bool bDone = sal_False;
2686 	if (pDocShell)
2687 	{
2688 		SCTAB nIndex;
2689 		String aString(aName);
2690 		if ( pDocShell->GetDocument()->GetTable( aString, nIndex ) )
2691 		{
2692 			ScDocFunc aFunc(*pDocShell);
2693 			bDone = aFunc.DeleteTable( nIndex, sal_True, sal_True );
2694 		}
2695 		else
2696 		{
2697 			//	not found
2698 			throw container::NoSuchElementException();
2699 		}
2700 	}
2701 
2702 	if (!bDone)
2703 		throw uno::RuntimeException();		// NoSuchElementException is handled above
2704 }
2705 
2706 // XCellRangesAccess
2707 
2708 uno::Reference< table::XCell > SAL_CALL ScTableSheetsObj::getCellByPosition( sal_Int32 nColumn, sal_Int32 nRow, sal_Int32 nSheet )
2709     throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2710 {
2711 	ScUnoGuard aGuard;
2712     uno::Reference<table::XCellRange> xSheet(static_cast<ScCellRangeObj*>(GetObjectByIndex_Impl((sal_uInt16)nSheet)));
2713 	if (! xSheet.is())
2714         throw lang::IndexOutOfBoundsException();
2715 
2716     return xSheet->getCellByPosition(nColumn, nRow);
2717 }
2718 
2719 uno::Reference< table::XCellRange > SAL_CALL ScTableSheetsObj::getCellRangeByPosition( sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom, sal_Int32 nSheet )
2720     throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2721 {
2722 	ScUnoGuard aGuard;
2723 	uno::Reference<table::XCellRange> xSheet(static_cast<ScCellRangeObj*>(GetObjectByIndex_Impl((sal_uInt16)nSheet)));
2724 	if (! xSheet.is())
2725         throw lang::IndexOutOfBoundsException();
2726 
2727     return xSheet->getCellRangeByPosition(nLeft, nTop, nRight, nBottom);
2728 }
2729 
2730 uno::Sequence < uno::Reference< table::XCellRange > > SAL_CALL ScTableSheetsObj::getCellRangesByName( const rtl::OUString& aRange )
2731     throw (lang::IllegalArgumentException, uno::RuntimeException)
2732 {
2733 	ScUnoGuard aGuard;
2734     uno::Sequence < uno::Reference < table::XCellRange > > xRet;
2735 
2736 	ScRangeList aRangeList;
2737     ScDocument* pDoc = pDocShell->GetDocument();
2738     if (ScRangeStringConverter::GetRangeListFromString( aRangeList, aRange, pDoc, ::formula::FormulaGrammar::CONV_OOO, ';' ))
2739     {
2740 	    sal_Int32 nCount = aRangeList.Count();
2741         if (nCount)
2742         {
2743             xRet.realloc(nCount);
2744 	        for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
2745 	        {
2746 		        const ScRange* pRange = aRangeList.GetObject( nIndex );
2747 		        if( pRange )
2748                     xRet[nIndex] = new ScCellRangeObj(pDocShell, *pRange);
2749             }
2750         }
2751         else
2752             throw lang::IllegalArgumentException();
2753     }
2754     else
2755         throw lang::IllegalArgumentException();
2756     return xRet;
2757 }
2758 
2759 // XEnumerationAccess
2760 
2761 uno::Reference<container::XEnumeration> SAL_CALL ScTableSheetsObj::createEnumeration()
2762 													throw(uno::RuntimeException)
2763 {
2764 	ScUnoGuard aGuard;
2765     return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.SpreadsheetsEnumeration")));
2766 }
2767 
2768 // XIndexAccess
2769 
2770 sal_Int32 SAL_CALL ScTableSheetsObj::getCount() throw(uno::RuntimeException)
2771 {
2772 	ScUnoGuard aGuard;
2773 	if (pDocShell)
2774 		return pDocShell->GetDocument()->GetTableCount();
2775 	return 0;
2776 }
2777 
2778 uno::Any SAL_CALL ScTableSheetsObj::getByIndex( sal_Int32 nIndex )
2779 							throw(lang::IndexOutOfBoundsException,
2780 									lang::WrappedTargetException, uno::RuntimeException)
2781 {
2782 	ScUnoGuard aGuard;
2783 	uno::Reference<sheet::XSpreadsheet> xSheet(GetObjectByIndex_Impl(nIndex));
2784 	if (xSheet.is())
2785         return uno::makeAny(xSheet);
2786 	else
2787 		throw lang::IndexOutOfBoundsException();
2788 //    return uno::Any();
2789 }
2790 
2791 uno::Type SAL_CALL ScTableSheetsObj::getElementType() throw(uno::RuntimeException)
2792 {
2793 	ScUnoGuard aGuard;
2794 	return getCppuType((uno::Reference<sheet::XSpreadsheet>*)0);
2795 }
2796 
2797 sal_Bool SAL_CALL ScTableSheetsObj::hasElements() throw(uno::RuntimeException)
2798 {
2799 	ScUnoGuard aGuard;
2800 	return ( getCount() != 0 );
2801 }
2802 
2803 // XNameAccess
2804 
2805 uno::Any SAL_CALL ScTableSheetsObj::getByName( const rtl::OUString& aName )
2806 			throw(container::NoSuchElementException,
2807 					lang::WrappedTargetException, uno::RuntimeException)
2808 {
2809 	ScUnoGuard aGuard;
2810 	uno::Reference<sheet::XSpreadsheet> xSheet(GetObjectByName_Impl(aName));
2811 	if (xSheet.is())
2812         return uno::makeAny(xSheet);
2813 	else
2814 		throw container::NoSuchElementException();
2815 //    return uno::Any();
2816 }
2817 
2818 uno::Sequence<rtl::OUString> SAL_CALL ScTableSheetsObj::getElementNames()
2819 												throw(uno::RuntimeException)
2820 {
2821 	ScUnoGuard aGuard;
2822 	if (pDocShell)
2823 	{
2824 		ScDocument* pDoc = pDocShell->GetDocument();
2825 		SCTAB nCount = pDoc->GetTableCount();
2826 		String aName;
2827 		uno::Sequence<rtl::OUString> aSeq(nCount);
2828 		rtl::OUString* pAry = aSeq.getArray();
2829 		for (SCTAB i=0; i<nCount; i++)
2830 		{
2831 			pDoc->GetName( i, aName );
2832 			pAry[i] = aName;
2833 		}
2834 		return aSeq;
2835 	}
2836 	return uno::Sequence<rtl::OUString>();
2837 }
2838 
2839 sal_Bool SAL_CALL ScTableSheetsObj::hasByName( const rtl::OUString& aName )
2840 										throw(uno::RuntimeException)
2841 {
2842 	ScUnoGuard aGuard;
2843 	if (pDocShell)
2844 	{
2845 		SCTAB nIndex;
2846 		if ( pDocShell->GetDocument()->GetTable( String(aName), nIndex ) )
2847 			return sal_True;
2848 	}
2849 	return sal_False;
2850 }
2851 
2852 //------------------------------------------------------------------------
2853 
2854 ScTableColumnsObj::ScTableColumnsObj(ScDocShell* pDocSh, SCTAB nT, SCCOL nSC, SCCOL nEC) :
2855 	pDocShell( pDocSh ),
2856 	nTab	 ( nT ),
2857 	nStartCol( nSC ),
2858 	nEndCol	 ( nEC )
2859 {
2860 	pDocShell->GetDocument()->AddUnoObject(*this);
2861 }
2862 
2863 ScTableColumnsObj::~ScTableColumnsObj()
2864 {
2865 	if (pDocShell)
2866 		pDocShell->GetDocument()->RemoveUnoObject(*this);
2867 }
2868 
2869 void ScTableColumnsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
2870 {
2871 	if ( rHint.ISA( ScUpdateRefHint ) )
2872 	{
2873 //        const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
2874 
2875 		//!	Referenz-Update fuer Tab und Start/Ende
2876 	}
2877 	else if ( rHint.ISA( SfxSimpleHint ) &&
2878 			((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
2879 	{
2880 		pDocShell = NULL;		// ungueltig geworden
2881 	}
2882 }
2883 
2884 // XTableColumns
2885 
2886 ScTableColumnObj* ScTableColumnsObj::GetObjectByIndex_Impl(sal_Int32 nIndex) const
2887 {
2888 	SCCOL nCol = static_cast<SCCOL>(nIndex) + nStartCol;
2889 	if ( pDocShell && nCol <= nEndCol )
2890 		return new ScTableColumnObj( pDocShell, nCol, nTab );
2891 
2892 	return NULL;	// falscher Index
2893 }
2894 
2895 ScTableColumnObj* ScTableColumnsObj::GetObjectByName_Impl(const rtl::OUString& aName) const
2896 {
2897 	SCCOL nCol = 0;
2898 	String aString(aName);
2899 	if ( ::AlphaToCol( nCol, aString) )
2900 		if ( pDocShell && nCol >= nStartCol && nCol <= nEndCol )
2901 			return new ScTableColumnObj( pDocShell, nCol, nTab );
2902 
2903 	return NULL;
2904 }
2905 
2906 void SAL_CALL ScTableColumnsObj::insertByIndex( sal_Int32 nPosition, sal_Int32 nCount )
2907 												throw(uno::RuntimeException)
2908 {
2909 	ScUnoGuard aGuard;
2910 	sal_Bool bDone = sal_False;
2911 	if ( pDocShell && nCount > 0 && nPosition >= 0 && nStartCol+nPosition <= nEndCol &&
2912 			nStartCol+nPosition+nCount-1 <= MAXCOL )
2913 	{
2914 		ScDocFunc aFunc(*pDocShell);
2915 		ScRange aRange( (SCCOL)(nStartCol+nPosition), 0, nTab,
2916 						(SCCOL)(nStartCol+nPosition+nCount-1), MAXROW, nTab );
2917 		bDone = aFunc.InsertCells( aRange, NULL, INS_INSCOLS, sal_True, sal_True );
2918 	}
2919 	if (!bDone)
2920 		throw uno::RuntimeException();		// no other exceptions specified
2921 }
2922 
2923 void SAL_CALL ScTableColumnsObj::removeByIndex( sal_Int32 nIndex, sal_Int32 nCount )
2924 												throw(uno::RuntimeException)
2925 {
2926 	ScUnoGuard aGuard;
2927 	sal_Bool bDone = sal_False;
2928 	//	Der zu loeschende Bereich muss innerhalb des Objekts liegen
2929 	if ( pDocShell && nCount > 0 && nIndex >= 0 && nStartCol+nIndex+nCount-1 <= nEndCol )
2930 	{
2931 		ScDocFunc aFunc(*pDocShell);
2932 		ScRange aRange( (SCCOL)(nStartCol+nIndex), 0, nTab,
2933 						(SCCOL)(nStartCol+nIndex+nCount-1), MAXROW, nTab );
2934 		bDone = aFunc.DeleteCells( aRange, NULL, DEL_DELCOLS, sal_True, sal_True );
2935 	}
2936 	if (!bDone)
2937 		throw uno::RuntimeException();		// no other exceptions specified
2938 }
2939 
2940 // XEnumerationAccess
2941 
2942 uno::Reference<container::XEnumeration> SAL_CALL ScTableColumnsObj::createEnumeration()
2943 													throw(uno::RuntimeException)
2944 {
2945 	ScUnoGuard aGuard;
2946     return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.table.TableColumnsEnumeration")));
2947 }
2948 
2949 // XIndexAccess
2950 
2951 sal_Int32 SAL_CALL ScTableColumnsObj::getCount() throw(uno::RuntimeException)
2952 {
2953 	ScUnoGuard aGuard;
2954 	return nEndCol - nStartCol + 1;
2955 }
2956 
2957 uno::Any SAL_CALL ScTableColumnsObj::getByIndex( sal_Int32 nIndex )
2958 							throw(lang::IndexOutOfBoundsException,
2959 									lang::WrappedTargetException, uno::RuntimeException)
2960 {
2961 	ScUnoGuard aGuard;
2962 	uno::Reference<table::XCellRange> xColumn(GetObjectByIndex_Impl(nIndex));
2963 	if (xColumn.is())
2964         return uno::makeAny(xColumn);
2965 	else
2966 		throw lang::IndexOutOfBoundsException();
2967 //    return uno::Any();
2968 }
2969 
2970 uno::Type SAL_CALL ScTableColumnsObj::getElementType() throw(uno::RuntimeException)
2971 {
2972 	ScUnoGuard aGuard;
2973 	return getCppuType((uno::Reference<table::XCellRange>*)0);
2974 }
2975 
2976 sal_Bool SAL_CALL ScTableColumnsObj::hasElements() throw(uno::RuntimeException)
2977 {
2978 	ScUnoGuard aGuard;
2979 	return ( getCount() != 0 );
2980 }
2981 
2982 uno::Any SAL_CALL ScTableColumnsObj::getByName( const rtl::OUString& aName )
2983 			throw(container::NoSuchElementException,
2984 					lang::WrappedTargetException, uno::RuntimeException)
2985 {
2986 	ScUnoGuard aGuard;
2987 	uno::Reference<table::XCellRange> xColumn(GetObjectByName_Impl(aName));
2988 	if (xColumn.is())
2989         return uno::makeAny(xColumn);
2990 	else
2991 		throw container::NoSuchElementException();
2992 //    return uno::Any();
2993 }
2994 
2995 uno::Sequence<rtl::OUString> SAL_CALL ScTableColumnsObj::getElementNames()
2996 												throw(uno::RuntimeException)
2997 {
2998 	ScUnoGuard aGuard;
2999 	SCCOL nCount = nEndCol - nStartCol + 1;
3000 	uno::Sequence<rtl::OUString> aSeq(nCount);
3001 	rtl::OUString* pAry = aSeq.getArray();
3002 	for (SCCOL i=0; i<nCount; i++)
3003 		pAry[i] = ::ScColToAlpha( nStartCol + i );
3004 
3005 	return aSeq;
3006 }
3007 
3008 sal_Bool SAL_CALL ScTableColumnsObj::hasByName( const rtl::OUString& aName )
3009 										throw(uno::RuntimeException)
3010 {
3011 	ScUnoGuard aGuard;
3012 	SCCOL nCol = 0;
3013 	String aString(aName);
3014 	if ( ::AlphaToCol( nCol, aString) )
3015 		if ( pDocShell && nCol >= nStartCol && nCol <= nEndCol )
3016 			return sal_True;
3017 
3018 	return sal_False;		// nicht gefunden
3019 }
3020 
3021 // XPropertySet
3022 
3023 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTableColumnsObj::getPropertySetInfo()
3024 														throw(uno::RuntimeException)
3025 {
3026 	ScUnoGuard aGuard;
3027 	static uno::Reference<beans::XPropertySetInfo> aRef(
3028 		new SfxItemPropertySetInfo( lcl_GetColumnsPropertyMap() ));
3029 	return aRef;
3030 }
3031 
3032 void SAL_CALL ScTableColumnsObj::setPropertyValue(
3033 						const rtl::OUString& aPropertyName, const uno::Any& aValue )
3034 				throw(beans::UnknownPropertyException, beans::PropertyVetoException,
3035 						lang::IllegalArgumentException, lang::WrappedTargetException,
3036 						uno::RuntimeException)
3037 {
3038 	ScUnoGuard aGuard;
3039 	if (!pDocShell)
3040 		throw uno::RuntimeException();
3041 
3042 	ScDocFunc aFunc(*pDocShell);
3043 	SCCOLROW nColArr[2];
3044 	nColArr[0] = nStartCol;
3045 	nColArr[1] = nEndCol;
3046 	String aNameString(aPropertyName);
3047 
3048 	if ( aNameString.EqualsAscii( SC_UNONAME_CELLWID ) )
3049 	{
3050 		sal_Int32 nNewWidth = 0;
3051 		if ( aValue >>= nNewWidth )
3052 			aFunc.SetWidthOrHeight( sal_True, 1, nColArr, nTab, SC_SIZE_ORIGINAL,
3053 									(sal_uInt16)HMMToTwips(nNewWidth), sal_True, sal_True );
3054 	}
3055 	else if ( aNameString.EqualsAscii( SC_UNONAME_CELLVIS ) )
3056 	{
3057 		sal_Bool bVis = ScUnoHelpFunctions::GetBoolFromAny( aValue );
3058 		ScSizeMode eMode = bVis ? SC_SIZE_SHOW : SC_SIZE_DIRECT;
3059 		aFunc.SetWidthOrHeight( sal_True, 1, nColArr, nTab, eMode, 0, sal_True, sal_True );
3060 		//	SC_SIZE_DIRECT with size 0: hide
3061 	}
3062 	else if ( aNameString.EqualsAscii( SC_UNONAME_OWIDTH ) )
3063 	{
3064 		sal_Bool bOpt = ScUnoHelpFunctions::GetBoolFromAny( aValue );
3065 		if (bOpt)
3066 			aFunc.SetWidthOrHeight( sal_True, 1, nColArr, nTab,
3067 									SC_SIZE_OPTIMAL, STD_EXTRA_WIDTH, sal_True, sal_True );
3068 		// sal_False for columns currently has no effect
3069 	}
3070 	else if ( aNameString.EqualsAscii( SC_UNONAME_NEWPAGE ) || aNameString.EqualsAscii( SC_UNONAME_MANPAGE ) )
3071 	{
3072 		//!	single function to set/remove all breaks?
3073 		sal_Bool bSet = ScUnoHelpFunctions::GetBoolFromAny( aValue );
3074 		for (SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++)
3075 			if (bSet)
3076 				aFunc.InsertPageBreak( sal_True, ScAddress(nCol,0,nTab), sal_True, sal_True, sal_True );
3077 			else
3078 				aFunc.RemovePageBreak( sal_True, ScAddress(nCol,0,nTab), sal_True, sal_True, sal_True );
3079 	}
3080 }
3081 
3082 uno::Any SAL_CALL ScTableColumnsObj::getPropertyValue( const rtl::OUString& aPropertyName )
3083 				throw(beans::UnknownPropertyException, lang::WrappedTargetException,
3084 						uno::RuntimeException)
3085 {
3086 	ScUnoGuard aGuard;
3087 	if (!pDocShell)
3088 		throw uno::RuntimeException();
3089 
3090 	ScDocument* pDoc = pDocShell->GetDocument();
3091 	String aNameString(aPropertyName);
3092 	uno::Any aAny;
3093 
3094 	//!	loop over all columns for current state?
3095 
3096 	if ( aNameString.EqualsAscii( SC_UNONAME_CELLWID ) )
3097 	{
3098 		// for hidden column, return original height
3099 		sal_uInt16 nWidth = pDoc->GetOriginalWidth( nStartCol, nTab );
3100 		aAny <<= (sal_Int32)TwipsToHMM(nWidth);
3101 	}
3102 	else if ( aNameString.EqualsAscii( SC_UNONAME_CELLVIS ) )
3103 	{
3104         SCCOL nLastCol;
3105         bool bVis = !pDoc->ColHidden(nStartCol, nTab, nLastCol);
3106 		ScUnoHelpFunctions::SetBoolInAny( aAny, bVis );
3107 	}
3108 	else if ( aNameString.EqualsAscii( SC_UNONAME_OWIDTH ) )
3109 	{
3110 		sal_Bool bOpt = !(pDoc->GetColFlags( nStartCol, nTab ) & CR_MANUALSIZE);
3111 		ScUnoHelpFunctions::SetBoolInAny( aAny, bOpt );
3112 	}
3113 	else if ( aNameString.EqualsAscii( SC_UNONAME_NEWPAGE ) )
3114 	{
3115         ScBreakType nBreak = pDoc->HasColBreak(nStartCol, nTab);
3116         ScUnoHelpFunctions::SetBoolInAny( aAny, nBreak );
3117 	}
3118 	else if ( aNameString.EqualsAscii( SC_UNONAME_MANPAGE ) )
3119 	{
3120         ScBreakType nBreak = pDoc->HasColBreak(nStartCol, nTab);
3121         ScUnoHelpFunctions::SetBoolInAny( aAny, (nBreak & BREAK_MANUAL) );
3122 	}
3123 
3124 	return aAny;
3125 }
3126 
3127 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScTableColumnsObj )
3128 
3129 //------------------------------------------------------------------------
3130 
3131 ScTableRowsObj::ScTableRowsObj(ScDocShell* pDocSh, SCTAB nT, SCROW nSR, SCROW nER) :
3132 	pDocShell( pDocSh ),
3133 	nTab	 ( nT ),
3134 	nStartRow( nSR ),
3135 	nEndRow	 ( nER )
3136 {
3137 	pDocShell->GetDocument()->AddUnoObject(*this);
3138 }
3139 
3140 ScTableRowsObj::~ScTableRowsObj()
3141 {
3142 	if (pDocShell)
3143 		pDocShell->GetDocument()->RemoveUnoObject(*this);
3144 }
3145 
3146 void ScTableRowsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
3147 {
3148 	if ( rHint.ISA( ScUpdateRefHint ) )
3149 	{
3150 //        const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
3151 
3152 		//!	Referenz-Update fuer Tab und Start/Ende
3153 	}
3154 	else if ( rHint.ISA( SfxSimpleHint ) &&
3155 			((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
3156 	{
3157 		pDocShell = NULL;		// ungueltig geworden
3158 	}
3159 }
3160 
3161 // XTableRows
3162 
3163 ScTableRowObj* ScTableRowsObj::GetObjectByIndex_Impl(sal_Int32 nIndex) const
3164 {
3165 	SCROW nRow = static_cast<SCROW>(nIndex) + nStartRow;
3166 	if ( pDocShell && nRow <= nEndRow )
3167 		return new ScTableRowObj( pDocShell, nRow, nTab );
3168 
3169 	return NULL;	// falscher Index
3170 }
3171 
3172 void SAL_CALL ScTableRowsObj::insertByIndex( sal_Int32 nPosition, sal_Int32 nCount )
3173 												throw(uno::RuntimeException)
3174 {
3175 	ScUnoGuard aGuard;
3176 	sal_Bool bDone = sal_False;
3177 	if ( pDocShell && nCount > 0 && nPosition >= 0 && nStartRow+nPosition <= nEndRow &&
3178 			nStartRow+nPosition+nCount-1 <= MAXROW )
3179 	{
3180 		ScDocFunc aFunc(*pDocShell);
3181 		ScRange aRange( 0, (SCROW)(nStartRow+nPosition), nTab,
3182 						MAXCOL, (SCROW)(nStartRow+nPosition+nCount-1), nTab );
3183 		bDone = aFunc.InsertCells( aRange, NULL, INS_INSROWS, sal_True, sal_True );
3184 	}
3185 	if (!bDone)
3186 		throw uno::RuntimeException();		// no other exceptions specified
3187 }
3188 
3189 void SAL_CALL ScTableRowsObj::removeByIndex( sal_Int32 nIndex, sal_Int32 nCount )
3190 												throw(uno::RuntimeException)
3191 {
3192 	ScUnoGuard aGuard;
3193 	sal_Bool bDone = sal_False;
3194 	//	Der zu loeschende Bereich muss innerhalb des Objekts liegen
3195 	if ( pDocShell && nCount > 0 && nIndex >= 0 && nStartRow+nIndex+nCount-1 <= nEndRow )
3196 	{
3197 		ScDocFunc aFunc(*pDocShell);
3198 		ScRange aRange( 0, (SCROW)(nStartRow+nIndex), nTab,
3199 						MAXCOL, (SCROW)(nStartRow+nIndex+nCount-1), nTab );
3200 		bDone = aFunc.DeleteCells( aRange, NULL, DEL_DELROWS, sal_True, sal_True );
3201 	}
3202 	if (!bDone)
3203 		throw uno::RuntimeException();		// no other exceptions specified
3204 }
3205 
3206 // XEnumerationAccess
3207 
3208 uno::Reference<container::XEnumeration> SAL_CALL ScTableRowsObj::createEnumeration()
3209 													throw(uno::RuntimeException)
3210 {
3211 	ScUnoGuard aGuard;
3212     return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.table.TableRowsEnumeration")));
3213 }
3214 
3215 // XIndexAccess
3216 
3217 sal_Int32 SAL_CALL ScTableRowsObj::getCount() throw(uno::RuntimeException)
3218 {
3219 	ScUnoGuard aGuard;
3220 	return nEndRow - nStartRow + 1;
3221 }
3222 
3223 uno::Any SAL_CALL ScTableRowsObj::getByIndex( sal_Int32 nIndex )
3224 							throw(lang::IndexOutOfBoundsException,
3225 									lang::WrappedTargetException, uno::RuntimeException)
3226 {
3227 	ScUnoGuard aGuard;
3228 	uno::Reference<table::XCellRange> xRow(GetObjectByIndex_Impl(nIndex));
3229 	if (xRow.is())
3230         return uno::makeAny(xRow);
3231 	else
3232 		throw lang::IndexOutOfBoundsException();
3233 //    return uno::Any();
3234 }
3235 
3236 uno::Type SAL_CALL ScTableRowsObj::getElementType() throw(uno::RuntimeException)
3237 {
3238 	ScUnoGuard aGuard;
3239 	return getCppuType((uno::Reference<table::XCellRange>*)0);
3240 }
3241 
3242 sal_Bool SAL_CALL ScTableRowsObj::hasElements() throw(uno::RuntimeException)
3243 {
3244 	ScUnoGuard aGuard;
3245 	return ( getCount() != 0 );
3246 }
3247 
3248 // XPropertySet
3249 
3250 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTableRowsObj::getPropertySetInfo()
3251 														throw(uno::RuntimeException)
3252 {
3253 	ScUnoGuard aGuard;
3254 	static uno::Reference<beans::XPropertySetInfo> aRef(
3255 		new SfxItemPropertySetInfo( lcl_GetRowsPropertyMap() ));
3256 	return aRef;
3257 }
3258 
3259 void SAL_CALL ScTableRowsObj::setPropertyValue(
3260 						const rtl::OUString& aPropertyName, const uno::Any& aValue )
3261 				throw(beans::UnknownPropertyException, beans::PropertyVetoException,
3262 						lang::IllegalArgumentException, lang::WrappedTargetException,
3263 						uno::RuntimeException)
3264 {
3265 	ScUnoGuard aGuard;
3266 	if (!pDocShell)
3267 		throw uno::RuntimeException();
3268 
3269 	ScDocFunc aFunc(*pDocShell);
3270 	ScDocument* pDoc = pDocShell->GetDocument();
3271 	SCCOLROW nRowArr[2];
3272 	nRowArr[0] = nStartRow;
3273 	nRowArr[1] = nEndRow;
3274 	String aNameString(aPropertyName);
3275 
3276     if ( aNameString.EqualsAscii( SC_UNONAME_OHEIGHT ) )
3277     {
3278         sal_Int32 nNewHeight = 0;
3279         if ( pDoc->IsImportingXML() && ( aValue >>= nNewHeight ) )
3280         {
3281             // used to set the stored row height for rows with optimal height when loading.
3282 
3283             // TODO: It's probably cleaner to use a different property name
3284             // for this.
3285             pDoc->SetRowHeightOnly( nStartRow, nEndRow, nTab, (sal_uInt16)HMMToTwips(nNewHeight) );
3286         }
3287         else
3288         {
3289             sal_Bool bOpt = ScUnoHelpFunctions::GetBoolFromAny( aValue );
3290             if (bOpt)
3291                 aFunc.SetWidthOrHeight( sal_False, 1, nRowArr, nTab, SC_SIZE_OPTIMAL, 0, sal_True, sal_True );
3292             else
3293             {
3294                 //! manually set old heights again?
3295             }
3296         }
3297     }
3298     else if ( aNameString.EqualsAscii( SC_UNONAME_CELLHGT ) )
3299 	{
3300 		sal_Int32 nNewHeight = 0;
3301 		if ( aValue >>= nNewHeight )
3302 			aFunc.SetWidthOrHeight( sal_False, 1, nRowArr, nTab, SC_SIZE_ORIGINAL,
3303 									(sal_uInt16)HMMToTwips(nNewHeight), sal_True, sal_True );
3304 	}
3305 	else if ( aNameString.EqualsAscii( SC_UNONAME_CELLVIS ) )
3306 	{
3307 		sal_Bool bVis = ScUnoHelpFunctions::GetBoolFromAny( aValue );
3308 		ScSizeMode eMode = bVis ? SC_SIZE_SHOW : SC_SIZE_DIRECT;
3309 		aFunc.SetWidthOrHeight( sal_False, 1, nRowArr, nTab, eMode, 0, sal_True, sal_True );
3310 		//	SC_SIZE_DIRECT with size 0: hide
3311 	}
3312     else if ( aNameString.EqualsAscii( SC_UNONAME_VISFLAG ) )
3313     {
3314         // #i116460# Shortcut to only set the flag, without drawing layer update etc.
3315         // Should only be used from import filters.
3316         pDoc->SetRowHidden(nStartRow, nEndRow, nTab, !ScUnoHelpFunctions::GetBoolFromAny( aValue ));
3317     }
3318 	else if ( aNameString.EqualsAscii( SC_UNONAME_CELLFILT ) )
3319 	{
3320 		//!	undo etc.
3321 		if (ScUnoHelpFunctions::GetBoolFromAny( aValue ))
3322             pDoc->SetRowFiltered(nStartRow, nEndRow, nTab, true);
3323         else
3324             pDoc->SetRowFiltered(nStartRow, nEndRow, nTab, false);
3325 	}
3326 	else if ( aNameString.EqualsAscii( SC_UNONAME_NEWPAGE) || aNameString.EqualsAscii( SC_UNONAME_MANPAGE) )
3327 	{
3328 		//!	single function to set/remove all breaks?
3329 		sal_Bool bSet = ScUnoHelpFunctions::GetBoolFromAny( aValue );
3330 		for (SCROW nRow=nStartRow; nRow<=nEndRow; nRow++)
3331 			if (bSet)
3332 				aFunc.InsertPageBreak( sal_False, ScAddress(0,nRow,nTab), sal_True, sal_True, sal_True );
3333 			else
3334 				aFunc.RemovePageBreak( sal_False, ScAddress(0,nRow,nTab), sal_True, sal_True, sal_True );
3335 	}
3336     else if ( aNameString.EqualsAscii( SC_UNONAME_CELLBACK ) || aNameString.EqualsAscii( SC_UNONAME_CELLTRAN ) )
3337     {
3338         // #i57867# Background color is specified for row styles in the file format,
3339         // so it has to be supported along with the row properties (import only).
3340 
3341         // Use ScCellRangeObj to set the property for all cells in the rows
3342         // (this means, the "row attribute" must be set before individual cell attributes).
3343 
3344         ScRange aRange( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab );
3345         uno::Reference<beans::XPropertySet> xRangeObj = new ScCellRangeObj( pDocShell, aRange );
3346         xRangeObj->setPropertyValue( aPropertyName, aValue );
3347     }
3348 }
3349 
3350 uno::Any SAL_CALL ScTableRowsObj::getPropertyValue( const rtl::OUString& aPropertyName )
3351 				throw(beans::UnknownPropertyException, lang::WrappedTargetException,
3352 						uno::RuntimeException)
3353 {
3354 	ScUnoGuard aGuard;
3355 	if (!pDocShell)
3356 		throw uno::RuntimeException();
3357 
3358 	ScDocument* pDoc = pDocShell->GetDocument();
3359 	String aNameString(aPropertyName);
3360 	uno::Any aAny;
3361 
3362 	//!	loop over all rows for current state?
3363 
3364 	if ( aNameString.EqualsAscii( SC_UNONAME_CELLHGT ) )
3365 	{
3366 		// for hidden row, return original height
3367 		sal_uInt16 nHeight = pDoc->GetOriginalHeight( nStartRow, nTab );
3368 		aAny <<= (sal_Int32)TwipsToHMM(nHeight);
3369 	}
3370 	else if ( aNameString.EqualsAscii( SC_UNONAME_CELLVIS ) )
3371 	{
3372         SCROW nLastRow;
3373         bool bVis = !pDoc->RowHidden(nStartRow, nTab, nLastRow);
3374 		ScUnoHelpFunctions::SetBoolInAny( aAny, bVis );
3375 	}
3376 	else if ( aNameString.EqualsAscii( SC_UNONAME_CELLFILT ) )
3377 	{
3378         bool bVis = pDoc->RowFiltered(nStartRow, nTab);
3379 		ScUnoHelpFunctions::SetBoolInAny( aAny, bVis );
3380 	}
3381 	else if ( aNameString.EqualsAscii( SC_UNONAME_OHEIGHT ) )
3382 	{
3383 		sal_Bool bOpt = !(pDoc->GetRowFlags( nStartRow, nTab ) & CR_MANUALSIZE);
3384 		ScUnoHelpFunctions::SetBoolInAny( aAny, bOpt );
3385 	}
3386 	else if ( aNameString.EqualsAscii( SC_UNONAME_NEWPAGE ) )
3387 	{
3388         ScBreakType nBreak = pDoc->HasRowBreak(nStartRow, nTab);
3389         ScUnoHelpFunctions::SetBoolInAny( aAny, nBreak );
3390 	}
3391 	else if ( aNameString.EqualsAscii( SC_UNONAME_MANPAGE ) )
3392 	{
3393         ScBreakType nBreak = pDoc->HasRowBreak(nStartRow, nTab);
3394         ScUnoHelpFunctions::SetBoolInAny( aAny, (nBreak & BREAK_MANUAL) );
3395 	}
3396     else if ( aNameString.EqualsAscii( SC_UNONAME_CELLBACK ) || aNameString.EqualsAscii( SC_UNONAME_CELLTRAN ) )
3397     {
3398         // Use ScCellRangeObj to get the property from the cell range
3399         // (for completeness only, this is not used by the XML filter).
3400 
3401         ScRange aRange( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab );
3402         uno::Reference<beans::XPropertySet> xRangeObj = new ScCellRangeObj( pDocShell, aRange );
3403         aAny = xRangeObj->getPropertyValue( aPropertyName );
3404     }
3405 
3406 	return aAny;
3407 }
3408 
3409 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScTableRowsObj )
3410 
3411 //------------------------------------------------------------------------
3412 
3413 //UNUSED2008-05  ScSpreadsheetSettingsObj::ScSpreadsheetSettingsObj(ScDocShell* pDocSh) :
3414 //UNUSED2008-05  pDocShell( pDocSh )
3415 //UNUSED2008-05  {
3416 //UNUSED2008-05      pDocShell->GetDocument()->AddUnoObject(*this);
3417 //UNUSED2008-05  }
3418 
3419 ScSpreadsheetSettingsObj::~ScSpreadsheetSettingsObj()
3420 {
3421 	if (pDocShell)
3422 		pDocShell->GetDocument()->RemoveUnoObject(*this);
3423 }
3424 
3425 void ScSpreadsheetSettingsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
3426 {
3427 	//	Referenz-Update interessiert hier nicht
3428 
3429 	if ( rHint.ISA( SfxSimpleHint ) &&
3430 			((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
3431 	{
3432 		pDocShell = NULL;		// ungueltig geworden
3433 	}
3434 }
3435 
3436 // XPropertySet
3437 
3438 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScSpreadsheetSettingsObj::getPropertySetInfo()
3439 														throw(uno::RuntimeException)
3440 {
3441 	//!	muss noch
3442 	return NULL;
3443 }
3444 
3445 void SAL_CALL ScSpreadsheetSettingsObj::setPropertyValue(
3446                         const rtl::OUString& /* aPropertyName */, const uno::Any& /* aValue */ )
3447 				throw(beans::UnknownPropertyException, beans::PropertyVetoException,
3448 						lang::IllegalArgumentException, lang::WrappedTargetException,
3449 						uno::RuntimeException)
3450 {
3451 	//!	muss noch
3452 }
3453 
3454 uno::Any SAL_CALL ScSpreadsheetSettingsObj::getPropertyValue( const rtl::OUString& /* aPropertyName */ )
3455 				throw(beans::UnknownPropertyException, lang::WrappedTargetException,
3456 						uno::RuntimeException)
3457 {
3458 	//!	muss noch
3459 	return uno::Any();
3460 }
3461 
3462 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScSpreadsheetSettingsObj )
3463 
3464 //------------------------------------------------------------------------
3465 
3466 ScAnnotationsObj::ScAnnotationsObj(ScDocShell* pDocSh, SCTAB nT) :
3467 	pDocShell( pDocSh ),
3468 	nTab( nT )
3469 {
3470 	pDocShell->GetDocument()->AddUnoObject(*this);
3471 }
3472 
3473 ScAnnotationsObj::~ScAnnotationsObj()
3474 {
3475 	if (pDocShell)
3476 		pDocShell->GetDocument()->RemoveUnoObject(*this);
3477 }
3478 
3479 void ScAnnotationsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
3480 {
3481 	//!	nTab bei Referenz-Update anpassen!!!
3482 
3483 	if ( rHint.ISA( SfxSimpleHint ) &&
3484 			((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
3485 	{
3486 		pDocShell = NULL;		// ungueltig geworden
3487 	}
3488 }
3489 
3490 bool ScAnnotationsObj::GetAddressByIndex_Impl( sal_Int32 nIndex, ScAddress& rPos ) const
3491 {
3492 	if (pDocShell)
3493 	{
3494 		sal_Int32 nFound = 0;
3495 		ScDocument* pDoc = pDocShell->GetDocument();
3496 		ScCellIterator aCellIter( pDoc, 0,0, nTab, MAXCOL,MAXROW, nTab );
3497 		for( ScBaseCell* pCell = aCellIter.GetFirst(); pCell; pCell = aCellIter.GetNext() )
3498 		{
3499             if (pCell->HasNote())
3500 			{
3501 				if (nFound == nIndex)
3502 				{
3503 					rPos = ScAddress( aCellIter.GetCol(), aCellIter.GetRow(), aCellIter.GetTab() );
3504 					return true;
3505 				}
3506 				++nFound;
3507 			}
3508 		}
3509 	}
3510 	return false;
3511 }
3512 
3513 ScAnnotationObj* ScAnnotationsObj::GetObjectByIndex_Impl( sal_Int32 nIndex ) const
3514 {
3515 	if (pDocShell)
3516 	{
3517 		ScAddress aPos;
3518 		if ( GetAddressByIndex_Impl( nIndex, aPos ) )
3519 			return new ScAnnotationObj( pDocShell, aPos );
3520 	}
3521 	return NULL;
3522 }
3523 
3524 // XSheetAnnotations
3525 
3526 void SAL_CALL ScAnnotationsObj::insertNew(
3527         const table::CellAddress& aPosition, const ::rtl::OUString& rText )
3528 												throw(uno::RuntimeException)
3529 {
3530 	ScUnoGuard aGuard;
3531 	if (pDocShell)
3532 	{
3533 		DBG_ASSERT( aPosition.Sheet == nTab, "addAnnotation mit falschem Sheet" );
3534 		ScAddress aPos( (SCCOL)aPosition.Column, (SCROW)aPosition.Row, nTab );
3535 
3536         ScDocFunc aFunc( *pDocShell );
3537         aFunc.ReplaceNote( aPos, rText, 0, 0, sal_True );
3538 	}
3539 }
3540 
3541 void SAL_CALL ScAnnotationsObj::removeByIndex( sal_Int32 nIndex ) throw(uno::RuntimeException)
3542 {
3543 	ScUnoGuard aGuard;
3544 	if (pDocShell)
3545 	{
3546 		ScAddress aPos;
3547 		if ( GetAddressByIndex_Impl( nIndex, aPos ) )
3548 		{
3549 			ScMarkData aMarkData;
3550 			aMarkData.SelectTable( aPos.Tab(), sal_True );
3551 			aMarkData.SetMultiMarkArea( ScRange(aPos) );
3552 
3553 			ScDocFunc aFunc(*pDocShell);
3554 			aFunc.DeleteContents( aMarkData, IDF_NOTE, sal_True, sal_True );
3555 		}
3556 	}
3557 }
3558 
3559 // XEnumerationAccess
3560 
3561 uno::Reference<container::XEnumeration> SAL_CALL ScAnnotationsObj::createEnumeration()
3562 													throw(uno::RuntimeException)
3563 {
3564 	//!	iterate directly (more efficiently)?
3565 
3566 	ScUnoGuard aGuard;
3567     return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.CellAnnotationsEnumeration")));
3568 }
3569 
3570 // XIndexAccess
3571 
3572 sal_Int32 SAL_CALL ScAnnotationsObj::getCount() throw(uno::RuntimeException)
3573 {
3574 	ScUnoGuard aGuard;
3575 	sal_uLong nCount = 0;
3576 	if (pDocShell)
3577 	{
3578         ScCellIterator aCellIter( pDocShell->GetDocument(), 0,0, nTab, MAXCOL,MAXROW, nTab );
3579         for( ScBaseCell* pCell = aCellIter.GetFirst(); pCell; pCell = aCellIter.GetNext() )
3580             if (pCell->HasNote())
3581 				++nCount;
3582 	}
3583 	return nCount;
3584 }
3585 
3586 uno::Any SAL_CALL ScAnnotationsObj::getByIndex( sal_Int32 nIndex )
3587 							throw(lang::IndexOutOfBoundsException,
3588 									lang::WrappedTargetException, uno::RuntimeException)
3589 {
3590 	ScUnoGuard aGuard;
3591 	uno::Reference<sheet::XSheetAnnotation> xAnnotation(GetObjectByIndex_Impl(nIndex));
3592 	if (xAnnotation.is())
3593         return uno::makeAny(xAnnotation);
3594 	else
3595 		throw lang::IndexOutOfBoundsException();
3596 //    return uno::Any();
3597 }
3598 
3599 uno::Type SAL_CALL ScAnnotationsObj::getElementType() throw(uno::RuntimeException)
3600 {
3601 	ScUnoGuard aGuard;
3602 	return getCppuType((uno::Reference<sheet::XSheetAnnotation>*)0);
3603 }
3604 
3605 sal_Bool SAL_CALL ScAnnotationsObj::hasElements() throw(uno::RuntimeException)
3606 {
3607 	ScUnoGuard aGuard;
3608 	return ( getCount() != 0 );
3609 }
3610 
3611 //------------------------------------------------------------------------
3612 
3613 ScScenariosObj::ScScenariosObj(ScDocShell* pDocSh, SCTAB nT) :
3614 	pDocShell( pDocSh ),
3615 	nTab	 ( nT )
3616 {
3617 	pDocShell->GetDocument()->AddUnoObject(*this);
3618 }
3619 
3620 ScScenariosObj::~ScScenariosObj()
3621 {
3622 	if (pDocShell)
3623 		pDocShell->GetDocument()->RemoveUnoObject(*this);
3624 }
3625 
3626 void ScScenariosObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
3627 {
3628 	if ( rHint.ISA( ScUpdateRefHint ) )
3629 	{
3630 //        const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
3631 
3632 		//!	Referenz-Update fuer Tab und Start/Ende
3633 	}
3634 	else if ( rHint.ISA( SfxSimpleHint ) &&
3635 			((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
3636 	{
3637 		pDocShell = NULL;		// ungueltig geworden
3638 	}
3639 }
3640 
3641 // XScenarios
3642 
3643 sal_Bool ScScenariosObj::GetScenarioIndex_Impl( const rtl::OUString& rName, SCTAB& rIndex )
3644 {
3645 	//!	Case-insensitiv ????
3646 
3647 	if ( pDocShell )
3648 	{
3649 		String aString(rName);
3650 
3651 		String aTabName;
3652 		ScDocument* pDoc = pDocShell->GetDocument();
3653 		SCTAB nCount = (SCTAB)getCount();
3654 		for (SCTAB i=0; i<nCount; i++)
3655 			if (pDoc->GetName( nTab+i+1, aTabName ))
3656 				if ( aTabName == aString )
3657 				{
3658 					rIndex = i;
3659 					return sal_True;
3660 				}
3661 	}
3662 
3663 	return sal_False;
3664 }
3665 
3666 ScTableSheetObj* ScScenariosObj::GetObjectByIndex_Impl(sal_Int32 nIndex)
3667 {
3668 	sal_uInt16 nCount = (sal_uInt16)getCount();
3669 	if ( pDocShell && nIndex >= 0 && nIndex < nCount )
3670 		return new ScTableSheetObj( pDocShell, nTab+static_cast<SCTAB>(nIndex)+1 );
3671 
3672 	return NULL;	// kein Dokument oder falscher Index
3673 }
3674 
3675 ScTableSheetObj* ScScenariosObj::GetObjectByName_Impl(const rtl::OUString& aName)
3676 {
3677 	SCTAB nIndex;
3678 	if ( pDocShell && GetScenarioIndex_Impl( aName, nIndex ) )
3679 		return new ScTableSheetObj( pDocShell, nTab+nIndex+1 );
3680 
3681 	return NULL;	// nicht gefunden
3682 }
3683 
3684 void SAL_CALL ScScenariosObj::addNewByName( const rtl::OUString& aName,
3685 								const uno::Sequence<table::CellRangeAddress>& aRanges,
3686 								const rtl::OUString& aComment )
3687 									throw(uno::RuntimeException)
3688 {
3689 	ScUnoGuard aGuard;
3690 	if ( pDocShell )
3691 	{
3692 		ScMarkData aMarkData;
3693 		aMarkData.SelectTable( nTab, sal_True );
3694 
3695 		sal_uInt16 nRangeCount = (sal_uInt16)aRanges.getLength();
3696 		if (nRangeCount)
3697 		{
3698 			const table::CellRangeAddress* pAry = aRanges.getConstArray();
3699 			for (sal_uInt16 i=0; i<nRangeCount; i++)
3700 			{
3701 				DBG_ASSERT( pAry[i].Sheet == nTab, "addScenario mit falscher Tab" );
3702 				ScRange aRange( (SCCOL)pAry[i].StartColumn, (SCROW)pAry[i].StartRow, nTab,
3703 								(SCCOL)pAry[i].EndColumn,   (SCROW)pAry[i].EndRow,   nTab );
3704 
3705 				aMarkData.SetMultiMarkArea( aRange );
3706 			}
3707 		}
3708 
3709 		String aNameStr(aName);
3710 		String aCommStr(aComment);
3711 
3712 		Color aColor( COL_LIGHTGRAY );	// Default
3713 		sal_uInt16 nFlags = SC_SCENARIO_SHOWFRAME | SC_SCENARIO_PRINTFRAME | SC_SCENARIO_TWOWAY | SC_SCENARIO_PROTECT;
3714 
3715 		pDocShell->MakeScenario( nTab, aNameStr, aCommStr, aColor, nFlags, aMarkData );
3716 	}
3717 }
3718 
3719 void SAL_CALL ScScenariosObj::removeByName( const rtl::OUString& aName )
3720 											throw(uno::RuntimeException)
3721 {
3722 	ScUnoGuard aGuard;
3723 	SCTAB nIndex;
3724 	if ( pDocShell && GetScenarioIndex_Impl( aName, nIndex ) )
3725 	{
3726 		ScDocFunc aFunc(*pDocShell);
3727 		aFunc.DeleteTable( nTab+nIndex+1, sal_True, sal_True );
3728 	}
3729 }
3730 
3731 // XEnumerationAccess
3732 
3733 uno::Reference<container::XEnumeration> SAL_CALL ScScenariosObj::createEnumeration()
3734 													throw(uno::RuntimeException)
3735 {
3736 	ScUnoGuard aGuard;
3737     return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.ScenariosEnumeration")));
3738 }
3739 
3740 // XIndexAccess
3741 
3742 sal_Int32 SAL_CALL ScScenariosObj::getCount() throw(uno::RuntimeException)
3743 {
3744 	ScUnoGuard aGuard;
3745 	SCTAB nCount = 0;
3746 	if ( pDocShell )
3747 	{
3748 		ScDocument* pDoc = pDocShell->GetDocument();
3749 		if (!pDoc->IsScenario(nTab))
3750 		{
3751 			SCTAB nTabCount = pDoc->GetTableCount();
3752 			SCTAB nNext = nTab + 1;
3753 			while (nNext < nTabCount && pDoc->IsScenario(nNext))
3754 			{
3755 				++nCount;
3756 				++nNext;
3757 			}
3758 		}
3759 	}
3760 	return nCount;
3761 }
3762 
3763 uno::Any SAL_CALL ScScenariosObj::getByIndex( sal_Int32 nIndex )
3764 							throw(lang::IndexOutOfBoundsException,
3765 									lang::WrappedTargetException, uno::RuntimeException)
3766 {
3767 	ScUnoGuard aGuard;
3768 	uno::Reference<sheet::XScenario> xScen(GetObjectByIndex_Impl(nIndex));
3769 	if (xScen.is())
3770         return uno::makeAny(xScen);
3771 	else
3772 		throw lang::IndexOutOfBoundsException();
3773 //    return uno::Any();
3774 }
3775 
3776 uno::Type SAL_CALL ScScenariosObj::getElementType() throw(uno::RuntimeException)
3777 {
3778 	ScUnoGuard aGuard;
3779 	return getCppuType((uno::Reference<sheet::XScenario>*)0);
3780 }
3781 
3782 sal_Bool SAL_CALL ScScenariosObj::hasElements() throw(uno::RuntimeException)
3783 {
3784 	ScUnoGuard aGuard;
3785 	return ( getCount() != 0 );
3786 }
3787 
3788 uno::Any SAL_CALL ScScenariosObj::getByName( const rtl::OUString& aName )
3789 			throw(container::NoSuchElementException,
3790 					lang::WrappedTargetException, uno::RuntimeException)
3791 {
3792 	ScUnoGuard aGuard;
3793 	uno::Reference<sheet::XScenario> xScen(GetObjectByName_Impl(aName));
3794 	if (xScen.is())
3795         return uno::makeAny(xScen);
3796 	else
3797 		throw container::NoSuchElementException();
3798 //    return uno::Any();
3799 }
3800 
3801 uno::Sequence<rtl::OUString> SAL_CALL ScScenariosObj::getElementNames()
3802 												throw(uno::RuntimeException)
3803 {
3804 	ScUnoGuard aGuard;
3805 	SCTAB nCount = (SCTAB)getCount();
3806 	uno::Sequence<rtl::OUString> aSeq(nCount);
3807 
3808 	if ( pDocShell )	// sonst ist auch Count = 0
3809 	{
3810 		String aTabName;
3811 		ScDocument* pDoc = pDocShell->GetDocument();
3812 		rtl::OUString* pAry = aSeq.getArray();
3813 		for (SCTAB i=0; i<nCount; i++)
3814 			if (pDoc->GetName( nTab+i+1, aTabName ))
3815 				pAry[i] = aTabName;
3816 	}
3817 
3818 	return aSeq;
3819 }
3820 
3821 sal_Bool SAL_CALL ScScenariosObj::hasByName( const rtl::OUString& aName )
3822 										throw(uno::RuntimeException)
3823 {
3824 	ScUnoGuard aGuard;
3825 	SCTAB nIndex;
3826 	return GetScenarioIndex_Impl( aName, nIndex );
3827 }
3828 
3829 
3830 
3831 
3832 
3833