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