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