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