xref: /trunk/main/sc/source/ui/unoobj/docuno.cxx (revision 66b843ff8f1eedd2e69941f1ea52fa080f01ec28)
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 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_sc.hxx"
24 
25 #include "scitems.hxx"
26 #include <svx/fmdpage.hxx>
27 #include <svx/fmview.hxx>
28 #include <svx/svditer.hxx>
29 #include <svx/svdpage.hxx>
30 #include <svx/svxids.hrc>
31 #include <svx/unoshape.hxx>
32 
33 #include <svl/numuno.hxx>
34 #include <svl/smplhint.hxx>
35 #include <unotools/undoopt.hxx>
36 #include <unotools/moduleoptions.hxx>
37 #include <sfx2/printer.hxx>
38 #include <sfx2/bindings.hxx>
39 #include <vcl/pdfextoutdevdata.hxx>
40 #include <vcl/waitobj.hxx>
41 #include <unotools/charclass.hxx>
42 #include <tools/multisel.hxx>
43 #include <tools/resary.hxx>
44 #include <toolkit/awt/vclxdevice.hxx>
45 
46 #include <ctype.h>
47 #include <float.h> // DBL_MAX
48 
49 #include <com/sun/star/util/Date.hpp>
50 #include <com/sun/star/sheet/XNamedRanges.hpp>
51 #include <com/sun/star/sheet/XNamedRanges2.hpp>
52 #include <com/sun/star/sheet/XLabelRanges.hpp>
53 #include <com/sun/star/i18n/XForbiddenCharacters.hpp>
54 #include <com/sun/star/script/XLibraryContainer.hpp>
55 #include <com/sun/star/lang/XInitialization.hpp>
56 #include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
57 #include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
58 #include <com/sun/star/script/XInvocation.hpp>
59 #include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
60 #include <com/sun/star/reflection/XIdlClassProvider.hpp>
61 #include <comphelper/processfactory.hxx>
62 
63 #include "docuno.hxx"
64 #include "cellsuno.hxx"
65 #include "nameuno.hxx"
66 #include "datauno.hxx"
67 #include "miscuno.hxx"
68 #include "notesuno.hxx"
69 #include "styleuno.hxx"
70 #include "linkuno.hxx"
71 #include "servuno.hxx"
72 #include "targuno.hxx"
73 #include "convuno.hxx"
74 #include "optuno.hxx"
75 #include "forbiuno.hxx"
76 #include "docsh.hxx"
77 #include "hints.hxx"
78 #include "docfunc.hxx"
79 #include "dociter.hxx"
80 #include "cell.hxx"
81 #include "drwlayer.hxx"
82 #include "rangeutl.hxx"
83 #include "markdata.hxx"
84 #include "docoptio.hxx"
85 #include "scextopt.hxx"
86 #include "unoguard.hxx"
87 #include "unonames.hxx"
88 #include "shapeuno.hxx"
89 #include "viewuno.hxx"
90 #include "tabvwsh.hxx"
91 #include "printfun.hxx"
92 #include "pfuncache.hxx"
93 #include "scmod.hxx"
94 #include "rangeutl.hxx"
95 #include "ViewSettingsSequenceDefines.hxx"
96 #include "sheetevents.hxx"
97 #include "sc.hrc"
98 #include "scresid.hxx"
99 
100 using namespace com::sun::star;
101 
102 // #i111553# provides the name of the VBA constant for this document type (e.g. 'ThisExcelDoc' for Calc)
103 #define SC_UNO_VBAGLOBNAME "VBAGlobalConstantName"
104 
105 //------------------------------------------------------------------------
106 
107 //  alles ohne Which-ID, Map nur für PropertySetInfo
108 
109 //! umbenennen, sind nicht mehr nur Options
110 const SfxItemPropertyMapEntry* lcl_GetDocOptPropertyMap()
111 {
112     static SfxItemPropertyMapEntry aDocOptPropertyMap_Impl[] =
113     {
114         {MAP_CHAR_LEN(SC_UNO_APPLYFMDES),        0, &getBooleanCppuType(),                                    0, 0},
115         {MAP_CHAR_LEN(SC_UNO_AREALINKS),         0, &getCppuType((uno::Reference<sheet::XAreaLinks>*)0),      0, 0},
116         {MAP_CHAR_LEN(SC_UNO_AUTOCONTFOC),       0, &getBooleanCppuType(),                                    0, 0},
117         {MAP_CHAR_LEN(SC_UNO_BASICLIBRARIES),    0, &getCppuType((uno::Reference< script::XLibraryContainer >*)0), beans::PropertyAttribute::READONLY, 0},
118         {MAP_CHAR_LEN(SC_UNO_DIALOGLIBRARIES),   0, &getCppuType((uno::Reference< script::XLibraryContainer >*)0), beans::PropertyAttribute::READONLY, 0},
119         {MAP_CHAR_LEN(SC_UNO_VBAGLOBNAME),       0, &getCppuType(static_cast< const rtl::OUString * >(0)),    beans::PropertyAttribute::READONLY, 0},
120         {MAP_CHAR_LEN(SC_UNO_CALCASSHOWN),       PROP_UNO_CALCASSHOWN, &getBooleanCppuType(),                                    0, 0},
121         {MAP_CHAR_LEN(SC_UNONAME_CLOCAL),        0, &getCppuType((lang::Locale*)0),                           0, 0},
122         {MAP_CHAR_LEN(SC_UNO_CJK_CLOCAL),        0, &getCppuType((lang::Locale*)0),                           0, 0},
123         {MAP_CHAR_LEN(SC_UNO_CTL_CLOCAL),        0, &getCppuType((lang::Locale*)0),                           0, 0},
124         {MAP_CHAR_LEN(SC_UNO_COLLABELRNG),       0, &getCppuType((uno::Reference<sheet::XLabelRanges>*)0),    0, 0},
125         {MAP_CHAR_LEN(SC_UNO_DDELINKS),          0, &getCppuType((uno::Reference<container::XNameAccess>*)0), 0, 0},
126         {MAP_CHAR_LEN(SC_UNO_DEFTABSTOP),        PROP_UNO_DEFTABSTOP, &getCppuType((sal_Int16*)0),                              0, 0},
127         {MAP_CHAR_LEN(SC_UNO_EXTERNALDOCLINKS),  0, &getCppuType((uno::Reference<sheet::XExternalDocLinks>*)0), 0, 0},
128         {MAP_CHAR_LEN(SC_UNO_FORBIDDEN),         0, &getCppuType((uno::Reference<i18n::XForbiddenCharacters>*)0), beans::PropertyAttribute::READONLY, 0},
129         {MAP_CHAR_LEN(SC_UNO_HASDRAWPAGES),      0, &getBooleanCppuType(),                                    beans::PropertyAttribute::READONLY, 0},
130         {MAP_CHAR_LEN(SC_UNO_IGNORECASE),        PROP_UNO_IGNORECASE, &getBooleanCppuType(),                                    0, 0},
131         {MAP_CHAR_LEN(SC_UNO_ITERENABLED),       PROP_UNO_ITERENABLED, &getBooleanCppuType(),                                    0, 0},
132         {MAP_CHAR_LEN(SC_UNO_ITERCOUNT),         PROP_UNO_ITERCOUNT, &getCppuType((sal_Int32*)0),                              0, 0},
133         {MAP_CHAR_LEN(SC_UNO_ITEREPSILON),       PROP_UNO_ITEREPSILON, &getCppuType((double*)0),                                 0, 0},
134         {MAP_CHAR_LEN(SC_UNO_LOOKUPLABELS),      PROP_UNO_LOOKUPLABELS, &getBooleanCppuType(),                                    0, 0},
135         {MAP_CHAR_LEN(SC_UNO_MATCHWHOLE),        PROP_UNO_MATCHWHOLE, &getBooleanCppuType(),                                    0, 0},
136         {MAP_CHAR_LEN(SC_UNO_NAMEDRANGES),       0, &getCppuType((uno::Reference<sheet::XNamedRanges>*)0),    0, 0},
137         {MAP_CHAR_LEN(SC_UNO_NAMEDRANGES2),       0, &getCppuType((uno::Reference<sheet::XNamedRanges2>*)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 verändert den RefCount, darum eine Referenz selber halten
383         // (direkt am m_refCount, um sich beim release nicht selbst zu löschen)
384         comphelper::increment( m_refCount );
385         // während des queryInterface braucht man ein Ref auf das
386         // SvNumberFormatsSupplierObj, sonst wird es gelöscht.
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 zusätzliche 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 könnte theoretisch ein fremdes Objekt sein, also nur das
1588     //  öffentliche 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_NAMEDRANGES2 ) )
1850         {
1851             aRet <<= uno::Reference<sheet::XNamedRanges2>(new ScNamedRangesObj( pDocShell ));
1852         }
1853         else if ( aString.EqualsAscii( SC_UNO_NAMEDRANGES ) )
1854         {
1855             aRet <<= uno::Reference<sheet::XNamedRanges>(new ScNamedRangesObj( pDocShell ));
1856         }
1857         else if ( aString.EqualsAscii( SC_UNO_DATABASERNG ) )
1858         {
1859             aRet <<= uno::Reference<sheet::XDatabaseRanges>(new ScDatabaseRangesObj( pDocShell ));
1860         }
1861         else if ( aString.EqualsAscii( SC_UNO_COLLABELRNG ) )
1862         {
1863             aRet <<= uno::Reference<sheet::XLabelRanges>(new ScLabelRangesObj( pDocShell, sal_True ));
1864         }
1865         else if ( aString.EqualsAscii( SC_UNO_ROWLABELRNG ) )
1866         {
1867             aRet <<= uno::Reference<sheet::XLabelRanges>(new ScLabelRangesObj( pDocShell, sal_False ));
1868         }
1869         else if ( aString.EqualsAscii( SC_UNO_AREALINKS ) )
1870         {
1871             aRet <<= uno::Reference<sheet::XAreaLinks>(new ScAreaLinksObj( pDocShell ));
1872         }
1873         else if ( aString.EqualsAscii( SC_UNO_DDELINKS ) )
1874         {
1875             aRet <<= uno::Reference<container::XNameAccess>(new ScDDELinksObj( pDocShell ));
1876         }
1877         else if ( aString.EqualsAscii( SC_UNO_EXTERNALDOCLINKS ) )
1878         {
1879             aRet <<= uno::Reference<sheet::XExternalDocLinks>(new ScExternalDocLinksObj(pDocShell));
1880         }
1881         else if ( aString.EqualsAscii( SC_UNO_SHEETLINKS ) )
1882         {
1883             aRet <<= uno::Reference<container::XNameAccess>(new ScSheetLinksObj( pDocShell ));
1884         }
1885         else if ( aString.EqualsAscii( SC_UNO_APPLYFMDES ) )
1886         {
1887             // default for no model is TRUE
1888             ScDrawLayer* pModel = pDoc->GetDrawLayer();
1889             sal_Bool bOpenInDesign = pModel ? pModel->GetOpenInDesignMode() : sal_True;
1890             ScUnoHelpFunctions::SetBoolInAny( aRet, bOpenInDesign );
1891         }
1892         else if ( aString.EqualsAscii( SC_UNO_AUTOCONTFOC ) )
1893         {
1894             // default for no model is FALSE
1895             ScDrawLayer* pModel = pDoc->GetDrawLayer();
1896             sal_Bool bAutoControlFocus = pModel ? pModel->GetAutoControlFocus() : sal_False;
1897             ScUnoHelpFunctions::SetBoolInAny( aRet, bAutoControlFocus );
1898         }
1899         else if ( aString.EqualsAscii( SC_UNO_FORBIDDEN ) )
1900         {
1901             aRet <<= uno::Reference<i18n::XForbiddenCharacters>(new ScForbiddenCharsObj( pDocShell ));
1902         }
1903         else if ( aString.EqualsAscii( SC_UNO_HASDRAWPAGES ) )
1904         {
1905             ScUnoHelpFunctions::SetBoolInAny( aRet, (pDocShell->GetDocument()->GetDrawLayer() != 0) );
1906         }
1907         else if ( aString.EqualsAscii( SC_UNO_BASICLIBRARIES ) )
1908         {
1909             aRet <<= pDocShell->GetBasicContainer();
1910         }
1911         else if ( aString.EqualsAscii( SC_UNO_DIALOGLIBRARIES ) )
1912         {
1913             aRet <<= pDocShell->GetDialogContainer();
1914         }
1915         else if ( aString.EqualsAscii( SC_UNO_VBAGLOBNAME ) )
1916         {
1917             /*  #i111553# This property provides the name of the constant that
1918                 will be used to store this model in the global Basic manager.
1919                 That constant will be equivalent to 'ThisComponent' but for
1920                 each application, so e.g. a 'ThisExcelDoc' and a 'ThisWordDoc'
1921                 constant can co-exist, as required by VBA. */
1922             aRet <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ThisExcelDoc" ) );
1923         }
1924         else if ( aString.EqualsAscii( SC_UNO_RUNTIMEUID ) )
1925         {
1926             aRet <<= getRuntimeUID();
1927         }
1928         else if ( aString.EqualsAscii( SC_UNO_HASVALIDSIGNATURES ) )
1929         {
1930             aRet <<= hasValidSignatures();
1931         }
1932         else if ( aString.EqualsAscii( SC_UNO_ISLOADED ) )
1933         {
1934             ScUnoHelpFunctions::SetBoolInAny( aRet, !pDocShell->IsEmpty() );
1935         }
1936         else if ( aString.EqualsAscii( SC_UNO_ISUNDOENABLED ) )
1937         {
1938             ScUnoHelpFunctions::SetBoolInAny( aRet, pDoc->IsUndoEnabled() );
1939         }
1940         else if ( aString.EqualsAscii( SC_UNO_ISADJUSTHEIGHTENABLED ) )
1941         {
1942             ScUnoHelpFunctions::SetBoolInAny( aRet, pDoc->IsAdjustHeightEnabled() );
1943         }
1944         else if ( aString.EqualsAscii( SC_UNO_ISEXECUTELINKENABLED ) )
1945         {
1946             ScUnoHelpFunctions::SetBoolInAny( aRet, pDoc->IsExecuteLinkEnabled() );
1947         }
1948         else if ( aString.EqualsAscii( SC_UNO_ISCHANGEREADONLYENABLED ) )
1949         {
1950             ScUnoHelpFunctions::SetBoolInAny( aRet, pDoc->IsChangeReadOnlyEnabled() );
1951         }
1952         else if ( aString.EqualsAscii( SC_UNO_REFERENCEDEVICE ) )
1953         {
1954             VCLXDevice* pXDev = new VCLXDevice();
1955             pXDev->SetOutputDevice( pDoc->GetRefDevice() );
1956             aRet <<= uno::Reference< awt::XDevice >( pXDev );
1957         }
1958         else if ( aString.EqualsAscii( "BuildId" ) )
1959         {
1960             aRet <<= maBuildId;
1961         }
1962         else if ( aString.EqualsAscii( "InternalDocument" ) )
1963         {
1964             ScUnoHelpFunctions::SetBoolInAny( aRet, (pDocShell->GetCreateMode() == SFX_CREATE_MODE_INTERNAL) );
1965         }
1966     }
1967 
1968     return aRet;
1969 }
1970 
1971 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScModelObj )
1972 
1973 // XMultiServiceFactory
1974 
1975 uno::Reference<uno::XInterface> SAL_CALL ScModelObj::createInstance(
1976                                 const rtl::OUString& aServiceSpecifier )
1977                                 throw(uno::Exception, uno::RuntimeException)
1978 {
1979     ScUnoGuard aGuard;
1980     uno::Reference<uno::XInterface> xRet;
1981     String aNameStr(aServiceSpecifier);
1982     sal_uInt16 nType = ScServiceProvider::GetProviderType(aNameStr);
1983     if ( nType != SC_SERVICE_INVALID )
1984     {
1985         //  drawing layer tables must be kept as long as the model is alive
1986         //  return stored instance if already set
1987         switch ( nType )
1988         {
1989             case SC_SERVICE_GRADTAB:    xRet.set(xDrawGradTab);     break;
1990             case SC_SERVICE_HATCHTAB:   xRet.set(xDrawHatchTab);    break;
1991             case SC_SERVICE_BITMAPTAB:  xRet.set(xDrawBitmapTab);   break;
1992             case SC_SERVICE_TRGRADTAB:  xRet.set(xDrawTrGradTab);   break;
1993             case SC_SERVICE_MARKERTAB:  xRet.set(xDrawMarkerTab);   break;
1994             case SC_SERVICE_DASHTAB:    xRet.set(xDrawDashTab);     break;
1995             case SC_SERVICE_CHDATAPROV: xRet.set(xChartDataProv);   break;
1996             case SC_SERVICE_VBAOBJECTPROVIDER: xRet.set(xObjProvider); break;
1997         }
1998 
1999         // #i64497# If a chart is in a temporary document during clipboard paste,
2000         // there should be no data provider, so that own data is used
2001         bool bCreate =
2002             ! ( nType == SC_SERVICE_CHDATAPROV &&
2003                 ( pDocShell->GetCreateMode() == SFX_CREATE_MODE_INTERNAL ));
2004         // this should never happen, i.e. the temporary document should never be
2005         // loaded, because this unlinks the data
2006         OSL_ASSERT( bCreate );
2007 
2008         if ( !xRet.is() && bCreate )
2009         {
2010             xRet.set(ScServiceProvider::MakeInstance( nType, pDocShell ));
2011 
2012             //  store created instance
2013             switch ( nType )
2014             {
2015                 case SC_SERVICE_GRADTAB:    xDrawGradTab.set(xRet);     break;
2016                 case SC_SERVICE_HATCHTAB:   xDrawHatchTab.set(xRet);    break;
2017                 case SC_SERVICE_BITMAPTAB:  xDrawBitmapTab.set(xRet);   break;
2018                 case SC_SERVICE_TRGRADTAB:  xDrawTrGradTab.set(xRet);   break;
2019                 case SC_SERVICE_MARKERTAB:  xDrawMarkerTab.set(xRet);   break;
2020                 case SC_SERVICE_DASHTAB:    xDrawDashTab.set(xRet);     break;
2021                 case SC_SERVICE_CHDATAPROV: xChartDataProv.set(xRet);   break;
2022                 case SC_SERVICE_VBAOBJECTPROVIDER: xObjProvider.set(xRet); break;
2023             }
2024         }
2025     }
2026     else
2027     {
2028         //  alles was ich nicht kenne, werfe ich der SvxFmMSFactory an den Hals,
2029         //  da wird dann 'ne Exception geworfen, wenn's nicht passt...
2030 
2031         try
2032         {
2033             xRet.set(SvxFmMSFactory::createInstance(aServiceSpecifier));
2034             // extra block to force deletion of the temporary before ScShapeObj ctor (setDelegator)
2035         }
2036         catch ( lang::ServiceNotRegisteredException & )
2037         {
2038         }
2039 
2040         //  #96117# if the drawing factory created a shape, a ScShapeObj has to be used
2041         //  to support own properties like ImageMap:
2042 
2043         uno::Reference<drawing::XShape> xShape( xRet, uno::UNO_QUERY );
2044         if ( xShape.is() )
2045         {
2046             xRet.clear(); // for aggregation, xShape must be the object's only ref
2047             new ScShapeObj( xShape ); // aggregates object and modifies xShape
2048             xRet.set(xShape);
2049         }
2050     }
2051     return xRet;
2052 }
2053 
2054 uno::Reference<uno::XInterface> SAL_CALL ScModelObj::createInstanceWithArguments(
2055                                 const rtl::OUString& ServiceSpecifier,
2056                                 const uno::Sequence<uno::Any>& aArgs )
2057                                 throw(uno::Exception, uno::RuntimeException)
2058 {
2059     //! unterscheiden zwischen eigenen Services und denen vom Drawing-Layer?
2060 
2061     ScUnoGuard aGuard;
2062     uno::Reference<uno::XInterface> xInt(createInstance(ServiceSpecifier));
2063 
2064     if ( aArgs.getLength() )
2065     {
2066         //  used only for cell value binding so far - it can be initialized after creating
2067 
2068         uno::Reference<lang::XInitialization> xInit( xInt, uno::UNO_QUERY );
2069         if ( xInit.is() )
2070             xInit->initialize( aArgs );
2071     }
2072 
2073     return xInt;
2074 }
2075 
2076 uno::Sequence<rtl::OUString> SAL_CALL ScModelObj::getAvailableServiceNames()
2077                                                 throw(uno::RuntimeException)
2078 {
2079     ScUnoGuard aGuard;
2080 
2081     //! warum sind die Parameter bei concatServiceNames nicht const ???
2082     //! return concatServiceNames( ScServiceProvider::GetAllServiceNames(),
2083     //!                            SvxFmMSFactory::getAvailableServiceNames() );
2084 
2085     uno::Sequence<rtl::OUString> aMyServices(ScServiceProvider::GetAllServiceNames());
2086     uno::Sequence<rtl::OUString> aDrawServices(SvxFmMSFactory::getAvailableServiceNames());
2087 
2088     return concatServiceNames( aMyServices, aDrawServices );
2089 }
2090 
2091 // XServiceInfo
2092 
2093 rtl::OUString SAL_CALL ScModelObj::getImplementationName() throw(uno::RuntimeException)
2094 {
2095     return rtl::OUString::createFromAscii( "ScModelObj" );
2096 }
2097 
2098 sal_Bool SAL_CALL ScModelObj::supportsService( const rtl::OUString& rServiceName )
2099                                                     throw(uno::RuntimeException)
2100 {
2101     String aServiceStr(rServiceName);
2102     return aServiceStr.EqualsAscii( SCMODELOBJ_SERVICE ) ||
2103            aServiceStr.EqualsAscii( SCDOCSETTINGS_SERVICE ) ||
2104            aServiceStr.EqualsAscii( SCDOC_SERVICE );
2105 }
2106 
2107 uno::Sequence<rtl::OUString> SAL_CALL ScModelObj::getSupportedServiceNames()
2108                                                     throw(uno::RuntimeException)
2109 {
2110     uno::Sequence<rtl::OUString> aRet(2);
2111     rtl::OUString* pArray = aRet.getArray();
2112     pArray[0] = rtl::OUString::createFromAscii( SCMODELOBJ_SERVICE );
2113     pArray[1] = rtl::OUString::createFromAscii( SCDOCSETTINGS_SERVICE );
2114     return aRet;
2115 }
2116 
2117 // XUnoTunnel
2118 
2119 sal_Int64 SAL_CALL ScModelObj::getSomething(
2120                 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
2121 {
2122     if ( rId.getLength() == 16 &&
2123           0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
2124                                     rId.getConstArray(), 16 ) )
2125     {
2126         return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
2127     }
2128 
2129     if ( rId.getLength() == 16 &&
2130         0 == rtl_compareMemory( SfxObjectShell::getUnoTunnelId().getConstArray(),
2131                                     rId.getConstArray(), 16 ) )
2132     {
2133         return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(pDocShell ));
2134     }
2135 
2136     //  aggregated number formats supplier has XUnoTunnel, too
2137     //  interface from aggregated object must be obtained via queryAggregation
2138 
2139     sal_Int64 nRet = SfxBaseModel::getSomething( rId );
2140     if ( nRet )
2141         return nRet;
2142 
2143     if ( GetFormatter().is() )
2144     {
2145         const uno::Type& rTunnelType = ::getCppuType((uno::Reference<lang::XUnoTunnel>*) 0);
2146         uno::Any aNumTunnel(xNumberAgg->queryAggregation(rTunnelType));
2147         if(aNumTunnel.getValueType() == rTunnelType)
2148         {
2149             uno::Reference<lang::XUnoTunnel> xTunnelAgg(
2150                 *(uno::Reference<lang::XUnoTunnel>*)aNumTunnel.getValue());
2151             return xTunnelAgg->getSomething( rId );
2152         }
2153     }
2154 
2155     return 0;
2156 }
2157 
2158 // static
2159 const uno::Sequence<sal_Int8>& ScModelObj::getUnoTunnelId()
2160 {
2161     static uno::Sequence<sal_Int8> * pSeq = 0;
2162     if( !pSeq )
2163     {
2164         osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
2165         if( !pSeq )
2166         {
2167             static uno::Sequence< sal_Int8 > aSeq( 16 );
2168             rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
2169             pSeq = &aSeq;
2170         }
2171     }
2172     return *pSeq;
2173 }
2174 
2175 // static
2176 ScModelObj* ScModelObj::getImplementation( const uno::Reference<uno::XInterface> xObj )
2177 {
2178     ScModelObj* pRet = NULL;
2179     uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
2180     if (xUT.is())
2181         pRet = reinterpret_cast<ScModelObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
2182     return pRet;
2183 }
2184 
2185 // XChangesNotifier
2186 
2187 void ScModelObj::addChangesListener( const uno::Reference< util::XChangesListener >& aListener )
2188     throw (uno::RuntimeException)
2189 {
2190     ScUnoGuard aGuard;
2191     maChangesListeners.addInterface( aListener );
2192 }
2193 
2194 void ScModelObj::removeChangesListener( const uno::Reference< util::XChangesListener >& aListener )
2195     throw (uno::RuntimeException)
2196 {
2197     ScUnoGuard aGuard;
2198     maChangesListeners.removeInterface( aListener );
2199 }
2200 
2201 bool ScModelObj::HasChangesListeners() const
2202 {
2203     if ( maChangesListeners.getLength() > 0 )
2204         return true;
2205 
2206     // "change" event set in any sheet?
2207     return pDocShell && pDocShell->GetDocument()->HasAnySheetEventScript(SC_SHEETEVENT_CHANGE);
2208 }
2209 
2210 void ScModelObj::NotifyChanges( const ::rtl::OUString& rOperation, const ScRangeList& rRanges,
2211     const uno::Sequence< beans::PropertyValue >& rProperties )
2212 {
2213     if ( pDocShell && HasChangesListeners() )
2214     {
2215         util::ChangesEvent aEvent;
2216         aEvent.Source.set( static_cast< cppu::OWeakObject* >( this ) );
2217         aEvent.Base <<= aEvent.Source;
2218 
2219         sal_uLong nRangeCount = rRanges.Count();
2220         aEvent.Changes.realloc( static_cast< sal_Int32 >( nRangeCount ) );
2221         for ( sal_uLong nIndex = 0; nIndex < nRangeCount; ++nIndex )
2222         {
2223             uno::Reference< table::XCellRange > xRangeObj;
2224 
2225             ScRange aRange( *rRanges.GetObject( nIndex ) );
2226             if ( aRange.aStart == aRange.aEnd )
2227             {
2228                 xRangeObj.set( new ScCellObj( pDocShell, aRange.aStart ) );
2229             }
2230             else
2231             {
2232                 xRangeObj.set( new ScCellRangeObj( pDocShell, aRange ) );
2233             }
2234 
2235             util::ElementChange& rChange = aEvent.Changes[ static_cast< sal_Int32 >( nIndex ) ];
2236             rChange.Accessor <<= rOperation;
2237             rChange.Element <<= rProperties;
2238             rChange.ReplacedElement <<= xRangeObj;
2239         }
2240 
2241         ::cppu::OInterfaceIteratorHelper aIter( maChangesListeners );
2242         while ( aIter.hasMoreElements() )
2243         {
2244             try
2245             {
2246                 static_cast< util::XChangesListener* >( aIter.next() )->changesOccurred( aEvent );
2247             }
2248             catch( uno::Exception& )
2249             {
2250             }
2251         }
2252     }
2253 
2254     // handle sheet events
2255     //! separate method with ScMarkData? Then change HasChangesListeners back.
2256     if ( rOperation.compareToAscii("cell-change") == 0 && pDocShell )
2257     {
2258         ScMarkData aMarkData;
2259         aMarkData.MarkFromRangeList( rRanges, sal_False );
2260         ScDocument* pDoc = pDocShell->GetDocument();
2261         SCTAB nTabCount = pDoc->GetTableCount();
2262         for (SCTAB nTab = 0; nTab < nTabCount; nTab++)
2263             if (aMarkData.GetTableSelect(nTab))
2264             {
2265                 const ScSheetEvents* pEvents = pDoc->GetSheetEvents(nTab);
2266                 if (pEvents)
2267                 {
2268                     const rtl::OUString* pScript = pEvents->GetScript(SC_SHEETEVENT_CHANGE);
2269                     if (pScript)
2270                     {
2271                         ScRangeList aTabRanges; // collect ranges on this sheet
2272                         sal_uLong nRangeCount = rRanges.Count();
2273                         for ( sal_uLong nIndex = 0; nIndex < nRangeCount; ++nIndex )
2274                         {
2275                             ScRange aRange( *rRanges.GetObject( nIndex ) );
2276                             if ( aRange.aStart.Tab() == nTab )
2277                                 aTabRanges.Append( aRange );
2278                         }
2279                         sal_uLong nTabRangeCount = aTabRanges.Count();
2280                         if ( nTabRangeCount > 0 )
2281                         {
2282                             uno::Reference<uno::XInterface> xTarget;
2283                             if ( nTabRangeCount == 1 )
2284                             {
2285                                 ScRange aRange( *aTabRanges.GetObject( 0 ) );
2286                                 if ( aRange.aStart == aRange.aEnd )
2287                                     xTarget.set( static_cast<cppu::OWeakObject*>( new ScCellObj( pDocShell, aRange.aStart ) ) );
2288                                 else
2289                                     xTarget.set( static_cast<cppu::OWeakObject*>( new ScCellRangeObj( pDocShell, aRange ) ) );
2290                             }
2291                             else
2292                                 xTarget.set( static_cast<cppu::OWeakObject*>( new ScCellRangesObj( pDocShell, aTabRanges ) ) );
2293 
2294                             uno::Sequence<uno::Any> aParams(1);
2295                             aParams[0] <<= xTarget;
2296 
2297                             uno::Any aRet;
2298                             uno::Sequence<sal_Int16> aOutArgsIndex;
2299                             uno::Sequence<uno::Any> aOutArgs;
2300 
2301                             /*ErrCode eRet =*/ pDocShell->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs );
2302                         }
2303                     }
2304                 }
2305             }
2306     }
2307 }
2308 
2309 void ScModelObj::HandleCalculateEvents()
2310 {
2311     if (pDocShell)
2312     {
2313         ScDocument* pDoc = pDocShell->GetDocument();
2314         // don't call events before the document is visible
2315         // (might also set a flag on SFX_EVENT_LOADFINISHED and only disable while loading)
2316         if ( pDoc->IsDocVisible() )
2317         {
2318             SCTAB nTabCount = pDoc->GetTableCount();
2319             for (SCTAB nTab = 0; nTab < nTabCount; nTab++)
2320             {
2321                 if (pDoc->HasCalcNotification(nTab))
2322                 {
2323                     if (const ScSheetEvents* pEvents = pDoc->GetSheetEvents( nTab ))
2324                     {
2325                         if (const rtl::OUString* pScript = pEvents->GetScript(SC_SHEETEVENT_CALCULATE))
2326                         {
2327                             uno::Any aRet;
2328                             uno::Sequence<uno::Any> aParams;
2329                             uno::Sequence<sal_Int16> aOutArgsIndex;
2330                             uno::Sequence<uno::Any> aOutArgs;
2331                             pDocShell->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs );
2332                         }
2333                     }
2334 
2335                     try
2336                     {
2337                         uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( pDoc->GetVbaEventProcessor(), uno::UNO_SET_THROW );
2338                         uno::Sequence< uno::Any > aArgs( 1 );
2339                         aArgs[ 0 ] <<= nTab;
2340                         xVbaEvents->processVbaEvent( ScSheetEvents::GetVbaSheetEventId( SC_SHEETEVENT_CALCULATE ), aArgs );
2341                     }
2342                     catch( uno::Exception& )
2343                     {
2344                     }
2345                 }
2346             }
2347         }
2348         pDoc->ResetCalcNotifications();
2349     }
2350 }
2351 
2352 //------------------------------------------------------------------------
2353 
2354 ScDrawPagesObj::ScDrawPagesObj(ScDocShell* pDocSh) :
2355     pDocShell( pDocSh )
2356 {
2357     pDocShell->GetDocument()->AddUnoObject(*this);
2358 }
2359 
2360 ScDrawPagesObj::~ScDrawPagesObj()
2361 {
2362     if (pDocShell)
2363         pDocShell->GetDocument()->RemoveUnoObject(*this);
2364 }
2365 
2366 void ScDrawPagesObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
2367 {
2368     //  Referenz-Update interessiert hier nicht
2369 
2370     if ( rHint.ISA( SfxSimpleHint ) &&
2371             ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
2372     {
2373         pDocShell = NULL; // ungültig geworden
2374     }
2375 }
2376 
2377 uno::Reference<drawing::XDrawPage> ScDrawPagesObj::GetObjectByIndex_Impl(sal_Int32 nIndex) const
2378 {
2379     if (pDocShell)
2380     {
2381         ScDrawLayer* pDrawLayer = pDocShell->MakeDrawLayer();
2382         DBG_ASSERT(pDrawLayer,"kann Draw-Layer nicht anlegen");
2383         if ( pDrawLayer && nIndex >= 0 && nIndex < pDocShell->GetDocument()->GetTableCount() )
2384         {
2385             SdrPage* pPage = pDrawLayer->GetPage((sal_uInt16)nIndex);
2386             DBG_ASSERT(pPage,"Draw-Page not found");
2387             if (pPage)
2388             {
2389                 return uno::Reference<drawing::XDrawPage> (pPage->getUnoPage(), uno::UNO_QUERY);
2390             }
2391         }
2392     }
2393     return NULL;
2394 }
2395 
2396 // XDrawPages
2397 
2398 uno::Reference<drawing::XDrawPage> SAL_CALL ScDrawPagesObj::insertNewByIndex( sal_Int32 nPos )
2399                                             throw(uno::RuntimeException)
2400 {
2401     ScUnoGuard aGuard;
2402     uno::Reference<drawing::XDrawPage> xRet;
2403     if (pDocShell)
2404     {
2405         String aNewName;
2406         pDocShell->GetDocument()->CreateValidTabName(aNewName);
2407         ScDocFunc aFunc(*pDocShell);
2408         if ( aFunc.InsertTable( (SCTAB)nPos, aNewName, sal_True, sal_True ) )
2409             xRet.set(GetObjectByIndex_Impl( nPos ));
2410     }
2411     return xRet;
2412 }
2413 
2414 void SAL_CALL ScDrawPagesObj::remove( const uno::Reference<drawing::XDrawPage>& xPage )
2415                                             throw(uno::RuntimeException)
2416 {
2417     ScUnoGuard aGuard;
2418     SvxDrawPage* pImp = SvxDrawPage::getImplementation( xPage );
2419     if ( pDocShell && pImp )
2420     {
2421         SdrPage* pPage = pImp->GetSdrPage();
2422         if (pPage)
2423         {
2424             SCTAB nPageNum = static_cast<SCTAB>(pPage->GetPageNum());
2425             ScDocFunc aFunc(*pDocShell);
2426             aFunc.DeleteTable( nPageNum, sal_True, sal_True );
2427         }
2428     }
2429 }
2430 
2431 // XIndexAccess
2432 
2433 sal_Int32 SAL_CALL ScDrawPagesObj::getCount() throw(uno::RuntimeException)
2434 {
2435     ScUnoGuard aGuard;
2436     if (pDocShell)
2437         return pDocShell->GetDocument()->GetTableCount();
2438     return 0;
2439 }
2440 
2441 uno::Any SAL_CALL ScDrawPagesObj::getByIndex( sal_Int32 nIndex )
2442                             throw(lang::IndexOutOfBoundsException,
2443                                     lang::WrappedTargetException, uno::RuntimeException)
2444 {
2445     ScUnoGuard aGuard;
2446     uno::Reference<drawing::XDrawPage> xPage(GetObjectByIndex_Impl(nIndex));
2447     if (xPage.is())
2448         return uno::makeAny(xPage);
2449     else
2450         throw lang::IndexOutOfBoundsException();
2451 //  return uno::Any();
2452 }
2453 
2454 uno::Type SAL_CALL ScDrawPagesObj::getElementType() throw(uno::RuntimeException)
2455 {
2456     ScUnoGuard aGuard;
2457     return getCppuType((uno::Reference<drawing::XDrawPage>*)0);
2458 }
2459 
2460 sal_Bool SAL_CALL ScDrawPagesObj::hasElements() throw(uno::RuntimeException)
2461 {
2462     ScUnoGuard aGuard;
2463     return ( getCount() != 0 );
2464 }
2465 
2466 //------------------------------------------------------------------------
2467 
2468 ScTableSheetsObj::ScTableSheetsObj(ScDocShell* pDocSh) :
2469     pDocShell( pDocSh )
2470 {
2471     pDocShell->GetDocument()->AddUnoObject(*this);
2472 }
2473 
2474 ScTableSheetsObj::~ScTableSheetsObj()
2475 {
2476     if (pDocShell)
2477         pDocShell->GetDocument()->RemoveUnoObject(*this);
2478 }
2479 
2480 void ScTableSheetsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
2481 {
2482     //  Referenz-Update interessiert hier nicht
2483 
2484     if ( rHint.ISA( SfxSimpleHint ) &&
2485             ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
2486     {
2487         pDocShell = NULL; // ungültig geworden
2488     }
2489 }
2490 
2491 // XSpreadsheets
2492 
2493 ScTableSheetObj* ScTableSheetsObj::GetObjectByIndex_Impl(sal_Int32 nIndex) const
2494 {
2495     if ( pDocShell && nIndex >= 0 && nIndex < pDocShell->GetDocument()->GetTableCount() )
2496         return new ScTableSheetObj( pDocShell, static_cast<SCTAB>(nIndex) );
2497 
2498     return NULL;
2499 }
2500 
2501 ScTableSheetObj* ScTableSheetsObj::GetObjectByName_Impl(const rtl::OUString& aName) const
2502 {
2503     if (pDocShell)
2504     {
2505         SCTAB nIndex;
2506         String aString(aName);
2507         if ( pDocShell->GetDocument()->GetTable( aString, nIndex ) )
2508             return new ScTableSheetObj( pDocShell, nIndex );
2509     }
2510     return NULL;
2511 }
2512 
2513 void SAL_CALL ScTableSheetsObj::insertNewByName( const rtl::OUString& aName, sal_Int16 nPosition )
2514                                                 throw(uno::RuntimeException)
2515 {
2516     ScUnoGuard aGuard;
2517     sal_Bool bDone = sal_False;
2518     if (pDocShell)
2519     {
2520         String aNamStr(aName);
2521         ScDocFunc aFunc(*pDocShell);
2522         bDone = aFunc.InsertTable( nPosition, aNamStr, sal_True, sal_True );
2523     }
2524     if (!bDone)
2525         throw uno::RuntimeException(); // no other exceptions specified
2526 }
2527 
2528 void SAL_CALL ScTableSheetsObj::moveByName( const rtl::OUString& aName, sal_Int16 nDestination )
2529                                             throw(uno::RuntimeException)
2530 {
2531     ScUnoGuard aGuard;
2532     sal_Bool bDone = sal_False;
2533     if (pDocShell)
2534     {
2535         String aNamStr(aName);
2536         SCTAB nSource;
2537         if ( pDocShell->GetDocument()->GetTable( aNamStr, nSource ) )
2538             bDone = pDocShell->MoveTable( nSource, nDestination, sal_False, sal_True );
2539     }
2540     if (!bDone)
2541         throw uno::RuntimeException(); // no other exceptions specified
2542 }
2543 
2544 void SAL_CALL ScTableSheetsObj::copyByName( const rtl::OUString& aName,
2545                                 const rtl::OUString& aCopy, sal_Int16 nDestination )
2546                                                 throw(uno::RuntimeException)
2547 {
2548     ScUnoGuard aGuard;
2549     sal_Bool bDone = sal_False;
2550     if (pDocShell)
2551     {
2552         String aNamStr(aName);
2553         String aNewStr(aCopy);
2554         SCTAB nSource;
2555         if ( pDocShell->GetDocument()->GetTable( aNamStr, nSource ) )
2556         {
2557             bDone = pDocShell->MoveTable( nSource, nDestination, sal_True, sal_True );
2558             if (bDone)
2559             {
2560                 // #i92477# any index past the last sheet means "append" in MoveTable
2561                 SCTAB nResultTab = static_cast<SCTAB>(nDestination);
2562                 SCTAB nTabCount = pDocShell->GetDocument()->GetTableCount(); // count after copying
2563                 if (nResultTab >= nTabCount)
2564                     nResultTab = nTabCount - 1;
2565 
2566                 ScDocFunc aFunc(*pDocShell);
2567                 bDone = aFunc.RenameTable( nResultTab, aNewStr, sal_True, sal_True );
2568             }
2569         }
2570     }
2571     if (!bDone)
2572         throw uno::RuntimeException(); // no other exceptions specified
2573 }
2574 
2575 void SAL_CALL ScTableSheetsObj::insertByName( const rtl::OUString& aName, const uno::Any& aElement )
2576                             throw(lang::IllegalArgumentException, container::ElementExistException,
2577                                     lang::WrappedTargetException, uno::RuntimeException)
2578 {
2579     ScUnoGuard aGuard;
2580     sal_Bool bDone = sal_False;
2581     sal_Bool bIllArg = sal_False;
2582 
2583     //! Type of aElement can be some specific interface instead of XInterface
2584 
2585     if ( pDocShell )
2586     {
2587         uno::Reference<uno::XInterface> xInterface(aElement, uno::UNO_QUERY);
2588         if ( xInterface.is() )
2589         {
2590             ScTableSheetObj* pSheetObj = ScTableSheetObj::getImplementation( xInterface );
2591             if ( pSheetObj && !pSheetObj->GetDocShell() ) // noch nicht eingefuegt?
2592             {
2593                 ScDocument* pDoc = pDocShell->GetDocument();
2594                 String aNamStr(aName);
2595                 SCTAB nDummy;
2596                 if ( pDoc->GetTable( aNamStr, nDummy ) )
2597                 {
2598                     // name already exists
2599                     throw container::ElementExistException();
2600                 }
2601                 else
2602                 {
2603                     SCTAB nPosition = pDoc->GetTableCount();
2604                     ScDocFunc aFunc(*pDocShell);
2605                     bDone = aFunc.InsertTable( nPosition, aNamStr, sal_True, sal_True );
2606                     if (bDone)
2607                         pSheetObj->InitInsertSheet( pDocShell, nPosition );
2608                     //  Dokument und neuen Range am Objekt setzen
2609                 }
2610             }
2611             else
2612                 bIllArg = sal_True;
2613         }
2614         else
2615             bIllArg = sal_True;
2616     }
2617 
2618     if (!bDone)
2619     {
2620         if (bIllArg)
2621             throw lang::IllegalArgumentException();
2622         else
2623             throw uno::RuntimeException(); // ElementExistException is handled above
2624     }
2625 }
2626 
2627 void SAL_CALL ScTableSheetsObj::replaceByName( const rtl::OUString& aName, const uno::Any& aElement )
2628                             throw(lang::IllegalArgumentException, container::NoSuchElementException,
2629                                     lang::WrappedTargetException, uno::RuntimeException)
2630 {
2631     ScUnoGuard aGuard;
2632     sal_Bool bDone = sal_False;
2633     sal_Bool bIllArg = sal_False;
2634 
2635     //! Type of aElement can be some specific interface instead of XInterface
2636 
2637     if ( pDocShell )
2638     {
2639         uno::Reference<uno::XInterface> xInterface(aElement, uno::UNO_QUERY);
2640         if ( xInterface.is() )
2641         {
2642             ScTableSheetObj* pSheetObj = ScTableSheetObj::getImplementation( xInterface );
2643             if ( pSheetObj && !pSheetObj->GetDocShell() ) // noch nicht eingefuegt?
2644             {
2645                 String aNamStr(aName);
2646                 SCTAB nPosition;
2647                 if ( pDocShell->GetDocument()->GetTable( aNamStr, nPosition ) )
2648                 {
2649                     ScDocFunc aFunc(*pDocShell);
2650                     if ( aFunc.DeleteTable( nPosition, sal_True, sal_True ) )
2651                     {
2652                         //  InsertTable kann jetzt eigentlich nicht schiefgehen...
2653                         bDone = aFunc.InsertTable( nPosition, aNamStr, sal_True, sal_True );
2654                         if (bDone)
2655                             pSheetObj->InitInsertSheet( pDocShell, nPosition );
2656                     }
2657                 }
2658                 else
2659                 {
2660                     // not found
2661                     throw container::NoSuchElementException();
2662                 }
2663             }
2664             else
2665                 bIllArg = sal_True;
2666         }
2667         else
2668             bIllArg = sal_True;
2669     }
2670 
2671     if (!bDone)
2672     {
2673         if (bIllArg)
2674             throw lang::IllegalArgumentException();
2675         else
2676             throw uno::RuntimeException(); // NoSuchElementException is handled above
2677     }
2678 }
2679 
2680 void SAL_CALL ScTableSheetsObj::removeByName( const rtl::OUString& aName )
2681                                 throw(container::NoSuchElementException,
2682                                     lang::WrappedTargetException, uno::RuntimeException)
2683 {
2684     ScUnoGuard aGuard;
2685     sal_Bool bDone = sal_False;
2686     if (pDocShell)
2687     {
2688         SCTAB nIndex;
2689         String aString(aName);
2690         if ( pDocShell->GetDocument()->GetTable( aString, nIndex ) )
2691         {
2692             ScDocFunc aFunc(*pDocShell);
2693             bDone = aFunc.DeleteTable( nIndex, sal_True, sal_True );
2694         }
2695         else
2696         {
2697             // not found
2698             throw container::NoSuchElementException();
2699         }
2700     }
2701 
2702     if (!bDone)
2703         throw uno::RuntimeException(); // NoSuchElementException is handled above
2704 }
2705 
2706 // XCellRangesAccess
2707 
2708 uno::Reference< table::XCell > SAL_CALL ScTableSheetsObj::getCellByPosition( sal_Int32 nColumn, sal_Int32 nRow, sal_Int32 nSheet )
2709     throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2710 {
2711     ScUnoGuard aGuard;
2712     uno::Reference<table::XCellRange> xSheet(static_cast<ScCellRangeObj*>(GetObjectByIndex_Impl((sal_uInt16)nSheet)));
2713     if (! xSheet.is())
2714         throw lang::IndexOutOfBoundsException();
2715 
2716     return xSheet->getCellByPosition(nColumn, nRow);
2717 }
2718 
2719 uno::Reference< table::XCellRange > SAL_CALL ScTableSheetsObj::getCellRangeByPosition( sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom, sal_Int32 nSheet )
2720     throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2721 {
2722     ScUnoGuard aGuard;
2723     uno::Reference<table::XCellRange> xSheet(static_cast<ScCellRangeObj*>(GetObjectByIndex_Impl((sal_uInt16)nSheet)));
2724     if (! xSheet.is())
2725         throw lang::IndexOutOfBoundsException();
2726 
2727     return xSheet->getCellRangeByPosition(nLeft, nTop, nRight, nBottom);
2728 }
2729 
2730 uno::Sequence < uno::Reference< table::XCellRange > > SAL_CALL ScTableSheetsObj::getCellRangesByName( const rtl::OUString& aRange )
2731     throw (lang::IllegalArgumentException, uno::RuntimeException)
2732 {
2733     ScUnoGuard aGuard;
2734     uno::Sequence < uno::Reference < table::XCellRange > > xRet;
2735 
2736     ScRangeList aRangeList;
2737     ScDocument* pDoc = pDocShell->GetDocument();
2738     if (ScRangeStringConverter::GetRangeListFromString( aRangeList, aRange, pDoc, ::formula::FormulaGrammar::CONV_OOO, ';' ))
2739     {
2740         sal_Int32 nCount = aRangeList.Count();
2741         if (nCount)
2742         {
2743             xRet.realloc(nCount);
2744             for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
2745             {
2746                 const ScRange* pRange = aRangeList.GetObject( nIndex );
2747                 if( pRange )
2748                     xRet[nIndex] = new ScCellRangeObj(pDocShell, *pRange);
2749             }
2750         }
2751         else
2752             throw lang::IllegalArgumentException();
2753     }
2754     else
2755         throw lang::IllegalArgumentException();
2756     return xRet;
2757 }
2758 
2759 // XEnumerationAccess
2760 
2761 uno::Reference<container::XEnumeration> SAL_CALL ScTableSheetsObj::createEnumeration()
2762                                                     throw(uno::RuntimeException)
2763 {
2764     ScUnoGuard aGuard;
2765     return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.SpreadsheetsEnumeration")));
2766 }
2767 
2768 // XIndexAccess
2769 
2770 sal_Int32 SAL_CALL ScTableSheetsObj::getCount() throw(uno::RuntimeException)
2771 {
2772     ScUnoGuard aGuard;
2773     if (pDocShell)
2774         return pDocShell->GetDocument()->GetTableCount();
2775     return 0;
2776 }
2777 
2778 uno::Any SAL_CALL ScTableSheetsObj::getByIndex( sal_Int32 nIndex )
2779                             throw(lang::IndexOutOfBoundsException,
2780                                     lang::WrappedTargetException, uno::RuntimeException)
2781 {
2782     ScUnoGuard aGuard;
2783     uno::Reference<sheet::XSpreadsheet> xSheet(GetObjectByIndex_Impl(nIndex));
2784     if (xSheet.is())
2785         return uno::makeAny(xSheet);
2786     else
2787         throw lang::IndexOutOfBoundsException();
2788 //    return uno::Any();
2789 }
2790 
2791 uno::Type SAL_CALL ScTableSheetsObj::getElementType() throw(uno::RuntimeException)
2792 {
2793     ScUnoGuard aGuard;
2794     return getCppuType((uno::Reference<sheet::XSpreadsheet>*)0);
2795 }
2796 
2797 sal_Bool SAL_CALL ScTableSheetsObj::hasElements() throw(uno::RuntimeException)
2798 {
2799     ScUnoGuard aGuard;
2800     return ( getCount() != 0 );
2801 }
2802 
2803 // XNameAccess
2804 
2805 uno::Any SAL_CALL ScTableSheetsObj::getByName( const rtl::OUString& aName )
2806             throw(container::NoSuchElementException,
2807                     lang::WrappedTargetException, uno::RuntimeException)
2808 {
2809     ScUnoGuard aGuard;
2810     uno::Reference<sheet::XSpreadsheet> xSheet(GetObjectByName_Impl(aName));
2811     if (xSheet.is())
2812         return uno::makeAny(xSheet);
2813     else
2814         throw container::NoSuchElementException();
2815 //    return uno::Any();
2816 }
2817 
2818 uno::Sequence<rtl::OUString> SAL_CALL ScTableSheetsObj::getElementNames()
2819                                                 throw(uno::RuntimeException)
2820 {
2821     ScUnoGuard aGuard;
2822     if (pDocShell)
2823     {
2824         ScDocument* pDoc = pDocShell->GetDocument();
2825         SCTAB nCount = pDoc->GetTableCount();
2826         String aName;
2827         uno::Sequence<rtl::OUString> aSeq(nCount);
2828         rtl::OUString* pAry = aSeq.getArray();
2829         for (SCTAB i=0; i<nCount; i++)
2830         {
2831             pDoc->GetName( i, aName );
2832             pAry[i] = aName;
2833         }
2834         return aSeq;
2835     }
2836     return uno::Sequence<rtl::OUString>();
2837 }
2838 
2839 sal_Bool SAL_CALL ScTableSheetsObj::hasByName( const rtl::OUString& aName )
2840                                         throw(uno::RuntimeException)
2841 {
2842     ScUnoGuard aGuard;
2843     if (pDocShell)
2844     {
2845         SCTAB nIndex;
2846         if ( pDocShell->GetDocument()->GetTable( String(aName), nIndex ) )
2847             return sal_True;
2848     }
2849     return sal_False;
2850 }
2851 
2852 //------------------------------------------------------------------------
2853 
2854 ScTableColumnsObj::ScTableColumnsObj(ScDocShell* pDocSh, SCTAB nT, SCCOL nSC, SCCOL nEC) :
2855     pDocShell( pDocSh ),
2856     nTab     ( nT ),
2857     nStartCol( nSC ),
2858     nEndCol  ( nEC )
2859 {
2860     pDocShell->GetDocument()->AddUnoObject(*this);
2861 }
2862 
2863 ScTableColumnsObj::~ScTableColumnsObj()
2864 {
2865     if (pDocShell)
2866         pDocShell->GetDocument()->RemoveUnoObject(*this);
2867 }
2868 
2869 void ScTableColumnsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
2870 {
2871     if ( rHint.ISA( ScUpdateRefHint ) )
2872     {
2873 //        const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
2874 
2875         //! Referenz-Update für Tab und Start/Ende
2876     }
2877     else if ( rHint.ISA( SfxSimpleHint ) &&
2878             ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
2879     {
2880         pDocShell = NULL; // ungültig geworden
2881     }
2882 }
2883 
2884 // XTableColumns
2885 
2886 ScTableColumnObj* ScTableColumnsObj::GetObjectByIndex_Impl(sal_Int32 nIndex) const
2887 {
2888     SCCOL nCol = static_cast<SCCOL>(nIndex) + nStartCol;
2889     if ( pDocShell && nCol <= nEndCol )
2890         return new ScTableColumnObj( pDocShell, nCol, nTab );
2891 
2892     return NULL; // falscher Index
2893 }
2894 
2895 ScTableColumnObj* ScTableColumnsObj::GetObjectByName_Impl(const rtl::OUString& aName) const
2896 {
2897     SCCOL nCol = 0;
2898     String aString(aName);
2899     if ( ::AlphaToCol( nCol, aString) )
2900         if ( pDocShell && nCol >= nStartCol && nCol <= nEndCol )
2901             return new ScTableColumnObj( pDocShell, nCol, nTab );
2902 
2903     return NULL;
2904 }
2905 
2906 void SAL_CALL ScTableColumnsObj::insertByIndex( sal_Int32 nPosition, sal_Int32 nCount )
2907                                                 throw(uno::RuntimeException)
2908 {
2909     ScUnoGuard aGuard;
2910     sal_Bool bDone = sal_False;
2911     if ( pDocShell && nCount > 0 && nPosition >= 0 && nStartCol+nPosition <= nEndCol &&
2912             nStartCol+nPosition+nCount-1 <= MAXCOL )
2913     {
2914         ScDocFunc aFunc(*pDocShell);
2915         ScRange aRange( (SCCOL)(nStartCol+nPosition), 0, nTab,
2916                         (SCCOL)(nStartCol+nPosition+nCount-1), MAXROW, nTab );
2917         bDone = aFunc.InsertCells( aRange, NULL, INS_INSCOLS, sal_True, sal_True );
2918     }
2919     if (!bDone)
2920         throw uno::RuntimeException(); // no other exceptions specified
2921 }
2922 
2923 void SAL_CALL ScTableColumnsObj::removeByIndex( sal_Int32 nIndex, sal_Int32 nCount )
2924                                                 throw(uno::RuntimeException)
2925 {
2926     ScUnoGuard aGuard;
2927     sal_Bool bDone = sal_False;
2928     //  Der zu löschende Bereich muss innerhalb des Objekts liegen
2929     if ( pDocShell && nCount > 0 && nIndex >= 0 && nStartCol+nIndex+nCount-1 <= nEndCol )
2930     {
2931         ScDocFunc aFunc(*pDocShell);
2932         ScRange aRange( (SCCOL)(nStartCol+nIndex), 0, nTab,
2933                         (SCCOL)(nStartCol+nIndex+nCount-1), MAXROW, nTab );
2934         bDone = aFunc.DeleteCells( aRange, NULL, DEL_DELCOLS, sal_True, sal_True );
2935     }
2936     if (!bDone)
2937         throw uno::RuntimeException(); // no other exceptions specified
2938 }
2939 
2940 // XEnumerationAccess
2941 
2942 uno::Reference<container::XEnumeration> SAL_CALL ScTableColumnsObj::createEnumeration()
2943                                                     throw(uno::RuntimeException)
2944 {
2945     ScUnoGuard aGuard;
2946     return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.table.TableColumnsEnumeration")));
2947 }
2948 
2949 // XIndexAccess
2950 
2951 sal_Int32 SAL_CALL ScTableColumnsObj::getCount() throw(uno::RuntimeException)
2952 {
2953     ScUnoGuard aGuard;
2954     return nEndCol - nStartCol + 1;
2955 }
2956 
2957 uno::Any SAL_CALL ScTableColumnsObj::getByIndex( sal_Int32 nIndex )
2958                             throw(lang::IndexOutOfBoundsException,
2959                                     lang::WrappedTargetException, uno::RuntimeException)
2960 {
2961     ScUnoGuard aGuard;
2962     uno::Reference<table::XCellRange> xColumn(GetObjectByIndex_Impl(nIndex));
2963     if (xColumn.is())
2964         return uno::makeAny(xColumn);
2965     else
2966         throw lang::IndexOutOfBoundsException();
2967 //    return uno::Any();
2968 }
2969 
2970 uno::Type SAL_CALL ScTableColumnsObj::getElementType() throw(uno::RuntimeException)
2971 {
2972     ScUnoGuard aGuard;
2973     return getCppuType((uno::Reference<table::XCellRange>*)0);
2974 }
2975 
2976 sal_Bool SAL_CALL ScTableColumnsObj::hasElements() throw(uno::RuntimeException)
2977 {
2978     ScUnoGuard aGuard;
2979     return ( getCount() != 0 );
2980 }
2981 
2982 uno::Any SAL_CALL ScTableColumnsObj::getByName( const rtl::OUString& aName )
2983             throw(container::NoSuchElementException,
2984                     lang::WrappedTargetException, uno::RuntimeException)
2985 {
2986     ScUnoGuard aGuard;
2987     uno::Reference<table::XCellRange> xColumn(GetObjectByName_Impl(aName));
2988     if (xColumn.is())
2989         return uno::makeAny(xColumn);
2990     else
2991         throw container::NoSuchElementException();
2992 //    return uno::Any();
2993 }
2994 
2995 uno::Sequence<rtl::OUString> SAL_CALL ScTableColumnsObj::getElementNames()
2996                                                 throw(uno::RuntimeException)
2997 {
2998     ScUnoGuard aGuard;
2999     SCCOL nCount = nEndCol - nStartCol + 1;
3000     uno::Sequence<rtl::OUString> aSeq(nCount);
3001     rtl::OUString* pAry = aSeq.getArray();
3002     for (SCCOL i=0; i<nCount; i++)
3003         pAry[i] = ::ScColToAlpha( nStartCol + i );
3004 
3005     return aSeq;
3006 }
3007 
3008 sal_Bool SAL_CALL ScTableColumnsObj::hasByName( const rtl::OUString& aName )
3009                                         throw(uno::RuntimeException)
3010 {
3011     ScUnoGuard aGuard;
3012     SCCOL nCol = 0;
3013     String aString(aName);
3014     if ( ::AlphaToCol( nCol, aString) )
3015         if ( pDocShell && nCol >= nStartCol && nCol <= nEndCol )
3016             return sal_True;
3017 
3018     return sal_False; // not found
3019 }
3020 
3021 // XPropertySet
3022 
3023 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTableColumnsObj::getPropertySetInfo()
3024                                                         throw(uno::RuntimeException)
3025 {
3026     ScUnoGuard aGuard;
3027     static uno::Reference<beans::XPropertySetInfo> aRef(
3028         new SfxItemPropertySetInfo( lcl_GetColumnsPropertyMap() ));
3029     return aRef;
3030 }
3031 
3032 void SAL_CALL ScTableColumnsObj::setPropertyValue(
3033                         const rtl::OUString& aPropertyName, const uno::Any& aValue )
3034                 throw(beans::UnknownPropertyException, beans::PropertyVetoException,
3035                         lang::IllegalArgumentException, lang::WrappedTargetException,
3036                         uno::RuntimeException)
3037 {
3038     ScUnoGuard aGuard;
3039     if (!pDocShell)
3040         throw uno::RuntimeException();
3041 
3042     ScDocFunc aFunc(*pDocShell);
3043     SCCOLROW nColArr[2];
3044     nColArr[0] = nStartCol;
3045     nColArr[1] = nEndCol;
3046     String aNameString(aPropertyName);
3047 
3048     if ( aNameString.EqualsAscii( SC_UNONAME_CELLWID ) )
3049     {
3050         sal_Int32 nNewWidth = 0;
3051         if ( aValue >>= nNewWidth )
3052             aFunc.SetWidthOrHeight( sal_True, 1, nColArr, nTab, SC_SIZE_ORIGINAL,
3053                                     (sal_uInt16)HMMToTwips(nNewWidth), sal_True, sal_True );
3054     }
3055     else if ( aNameString.EqualsAscii( SC_UNONAME_CELLVIS ) )
3056     {
3057         sal_Bool bVis = ScUnoHelpFunctions::GetBoolFromAny( aValue );
3058         ScSizeMode eMode = bVis ? SC_SIZE_SHOW : SC_SIZE_DIRECT;
3059         aFunc.SetWidthOrHeight( sal_True, 1, nColArr, nTab, eMode, 0, sal_True, sal_True );
3060         //  SC_SIZE_DIRECT with size 0: hide
3061     }
3062     else if ( aNameString.EqualsAscii( SC_UNONAME_OWIDTH ) )
3063     {
3064         sal_Bool bOpt = ScUnoHelpFunctions::GetBoolFromAny( aValue );
3065         if (bOpt)
3066             aFunc.SetWidthOrHeight( sal_True, 1, nColArr, nTab,
3067                                     SC_SIZE_OPTIMAL, STD_EXTRA_WIDTH, sal_True, sal_True );
3068         // sal_False for columns currently has no effect
3069     }
3070     else if ( aNameString.EqualsAscii( SC_UNONAME_NEWPAGE ) || aNameString.EqualsAscii( SC_UNONAME_MANPAGE ) )
3071     {
3072         //! single function to set/remove all breaks?
3073         sal_Bool bSet = ScUnoHelpFunctions::GetBoolFromAny( aValue );
3074         for (SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++)
3075             if (bSet)
3076                 aFunc.InsertPageBreak( sal_True, ScAddress(nCol,0,nTab), sal_True, sal_True, sal_True );
3077             else
3078                 aFunc.RemovePageBreak( sal_True, ScAddress(nCol,0,nTab), sal_True, sal_True, sal_True );
3079     }
3080 }
3081 
3082 uno::Any SAL_CALL ScTableColumnsObj::getPropertyValue( const rtl::OUString& aPropertyName )
3083                 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
3084                         uno::RuntimeException)
3085 {
3086     ScUnoGuard aGuard;
3087     if (!pDocShell)
3088         throw uno::RuntimeException();
3089 
3090     ScDocument* pDoc = pDocShell->GetDocument();
3091     String aNameString(aPropertyName);
3092     uno::Any aAny;
3093 
3094     //! loop over all columns for current state?
3095 
3096     if ( aNameString.EqualsAscii( SC_UNONAME_CELLWID ) )
3097     {
3098         // for hidden column, return original height
3099         sal_uInt16 nWidth = pDoc->GetOriginalWidth( nStartCol, nTab );
3100         aAny <<= (sal_Int32)TwipsToHMM(nWidth);
3101     }
3102     else if ( aNameString.EqualsAscii( SC_UNONAME_CELLVIS ) )
3103     {
3104         SCCOL nLastCol;
3105         bool bVis = !pDoc->ColHidden(nStartCol, nTab, nLastCol);
3106         ScUnoHelpFunctions::SetBoolInAny( aAny, bVis );
3107     }
3108     else if ( aNameString.EqualsAscii( SC_UNONAME_OWIDTH ) )
3109     {
3110         sal_Bool bOpt = !(pDoc->GetColFlags( nStartCol, nTab ) & CR_MANUALSIZE);
3111         ScUnoHelpFunctions::SetBoolInAny( aAny, bOpt );
3112     }
3113     else if ( aNameString.EqualsAscii( SC_UNONAME_NEWPAGE ) )
3114     {
3115         ScBreakType nBreak = pDoc->HasColBreak(nStartCol, nTab);
3116         ScUnoHelpFunctions::SetBoolInAny( aAny, nBreak );
3117     }
3118     else if ( aNameString.EqualsAscii( SC_UNONAME_MANPAGE ) )
3119     {
3120         ScBreakType nBreak = pDoc->HasColBreak(nStartCol, nTab);
3121         ScUnoHelpFunctions::SetBoolInAny( aAny, (nBreak & BREAK_MANUAL) );
3122     }
3123 
3124     return aAny;
3125 }
3126 
3127 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScTableColumnsObj )
3128 
3129 //------------------------------------------------------------------------
3130 
3131 ScTableRowsObj::ScTableRowsObj(ScDocShell* pDocSh, SCTAB nT, SCROW nSR, SCROW nER) :
3132     pDocShell( pDocSh ),
3133     nTab     ( nT ),
3134     nStartRow( nSR ),
3135     nEndRow  ( nER )
3136 {
3137     pDocShell->GetDocument()->AddUnoObject(*this);
3138 }
3139 
3140 ScTableRowsObj::~ScTableRowsObj()
3141 {
3142     if (pDocShell)
3143         pDocShell->GetDocument()->RemoveUnoObject(*this);
3144 }
3145 
3146 void ScTableRowsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
3147 {
3148     if ( rHint.ISA( ScUpdateRefHint ) )
3149     {
3150 //        const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
3151 
3152         //! Referenz-Update fuer Tab und Start/Ende
3153     }
3154     else if ( rHint.ISA( SfxSimpleHint ) &&
3155             ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
3156     {
3157         pDocShell = NULL; // ungültig geworden
3158     }
3159 }
3160 
3161 // XTableRows
3162 
3163 ScTableRowObj* ScTableRowsObj::GetObjectByIndex_Impl(sal_Int32 nIndex) const
3164 {
3165     SCROW nRow = static_cast<SCROW>(nIndex) + nStartRow;
3166     if ( pDocShell && nRow <= nEndRow )
3167         return new ScTableRowObj( pDocShell, nRow, nTab );
3168 
3169     return NULL; // falscher Index
3170 }
3171 
3172 void SAL_CALL ScTableRowsObj::insertByIndex( sal_Int32 nPosition, sal_Int32 nCount )
3173                                                 throw(uno::RuntimeException)
3174 {
3175     ScUnoGuard aGuard;
3176     sal_Bool bDone = sal_False;
3177     if ( pDocShell && nCount > 0 && nPosition >= 0 && nStartRow+nPosition <= nEndRow &&
3178             nStartRow+nPosition+nCount-1 <= MAXROW )
3179     {
3180         ScDocFunc aFunc(*pDocShell);
3181         ScRange aRange( 0, (SCROW)(nStartRow+nPosition), nTab,
3182                         MAXCOL, (SCROW)(nStartRow+nPosition+nCount-1), nTab );
3183         bDone = aFunc.InsertCells( aRange, NULL, INS_INSROWS, sal_True, sal_True );
3184     }
3185     if (!bDone)
3186         throw uno::RuntimeException(); // no other exceptions specified
3187 }
3188 
3189 void SAL_CALL ScTableRowsObj::removeByIndex( sal_Int32 nIndex, sal_Int32 nCount )
3190                                                 throw(uno::RuntimeException)
3191 {
3192     ScUnoGuard aGuard;
3193     sal_Bool bDone = sal_False;
3194     //  Der zu löschende Bereich muss innerhalb des Objekts liegen
3195     if ( pDocShell && nCount > 0 && nIndex >= 0 && nStartRow+nIndex+nCount-1 <= nEndRow )
3196     {
3197         ScDocFunc aFunc(*pDocShell);
3198         ScRange aRange( 0, (SCROW)(nStartRow+nIndex), nTab,
3199                         MAXCOL, (SCROW)(nStartRow+nIndex+nCount-1), nTab );
3200         bDone = aFunc.DeleteCells( aRange, NULL, DEL_DELROWS, sal_True, sal_True );
3201     }
3202     if (!bDone)
3203         throw uno::RuntimeException(); // no other exceptions specified
3204 }
3205 
3206 // XEnumerationAccess
3207 
3208 uno::Reference<container::XEnumeration> SAL_CALL ScTableRowsObj::createEnumeration()
3209                                                     throw(uno::RuntimeException)
3210 {
3211     ScUnoGuard aGuard;
3212     return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.table.TableRowsEnumeration")));
3213 }
3214 
3215 // XIndexAccess
3216 
3217 sal_Int32 SAL_CALL ScTableRowsObj::getCount() throw(uno::RuntimeException)
3218 {
3219     ScUnoGuard aGuard;
3220     return nEndRow - nStartRow + 1;
3221 }
3222 
3223 uno::Any SAL_CALL ScTableRowsObj::getByIndex( sal_Int32 nIndex )
3224                             throw(lang::IndexOutOfBoundsException,
3225                                     lang::WrappedTargetException, uno::RuntimeException)
3226 {
3227     ScUnoGuard aGuard;
3228     uno::Reference<table::XCellRange> xRow(GetObjectByIndex_Impl(nIndex));
3229     if (xRow.is())
3230         return uno::makeAny(xRow);
3231     else
3232         throw lang::IndexOutOfBoundsException();
3233 //    return uno::Any();
3234 }
3235 
3236 uno::Type SAL_CALL ScTableRowsObj::getElementType() throw(uno::RuntimeException)
3237 {
3238     ScUnoGuard aGuard;
3239     return getCppuType((uno::Reference<table::XCellRange>*)0);
3240 }
3241 
3242 sal_Bool SAL_CALL ScTableRowsObj::hasElements() throw(uno::RuntimeException)
3243 {
3244     ScUnoGuard aGuard;
3245     return ( getCount() != 0 );
3246 }
3247 
3248 // XPropertySet
3249 
3250 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTableRowsObj::getPropertySetInfo()
3251                                                         throw(uno::RuntimeException)
3252 {
3253     ScUnoGuard aGuard;
3254     static uno::Reference<beans::XPropertySetInfo> aRef(
3255         new SfxItemPropertySetInfo( lcl_GetRowsPropertyMap() ));
3256     return aRef;
3257 }
3258 
3259 void SAL_CALL ScTableRowsObj::setPropertyValue(
3260                         const rtl::OUString& aPropertyName, const uno::Any& aValue )
3261                 throw(beans::UnknownPropertyException, beans::PropertyVetoException,
3262                         lang::IllegalArgumentException, lang::WrappedTargetException,
3263                         uno::RuntimeException)
3264 {
3265     ScUnoGuard aGuard;
3266     if (!pDocShell)
3267         throw uno::RuntimeException();
3268 
3269     ScDocFunc aFunc(*pDocShell);
3270     ScDocument* pDoc = pDocShell->GetDocument();
3271     SCCOLROW nRowArr[2];
3272     nRowArr[0] = nStartRow;
3273     nRowArr[1] = nEndRow;
3274     String aNameString(aPropertyName);
3275 
3276     if ( aNameString.EqualsAscii( SC_UNONAME_OHEIGHT ) )
3277     {
3278         sal_Int32 nNewHeight = 0;
3279         if ( pDoc->IsImportingXML() && ( aValue >>= nNewHeight ) )
3280         {
3281             // used to set the stored row height for rows with optimal height when loading.
3282 
3283             // TODO: It's probably cleaner to use a different property name
3284             // for this.
3285             pDoc->SetRowHeightOnly( nStartRow, nEndRow, nTab, (sal_uInt16)HMMToTwips(nNewHeight) );
3286         }
3287         else
3288         {
3289             sal_Bool bOpt = ScUnoHelpFunctions::GetBoolFromAny( aValue );
3290             if (bOpt)
3291                 aFunc.SetWidthOrHeight( sal_False, 1, nRowArr, nTab, SC_SIZE_OPTIMAL, 0, sal_True, sal_True );
3292             else
3293             {
3294                 //! manually set old heights again?
3295             }
3296         }
3297     }
3298     else if ( aNameString.EqualsAscii( SC_UNONAME_CELLHGT ) )
3299     {
3300         sal_Int32 nNewHeight = 0;
3301         if ( aValue >>= nNewHeight )
3302             aFunc.SetWidthOrHeight( sal_False, 1, nRowArr, nTab, SC_SIZE_ORIGINAL,
3303                                     (sal_uInt16)HMMToTwips(nNewHeight), sal_True, sal_True );
3304     }
3305     else if ( aNameString.EqualsAscii( SC_UNONAME_CELLVIS ) )
3306     {
3307         sal_Bool bVis = ScUnoHelpFunctions::GetBoolFromAny( aValue );
3308         ScSizeMode eMode = bVis ? SC_SIZE_SHOW : SC_SIZE_DIRECT;
3309         aFunc.SetWidthOrHeight( sal_False, 1, nRowArr, nTab, eMode, 0, sal_True, sal_True );
3310         // SC_SIZE_DIRECT with size 0: hide
3311     }
3312     else if ( aNameString.EqualsAscii( SC_UNONAME_VISFLAG ) )
3313     {
3314         // #i116460# Shortcut to only set the flag, without drawing layer update etc.
3315         // Should only be used from import filters.
3316         pDoc->SetRowHidden(nStartRow, nEndRow, nTab, !ScUnoHelpFunctions::GetBoolFromAny( aValue ));
3317     }
3318     else if ( aNameString.EqualsAscii( SC_UNONAME_CELLFILT ) )
3319     {
3320         //! undo etc.
3321         if (ScUnoHelpFunctions::GetBoolFromAny( aValue ))
3322             pDoc->SetRowFiltered(nStartRow, nEndRow, nTab, true);
3323         else
3324             pDoc->SetRowFiltered(nStartRow, nEndRow, nTab, false);
3325     }
3326     else if ( aNameString.EqualsAscii( SC_UNONAME_NEWPAGE) || aNameString.EqualsAscii( SC_UNONAME_MANPAGE) )
3327     {
3328         //! single function to set/remove all breaks?
3329         sal_Bool bSet = ScUnoHelpFunctions::GetBoolFromAny( aValue );
3330         for (SCROW nRow=nStartRow; nRow<=nEndRow; nRow++)
3331             if (bSet)
3332                 aFunc.InsertPageBreak( sal_False, ScAddress(0,nRow,nTab), sal_True, sal_True, sal_True );
3333             else
3334                 aFunc.RemovePageBreak( sal_False, ScAddress(0,nRow,nTab), sal_True, sal_True, sal_True );
3335     }
3336     else if ( aNameString.EqualsAscii( SC_UNONAME_CELLBACK ) || aNameString.EqualsAscii( SC_UNONAME_CELLTRAN ) )
3337     {
3338         // #i57867# Background color is specified for row styles in the file format,
3339         // so it has to be supported along with the row properties (import only).
3340 
3341         // Use ScCellRangeObj to set the property for all cells in the rows
3342         // (this means, the "row attribute" must be set before individual cell attributes).
3343 
3344         ScRange aRange( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab );
3345         uno::Reference<beans::XPropertySet> xRangeObj = new ScCellRangeObj( pDocShell, aRange );
3346         xRangeObj->setPropertyValue( aPropertyName, aValue );
3347     }
3348 }
3349 
3350 uno::Any SAL_CALL ScTableRowsObj::getPropertyValue( const rtl::OUString& aPropertyName )
3351                 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
3352                         uno::RuntimeException)
3353 {
3354     ScUnoGuard aGuard;
3355     if (!pDocShell)
3356         throw uno::RuntimeException();
3357 
3358     ScDocument* pDoc = pDocShell->GetDocument();
3359     String aNameString(aPropertyName);
3360     uno::Any aAny;
3361 
3362     //! loop over all rows for current state?
3363 
3364     if ( aNameString.EqualsAscii( SC_UNONAME_CELLHGT ) )
3365     {
3366         // for hidden row, return original height
3367         sal_uInt16 nHeight = pDoc->GetOriginalHeight( nStartRow, nTab );
3368         aAny <<= (sal_Int32)TwipsToHMM(nHeight);
3369     }
3370     else if ( aNameString.EqualsAscii( SC_UNONAME_CELLVIS ) )
3371     {
3372         SCROW nLastRow;
3373         bool bVis = !pDoc->RowHidden(nStartRow, nTab, nLastRow);
3374         ScUnoHelpFunctions::SetBoolInAny( aAny, bVis );
3375     }
3376     else if ( aNameString.EqualsAscii( SC_UNONAME_CELLFILT ) )
3377     {
3378         bool bVis = pDoc->RowFiltered(nStartRow, nTab);
3379         ScUnoHelpFunctions::SetBoolInAny( aAny, bVis );
3380     }
3381     else if ( aNameString.EqualsAscii( SC_UNONAME_OHEIGHT ) )
3382     {
3383         sal_Bool bOpt = !(pDoc->GetRowFlags( nStartRow, nTab ) & CR_MANUALSIZE);
3384         ScUnoHelpFunctions::SetBoolInAny( aAny, bOpt );
3385     }
3386     else if ( aNameString.EqualsAscii( SC_UNONAME_NEWPAGE ) )
3387     {
3388         ScBreakType nBreak = pDoc->HasRowBreak(nStartRow, nTab);
3389         ScUnoHelpFunctions::SetBoolInAny( aAny, nBreak );
3390     }
3391     else if ( aNameString.EqualsAscii( SC_UNONAME_MANPAGE ) )
3392     {
3393         ScBreakType nBreak = pDoc->HasRowBreak(nStartRow, nTab);
3394         ScUnoHelpFunctions::SetBoolInAny( aAny, (nBreak & BREAK_MANUAL) );
3395     }
3396     else if ( aNameString.EqualsAscii( SC_UNONAME_CELLBACK ) || aNameString.EqualsAscii( SC_UNONAME_CELLTRAN ) )
3397     {
3398         // Use ScCellRangeObj to get the property from the cell range
3399         // (for completeness only, this is not used by the XML filter).
3400 
3401         ScRange aRange( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab );
3402         uno::Reference<beans::XPropertySet> xRangeObj = new ScCellRangeObj( pDocShell, aRange );
3403         aAny = xRangeObj->getPropertyValue( aPropertyName );
3404     }
3405 
3406     return aAny;
3407 }
3408 
3409 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScTableRowsObj )
3410 
3411 //------------------------------------------------------------------------
3412 
3413 //UNUSED2008-05  ScSpreadsheetSettingsObj::ScSpreadsheetSettingsObj(ScDocShell* pDocSh) :
3414 //UNUSED2008-05  pDocShell( pDocSh )
3415 //UNUSED2008-05  {
3416 //UNUSED2008-05      pDocShell->GetDocument()->AddUnoObject(*this);
3417 //UNUSED2008-05  }
3418 
3419 ScSpreadsheetSettingsObj::~ScSpreadsheetSettingsObj()
3420 {
3421     if (pDocShell)
3422         pDocShell->GetDocument()->RemoveUnoObject(*this);
3423 }
3424 
3425 void ScSpreadsheetSettingsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
3426 {
3427     // Referenz-Update interessiert hier nicht
3428 
3429     if ( rHint.ISA( SfxSimpleHint ) &&
3430             ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
3431     {
3432         pDocShell = NULL; // ungültig geworden
3433     }
3434 }
3435 
3436 // XPropertySet
3437 
3438 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScSpreadsheetSettingsObj::getPropertySetInfo()
3439                                                         throw(uno::RuntimeException)
3440 {
3441     //! muss noch
3442     return NULL;
3443 }
3444 
3445 void SAL_CALL ScSpreadsheetSettingsObj::setPropertyValue(
3446                         const rtl::OUString& /* aPropertyName */, const uno::Any& /* aValue */ )
3447                 throw(beans::UnknownPropertyException, beans::PropertyVetoException,
3448                         lang::IllegalArgumentException, lang::WrappedTargetException,
3449                         uno::RuntimeException)
3450 {
3451     //! muss noch
3452 }
3453 
3454 uno::Any SAL_CALL ScSpreadsheetSettingsObj::getPropertyValue( const rtl::OUString& /* aPropertyName */ )
3455                 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
3456                         uno::RuntimeException)
3457 {
3458     //! muss noch
3459     return uno::Any();
3460 }
3461 
3462 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScSpreadsheetSettingsObj )
3463 
3464 //------------------------------------------------------------------------
3465 
3466 ScAnnotationsObj::ScAnnotationsObj(ScDocShell* pDocSh, SCTAB nT) :
3467     pDocShell( pDocSh ),
3468     nTab( nT )
3469 {
3470     pDocShell->GetDocument()->AddUnoObject(*this);
3471 }
3472 
3473 ScAnnotationsObj::~ScAnnotationsObj()
3474 {
3475     if (pDocShell)
3476         pDocShell->GetDocument()->RemoveUnoObject(*this);
3477 }
3478 
3479 void ScAnnotationsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
3480 {
3481     //! nTab bei Referenz-Update anpassen!!!
3482 
3483     if ( rHint.ISA( SfxSimpleHint ) &&
3484             ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
3485     {
3486         pDocShell = NULL; // ungültig geworden
3487     }
3488 }
3489 
3490 bool ScAnnotationsObj::GetAddressByIndex_Impl( sal_Int32 nIndex, ScAddress& rPos ) const
3491 {
3492     if (pDocShell)
3493     {
3494         sal_Int32 nFound = 0;
3495         ScDocument* pDoc = pDocShell->GetDocument();
3496         ScCellIterator aCellIter( pDoc, 0,0, nTab, MAXCOL,MAXROW, nTab );
3497         for( ScBaseCell* pCell = aCellIter.GetFirst(); pCell; pCell = aCellIter.GetNext() )
3498         {
3499             if (pCell->HasNote())
3500             {
3501                 if (nFound == nIndex)
3502                 {
3503                     rPos = ScAddress( aCellIter.GetCol(), aCellIter.GetRow(), aCellIter.GetTab() );
3504                     return true;
3505                 }
3506                 ++nFound;
3507             }
3508         }
3509     }
3510     return false;
3511 }
3512 
3513 ScAnnotationObj* ScAnnotationsObj::GetObjectByIndex_Impl( sal_Int32 nIndex ) const
3514 {
3515     if (pDocShell)
3516     {
3517         ScAddress aPos;
3518         if ( GetAddressByIndex_Impl( nIndex, aPos ) )
3519             return new ScAnnotationObj( pDocShell, aPos );
3520     }
3521     return NULL;
3522 }
3523 
3524 // XSheetAnnotations
3525 
3526 void SAL_CALL ScAnnotationsObj::insertNew(
3527         const table::CellAddress& aPosition, const ::rtl::OUString& rText )
3528                                                 throw(uno::RuntimeException)
3529 {
3530     ScUnoGuard aGuard;
3531     if (pDocShell)
3532     {
3533         DBG_ASSERT( aPosition.Sheet == nTab, "addAnnotation mit falschem Sheet" );
3534         ScAddress aPos( (SCCOL)aPosition.Column, (SCROW)aPosition.Row, nTab );
3535 
3536         ScDocFunc aFunc( *pDocShell );
3537         aFunc.ReplaceNote( aPos, rText, 0, 0, sal_True );
3538     }
3539 }
3540 
3541 void SAL_CALL ScAnnotationsObj::removeByIndex( sal_Int32 nIndex ) throw(uno::RuntimeException)
3542 {
3543     ScUnoGuard aGuard;
3544     if (pDocShell)
3545     {
3546         ScAddress aPos;
3547         if ( GetAddressByIndex_Impl( nIndex, aPos ) )
3548         {
3549             ScMarkData aMarkData;
3550             aMarkData.SelectTable( aPos.Tab(), sal_True );
3551             aMarkData.SetMultiMarkArea( ScRange(aPos) );
3552 
3553             ScDocFunc aFunc(*pDocShell);
3554             aFunc.DeleteContents( aMarkData, IDF_NOTE, sal_True, sal_True );
3555         }
3556     }
3557 }
3558 
3559 // XEnumerationAccess
3560 
3561 uno::Reference<container::XEnumeration> SAL_CALL ScAnnotationsObj::createEnumeration()
3562                                                     throw(uno::RuntimeException)
3563 {
3564     //! iterate directly (more efficiently)?
3565 
3566     ScUnoGuard aGuard;
3567     return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.CellAnnotationsEnumeration")));
3568 }
3569 
3570 // XIndexAccess
3571 
3572 sal_Int32 SAL_CALL ScAnnotationsObj::getCount() throw(uno::RuntimeException)
3573 {
3574     ScUnoGuard aGuard;
3575     sal_uLong nCount = 0;
3576     if (pDocShell)
3577     {
3578         ScCellIterator aCellIter( pDocShell->GetDocument(), 0,0, nTab, MAXCOL,MAXROW, nTab );
3579         for( ScBaseCell* pCell = aCellIter.GetFirst(); pCell; pCell = aCellIter.GetNext() )
3580             if (pCell->HasNote())
3581                 ++nCount;
3582     }
3583     return nCount;
3584 }
3585 
3586 uno::Any SAL_CALL ScAnnotationsObj::getByIndex( sal_Int32 nIndex )
3587                             throw(lang::IndexOutOfBoundsException,
3588                                     lang::WrappedTargetException, uno::RuntimeException)
3589 {
3590     ScUnoGuard aGuard;
3591     uno::Reference<sheet::XSheetAnnotation> xAnnotation(GetObjectByIndex_Impl(nIndex));
3592     if (xAnnotation.is())
3593         return uno::makeAny(xAnnotation);
3594     else
3595         throw lang::IndexOutOfBoundsException();
3596 //    return uno::Any();
3597 }
3598 
3599 uno::Type SAL_CALL ScAnnotationsObj::getElementType() throw(uno::RuntimeException)
3600 {
3601     ScUnoGuard aGuard;
3602     return getCppuType((uno::Reference<sheet::XSheetAnnotation>*)0);
3603 }
3604 
3605 sal_Bool SAL_CALL ScAnnotationsObj::hasElements() throw(uno::RuntimeException)
3606 {
3607     ScUnoGuard aGuard;
3608     return ( getCount() != 0 );
3609 }
3610 
3611 //------------------------------------------------------------------------
3612 
3613 ScScenariosObj::ScScenariosObj(ScDocShell* pDocSh, SCTAB nT) :
3614     pDocShell( pDocSh ),
3615     nTab     ( nT )
3616 {
3617     pDocShell->GetDocument()->AddUnoObject(*this);
3618 }
3619 
3620 ScScenariosObj::~ScScenariosObj()
3621 {
3622     if (pDocShell)
3623         pDocShell->GetDocument()->RemoveUnoObject(*this);
3624 }
3625 
3626 void ScScenariosObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
3627 {
3628     if ( rHint.ISA( ScUpdateRefHint ) )
3629     {
3630 //        const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
3631 
3632         //! Referenz-Update fuer Tab und Start/Ende
3633     }
3634     else if ( rHint.ISA( SfxSimpleHint ) &&
3635             ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
3636     {
3637         pDocShell = NULL; // ungültig geworden
3638     }
3639 }
3640 
3641 // XScenarios
3642 
3643 sal_Bool ScScenariosObj::GetScenarioIndex_Impl( const rtl::OUString& rName, SCTAB& rIndex )
3644 {
3645     //! Case-insensitiv ????
3646 
3647     if ( pDocShell )
3648     {
3649         String aString(rName);
3650 
3651         String aTabName;
3652         ScDocument* pDoc = pDocShell->GetDocument();
3653         SCTAB nCount = (SCTAB)getCount();
3654         for (SCTAB i=0; i<nCount; i++)
3655             if (pDoc->GetName( nTab+i+1, aTabName ))
3656                 if ( aTabName == aString )
3657                 {
3658                     rIndex = i;
3659                     return sal_True;
3660                 }
3661     }
3662 
3663     return sal_False;
3664 }
3665 
3666 ScTableSheetObj* ScScenariosObj::GetObjectByIndex_Impl(sal_Int32 nIndex)
3667 {
3668     sal_uInt16 nCount = (sal_uInt16)getCount();
3669     if ( pDocShell && nIndex >= 0 && nIndex < nCount )
3670         return new ScTableSheetObj( pDocShell, nTab+static_cast<SCTAB>(nIndex)+1 );
3671 
3672     return NULL; // kein Dokument oder falscher Index
3673 }
3674 
3675 ScTableSheetObj* ScScenariosObj::GetObjectByName_Impl(const rtl::OUString& aName)
3676 {
3677     SCTAB nIndex;
3678     if ( pDocShell && GetScenarioIndex_Impl( aName, nIndex ) )
3679         return new ScTableSheetObj( pDocShell, nTab+nIndex+1 );
3680 
3681     return NULL; // not found
3682 }
3683 
3684 void SAL_CALL ScScenariosObj::addNewByName( const rtl::OUString& aName,
3685                                 const uno::Sequence<table::CellRangeAddress>& aRanges,
3686                                 const rtl::OUString& aComment )
3687                                     throw(uno::RuntimeException)
3688 {
3689     ScUnoGuard aGuard;
3690     if ( pDocShell )
3691     {
3692         ScMarkData aMarkData;
3693         aMarkData.SelectTable( nTab, sal_True );
3694 
3695         sal_uInt16 nRangeCount = (sal_uInt16)aRanges.getLength();
3696         if (nRangeCount)
3697         {
3698             const table::CellRangeAddress* pAry = aRanges.getConstArray();
3699             for (sal_uInt16 i=0; i<nRangeCount; i++)
3700             {
3701                 DBG_ASSERT( pAry[i].Sheet == nTab, "addScenario mit falscher Tab" );
3702                 ScRange aRange( (SCCOL)pAry[i].StartColumn, (SCROW)pAry[i].StartRow, nTab,
3703                                 (SCCOL)pAry[i].EndColumn,   (SCROW)pAry[i].EndRow,   nTab );
3704 
3705                 aMarkData.SetMultiMarkArea( aRange );
3706             }
3707         }
3708 
3709         String aNameStr(aName);
3710         String aCommStr(aComment);
3711 
3712         Color aColor( COL_LIGHTGRAY ); // Default
3713         sal_uInt16 nFlags = SC_SCENARIO_SHOWFRAME | SC_SCENARIO_PRINTFRAME | SC_SCENARIO_TWOWAY | SC_SCENARIO_PROTECT;
3714 
3715         pDocShell->MakeScenario( nTab, aNameStr, aCommStr, aColor, nFlags, aMarkData );
3716     }
3717 }
3718 
3719 void SAL_CALL ScScenariosObj::removeByName( const rtl::OUString& aName )
3720                                             throw(uno::RuntimeException)
3721 {
3722     ScUnoGuard aGuard;
3723     SCTAB nIndex;
3724     if ( pDocShell && GetScenarioIndex_Impl( aName, nIndex ) )
3725     {
3726         ScDocFunc aFunc(*pDocShell);
3727         aFunc.DeleteTable( nTab+nIndex+1, sal_True, sal_True );
3728     }
3729 }
3730 
3731 // XEnumerationAccess
3732 
3733 uno::Reference<container::XEnumeration> SAL_CALL ScScenariosObj::createEnumeration()
3734                                                     throw(uno::RuntimeException)
3735 {
3736     ScUnoGuard aGuard;
3737     return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.ScenariosEnumeration")));
3738 }
3739 
3740 // XIndexAccess
3741 
3742 sal_Int32 SAL_CALL ScScenariosObj::getCount() throw(uno::RuntimeException)
3743 {
3744     ScUnoGuard aGuard;
3745     SCTAB nCount = 0;
3746     if ( pDocShell )
3747     {
3748         ScDocument* pDoc = pDocShell->GetDocument();
3749         if (!pDoc->IsScenario(nTab))
3750         {
3751             SCTAB nTabCount = pDoc->GetTableCount();
3752             SCTAB nNext = nTab + 1;
3753             while (nNext < nTabCount && pDoc->IsScenario(nNext))
3754             {
3755                 ++nCount;
3756                 ++nNext;
3757             }
3758         }
3759     }
3760     return nCount;
3761 }
3762 
3763 uno::Any SAL_CALL ScScenariosObj::getByIndex( sal_Int32 nIndex )
3764                             throw(lang::IndexOutOfBoundsException,
3765                                     lang::WrappedTargetException, uno::RuntimeException)
3766 {
3767     ScUnoGuard aGuard;
3768     uno::Reference<sheet::XScenario> xScen(GetObjectByIndex_Impl(nIndex));
3769     if (xScen.is())
3770         return uno::makeAny(xScen);
3771     else
3772         throw lang::IndexOutOfBoundsException();
3773 //    return uno::Any();
3774 }
3775 
3776 uno::Type SAL_CALL ScScenariosObj::getElementType() throw(uno::RuntimeException)
3777 {
3778     ScUnoGuard aGuard;
3779     return getCppuType((uno::Reference<sheet::XScenario>*)0);
3780 }
3781 
3782 sal_Bool SAL_CALL ScScenariosObj::hasElements() throw(uno::RuntimeException)
3783 {
3784     ScUnoGuard aGuard;
3785     return ( getCount() != 0 );
3786 }
3787 
3788 uno::Any SAL_CALL ScScenariosObj::getByName( const rtl::OUString& aName )
3789             throw(container::NoSuchElementException,
3790                     lang::WrappedTargetException, uno::RuntimeException)
3791 {
3792     ScUnoGuard aGuard;
3793     uno::Reference<sheet::XScenario> xScen(GetObjectByName_Impl(aName));
3794     if (xScen.is())
3795         return uno::makeAny(xScen);
3796     else
3797         throw container::NoSuchElementException();
3798 //    return uno::Any();
3799 }
3800 
3801 uno::Sequence<rtl::OUString> SAL_CALL ScScenariosObj::getElementNames()
3802                                                 throw(uno::RuntimeException)
3803 {
3804     ScUnoGuard aGuard;
3805     SCTAB nCount = (SCTAB)getCount();
3806     uno::Sequence<rtl::OUString> aSeq(nCount);
3807 
3808     if ( pDocShell ) // sonst ist auch Count = 0
3809     {
3810         String aTabName;
3811         ScDocument* pDoc = pDocShell->GetDocument();
3812         rtl::OUString* pAry = aSeq.getArray();
3813         for (SCTAB i=0; i<nCount; i++)
3814             if (pDoc->GetName( nTab+i+1, aTabName ))
3815                 pAry[i] = aTabName;
3816     }
3817 
3818     return aSeq;
3819 }
3820 
3821 sal_Bool SAL_CALL ScScenariosObj::hasByName( const rtl::OUString& aName )
3822                                         throw(uno::RuntimeException)
3823 {
3824     ScUnoGuard aGuard;
3825     SCTAB nIndex;
3826     return GetScenarioIndex_Impl( aName, nIndex );
3827 }
3828 
3829 /* vim: set noet sw=4 ts=4: */
3830