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