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