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