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