xref: /trunk/main/sc/source/ui/unoobj/docuno.cxx (revision 64e1a766db52c046a1b3492552b710b5da405cc5)
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->urlIsSafe( rURL ) ) {
1320             return sal_True;
1321         }
1322         Window* pDlgParent = 0;
1323         if ( pFrm )
1324             pDlgParent = &pFrm->GetWindow();
1325         if ( !pDlgParent )
1326             pDlgParent = pDocShell->GetDialogParent( pMedium );
1327         if ( pDlgParent )
1328             return pLinkMgr->GetUserAllowsLinkUpdate( pDlgParent );
1329     }
1330     return sal_False;
1331 }
1332 
1333 // XLinkTargetSupplier
1334 
1335 uno::Reference<container::XNameAccess> SAL_CALL ScModelObj::getLinks() throw(uno::RuntimeException)
1336 {
1337     ScUnoGuard aGuard;
1338     if (pDocShell)
1339         return new ScLinkTargetTypesObj(pDocShell);
1340     return NULL;
1341 }
1342 
1343 // XActionLockable
1344 
1345 sal_Bool SAL_CALL ScModelObj::isActionLocked() throw(uno::RuntimeException)
1346 {
1347     ScUnoGuard aGuard;
1348     sal_Bool bLocked = sal_False;
1349     if (pDocShell)
1350         bLocked = ( pDocShell->GetLockCount() != 0 );
1351     return bLocked;
1352 }
1353 
1354 void SAL_CALL ScModelObj::addActionLock() throw(uno::RuntimeException)
1355 {
1356     ScUnoGuard aGuard;
1357     if (pDocShell)
1358         pDocShell->LockDocument();
1359 }
1360 
1361 void SAL_CALL ScModelObj::removeActionLock() throw(uno::RuntimeException)
1362 {
1363     ScUnoGuard aGuard;
1364     if (pDocShell)
1365         pDocShell->UnlockDocument();
1366 }
1367 
1368 void SAL_CALL ScModelObj::setActionLocks( sal_Int16 nLock ) throw(uno::RuntimeException)
1369 {
1370     ScUnoGuard aGuard;
1371     if (pDocShell)
1372         pDocShell->SetLockCount(nLock);
1373 }
1374 
1375 sal_Int16 SAL_CALL ScModelObj::resetActionLocks() throw(uno::RuntimeException)
1376 {
1377     ScUnoGuard aGuard;
1378     sal_uInt16 nRet = 0;
1379     if (pDocShell)
1380     {
1381         nRet = pDocShell->GetLockCount();
1382         pDocShell->SetLockCount(0);
1383     }
1384     return nRet;
1385 }
1386 
1387 void SAL_CALL ScModelObj::lockControllers() throw (::com::sun::star::uno::RuntimeException)
1388 {
1389     ScUnoGuard aGuard;
1390     SfxBaseModel::lockControllers();
1391     if (pDocShell)
1392         pDocShell->LockPaint();
1393 }
1394 
1395 void SAL_CALL ScModelObj::unlockControllers() throw (::com::sun::star::uno::RuntimeException)
1396 {
1397     ScUnoGuard aGuard;
1398     if (hasControllersLocked())
1399     {
1400         SfxBaseModel::unlockControllers();
1401         if (pDocShell)
1402             pDocShell->UnlockPaint();
1403     }
1404 }
1405 
1406 // XCalculate
1407 
1408 void SAL_CALL ScModelObj::calculate() throw(uno::RuntimeException)
1409 {
1410     ScUnoGuard aGuard;
1411     if (pDocShell)
1412         pDocShell->DoRecalc(sal_True);
1413     else
1414     {
1415         DBG_ERROR("keine DocShell"); //! Exception oder so?
1416     }
1417 }
1418 
1419 void SAL_CALL ScModelObj::calculateAll() throw(uno::RuntimeException)
1420 {
1421     ScUnoGuard aGuard;
1422     if (pDocShell)
1423         pDocShell->DoHardRecalc(sal_True);
1424     else
1425     {
1426         DBG_ERROR("keine DocShell"); //! Exception oder so?
1427     }
1428 }
1429 
1430 sal_Bool SAL_CALL ScModelObj::isAutomaticCalculationEnabled() throw(uno::RuntimeException)
1431 {
1432     ScUnoGuard aGuard;
1433     if (pDocShell)
1434         return pDocShell->GetDocument()->GetAutoCalc();
1435 
1436     DBG_ERROR("keine DocShell"); //! Exception oder so?
1437     return sal_False;
1438 }
1439 
1440 void SAL_CALL ScModelObj::enableAutomaticCalculation( sal_Bool bEnabled )
1441                                                 throw(uno::RuntimeException)
1442 {
1443     ScUnoGuard aGuard;
1444     if (pDocShell)
1445     {
1446         ScDocument* pDoc = pDocShell->GetDocument();
1447         if ( pDoc->GetAutoCalc() != bEnabled )
1448         {
1449             pDoc->SetAutoCalc( bEnabled );
1450             pDocShell->SetDocumentModified();
1451         }
1452     }
1453     else
1454     {
1455         DBG_ERROR("keine DocShell"); //! Exception oder so?
1456     }
1457 }
1458 
1459 // XProtectable
1460 
1461 void SAL_CALL ScModelObj::protect( const rtl::OUString& aPassword ) throw(uno::RuntimeException)
1462 {
1463     ScUnoGuard aGuard;
1464     // #i108245# if already protected, don't change anything
1465     if ( pDocShell && !pDocShell->GetDocument()->IsDocProtected() )
1466     {
1467         String aString(aPassword);
1468 
1469         ScDocFunc aFunc(*pDocShell);
1470         aFunc.Protect( TABLEID_DOC, aString, sal_True );
1471     }
1472 }
1473 
1474 void SAL_CALL ScModelObj::unprotect( const rtl::OUString& aPassword )
1475                         throw(lang::IllegalArgumentException, uno::RuntimeException)
1476 {
1477     ScUnoGuard aGuard;
1478     if (pDocShell)
1479     {
1480         String aString(aPassword);
1481 
1482         ScDocFunc aFunc(*pDocShell);
1483         sal_Bool bDone = aFunc.Unprotect( TABLEID_DOC, aString, sal_True );
1484         if (!bDone)
1485             throw lang::IllegalArgumentException();
1486     }
1487 }
1488 
1489 sal_Bool SAL_CALL ScModelObj::isProtected() throw(uno::RuntimeException)
1490 {
1491     ScUnoGuard aGuard;
1492     if (pDocShell)
1493         return pDocShell->GetDocument()->IsDocProtected();
1494 
1495     DBG_ERROR("keine DocShell"); //! Exception oder so?
1496     return sal_False;
1497 }
1498 
1499 // XDrawPagesSupplier
1500 
1501 uno::Reference<drawing::XDrawPages> SAL_CALL ScModelObj::getDrawPages() throw(uno::RuntimeException)
1502 {
1503     ScUnoGuard aGuard;
1504     if (pDocShell)
1505         return new ScDrawPagesObj(pDocShell);
1506 
1507     DBG_ERROR("keine DocShell"); //! Exception oder so?
1508     return NULL;
1509 }
1510 
1511 #if 0
1512 // XPrintable
1513 
1514 rtl::OUString ScModelObj::getPrinterName(void) const
1515 {
1516     ScUnoGuard aGuard;
1517     if (pDocShell)
1518     {
1519         SfxPrinter* pPrinter = pDocShell->GetPrinter();
1520         if (pPrinter)
1521             return pPrinter->GetName();
1522     }
1523 
1524     DBG_ERROR("getPrinterName: keine DocShell oder kein Printer");
1525     return rtl::OUString();
1526 }
1527 
1528 void ScModelObj::setPrinterName(const rtl::OUString& PrinterName)
1529 {
1530     ScUnoGuard aGuard;
1531     //  Drucker setzen - wie in SfxViewShell::ExecPrint_Impl
1532 
1533     if (pDocShell)
1534     {
1535         SfxPrinter* pPrinter = pDocShell->GetPrinter();
1536         if (pPrinter)
1537         {
1538             String aString(PrinterName);
1539             SfxPrinter* pNewPrinter = new SfxPrinter( pPrinter->GetOptions().Clone(), aString );
1540             if (pNewPrinter->IsKnown())
1541                 pDocShell->SetPrinter( pNewPrinter, SFX_PRINTER_PRINTER );
1542             else
1543                 delete pNewPrinter;
1544         }
1545     }
1546 }
1547 
1548 XPropertySetRef ScModelObj::createPrintOptions(void)
1549 {
1550     ScUnoGuard aGuard;
1551     return new ScPrintSettingsObj; //! ScPrintSettingsObj implementieren!
1552 }
1553 
1554 void ScModelObj::print(const XPropertySetRef& xOptions)
1555 {
1556     ScUnoGuard aGuard;
1557     if (pDocShell)
1558     {
1559         //! xOptions auswerten (wie denn?)
1560 
1561         //! muss noch
1562     }
1563 }
1564 #endif
1565 
1566 // XGoalSeek
1567 
1568 sheet::GoalResult SAL_CALL ScModelObj::seekGoal(
1569                                 const table::CellAddress& aFormulaPosition,
1570                                 const table::CellAddress& aVariablePosition,
1571                                 const ::rtl::OUString& aGoalValue )
1572                                     throw(uno::RuntimeException)
1573 {
1574     ScUnoGuard aGuard;
1575     sheet::GoalResult aResult;
1576     aResult.Divergence = DBL_MAX; // nichts gefunden
1577     if (pDocShell)
1578     {
1579         WaitObject aWait( pDocShell->GetActiveDialogParent() );
1580         String aGoalString(aGoalValue);
1581         ScDocument* pDoc = pDocShell->GetDocument();
1582         double fValue = 0.0;
1583         sal_Bool bFound = pDoc->Solver(
1584                     (SCCOL)aFormulaPosition.Column, (SCROW)aFormulaPosition.Row, aFormulaPosition.Sheet,
1585                     (SCCOL)aVariablePosition.Column, (SCROW)aVariablePosition.Row, aVariablePosition.Sheet,
1586                     aGoalString, fValue );
1587         aResult.Result = fValue;
1588         if (bFound)
1589             aResult.Divergence = 0.0; //! das ist gelogen
1590     }
1591     return aResult;
1592 }
1593 
1594 // XConsolidatable
1595 
1596 uno::Reference<sheet::XConsolidationDescriptor> SAL_CALL ScModelObj::createConsolidationDescriptor(
1597                                 sal_Bool bEmpty ) throw(uno::RuntimeException)
1598 {
1599     ScUnoGuard aGuard;
1600     ScConsolidationDescriptor* pNew = new ScConsolidationDescriptor;
1601     if ( pDocShell && !bEmpty )
1602     {
1603         ScDocument* pDoc = pDocShell->GetDocument();
1604         const ScConsolidateParam* pParam = pDoc->GetConsolidateDlgData();
1605         if (pParam)
1606             pNew->SetParam( *pParam );
1607     }
1608     return pNew;
1609 }
1610 
1611 void SAL_CALL ScModelObj::consolidate(
1612         const uno::Reference<sheet::XConsolidationDescriptor>& xDescriptor )
1613                                                 throw(uno::RuntimeException)
1614 {
1615     ScUnoGuard aGuard;
1616     //  das könnte theoretisch ein fremdes Objekt sein, also nur das
1617     //  öffentliche XConsolidationDescriptor Interface benutzen, um
1618     //  die Daten in ein ScConsolidationDescriptor Objekt zu kopieren:
1619     //! wenn es schon ein ScConsolidationDescriptor ist, direkt per getImplementation?
1620 
1621     ScConsolidationDescriptor aImpl;
1622     aImpl.setFunction( xDescriptor->getFunction() );
1623     aImpl.setSources( xDescriptor->getSources() );
1624     aImpl.setStartOutputPosition( xDescriptor->getStartOutputPosition() );
1625     aImpl.setUseColumnHeaders( xDescriptor->getUseColumnHeaders() );
1626     aImpl.setUseRowHeaders( xDescriptor->getUseRowHeaders() );
1627     aImpl.setInsertLinks( xDescriptor->getInsertLinks() );
1628 
1629     if (pDocShell)
1630     {
1631         const ScConsolidateParam& rParam = aImpl.GetParam();
1632         pDocShell->DoConsolidate( rParam, sal_True );
1633         pDocShell->GetDocument()->SetConsolidateDlgData( &rParam );
1634     }
1635 }
1636 
1637 // XDocumentAuditing
1638 
1639 void SAL_CALL ScModelObj::refreshArrows() throw(uno::RuntimeException)
1640 {
1641     ScUnoGuard aGuard;
1642     if (pDocShell)
1643     {
1644         ScDocFunc aFunc(*pDocShell);
1645         aFunc.DetectiveRefresh();
1646     }
1647 }
1648 
1649 // XViewDataSupplier
1650 uno::Reference< container::XIndexAccess > SAL_CALL ScModelObj::getViewData(  )
1651     throw (uno::RuntimeException)
1652 {
1653     uno::Reference < container::XIndexAccess > xRet( SfxBaseModel::getViewData() );
1654 
1655     if( !xRet.is() )
1656     {
1657         ScUnoGuard aGuard;
1658         if (pDocShell && pDocShell->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED)
1659         {
1660             xRet.set(uno::Reference < container::XIndexAccess >::query(::comphelper::getProcessServiceFactory()->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.document.IndexedPropertyValues")))));
1661 
1662             uno::Reference < container::XIndexContainer > xCont( xRet, uno::UNO_QUERY );
1663             DBG_ASSERT( xCont.is(), "ScModelObj::getViewData() failed for OLE object" );
1664             if( xCont.is() )
1665             {
1666                 uno::Sequence< beans::PropertyValue > aSeq;
1667                 aSeq.realloc(1);
1668                 String sName;
1669                 pDocShell->GetDocument()->GetName( pDocShell->GetDocument()->GetVisibleTab(), sName );
1670                 rtl::OUString sOUName(sName);
1671                 aSeq[0].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ACTIVETABLE));
1672                 aSeq[0].Value <<= sOUName;
1673                 xCont->insertByIndex( 0, uno::makeAny( aSeq ) );
1674             }
1675         }
1676     }
1677 
1678     return xRet;
1679 }
1680 
1681 //  XPropertySet (Doc-Optionen)
1682 //! auch an der Applikation anbieten?
1683 
1684 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScModelObj::getPropertySetInfo()
1685                                                         throw(uno::RuntimeException)
1686 {
1687     ScUnoGuard aGuard;
1688     static uno::Reference<beans::XPropertySetInfo> aRef(
1689         new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
1690     return aRef;
1691 }
1692 
1693 void SAL_CALL ScModelObj::setPropertyValue(
1694                         const rtl::OUString& aPropertyName, const uno::Any& aValue )
1695                 throw(beans::UnknownPropertyException, beans::PropertyVetoException,
1696                         lang::IllegalArgumentException, lang::WrappedTargetException,
1697                         uno::RuntimeException)
1698 {
1699     ScUnoGuard aGuard;
1700     String aString(aPropertyName);
1701 
1702     if (pDocShell)
1703     {
1704         ScDocument* pDoc = pDocShell->GetDocument();
1705         const ScDocOptions& rOldOpt = pDoc->GetDocOptions();
1706         ScDocOptions aNewOpt = rOldOpt;
1707 
1708         sal_Bool bOpt = ScDocOptionsHelper::setPropertyValue( aNewOpt, *aPropSet.getPropertyMap(), aPropertyName, aValue );
1709         if (bOpt)
1710         {
1711             // done...
1712         }
1713         else if ( aString.EqualsAscii( SC_UNONAME_CLOCAL ) )
1714         {
1715             lang::Locale aLocale;
1716             if ( aValue >>= aLocale )
1717             {
1718                 LanguageType eLatin, eCjk, eCtl;
1719                 pDoc->GetLanguage( eLatin, eCjk, eCtl );
1720                 eLatin = ScUnoConversion::GetLanguage(aLocale);
1721                 pDoc->SetLanguage( eLatin, eCjk, eCtl );
1722             }
1723         }
1724         else if ( aString.EqualsAscii( SC_UNO_CODENAME ) )
1725         {
1726             rtl::OUString sCodeName;
1727             if ( aValue >>= sCodeName )
1728                 pDoc->SetCodeName( sCodeName );
1729         }
1730         else if ( aString.EqualsAscii( SC_UNO_CJK_CLOCAL ) )
1731         {
1732             lang::Locale aLocale;
1733             if ( aValue >>= aLocale )
1734             {
1735                 LanguageType eLatin, eCjk, eCtl;
1736                 pDoc->GetLanguage( eLatin, eCjk, eCtl );
1737                 eCjk = ScUnoConversion::GetLanguage(aLocale);
1738                 pDoc->SetLanguage( eLatin, eCjk, eCtl );
1739             }
1740         }
1741         else if ( aString.EqualsAscii( SC_UNO_CTL_CLOCAL ) )
1742         {
1743             lang::Locale aLocale;
1744             if ( aValue >>= aLocale )
1745             {
1746                 LanguageType eLatin, eCjk, eCtl;
1747                 pDoc->GetLanguage( eLatin, eCjk, eCtl );
1748                 eCtl = ScUnoConversion::GetLanguage(aLocale);
1749                 pDoc->SetLanguage( eLatin, eCjk, eCtl );
1750             }
1751         }
1752         else if ( aString.EqualsAscii( SC_UNO_APPLYFMDES ) )
1753         {
1754             //  model is created if not there
1755             ScDrawLayer* pModel = pDocShell->MakeDrawLayer();
1756             pModel->SetOpenInDesignMode( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1757 
1758             SfxBindings* pBindings = pDocShell->GetViewBindings();
1759             if (pBindings)
1760                 pBindings->Invalidate( SID_FM_OPEN_READONLY );
1761         }
1762         else if ( aString.EqualsAscii( SC_UNO_AUTOCONTFOC ) )
1763         {
1764             //  model is created if not there
1765             ScDrawLayer* pModel = pDocShell->MakeDrawLayer();
1766             pModel->SetAutoControlFocus( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1767 
1768             SfxBindings* pBindings = pDocShell->GetViewBindings();
1769             if (pBindings)
1770                 pBindings->Invalidate( SID_FM_AUTOCONTROLFOCUS );
1771         }
1772         else if ( aString.EqualsAscii( SC_UNO_ISLOADED ) )
1773         {
1774             pDocShell->SetEmpty( !ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1775         }
1776         else if ( aString.EqualsAscii( SC_UNO_ISUNDOENABLED ) )
1777         {
1778             sal_Bool bUndoEnabled = ScUnoHelpFunctions::GetBoolFromAny( aValue );
1779             pDoc->EnableUndo( bUndoEnabled );
1780             sal_uInt16 nCount = ( bUndoEnabled ?
1781                 static_cast< sal_uInt16 >( SvtUndoOptions().GetUndoCount() ) : 0 );
1782             pDocShell->GetUndoManager()->SetMaxUndoActionCount( nCount );
1783         }
1784         else if ( aString.EqualsAscii( SC_UNO_ISADJUSTHEIGHTENABLED ) )
1785         {
1786             bool bOldAdjustHeightEnabled = pDoc->IsAdjustHeightEnabled();
1787             bool bAdjustHeightEnabled = ScUnoHelpFunctions::GetBoolFromAny( aValue );
1788             if( bOldAdjustHeightEnabled != bAdjustHeightEnabled )
1789             {
1790                 pDoc->EnableAdjustHeight( bAdjustHeightEnabled );
1791                 if( bAdjustHeightEnabled )
1792                     pDocShell->UpdateAllRowHeights();
1793             }
1794         }
1795         else if ( aString.EqualsAscii( SC_UNO_ISEXECUTELINKENABLED ) )
1796         {
1797             pDoc->EnableExecuteLink( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1798         }
1799         else if ( aString.EqualsAscii( SC_UNO_ISCHANGEREADONLYENABLED ) )
1800         {
1801             pDoc->EnableChangeReadOnly( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1802         }
1803         else if ( aString.EqualsAscii( "BuildId" ) )
1804         {
1805             aValue >>= maBuildId;
1806         }
1807         else if ( aString.EqualsAscii( "SavedObject" ) ) // set from chart after saving
1808         {
1809             rtl::OUString aObjName;
1810             aValue >>= aObjName;
1811             if ( aObjName.getLength() )
1812                 pDoc->RestoreChartListener( aObjName );
1813         }
1814 
1815         if ( aNewOpt != rOldOpt )
1816         {
1817             pDoc->SetDocOptions( aNewOpt );
1818             //  Don't recalculate while loading XML, when the formula text is stored.
1819             //  Recalculation after loading is handled separately.
1820             //! Recalc only for options that need it?
1821             if ( !pDoc->IsImportingXML() )
1822                 pDocShell->DoHardRecalc( sal_True );
1823             pDocShell->SetDocumentModified();
1824         }
1825     }
1826 }
1827 
1828 uno::Any SAL_CALL ScModelObj::getPropertyValue( const rtl::OUString& aPropertyName )
1829                 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
1830                         uno::RuntimeException)
1831 {
1832     ScUnoGuard aGuard;
1833     String aString(aPropertyName);
1834     uno::Any aRet;
1835 
1836     if (pDocShell)
1837     {
1838         ScDocument* pDoc = pDocShell->GetDocument();
1839         const ScDocOptions& rOpt = pDoc->GetDocOptions();
1840         aRet = ScDocOptionsHelper::getPropertyValue( rOpt, *aPropSet.getPropertyMap(), aPropertyName );
1841         if ( aRet.hasValue() )
1842         {
1843             // done...
1844         }
1845         else if ( aString.EqualsAscii( SC_UNONAME_CLOCAL ) )
1846         {
1847             LanguageType eLatin, eCjk, eCtl;
1848             pDoc->GetLanguage( eLatin, eCjk, eCtl );
1849 
1850             lang::Locale aLocale;
1851             ScUnoConversion::FillLocale( aLocale, eLatin );
1852             aRet <<= aLocale;
1853         }
1854         else if ( aString.EqualsAscii( SC_UNO_CODENAME ) )
1855         {
1856             rtl::OUString sCodeName = pDoc->GetCodeName();
1857             aRet <<= sCodeName;
1858         }
1859 
1860         else if ( aString.EqualsAscii( SC_UNO_CJK_CLOCAL ) )
1861         {
1862             LanguageType eLatin, eCjk, eCtl;
1863             pDoc->GetLanguage( eLatin, eCjk, eCtl );
1864 
1865             lang::Locale aLocale;
1866             ScUnoConversion::FillLocale( aLocale, eCjk );
1867             aRet <<= aLocale;
1868         }
1869         else if ( aString.EqualsAscii( SC_UNO_CTL_CLOCAL ) )
1870         {
1871             LanguageType eLatin, eCjk, eCtl;
1872             pDoc->GetLanguage( eLatin, eCjk, eCtl );
1873 
1874             lang::Locale aLocale;
1875             ScUnoConversion::FillLocale( aLocale, eCtl );
1876             aRet <<= aLocale;
1877         }
1878         else if ( aString.EqualsAscii( SC_UNO_NAMEDRANGES2 ) )
1879         {
1880             aRet <<= uno::Reference<sheet::XNamedRanges2>(new ScNamedRangesObj( pDocShell ));
1881         }
1882         else if ( aString.EqualsAscii( SC_UNO_NAMEDRANGES ) )
1883         {
1884             aRet <<= uno::Reference<sheet::XNamedRanges>(new ScNamedRangesObj( pDocShell ));
1885         }
1886         else if ( aString.EqualsAscii( SC_UNO_DATABASERNG ) )
1887         {
1888             aRet <<= uno::Reference<sheet::XDatabaseRanges>(new ScDatabaseRangesObj( pDocShell ));
1889         }
1890         else if ( aString.EqualsAscii( SC_UNO_COLLABELRNG ) )
1891         {
1892             aRet <<= uno::Reference<sheet::XLabelRanges>(new ScLabelRangesObj( pDocShell, sal_True ));
1893         }
1894         else if ( aString.EqualsAscii( SC_UNO_ROWLABELRNG ) )
1895         {
1896             aRet <<= uno::Reference<sheet::XLabelRanges>(new ScLabelRangesObj( pDocShell, sal_False ));
1897         }
1898         else if ( aString.EqualsAscii( SC_UNO_AREALINKS ) )
1899         {
1900             aRet <<= uno::Reference<sheet::XAreaLinks>(new ScAreaLinksObj( pDocShell ));
1901         }
1902         else if ( aString.EqualsAscii( SC_UNO_DDELINKS ) )
1903         {
1904             aRet <<= uno::Reference<container::XNameAccess>(new ScDDELinksObj( pDocShell ));
1905         }
1906         else if ( aString.EqualsAscii( SC_UNO_EXTERNALDOCLINKS ) )
1907         {
1908             aRet <<= uno::Reference<sheet::XExternalDocLinks>(new ScExternalDocLinksObj(pDocShell));
1909         }
1910         else if ( aString.EqualsAscii( SC_UNO_SHEETLINKS ) )
1911         {
1912             aRet <<= uno::Reference<container::XNameAccess>(new ScSheetLinksObj( pDocShell ));
1913         }
1914         else if ( aString.EqualsAscii( SC_UNO_APPLYFMDES ) )
1915         {
1916             // default for no model is TRUE
1917             ScDrawLayer* pModel = pDoc->GetDrawLayer();
1918             sal_Bool bOpenInDesign = pModel ? pModel->GetOpenInDesignMode() : sal_True;
1919             ScUnoHelpFunctions::SetBoolInAny( aRet, bOpenInDesign );
1920         }
1921         else if ( aString.EqualsAscii( SC_UNO_AUTOCONTFOC ) )
1922         {
1923             // default for no model is FALSE
1924             ScDrawLayer* pModel = pDoc->GetDrawLayer();
1925             sal_Bool bAutoControlFocus = pModel ? pModel->GetAutoControlFocus() : sal_False;
1926             ScUnoHelpFunctions::SetBoolInAny( aRet, bAutoControlFocus );
1927         }
1928         else if ( aString.EqualsAscii( SC_UNO_FORBIDDEN ) )
1929         {
1930             aRet <<= uno::Reference<i18n::XForbiddenCharacters>(new ScForbiddenCharsObj( pDocShell ));
1931         }
1932         else if ( aString.EqualsAscii( SC_UNO_HASDRAWPAGES ) )
1933         {
1934             ScUnoHelpFunctions::SetBoolInAny( aRet, (pDocShell->GetDocument()->GetDrawLayer() != 0) );
1935         }
1936         else if ( aString.EqualsAscii( SC_UNO_BASICLIBRARIES ) )
1937         {
1938             aRet <<= pDocShell->GetBasicContainer();
1939         }
1940         else if ( aString.EqualsAscii( SC_UNO_DIALOGLIBRARIES ) )
1941         {
1942             aRet <<= pDocShell->GetDialogContainer();
1943         }
1944         else if ( aString.EqualsAscii( SC_UNO_VBAGLOBNAME ) )
1945         {
1946             /*  #i111553# This property provides the name of the constant that
1947                 will be used to store this model in the global Basic manager.
1948                 That constant will be equivalent to 'ThisComponent' but for
1949                 each application, so e.g. a 'ThisExcelDoc' and a 'ThisWordDoc'
1950                 constant can co-exist, as required by VBA. */
1951             aRet <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ThisExcelDoc" ) );
1952         }
1953         else if ( aString.EqualsAscii( SC_UNO_RUNTIMEUID ) )
1954         {
1955             aRet <<= getRuntimeUID();
1956         }
1957         else if ( aString.EqualsAscii( SC_UNO_HASVALIDSIGNATURES ) )
1958         {
1959             aRet <<= hasValidSignatures();
1960         }
1961         else if ( aString.EqualsAscii( SC_UNO_ISLOADED ) )
1962         {
1963             ScUnoHelpFunctions::SetBoolInAny( aRet, !pDocShell->IsEmpty() );
1964         }
1965         else if ( aString.EqualsAscii( SC_UNO_ISUNDOENABLED ) )
1966         {
1967             ScUnoHelpFunctions::SetBoolInAny( aRet, pDoc->IsUndoEnabled() );
1968         }
1969         else if ( aString.EqualsAscii( SC_UNO_ISADJUSTHEIGHTENABLED ) )
1970         {
1971             ScUnoHelpFunctions::SetBoolInAny( aRet, pDoc->IsAdjustHeightEnabled() );
1972         }
1973         else if ( aString.EqualsAscii( SC_UNO_ISEXECUTELINKENABLED ) )
1974         {
1975             ScUnoHelpFunctions::SetBoolInAny( aRet, pDoc->IsExecuteLinkEnabled() );
1976         }
1977         else if ( aString.EqualsAscii( SC_UNO_ISCHANGEREADONLYENABLED ) )
1978         {
1979             ScUnoHelpFunctions::SetBoolInAny( aRet, pDoc->IsChangeReadOnlyEnabled() );
1980         }
1981         else if ( aString.EqualsAscii( SC_UNO_REFERENCEDEVICE ) )
1982         {
1983             VCLXDevice* pXDev = new VCLXDevice();
1984             pXDev->SetOutputDevice( pDoc->GetRefDevice() );
1985             aRet <<= uno::Reference< awt::XDevice >( pXDev );
1986         }
1987         else if ( aString.EqualsAscii( "BuildId" ) )
1988         {
1989             aRet <<= maBuildId;
1990         }
1991         else if ( aString.EqualsAscii( "InternalDocument" ) )
1992         {
1993             ScUnoHelpFunctions::SetBoolInAny( aRet, (pDocShell->GetCreateMode() == SFX_CREATE_MODE_INTERNAL) );
1994         }
1995     }
1996 
1997     return aRet;
1998 }
1999 
2000 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScModelObj )
2001 
2002 // XMultiServiceFactory
2003 
2004 uno::Reference<uno::XInterface> SAL_CALL ScModelObj::createInstance(
2005                                 const rtl::OUString& aServiceSpecifier )
2006                                 throw(uno::Exception, uno::RuntimeException)
2007 {
2008     ScUnoGuard aGuard;
2009     uno::Reference<uno::XInterface> xRet;
2010     String aNameStr(aServiceSpecifier);
2011     sal_uInt16 nType = ScServiceProvider::GetProviderType(aNameStr);
2012     if ( nType != SC_SERVICE_INVALID )
2013     {
2014         //  drawing layer tables must be kept as long as the model is alive
2015         //  return stored instance if already set
2016         switch ( nType )
2017         {
2018             case SC_SERVICE_GRADTAB:    xRet.set(xDrawGradTab);     break;
2019             case SC_SERVICE_HATCHTAB:   xRet.set(xDrawHatchTab);    break;
2020             case SC_SERVICE_BITMAPTAB:  xRet.set(xDrawBitmapTab);   break;
2021             case SC_SERVICE_TRGRADTAB:  xRet.set(xDrawTrGradTab);   break;
2022             case SC_SERVICE_MARKERTAB:  xRet.set(xDrawMarkerTab);   break;
2023             case SC_SERVICE_DASHTAB:    xRet.set(xDrawDashTab);     break;
2024             case SC_SERVICE_CHDATAPROV: xRet.set(xChartDataProv);   break;
2025             case SC_SERVICE_VBAOBJECTPROVIDER: xRet.set(xObjProvider); break;
2026         }
2027 
2028         // #i64497# If a chart is in a temporary document during clipboard paste,
2029         // there should be no data provider, so that own data is used
2030         bool bCreate =
2031             ! ( nType == SC_SERVICE_CHDATAPROV &&
2032                 ( pDocShell->GetCreateMode() == SFX_CREATE_MODE_INTERNAL ));
2033         // this should never happen, i.e. the temporary document should never be
2034         // loaded, because this unlinks the data
2035         OSL_ASSERT( bCreate );
2036 
2037         if ( !xRet.is() && bCreate )
2038         {
2039             xRet.set(ScServiceProvider::MakeInstance( nType, pDocShell ));
2040 
2041             //  store created instance
2042             switch ( nType )
2043             {
2044                 case SC_SERVICE_GRADTAB:    xDrawGradTab.set(xRet);     break;
2045                 case SC_SERVICE_HATCHTAB:   xDrawHatchTab.set(xRet);    break;
2046                 case SC_SERVICE_BITMAPTAB:  xDrawBitmapTab.set(xRet);   break;
2047                 case SC_SERVICE_TRGRADTAB:  xDrawTrGradTab.set(xRet);   break;
2048                 case SC_SERVICE_MARKERTAB:  xDrawMarkerTab.set(xRet);   break;
2049                 case SC_SERVICE_DASHTAB:    xDrawDashTab.set(xRet);     break;
2050                 case SC_SERVICE_CHDATAPROV: xChartDataProv.set(xRet);   break;
2051                 case SC_SERVICE_VBAOBJECTPROVIDER: xObjProvider.set(xRet); break;
2052             }
2053         }
2054     }
2055     else
2056     {
2057         //  alles was ich nicht kenne, werfe ich der SvxFmMSFactory an den Hals,
2058         //  da wird dann 'ne Exception geworfen, wenn's nicht passt...
2059 
2060         try
2061         {
2062             xRet.set(SvxFmMSFactory::createInstance(aServiceSpecifier));
2063             // extra block to force deletion of the temporary before ScShapeObj ctor (setDelegator)
2064         }
2065         catch ( lang::ServiceNotRegisteredException & )
2066         {
2067         }
2068 
2069         //  #96117# if the drawing factory created a shape, a ScShapeObj has to be used
2070         //  to support own properties like ImageMap:
2071 
2072         uno::Reference<drawing::XShape> xShape( xRet, uno::UNO_QUERY );
2073         if ( xShape.is() )
2074         {
2075             xRet.clear(); // for aggregation, xShape must be the object's only ref
2076             new ScShapeObj( xShape ); // aggregates object and modifies xShape
2077             xRet.set(xShape);
2078         }
2079     }
2080     return xRet;
2081 }
2082 
2083 uno::Reference<uno::XInterface> SAL_CALL ScModelObj::createInstanceWithArguments(
2084                                 const rtl::OUString& ServiceSpecifier,
2085                                 const uno::Sequence<uno::Any>& aArgs )
2086                                 throw(uno::Exception, uno::RuntimeException)
2087 {
2088     //! unterscheiden zwischen eigenen Services und denen vom Drawing-Layer?
2089 
2090     ScUnoGuard aGuard;
2091     uno::Reference<uno::XInterface> xInt(createInstance(ServiceSpecifier));
2092 
2093     if ( aArgs.getLength() )
2094     {
2095         //  used only for cell value binding so far - it can be initialized after creating
2096 
2097         uno::Reference<lang::XInitialization> xInit( xInt, uno::UNO_QUERY );
2098         if ( xInit.is() )
2099             xInit->initialize( aArgs );
2100     }
2101 
2102     return xInt;
2103 }
2104 
2105 uno::Sequence<rtl::OUString> SAL_CALL ScModelObj::getAvailableServiceNames()
2106                                                 throw(uno::RuntimeException)
2107 {
2108     ScUnoGuard aGuard;
2109 
2110     //! warum sind die Parameter bei concatServiceNames nicht const ???
2111     //! return concatServiceNames( ScServiceProvider::GetAllServiceNames(),
2112     //!                            SvxFmMSFactory::getAvailableServiceNames() );
2113 
2114     uno::Sequence<rtl::OUString> aMyServices(ScServiceProvider::GetAllServiceNames());
2115     uno::Sequence<rtl::OUString> aDrawServices(SvxFmMSFactory::getAvailableServiceNames());
2116 
2117     return concatServiceNames( aMyServices, aDrawServices );
2118 }
2119 
2120 // XServiceInfo
2121 
2122 rtl::OUString SAL_CALL ScModelObj::getImplementationName() throw(uno::RuntimeException)
2123 {
2124     return rtl::OUString::createFromAscii( "ScModelObj" );
2125 }
2126 
2127 sal_Bool SAL_CALL ScModelObj::supportsService( const rtl::OUString& rServiceName )
2128                                                     throw(uno::RuntimeException)
2129 {
2130     String aServiceStr(rServiceName);
2131     return aServiceStr.EqualsAscii( SCMODELOBJ_SERVICE ) ||
2132            aServiceStr.EqualsAscii( SCDOCSETTINGS_SERVICE ) ||
2133            aServiceStr.EqualsAscii( SCDOC_SERVICE );
2134 }
2135 
2136 uno::Sequence<rtl::OUString> SAL_CALL ScModelObj::getSupportedServiceNames()
2137                                                     throw(uno::RuntimeException)
2138 {
2139     uno::Sequence<rtl::OUString> aRet(2);
2140     rtl::OUString* pArray = aRet.getArray();
2141     pArray[0] = rtl::OUString::createFromAscii( SCMODELOBJ_SERVICE );
2142     pArray[1] = rtl::OUString::createFromAscii( SCDOCSETTINGS_SERVICE );
2143     return aRet;
2144 }
2145 
2146 // XUnoTunnel
2147 
2148 sal_Int64 SAL_CALL ScModelObj::getSomething(
2149                 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
2150 {
2151     if ( rId.getLength() == 16 &&
2152           0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
2153                                     rId.getConstArray(), 16 ) )
2154     {
2155         return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
2156     }
2157 
2158     if ( rId.getLength() == 16 &&
2159         0 == rtl_compareMemory( SfxObjectShell::getUnoTunnelId().getConstArray(),
2160                                     rId.getConstArray(), 16 ) )
2161     {
2162         return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(pDocShell ));
2163     }
2164 
2165     //  aggregated number formats supplier has XUnoTunnel, too
2166     //  interface from aggregated object must be obtained via queryAggregation
2167 
2168     sal_Int64 nRet = SfxBaseModel::getSomething( rId );
2169     if ( nRet )
2170         return nRet;
2171 
2172     if ( GetFormatter().is() )
2173     {
2174         const uno::Type& rTunnelType = ::getCppuType((uno::Reference<lang::XUnoTunnel>*) 0);
2175         uno::Any aNumTunnel(xNumberAgg->queryAggregation(rTunnelType));
2176         if(aNumTunnel.getValueType() == rTunnelType)
2177         {
2178             uno::Reference<lang::XUnoTunnel> xTunnelAgg(
2179                 *(uno::Reference<lang::XUnoTunnel>*)aNumTunnel.getValue());
2180             return xTunnelAgg->getSomething( rId );
2181         }
2182     }
2183 
2184     return 0;
2185 }
2186 
2187 // static
2188 const uno::Sequence<sal_Int8>& ScModelObj::getUnoTunnelId()
2189 {
2190     static uno::Sequence<sal_Int8> * pSeq = 0;
2191     if( !pSeq )
2192     {
2193         osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
2194         if( !pSeq )
2195         {
2196             static uno::Sequence< sal_Int8 > aSeq( 16 );
2197             rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
2198             pSeq = &aSeq;
2199         }
2200     }
2201     return *pSeq;
2202 }
2203 
2204 // static
2205 ScModelObj* ScModelObj::getImplementation( const uno::Reference<uno::XInterface> xObj )
2206 {
2207     ScModelObj* pRet = NULL;
2208     uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
2209     if (xUT.is())
2210         pRet = reinterpret_cast<ScModelObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
2211     return pRet;
2212 }
2213 
2214 // XChangesNotifier
2215 
2216 void ScModelObj::addChangesListener( const uno::Reference< util::XChangesListener >& aListener )
2217     throw (uno::RuntimeException)
2218 {
2219     ScUnoGuard aGuard;
2220     maChangesListeners.addInterface( aListener );
2221 }
2222 
2223 void ScModelObj::removeChangesListener( const uno::Reference< util::XChangesListener >& aListener )
2224     throw (uno::RuntimeException)
2225 {
2226     ScUnoGuard aGuard;
2227     maChangesListeners.removeInterface( aListener );
2228 }
2229 
2230 bool ScModelObj::HasChangesListeners() const
2231 {
2232     if ( maChangesListeners.getLength() > 0 )
2233         return true;
2234 
2235     // "change" event set in any sheet?
2236     return pDocShell && pDocShell->GetDocument()->HasAnySheetEventScript(SC_SHEETEVENT_CHANGE);
2237 }
2238 
2239 void ScModelObj::NotifyChanges( const ::rtl::OUString& rOperation, const ScRangeList& rRanges,
2240     const uno::Sequence< beans::PropertyValue >& rProperties )
2241 {
2242     if ( pDocShell && HasChangesListeners() )
2243     {
2244         util::ChangesEvent aEvent;
2245         aEvent.Source.set( static_cast< cppu::OWeakObject* >( this ) );
2246         aEvent.Base <<= aEvent.Source;
2247 
2248         sal_uLong nRangeCount = rRanges.Count();
2249         aEvent.Changes.realloc( static_cast< sal_Int32 >( nRangeCount ) );
2250         for ( sal_uLong nIndex = 0; nIndex < nRangeCount; ++nIndex )
2251         {
2252             uno::Reference< table::XCellRange > xRangeObj;
2253 
2254             ScRange aRange( *rRanges.GetObject( nIndex ) );
2255             if ( aRange.aStart == aRange.aEnd )
2256             {
2257                 xRangeObj.set( new ScCellObj( pDocShell, aRange.aStart ) );
2258             }
2259             else
2260             {
2261                 xRangeObj.set( new ScCellRangeObj( pDocShell, aRange ) );
2262             }
2263 
2264             util::ElementChange& rChange = aEvent.Changes[ static_cast< sal_Int32 >( nIndex ) ];
2265             rChange.Accessor <<= rOperation;
2266             rChange.Element <<= rProperties;
2267             rChange.ReplacedElement <<= xRangeObj;
2268         }
2269 
2270         ::cppu::OInterfaceIteratorHelper aIter( maChangesListeners );
2271         while ( aIter.hasMoreElements() )
2272         {
2273             try
2274             {
2275                 static_cast< util::XChangesListener* >( aIter.next() )->changesOccurred( aEvent );
2276             }
2277             catch( uno::Exception& )
2278             {
2279             }
2280         }
2281     }
2282 
2283     // handle sheet events
2284     //! separate method with ScMarkData? Then change HasChangesListeners back.
2285     if ( rOperation.compareToAscii("cell-change") == 0 && pDocShell )
2286     {
2287         ScMarkData aMarkData;
2288         aMarkData.MarkFromRangeList( rRanges, sal_False );
2289         ScDocument* pDoc = pDocShell->GetDocument();
2290         SCTAB nTabCount = pDoc->GetTableCount();
2291         for (SCTAB nTab = 0; nTab < nTabCount; nTab++)
2292             if (aMarkData.GetTableSelect(nTab))
2293             {
2294                 const ScSheetEvents* pEvents = pDoc->GetSheetEvents(nTab);
2295                 if (pEvents)
2296                 {
2297                     const rtl::OUString* pScript = pEvents->GetScript(SC_SHEETEVENT_CHANGE);
2298                     if (pScript)
2299                     {
2300                         ScRangeList aTabRanges; // collect ranges on this sheet
2301                         sal_uLong nRangeCount = rRanges.Count();
2302                         for ( sal_uLong nIndex = 0; nIndex < nRangeCount; ++nIndex )
2303                         {
2304                             ScRange aRange( *rRanges.GetObject( nIndex ) );
2305                             if ( aRange.aStart.Tab() == nTab )
2306                                 aTabRanges.Append( aRange );
2307                         }
2308                         sal_uLong nTabRangeCount = aTabRanges.Count();
2309                         if ( nTabRangeCount > 0 )
2310                         {
2311                             uno::Reference<uno::XInterface> xTarget;
2312                             if ( nTabRangeCount == 1 )
2313                             {
2314                                 ScRange aRange( *aTabRanges.GetObject( 0 ) );
2315                                 if ( aRange.aStart == aRange.aEnd )
2316                                     xTarget.set( static_cast<cppu::OWeakObject*>( new ScCellObj( pDocShell, aRange.aStart ) ) );
2317                                 else
2318                                     xTarget.set( static_cast<cppu::OWeakObject*>( new ScCellRangeObj( pDocShell, aRange ) ) );
2319                             }
2320                             else
2321                                 xTarget.set( static_cast<cppu::OWeakObject*>( new ScCellRangesObj( pDocShell, aTabRanges ) ) );
2322 
2323                             uno::Sequence<uno::Any> aParams(1);
2324                             aParams[0] <<= xTarget;
2325 
2326                             uno::Any aRet;
2327                             uno::Sequence<sal_Int16> aOutArgsIndex;
2328                             uno::Sequence<uno::Any> aOutArgs;
2329 
2330                             /*ErrCode eRet =*/ pDocShell->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs );
2331                         }
2332                     }
2333                 }
2334             }
2335     }
2336 }
2337 
2338 void ScModelObj::HandleCalculateEvents()
2339 {
2340     if (pDocShell)
2341     {
2342         ScDocument* pDoc = pDocShell->GetDocument();
2343         // don't call events before the document is visible
2344         // (might also set a flag on SFX_EVENT_LOADFINISHED and only disable while loading)
2345         if ( pDoc->IsDocVisible() )
2346         {
2347             SCTAB nTabCount = pDoc->GetTableCount();
2348             for (SCTAB nTab = 0; nTab < nTabCount; nTab++)
2349             {
2350                 if (pDoc->HasCalcNotification(nTab))
2351                 {
2352                     if (const ScSheetEvents* pEvents = pDoc->GetSheetEvents( nTab ))
2353                     {
2354                         if (const rtl::OUString* pScript = pEvents->GetScript(SC_SHEETEVENT_CALCULATE))
2355                         {
2356                             uno::Any aRet;
2357                             uno::Sequence<uno::Any> aParams;
2358                             uno::Sequence<sal_Int16> aOutArgsIndex;
2359                             uno::Sequence<uno::Any> aOutArgs;
2360                             pDocShell->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs );
2361                         }
2362                     }
2363 
2364                     try
2365                     {
2366                         uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( pDoc->GetVbaEventProcessor(), uno::UNO_SET_THROW );
2367                         uno::Sequence< uno::Any > aArgs( 1 );
2368                         aArgs[ 0 ] <<= nTab;
2369                         xVbaEvents->processVbaEvent( ScSheetEvents::GetVbaSheetEventId( SC_SHEETEVENT_CALCULATE ), aArgs );
2370                     }
2371                     catch( uno::Exception& )
2372                     {
2373                     }
2374                 }
2375             }
2376         }
2377         pDoc->ResetCalcNotifications();
2378     }
2379 }
2380 
2381 //------------------------------------------------------------------------
2382 
2383 ScDrawPagesObj::ScDrawPagesObj(ScDocShell* pDocSh) :
2384     pDocShell( pDocSh )
2385 {
2386     pDocShell->GetDocument()->AddUnoObject(*this);
2387 }
2388 
2389 ScDrawPagesObj::~ScDrawPagesObj()
2390 {
2391     if (pDocShell)
2392         pDocShell->GetDocument()->RemoveUnoObject(*this);
2393 }
2394 
2395 void ScDrawPagesObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
2396 {
2397     //  Referenz-Update interessiert hier nicht
2398 
2399     if ( rHint.ISA( SfxSimpleHint ) &&
2400             ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
2401     {
2402         pDocShell = NULL; // ungültig geworden
2403     }
2404 }
2405 
2406 uno::Reference<drawing::XDrawPage> ScDrawPagesObj::GetObjectByIndex_Impl(sal_Int32 nIndex) const
2407 {
2408     if (pDocShell)
2409     {
2410         ScDrawLayer* pDrawLayer = pDocShell->MakeDrawLayer();
2411         DBG_ASSERT(pDrawLayer,"kann Draw-Layer nicht anlegen");
2412         if ( pDrawLayer && nIndex >= 0 && nIndex < pDocShell->GetDocument()->GetTableCount() )
2413         {
2414             SdrPage* pPage = pDrawLayer->GetPage((sal_uInt16)nIndex);
2415             DBG_ASSERT(pPage,"Draw-Page not found");
2416             if (pPage)
2417             {
2418                 return uno::Reference<drawing::XDrawPage> (pPage->getUnoPage(), uno::UNO_QUERY);
2419             }
2420         }
2421     }
2422     return NULL;
2423 }
2424 
2425 // XDrawPages
2426 
2427 uno::Reference<drawing::XDrawPage> SAL_CALL ScDrawPagesObj::insertNewByIndex( sal_Int32 nPos )
2428                                             throw(uno::RuntimeException)
2429 {
2430     ScUnoGuard aGuard;
2431     uno::Reference<drawing::XDrawPage> xRet;
2432     if (pDocShell)
2433     {
2434         String aNewName;
2435         pDocShell->GetDocument()->CreateValidTabName(aNewName);
2436         ScDocFunc aFunc(*pDocShell);
2437         if ( aFunc.InsertTable( (SCTAB)nPos, aNewName, sal_True, sal_True ) )
2438             xRet.set(GetObjectByIndex_Impl( nPos ));
2439     }
2440     return xRet;
2441 }
2442 
2443 void SAL_CALL ScDrawPagesObj::remove( const uno::Reference<drawing::XDrawPage>& xPage )
2444                                             throw(uno::RuntimeException)
2445 {
2446     ScUnoGuard aGuard;
2447     SvxDrawPage* pImp = SvxDrawPage::getImplementation( xPage );
2448     if ( pDocShell && pImp )
2449     {
2450         SdrPage* pPage = pImp->GetSdrPage();
2451         if (pPage)
2452         {
2453             SCTAB nPageNum = static_cast<SCTAB>(pPage->GetPageNum());
2454             ScDocFunc aFunc(*pDocShell);
2455             aFunc.DeleteTable( nPageNum, sal_True, sal_True );
2456         }
2457     }
2458 }
2459 
2460 // XIndexAccess
2461 
2462 sal_Int32 SAL_CALL ScDrawPagesObj::getCount() throw(uno::RuntimeException)
2463 {
2464     ScUnoGuard aGuard;
2465     if (pDocShell)
2466         return pDocShell->GetDocument()->GetTableCount();
2467     return 0;
2468 }
2469 
2470 uno::Any SAL_CALL ScDrawPagesObj::getByIndex( sal_Int32 nIndex )
2471                             throw(lang::IndexOutOfBoundsException,
2472                                     lang::WrappedTargetException, uno::RuntimeException)
2473 {
2474     ScUnoGuard aGuard;
2475     uno::Reference<drawing::XDrawPage> xPage(GetObjectByIndex_Impl(nIndex));
2476     if (xPage.is())
2477         return uno::makeAny(xPage);
2478     else
2479         throw lang::IndexOutOfBoundsException();
2480 //  return uno::Any();
2481 }
2482 
2483 uno::Type SAL_CALL ScDrawPagesObj::getElementType() throw(uno::RuntimeException)
2484 {
2485     ScUnoGuard aGuard;
2486     return getCppuType((uno::Reference<drawing::XDrawPage>*)0);
2487 }
2488 
2489 sal_Bool SAL_CALL ScDrawPagesObj::hasElements() throw(uno::RuntimeException)
2490 {
2491     ScUnoGuard aGuard;
2492     return ( getCount() != 0 );
2493 }
2494 
2495 //------------------------------------------------------------------------
2496 
2497 ScTableSheetsObj::ScTableSheetsObj(ScDocShell* pDocSh) :
2498     pDocShell( pDocSh )
2499 {
2500     pDocShell->GetDocument()->AddUnoObject(*this);
2501 }
2502 
2503 ScTableSheetsObj::~ScTableSheetsObj()
2504 {
2505     if (pDocShell)
2506         pDocShell->GetDocument()->RemoveUnoObject(*this);
2507 }
2508 
2509 void ScTableSheetsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
2510 {
2511     //  Referenz-Update interessiert hier nicht
2512 
2513     if ( rHint.ISA( SfxSimpleHint ) &&
2514             ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
2515     {
2516         pDocShell = NULL; // ungültig geworden
2517     }
2518 }
2519 
2520 // XSpreadsheets
2521 
2522 ScTableSheetObj* ScTableSheetsObj::GetObjectByIndex_Impl(sal_Int32 nIndex) const
2523 {
2524     if ( pDocShell && nIndex >= 0 && nIndex < pDocShell->GetDocument()->GetTableCount() )
2525         return new ScTableSheetObj( pDocShell, static_cast<SCTAB>(nIndex) );
2526 
2527     return NULL;
2528 }
2529 
2530 ScTableSheetObj* ScTableSheetsObj::GetObjectByName_Impl(const rtl::OUString& aName) const
2531 {
2532     if (pDocShell)
2533     {
2534         SCTAB nIndex;
2535         String aString(aName);
2536         if ( pDocShell->GetDocument()->GetTable( aString, nIndex ) )
2537             return new ScTableSheetObj( pDocShell, nIndex );
2538     }
2539     return NULL;
2540 }
2541 
2542 void SAL_CALL ScTableSheetsObj::insertNewByName( const rtl::OUString& aName, sal_Int16 nPosition )
2543                                                 throw(uno::RuntimeException)
2544 {
2545     ScUnoGuard aGuard;
2546     sal_Bool bDone = sal_False;
2547     if (pDocShell)
2548     {
2549         String aNamStr(aName);
2550         ScDocFunc aFunc(*pDocShell);
2551         bDone = aFunc.InsertTable( nPosition, aNamStr, sal_True, sal_True );
2552     }
2553     if (!bDone)
2554         throw uno::RuntimeException(); // no other exceptions specified
2555 }
2556 
2557 void SAL_CALL ScTableSheetsObj::moveByName( const rtl::OUString& aName, sal_Int16 nDestination )
2558                                             throw(uno::RuntimeException)
2559 {
2560     ScUnoGuard aGuard;
2561     sal_Bool bDone = sal_False;
2562     if (pDocShell)
2563     {
2564         String aNamStr(aName);
2565         SCTAB nSource;
2566         if ( pDocShell->GetDocument()->GetTable( aNamStr, nSource ) )
2567             bDone = pDocShell->MoveTable( nSource, nDestination, sal_False, sal_True );
2568     }
2569     if (!bDone)
2570         throw uno::RuntimeException(); // no other exceptions specified
2571 }
2572 
2573 void SAL_CALL ScTableSheetsObj::copyByName( const rtl::OUString& aName,
2574                                 const rtl::OUString& aCopy, sal_Int16 nDestination )
2575                                                 throw(uno::RuntimeException)
2576 {
2577     ScUnoGuard aGuard;
2578     sal_Bool bDone = sal_False;
2579     if (pDocShell)
2580     {
2581         String aNamStr(aName);
2582         String aNewStr(aCopy);
2583         SCTAB nSource;
2584         if ( pDocShell->GetDocument()->GetTable( aNamStr, nSource ) )
2585         {
2586             bDone = pDocShell->MoveTable( nSource, nDestination, sal_True, sal_True );
2587             if (bDone)
2588             {
2589                 // #i92477# any index past the last sheet means "append" in MoveTable
2590                 SCTAB nResultTab = static_cast<SCTAB>(nDestination);
2591                 SCTAB nTabCount = pDocShell->GetDocument()->GetTableCount(); // count after copying
2592                 if (nResultTab >= nTabCount)
2593                     nResultTab = nTabCount - 1;
2594 
2595                 ScDocFunc aFunc(*pDocShell);
2596                 bDone = aFunc.RenameTable( nResultTab, aNewStr, sal_True, sal_True );
2597             }
2598         }
2599     }
2600     if (!bDone)
2601         throw uno::RuntimeException(); // no other exceptions specified
2602 }
2603 
2604 void SAL_CALL ScTableSheetsObj::insertByName( const rtl::OUString& aName, const uno::Any& aElement )
2605                             throw(lang::IllegalArgumentException, container::ElementExistException,
2606                                     lang::WrappedTargetException, uno::RuntimeException)
2607 {
2608     ScUnoGuard aGuard;
2609     sal_Bool bDone = sal_False;
2610     sal_Bool bIllArg = sal_False;
2611 
2612     //! Type of aElement can be some specific interface instead of XInterface
2613 
2614     if ( pDocShell )
2615     {
2616         uno::Reference<uno::XInterface> xInterface(aElement, uno::UNO_QUERY);
2617         if ( xInterface.is() )
2618         {
2619             ScTableSheetObj* pSheetObj = ScTableSheetObj::getImplementation( xInterface );
2620             if ( pSheetObj && !pSheetObj->GetDocShell() ) // noch nicht eingefuegt?
2621             {
2622                 ScDocument* pDoc = pDocShell->GetDocument();
2623                 String aNamStr(aName);
2624                 SCTAB nDummy;
2625                 if ( pDoc->GetTable( aNamStr, nDummy ) )
2626                 {
2627                     // name already exists
2628                     throw container::ElementExistException();
2629                 }
2630                 else
2631                 {
2632                     SCTAB nPosition = pDoc->GetTableCount();
2633                     ScDocFunc aFunc(*pDocShell);
2634                     bDone = aFunc.InsertTable( nPosition, aNamStr, sal_True, sal_True );
2635                     if (bDone)
2636                         pSheetObj->InitInsertSheet( pDocShell, nPosition );
2637                     //  Dokument und neuen Range am Objekt setzen
2638                 }
2639             }
2640             else
2641                 bIllArg = sal_True;
2642         }
2643         else
2644             bIllArg = sal_True;
2645     }
2646 
2647     if (!bDone)
2648     {
2649         if (bIllArg)
2650             throw lang::IllegalArgumentException();
2651         else
2652             throw uno::RuntimeException(); // ElementExistException is handled above
2653     }
2654 }
2655 
2656 void SAL_CALL ScTableSheetsObj::replaceByName( const rtl::OUString& aName, const uno::Any& aElement )
2657                             throw(lang::IllegalArgumentException, container::NoSuchElementException,
2658                                     lang::WrappedTargetException, uno::RuntimeException)
2659 {
2660     ScUnoGuard aGuard;
2661     sal_Bool bDone = sal_False;
2662     sal_Bool bIllArg = sal_False;
2663 
2664     //! Type of aElement can be some specific interface instead of XInterface
2665 
2666     if ( pDocShell )
2667     {
2668         uno::Reference<uno::XInterface> xInterface(aElement, uno::UNO_QUERY);
2669         if ( xInterface.is() )
2670         {
2671             ScTableSheetObj* pSheetObj = ScTableSheetObj::getImplementation( xInterface );
2672             if ( pSheetObj && !pSheetObj->GetDocShell() ) // noch nicht eingefuegt?
2673             {
2674                 String aNamStr(aName);
2675                 SCTAB nPosition;
2676                 if ( pDocShell->GetDocument()->GetTable( aNamStr, nPosition ) )
2677                 {
2678                     ScDocFunc aFunc(*pDocShell);
2679                     if ( aFunc.DeleteTable( nPosition, sal_True, sal_True ) )
2680                     {
2681                         //  InsertTable kann jetzt eigentlich nicht schiefgehen...
2682                         bDone = aFunc.InsertTable( nPosition, aNamStr, sal_True, sal_True );
2683                         if (bDone)
2684                             pSheetObj->InitInsertSheet( pDocShell, nPosition );
2685                     }
2686                 }
2687                 else
2688                 {
2689                     // not found
2690                     throw container::NoSuchElementException();
2691                 }
2692             }
2693             else
2694                 bIllArg = sal_True;
2695         }
2696         else
2697             bIllArg = sal_True;
2698     }
2699 
2700     if (!bDone)
2701     {
2702         if (bIllArg)
2703             throw lang::IllegalArgumentException();
2704         else
2705             throw uno::RuntimeException(); // NoSuchElementException is handled above
2706     }
2707 }
2708 
2709 void SAL_CALL ScTableSheetsObj::removeByName( const rtl::OUString& aName )
2710                                 throw(container::NoSuchElementException,
2711                                     lang::WrappedTargetException, uno::RuntimeException)
2712 {
2713     ScUnoGuard aGuard;
2714     sal_Bool bDone = sal_False;
2715     if (pDocShell)
2716     {
2717         SCTAB nIndex;
2718         String aString(aName);
2719         if ( pDocShell->GetDocument()->GetTable( aString, nIndex ) )
2720         {
2721             ScDocFunc aFunc(*pDocShell);
2722             bDone = aFunc.DeleteTable( nIndex, sal_True, sal_True );
2723         }
2724         else
2725         {
2726             // not found
2727             throw container::NoSuchElementException();
2728         }
2729     }
2730 
2731     if (!bDone)
2732         throw uno::RuntimeException(); // NoSuchElementException is handled above
2733 }
2734 
2735 // XCellRangesAccess
2736 
2737 uno::Reference< table::XCell > SAL_CALL ScTableSheetsObj::getCellByPosition( sal_Int32 nColumn, sal_Int32 nRow, sal_Int32 nSheet )
2738     throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2739 {
2740     ScUnoGuard aGuard;
2741     uno::Reference<table::XCellRange> xSheet(static_cast<ScCellRangeObj*>(GetObjectByIndex_Impl((sal_uInt16)nSheet)));
2742     if (! xSheet.is())
2743         throw lang::IndexOutOfBoundsException();
2744 
2745     return xSheet->getCellByPosition(nColumn, nRow);
2746 }
2747 
2748 uno::Reference< table::XCellRange > SAL_CALL ScTableSheetsObj::getCellRangeByPosition( sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom, sal_Int32 nSheet )
2749     throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2750 {
2751     ScUnoGuard aGuard;
2752     uno::Reference<table::XCellRange> xSheet(static_cast<ScCellRangeObj*>(GetObjectByIndex_Impl((sal_uInt16)nSheet)));
2753     if (! xSheet.is())
2754         throw lang::IndexOutOfBoundsException();
2755 
2756     return xSheet->getCellRangeByPosition(nLeft, nTop, nRight, nBottom);
2757 }
2758 
2759 uno::Sequence < uno::Reference< table::XCellRange > > SAL_CALL ScTableSheetsObj::getCellRangesByName( const rtl::OUString& aRange )
2760     throw (lang::IllegalArgumentException, uno::RuntimeException)
2761 {
2762     ScUnoGuard aGuard;
2763     uno::Sequence < uno::Reference < table::XCellRange > > xRet;
2764 
2765     ScRangeList aRangeList;
2766     ScDocument* pDoc = pDocShell->GetDocument();
2767     if (ScRangeStringConverter::GetRangeListFromString( aRangeList, aRange, pDoc, ::formula::FormulaGrammar::CONV_OOO, ';' ))
2768     {
2769         sal_Int32 nCount = aRangeList.Count();
2770         if (nCount)
2771         {
2772             xRet.realloc(nCount);
2773             for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
2774             {
2775                 const ScRange* pRange = aRangeList.GetObject( nIndex );
2776                 if( pRange )
2777                     xRet[nIndex] = new ScCellRangeObj(pDocShell, *pRange);
2778             }
2779         }
2780         else
2781             throw lang::IllegalArgumentException();
2782     }
2783     else
2784         throw lang::IllegalArgumentException();
2785     return xRet;
2786 }
2787 
2788 // XEnumerationAccess
2789 
2790 uno::Reference<container::XEnumeration> SAL_CALL ScTableSheetsObj::createEnumeration()
2791                                                     throw(uno::RuntimeException)
2792 {
2793     ScUnoGuard aGuard;
2794     return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.SpreadsheetsEnumeration")));
2795 }
2796 
2797 // XIndexAccess
2798 
2799 sal_Int32 SAL_CALL ScTableSheetsObj::getCount() throw(uno::RuntimeException)
2800 {
2801     ScUnoGuard aGuard;
2802     if (pDocShell)
2803         return pDocShell->GetDocument()->GetTableCount();
2804     return 0;
2805 }
2806 
2807 uno::Any SAL_CALL ScTableSheetsObj::getByIndex( sal_Int32 nIndex )
2808                             throw(lang::IndexOutOfBoundsException,
2809                                     lang::WrappedTargetException, uno::RuntimeException)
2810 {
2811     ScUnoGuard aGuard;
2812     uno::Reference<sheet::XSpreadsheet> xSheet(GetObjectByIndex_Impl(nIndex));
2813     if (xSheet.is())
2814         return uno::makeAny(xSheet);
2815     else
2816         throw lang::IndexOutOfBoundsException();
2817 //    return uno::Any();
2818 }
2819 
2820 uno::Type SAL_CALL ScTableSheetsObj::getElementType() throw(uno::RuntimeException)
2821 {
2822     ScUnoGuard aGuard;
2823     return getCppuType((uno::Reference<sheet::XSpreadsheet>*)0);
2824 }
2825 
2826 sal_Bool SAL_CALL ScTableSheetsObj::hasElements() throw(uno::RuntimeException)
2827 {
2828     ScUnoGuard aGuard;
2829     return ( getCount() != 0 );
2830 }
2831 
2832 // XNameAccess
2833 
2834 uno::Any SAL_CALL ScTableSheetsObj::getByName( const rtl::OUString& aName )
2835             throw(container::NoSuchElementException,
2836                     lang::WrappedTargetException, uno::RuntimeException)
2837 {
2838     ScUnoGuard aGuard;
2839     uno::Reference<sheet::XSpreadsheet> xSheet(GetObjectByName_Impl(aName));
2840     if (xSheet.is())
2841         return uno::makeAny(xSheet);
2842     else
2843         throw container::NoSuchElementException();
2844 //    return uno::Any();
2845 }
2846 
2847 uno::Sequence<rtl::OUString> SAL_CALL ScTableSheetsObj::getElementNames()
2848                                                 throw(uno::RuntimeException)
2849 {
2850     ScUnoGuard aGuard;
2851     if (pDocShell)
2852     {
2853         ScDocument* pDoc = pDocShell->GetDocument();
2854         SCTAB nCount = pDoc->GetTableCount();
2855         String aName;
2856         uno::Sequence<rtl::OUString> aSeq(nCount);
2857         rtl::OUString* pAry = aSeq.getArray();
2858         for (SCTAB i=0; i<nCount; i++)
2859         {
2860             pDoc->GetName( i, aName );
2861             pAry[i] = aName;
2862         }
2863         return aSeq;
2864     }
2865     return uno::Sequence<rtl::OUString>();
2866 }
2867 
2868 sal_Bool SAL_CALL ScTableSheetsObj::hasByName( const rtl::OUString& aName )
2869                                         throw(uno::RuntimeException)
2870 {
2871     ScUnoGuard aGuard;
2872     if (pDocShell)
2873     {
2874         SCTAB nIndex;
2875         if ( pDocShell->GetDocument()->GetTable( String(aName), nIndex ) )
2876             return sal_True;
2877     }
2878     return sal_False;
2879 }
2880 
2881 //------------------------------------------------------------------------
2882 
2883 ScTableColumnsObj::ScTableColumnsObj(ScDocShell* pDocSh, SCTAB nT, SCCOL nSC, SCCOL nEC) :
2884     pDocShell( pDocSh ),
2885     nTab     ( nT ),
2886     nStartCol( nSC ),
2887     nEndCol  ( nEC )
2888 {
2889     pDocShell->GetDocument()->AddUnoObject(*this);
2890 }
2891 
2892 ScTableColumnsObj::~ScTableColumnsObj()
2893 {
2894     if (pDocShell)
2895         pDocShell->GetDocument()->RemoveUnoObject(*this);
2896 }
2897 
2898 void ScTableColumnsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
2899 {
2900     if ( rHint.ISA( ScUpdateRefHint ) )
2901     {
2902 //        const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
2903 
2904         //! Referenz-Update für Tab und Start/Ende
2905     }
2906     else if ( rHint.ISA( SfxSimpleHint ) &&
2907             ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
2908     {
2909         pDocShell = NULL; // ungültig geworden
2910     }
2911 }
2912 
2913 // XTableColumns
2914 
2915 ScTableColumnObj* ScTableColumnsObj::GetObjectByIndex_Impl(sal_Int32 nIndex) const
2916 {
2917     SCCOL nCol = static_cast<SCCOL>(nIndex) + nStartCol;
2918     if ( pDocShell && nCol <= nEndCol )
2919         return new ScTableColumnObj( pDocShell, nCol, nTab );
2920 
2921     return NULL; // falscher Index
2922 }
2923 
2924 ScTableColumnObj* ScTableColumnsObj::GetObjectByName_Impl(const rtl::OUString& aName) const
2925 {
2926     SCCOL nCol = 0;
2927     String aString(aName);
2928     if ( ::AlphaToCol( nCol, aString) )
2929         if ( pDocShell && nCol >= nStartCol && nCol <= nEndCol )
2930             return new ScTableColumnObj( pDocShell, nCol, nTab );
2931 
2932     return NULL;
2933 }
2934 
2935 void SAL_CALL ScTableColumnsObj::insertByIndex( sal_Int32 nPosition, sal_Int32 nCount )
2936                                                 throw(uno::RuntimeException)
2937 {
2938     ScUnoGuard aGuard;
2939     sal_Bool bDone = sal_False;
2940     if ( pDocShell && nCount > 0 && nPosition >= 0 && nStartCol+nPosition <= nEndCol &&
2941             nStartCol+nPosition+nCount-1 <= MAXCOL )
2942     {
2943         ScDocFunc aFunc(*pDocShell);
2944         ScRange aRange( (SCCOL)(nStartCol+nPosition), 0, nTab,
2945                         (SCCOL)(nStartCol+nPosition+nCount-1), MAXROW, nTab );
2946         bDone = aFunc.InsertCells( aRange, NULL, INS_INSCOLS, sal_True, sal_True );
2947     }
2948     if (!bDone)
2949         throw uno::RuntimeException(); // no other exceptions specified
2950 }
2951 
2952 void SAL_CALL ScTableColumnsObj::removeByIndex( sal_Int32 nIndex, sal_Int32 nCount )
2953                                                 throw(uno::RuntimeException)
2954 {
2955     ScUnoGuard aGuard;
2956     sal_Bool bDone = sal_False;
2957     //  Der zu löschende Bereich muss innerhalb des Objekts liegen
2958     if ( pDocShell && nCount > 0 && nIndex >= 0 && nStartCol+nIndex+nCount-1 <= nEndCol )
2959     {
2960         ScDocFunc aFunc(*pDocShell);
2961         ScRange aRange( (SCCOL)(nStartCol+nIndex), 0, nTab,
2962                         (SCCOL)(nStartCol+nIndex+nCount-1), MAXROW, nTab );
2963         bDone = aFunc.DeleteCells( aRange, NULL, DEL_DELCOLS, sal_True, sal_True );
2964     }
2965     if (!bDone)
2966         throw uno::RuntimeException(); // no other exceptions specified
2967 }
2968 
2969 // XEnumerationAccess
2970 
2971 uno::Reference<container::XEnumeration> SAL_CALL ScTableColumnsObj::createEnumeration()
2972                                                     throw(uno::RuntimeException)
2973 {
2974     ScUnoGuard aGuard;
2975     return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.table.TableColumnsEnumeration")));
2976 }
2977 
2978 // XIndexAccess
2979 
2980 sal_Int32 SAL_CALL ScTableColumnsObj::getCount() throw(uno::RuntimeException)
2981 {
2982     ScUnoGuard aGuard;
2983     return nEndCol - nStartCol + 1;
2984 }
2985 
2986 uno::Any SAL_CALL ScTableColumnsObj::getByIndex( sal_Int32 nIndex )
2987                             throw(lang::IndexOutOfBoundsException,
2988                                     lang::WrappedTargetException, uno::RuntimeException)
2989 {
2990     ScUnoGuard aGuard;
2991     uno::Reference<table::XCellRange> xColumn(GetObjectByIndex_Impl(nIndex));
2992     if (xColumn.is())
2993         return uno::makeAny(xColumn);
2994     else
2995         throw lang::IndexOutOfBoundsException();
2996 //    return uno::Any();
2997 }
2998 
2999 uno::Type SAL_CALL ScTableColumnsObj::getElementType() throw(uno::RuntimeException)
3000 {
3001     ScUnoGuard aGuard;
3002     return getCppuType((uno::Reference<table::XCellRange>*)0);
3003 }
3004 
3005 sal_Bool SAL_CALL ScTableColumnsObj::hasElements() throw(uno::RuntimeException)
3006 {
3007     ScUnoGuard aGuard;
3008     return ( getCount() != 0 );
3009 }
3010 
3011 uno::Any SAL_CALL ScTableColumnsObj::getByName( const rtl::OUString& aName )
3012             throw(container::NoSuchElementException,
3013                     lang::WrappedTargetException, uno::RuntimeException)
3014 {
3015     ScUnoGuard aGuard;
3016     uno::Reference<table::XCellRange> xColumn(GetObjectByName_Impl(aName));
3017     if (xColumn.is())
3018         return uno::makeAny(xColumn);
3019     else
3020         throw container::NoSuchElementException();
3021 //    return uno::Any();
3022 }
3023 
3024 uno::Sequence<rtl::OUString> SAL_CALL ScTableColumnsObj::getElementNames()
3025                                                 throw(uno::RuntimeException)
3026 {
3027     ScUnoGuard aGuard;
3028     SCCOL nCount = nEndCol - nStartCol + 1;
3029     uno::Sequence<rtl::OUString> aSeq(nCount);
3030     rtl::OUString* pAry = aSeq.getArray();
3031     for (SCCOL i=0; i<nCount; i++)
3032         pAry[i] = ::ScColToAlpha( nStartCol + i );
3033 
3034     return aSeq;
3035 }
3036 
3037 sal_Bool SAL_CALL ScTableColumnsObj::hasByName( const rtl::OUString& aName )
3038                                         throw(uno::RuntimeException)
3039 {
3040     ScUnoGuard aGuard;
3041     SCCOL nCol = 0;
3042     String aString(aName);
3043     if ( ::AlphaToCol( nCol, aString) )
3044         if ( pDocShell && nCol >= nStartCol && nCol <= nEndCol )
3045             return sal_True;
3046 
3047     return sal_False; // not found
3048 }
3049 
3050 // XPropertySet
3051 
3052 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTableColumnsObj::getPropertySetInfo()
3053                                                         throw(uno::RuntimeException)
3054 {
3055     ScUnoGuard aGuard;
3056     static uno::Reference<beans::XPropertySetInfo> aRef(
3057         new SfxItemPropertySetInfo( lcl_GetColumnsPropertyMap() ));
3058     return aRef;
3059 }
3060 
3061 void SAL_CALL ScTableColumnsObj::setPropertyValue(
3062                         const rtl::OUString& aPropertyName, const uno::Any& aValue )
3063                 throw(beans::UnknownPropertyException, beans::PropertyVetoException,
3064                         lang::IllegalArgumentException, lang::WrappedTargetException,
3065                         uno::RuntimeException)
3066 {
3067     ScUnoGuard aGuard;
3068     if (!pDocShell)
3069         throw uno::RuntimeException();
3070 
3071     ScDocFunc aFunc(*pDocShell);
3072     SCCOLROW nColArr[2];
3073     nColArr[0] = nStartCol;
3074     nColArr[1] = nEndCol;
3075     String aNameString(aPropertyName);
3076 
3077     if ( aNameString.EqualsAscii( SC_UNONAME_CELLWID ) )
3078     {
3079         sal_Int32 nNewWidth = 0;
3080         if ( aValue >>= nNewWidth )
3081             aFunc.SetWidthOrHeight( sal_True, 1, nColArr, nTab, SC_SIZE_ORIGINAL,
3082                                     (sal_uInt16)HMMToTwips(nNewWidth), sal_True, sal_True );
3083     }
3084     else if ( aNameString.EqualsAscii( SC_UNONAME_CELLVIS ) )
3085     {
3086         sal_Bool bVis = ScUnoHelpFunctions::GetBoolFromAny( aValue );
3087         ScSizeMode eMode = bVis ? SC_SIZE_SHOW : SC_SIZE_DIRECT;
3088         aFunc.SetWidthOrHeight( sal_True, 1, nColArr, nTab, eMode, 0, sal_True, sal_True );
3089         //  SC_SIZE_DIRECT with size 0: hide
3090     }
3091     else if ( aNameString.EqualsAscii( SC_UNONAME_OWIDTH ) )
3092     {
3093         sal_Bool bOpt = ScUnoHelpFunctions::GetBoolFromAny( aValue );
3094         if (bOpt)
3095             aFunc.SetWidthOrHeight( sal_True, 1, nColArr, nTab,
3096                                     SC_SIZE_OPTIMAL, STD_EXTRA_WIDTH, sal_True, sal_True );
3097         // sal_False for columns currently has no effect
3098     }
3099     else if ( aNameString.EqualsAscii( SC_UNONAME_NEWPAGE ) || aNameString.EqualsAscii( SC_UNONAME_MANPAGE ) )
3100     {
3101         //! single function to set/remove all breaks?
3102         sal_Bool bSet = ScUnoHelpFunctions::GetBoolFromAny( aValue );
3103         for (SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++)
3104             if (bSet)
3105                 aFunc.InsertPageBreak( sal_True, ScAddress(nCol,0,nTab), sal_True, sal_True, sal_True );
3106             else
3107                 aFunc.RemovePageBreak( sal_True, ScAddress(nCol,0,nTab), sal_True, sal_True, sal_True );
3108     }
3109 }
3110 
3111 uno::Any SAL_CALL ScTableColumnsObj::getPropertyValue( const rtl::OUString& aPropertyName )
3112                 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
3113                         uno::RuntimeException)
3114 {
3115     ScUnoGuard aGuard;
3116     if (!pDocShell)
3117         throw uno::RuntimeException();
3118 
3119     ScDocument* pDoc = pDocShell->GetDocument();
3120     String aNameString(aPropertyName);
3121     uno::Any aAny;
3122 
3123     //! loop over all columns for current state?
3124 
3125     if ( aNameString.EqualsAscii( SC_UNONAME_CELLWID ) )
3126     {
3127         // for hidden column, return original height
3128         sal_uInt16 nWidth = pDoc->GetOriginalWidth( nStartCol, nTab );
3129         aAny <<= (sal_Int32)TwipsToHMM(nWidth);
3130     }
3131     else if ( aNameString.EqualsAscii( SC_UNONAME_CELLVIS ) )
3132     {
3133         SCCOL nLastCol;
3134         bool bVis = !pDoc->ColHidden(nStartCol, nTab, nLastCol);
3135         ScUnoHelpFunctions::SetBoolInAny( aAny, bVis );
3136     }
3137     else if ( aNameString.EqualsAscii( SC_UNONAME_OWIDTH ) )
3138     {
3139         sal_Bool bOpt = !(pDoc->GetColFlags( nStartCol, nTab ) & CR_MANUALSIZE);
3140         ScUnoHelpFunctions::SetBoolInAny( aAny, bOpt );
3141     }
3142     else if ( aNameString.EqualsAscii( SC_UNONAME_NEWPAGE ) )
3143     {
3144         ScBreakType nBreak = pDoc->HasColBreak(nStartCol, nTab);
3145         ScUnoHelpFunctions::SetBoolInAny( aAny, nBreak );
3146     }
3147     else if ( aNameString.EqualsAscii( SC_UNONAME_MANPAGE ) )
3148     {
3149         ScBreakType nBreak = pDoc->HasColBreak(nStartCol, nTab);
3150         ScUnoHelpFunctions::SetBoolInAny( aAny, (nBreak & BREAK_MANUAL) );
3151     }
3152 
3153     return aAny;
3154 }
3155 
3156 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScTableColumnsObj )
3157 
3158 //------------------------------------------------------------------------
3159 
3160 ScTableRowsObj::ScTableRowsObj(ScDocShell* pDocSh, SCTAB nT, SCROW nSR, SCROW nER) :
3161     pDocShell( pDocSh ),
3162     nTab     ( nT ),
3163     nStartRow( nSR ),
3164     nEndRow  ( nER )
3165 {
3166     pDocShell->GetDocument()->AddUnoObject(*this);
3167 }
3168 
3169 ScTableRowsObj::~ScTableRowsObj()
3170 {
3171     if (pDocShell)
3172         pDocShell->GetDocument()->RemoveUnoObject(*this);
3173 }
3174 
3175 void ScTableRowsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
3176 {
3177     if ( rHint.ISA( ScUpdateRefHint ) )
3178     {
3179 //        const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
3180 
3181         //! Referenz-Update fuer Tab und Start/Ende
3182     }
3183     else if ( rHint.ISA( SfxSimpleHint ) &&
3184             ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
3185     {
3186         pDocShell = NULL; // ungültig geworden
3187     }
3188 }
3189 
3190 // XTableRows
3191 
3192 ScTableRowObj* ScTableRowsObj::GetObjectByIndex_Impl(sal_Int32 nIndex) const
3193 {
3194     SCROW nRow = static_cast<SCROW>(nIndex) + nStartRow;
3195     if ( pDocShell && nRow <= nEndRow )
3196         return new ScTableRowObj( pDocShell, nRow, nTab );
3197 
3198     return NULL; // falscher Index
3199 }
3200 
3201 void SAL_CALL ScTableRowsObj::insertByIndex( sal_Int32 nPosition, sal_Int32 nCount )
3202                                                 throw(uno::RuntimeException)
3203 {
3204     ScUnoGuard aGuard;
3205     sal_Bool bDone = sal_False;
3206     if ( pDocShell && nCount > 0 && nPosition >= 0 && nStartRow+nPosition <= nEndRow &&
3207             nStartRow+nPosition+nCount-1 <= MAXROW )
3208     {
3209         ScDocFunc aFunc(*pDocShell);
3210         ScRange aRange( 0, (SCROW)(nStartRow+nPosition), nTab,
3211                         MAXCOL, (SCROW)(nStartRow+nPosition+nCount-1), nTab );
3212         bDone = aFunc.InsertCells( aRange, NULL, INS_INSROWS, sal_True, sal_True );
3213     }
3214     if (!bDone)
3215         throw uno::RuntimeException(); // no other exceptions specified
3216 }
3217 
3218 void SAL_CALL ScTableRowsObj::removeByIndex( sal_Int32 nIndex, sal_Int32 nCount )
3219                                                 throw(uno::RuntimeException)
3220 {
3221     ScUnoGuard aGuard;
3222     sal_Bool bDone = sal_False;
3223     //  Der zu löschende Bereich muss innerhalb des Objekts liegen
3224     if ( pDocShell && nCount > 0 && nIndex >= 0 && nStartRow+nIndex+nCount-1 <= nEndRow )
3225     {
3226         ScDocFunc aFunc(*pDocShell);
3227         ScRange aRange( 0, (SCROW)(nStartRow+nIndex), nTab,
3228                         MAXCOL, (SCROW)(nStartRow+nIndex+nCount-1), nTab );
3229         bDone = aFunc.DeleteCells( aRange, NULL, DEL_DELROWS, sal_True, sal_True );
3230     }
3231     if (!bDone)
3232         throw uno::RuntimeException(); // no other exceptions specified
3233 }
3234 
3235 // XEnumerationAccess
3236 
3237 uno::Reference<container::XEnumeration> SAL_CALL ScTableRowsObj::createEnumeration()
3238                                                     throw(uno::RuntimeException)
3239 {
3240     ScUnoGuard aGuard;
3241     return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.table.TableRowsEnumeration")));
3242 }
3243 
3244 // XIndexAccess
3245 
3246 sal_Int32 SAL_CALL ScTableRowsObj::getCount() throw(uno::RuntimeException)
3247 {
3248     ScUnoGuard aGuard;
3249     return nEndRow - nStartRow + 1;
3250 }
3251 
3252 uno::Any SAL_CALL ScTableRowsObj::getByIndex( sal_Int32 nIndex )
3253                             throw(lang::IndexOutOfBoundsException,
3254                                     lang::WrappedTargetException, uno::RuntimeException)
3255 {
3256     ScUnoGuard aGuard;
3257     uno::Reference<table::XCellRange> xRow(GetObjectByIndex_Impl(nIndex));
3258     if (xRow.is())
3259         return uno::makeAny(xRow);
3260     else
3261         throw lang::IndexOutOfBoundsException();
3262 //    return uno::Any();
3263 }
3264 
3265 uno::Type SAL_CALL ScTableRowsObj::getElementType() throw(uno::RuntimeException)
3266 {
3267     ScUnoGuard aGuard;
3268     return getCppuType((uno::Reference<table::XCellRange>*)0);
3269 }
3270 
3271 sal_Bool SAL_CALL ScTableRowsObj::hasElements() throw(uno::RuntimeException)
3272 {
3273     ScUnoGuard aGuard;
3274     return ( getCount() != 0 );
3275 }
3276 
3277 // XPropertySet
3278 
3279 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTableRowsObj::getPropertySetInfo()
3280                                                         throw(uno::RuntimeException)
3281 {
3282     ScUnoGuard aGuard;
3283     static uno::Reference<beans::XPropertySetInfo> aRef(
3284         new SfxItemPropertySetInfo( lcl_GetRowsPropertyMap() ));
3285     return aRef;
3286 }
3287 
3288 void SAL_CALL ScTableRowsObj::setPropertyValue(
3289                         const rtl::OUString& aPropertyName, const uno::Any& aValue )
3290                 throw(beans::UnknownPropertyException, beans::PropertyVetoException,
3291                         lang::IllegalArgumentException, lang::WrappedTargetException,
3292                         uno::RuntimeException)
3293 {
3294     ScUnoGuard aGuard;
3295     if (!pDocShell)
3296         throw uno::RuntimeException();
3297 
3298     ScDocFunc aFunc(*pDocShell);
3299     ScDocument* pDoc = pDocShell->GetDocument();
3300     SCCOLROW nRowArr[2];
3301     nRowArr[0] = nStartRow;
3302     nRowArr[1] = nEndRow;
3303     String aNameString(aPropertyName);
3304 
3305     if ( aNameString.EqualsAscii( SC_UNONAME_OHEIGHT ) )
3306     {
3307         sal_Int32 nNewHeight = 0;
3308         if ( pDoc->IsImportingXML() && ( aValue >>= nNewHeight ) )
3309         {
3310             // used to set the stored row height for rows with optimal height when loading.
3311 
3312             // TODO: It's probably cleaner to use a different property name
3313             // for this.
3314             pDoc->SetRowHeightOnly( nStartRow, nEndRow, nTab, (sal_uInt16)HMMToTwips(nNewHeight) );
3315         }
3316         else
3317         {
3318             sal_Bool bOpt = ScUnoHelpFunctions::GetBoolFromAny( aValue );
3319             if (bOpt)
3320                 aFunc.SetWidthOrHeight( sal_False, 1, nRowArr, nTab, SC_SIZE_OPTIMAL, 0, sal_True, sal_True );
3321             else
3322             {
3323                 //! manually set old heights again?
3324             }
3325         }
3326     }
3327     else if ( aNameString.EqualsAscii( SC_UNONAME_CELLHGT ) )
3328     {
3329         sal_Int32 nNewHeight = 0;
3330         if ( aValue >>= nNewHeight )
3331             aFunc.SetWidthOrHeight( sal_False, 1, nRowArr, nTab, SC_SIZE_ORIGINAL,
3332                                     (sal_uInt16)HMMToTwips(nNewHeight), sal_True, sal_True );
3333     }
3334     else if ( aNameString.EqualsAscii( SC_UNONAME_CELLVIS ) )
3335     {
3336         sal_Bool bVis = ScUnoHelpFunctions::GetBoolFromAny( aValue );
3337         ScSizeMode eMode = bVis ? SC_SIZE_SHOW : SC_SIZE_DIRECT;
3338         aFunc.SetWidthOrHeight( sal_False, 1, nRowArr, nTab, eMode, 0, sal_True, sal_True );
3339         // SC_SIZE_DIRECT with size 0: hide
3340     }
3341     else if ( aNameString.EqualsAscii( SC_UNONAME_VISFLAG ) )
3342     {
3343         // #i116460# Shortcut to only set the flag, without drawing layer update etc.
3344         // Should only be used from import filters.
3345         pDoc->SetRowHidden(nStartRow, nEndRow, nTab, !ScUnoHelpFunctions::GetBoolFromAny( aValue ));
3346     }
3347     else if ( aNameString.EqualsAscii( SC_UNONAME_CELLFILT ) )
3348     {
3349         //! undo etc.
3350         if (ScUnoHelpFunctions::GetBoolFromAny( aValue ))
3351             pDoc->SetRowFiltered(nStartRow, nEndRow, nTab, true);
3352         else
3353             pDoc->SetRowFiltered(nStartRow, nEndRow, nTab, false);
3354     }
3355     else if ( aNameString.EqualsAscii( SC_UNONAME_NEWPAGE) || aNameString.EqualsAscii( SC_UNONAME_MANPAGE) )
3356     {
3357         //! single function to set/remove all breaks?
3358         sal_Bool bSet = ScUnoHelpFunctions::GetBoolFromAny( aValue );
3359         for (SCROW nRow=nStartRow; nRow<=nEndRow; nRow++)
3360             if (bSet)
3361                 aFunc.InsertPageBreak( sal_False, ScAddress(0,nRow,nTab), sal_True, sal_True, sal_True );
3362             else
3363                 aFunc.RemovePageBreak( sal_False, ScAddress(0,nRow,nTab), sal_True, sal_True, sal_True );
3364     }
3365     else if ( aNameString.EqualsAscii( SC_UNONAME_CELLBACK ) || aNameString.EqualsAscii( SC_UNONAME_CELLTRAN ) )
3366     {
3367         // #i57867# Background color is specified for row styles in the file format,
3368         // so it has to be supported along with the row properties (import only).
3369 
3370         // Use ScCellRangeObj to set the property for all cells in the rows
3371         // (this means, the "row attribute" must be set before individual cell attributes).
3372 
3373         ScRange aRange( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab );
3374         uno::Reference<beans::XPropertySet> xRangeObj = new ScCellRangeObj( pDocShell, aRange );
3375         xRangeObj->setPropertyValue( aPropertyName, aValue );
3376     }
3377 }
3378 
3379 uno::Any SAL_CALL ScTableRowsObj::getPropertyValue( const rtl::OUString& aPropertyName )
3380                 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
3381                         uno::RuntimeException)
3382 {
3383     ScUnoGuard aGuard;
3384     if (!pDocShell)
3385         throw uno::RuntimeException();
3386 
3387     ScDocument* pDoc = pDocShell->GetDocument();
3388     String aNameString(aPropertyName);
3389     uno::Any aAny;
3390 
3391     //! loop over all rows for current state?
3392 
3393     if ( aNameString.EqualsAscii( SC_UNONAME_CELLHGT ) )
3394     {
3395         // for hidden row, return original height
3396         sal_uInt16 nHeight = pDoc->GetOriginalHeight( nStartRow, nTab );
3397         aAny <<= (sal_Int32)TwipsToHMM(nHeight);
3398     }
3399     else if ( aNameString.EqualsAscii( SC_UNONAME_CELLVIS ) )
3400     {
3401         SCROW nLastRow;
3402         bool bVis = !pDoc->RowHidden(nStartRow, nTab, nLastRow);
3403         ScUnoHelpFunctions::SetBoolInAny( aAny, bVis );
3404     }
3405     else if ( aNameString.EqualsAscii( SC_UNONAME_CELLFILT ) )
3406     {
3407         bool bVis = pDoc->RowFiltered(nStartRow, nTab);
3408         ScUnoHelpFunctions::SetBoolInAny( aAny, bVis );
3409     }
3410     else if ( aNameString.EqualsAscii( SC_UNONAME_OHEIGHT ) )
3411     {
3412         sal_Bool bOpt = !(pDoc->GetRowFlags( nStartRow, nTab ) & CR_MANUALSIZE);
3413         ScUnoHelpFunctions::SetBoolInAny( aAny, bOpt );
3414     }
3415     else if ( aNameString.EqualsAscii( SC_UNONAME_NEWPAGE ) )
3416     {
3417         ScBreakType nBreak = pDoc->HasRowBreak(nStartRow, nTab);
3418         ScUnoHelpFunctions::SetBoolInAny( aAny, nBreak );
3419     }
3420     else if ( aNameString.EqualsAscii( SC_UNONAME_MANPAGE ) )
3421     {
3422         ScBreakType nBreak = pDoc->HasRowBreak(nStartRow, nTab);
3423         ScUnoHelpFunctions::SetBoolInAny( aAny, (nBreak & BREAK_MANUAL) );
3424     }
3425     else if ( aNameString.EqualsAscii( SC_UNONAME_CELLBACK ) || aNameString.EqualsAscii( SC_UNONAME_CELLTRAN ) )
3426     {
3427         // Use ScCellRangeObj to get the property from the cell range
3428         // (for completeness only, this is not used by the XML filter).
3429 
3430         ScRange aRange( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab );
3431         uno::Reference<beans::XPropertySet> xRangeObj = new ScCellRangeObj( pDocShell, aRange );
3432         aAny = xRangeObj->getPropertyValue( aPropertyName );
3433     }
3434 
3435     return aAny;
3436 }
3437 
3438 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScTableRowsObj )
3439 
3440 //------------------------------------------------------------------------
3441 
3442 //UNUSED2008-05  ScSpreadsheetSettingsObj::ScSpreadsheetSettingsObj(ScDocShell* pDocSh) :
3443 //UNUSED2008-05  pDocShell( pDocSh )
3444 //UNUSED2008-05  {
3445 //UNUSED2008-05      pDocShell->GetDocument()->AddUnoObject(*this);
3446 //UNUSED2008-05  }
3447 
3448 ScSpreadsheetSettingsObj::~ScSpreadsheetSettingsObj()
3449 {
3450     if (pDocShell)
3451         pDocShell->GetDocument()->RemoveUnoObject(*this);
3452 }
3453 
3454 void ScSpreadsheetSettingsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
3455 {
3456     // Referenz-Update interessiert hier nicht
3457 
3458     if ( rHint.ISA( SfxSimpleHint ) &&
3459             ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
3460     {
3461         pDocShell = NULL; // ungültig geworden
3462     }
3463 }
3464 
3465 // XPropertySet
3466 
3467 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScSpreadsheetSettingsObj::getPropertySetInfo()
3468                                                         throw(uno::RuntimeException)
3469 {
3470     //! muss noch
3471     return NULL;
3472 }
3473 
3474 void SAL_CALL ScSpreadsheetSettingsObj::setPropertyValue(
3475                         const rtl::OUString& /* aPropertyName */, const uno::Any& /* aValue */ )
3476                 throw(beans::UnknownPropertyException, beans::PropertyVetoException,
3477                         lang::IllegalArgumentException, lang::WrappedTargetException,
3478                         uno::RuntimeException)
3479 {
3480     //! muss noch
3481 }
3482 
3483 uno::Any SAL_CALL ScSpreadsheetSettingsObj::getPropertyValue( const rtl::OUString& /* aPropertyName */ )
3484                 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
3485                         uno::RuntimeException)
3486 {
3487     //! muss noch
3488     return uno::Any();
3489 }
3490 
3491 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScSpreadsheetSettingsObj )
3492 
3493 //------------------------------------------------------------------------
3494 
3495 ScAnnotationsObj::ScAnnotationsObj(ScDocShell* pDocSh, SCTAB nT) :
3496     pDocShell( pDocSh ),
3497     nTab( nT )
3498 {
3499     pDocShell->GetDocument()->AddUnoObject(*this);
3500 }
3501 
3502 ScAnnotationsObj::~ScAnnotationsObj()
3503 {
3504     if (pDocShell)
3505         pDocShell->GetDocument()->RemoveUnoObject(*this);
3506 }
3507 
3508 void ScAnnotationsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
3509 {
3510     //! nTab bei Referenz-Update anpassen!!!
3511 
3512     if ( rHint.ISA( SfxSimpleHint ) &&
3513             ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
3514     {
3515         pDocShell = NULL; // ungültig geworden
3516     }
3517 }
3518 
3519 bool ScAnnotationsObj::GetAddressByIndex_Impl( sal_Int32 nIndex, ScAddress& rPos ) const
3520 {
3521     if (pDocShell)
3522     {
3523         sal_Int32 nFound = 0;
3524         ScDocument* pDoc = pDocShell->GetDocument();
3525         ScCellIterator aCellIter( pDoc, 0,0, nTab, MAXCOL,MAXROW, nTab );
3526         for( ScBaseCell* pCell = aCellIter.GetFirst(); pCell; pCell = aCellIter.GetNext() )
3527         {
3528             if (pCell->HasNote())
3529             {
3530                 if (nFound == nIndex)
3531                 {
3532                     rPos = ScAddress( aCellIter.GetCol(), aCellIter.GetRow(), aCellIter.GetTab() );
3533                     return true;
3534                 }
3535                 ++nFound;
3536             }
3537         }
3538     }
3539     return false;
3540 }
3541 
3542 ScAnnotationObj* ScAnnotationsObj::GetObjectByIndex_Impl( sal_Int32 nIndex ) const
3543 {
3544     if (pDocShell)
3545     {
3546         ScAddress aPos;
3547         if ( GetAddressByIndex_Impl( nIndex, aPos ) )
3548             return new ScAnnotationObj( pDocShell, aPos );
3549     }
3550     return NULL;
3551 }
3552 
3553 // XSheetAnnotations
3554 
3555 void SAL_CALL ScAnnotationsObj::insertNew(
3556         const table::CellAddress& aPosition, const ::rtl::OUString& rText )
3557                                                 throw(uno::RuntimeException)
3558 {
3559     ScUnoGuard aGuard;
3560     if (pDocShell)
3561     {
3562         DBG_ASSERT( aPosition.Sheet == nTab, "addAnnotation mit falschem Sheet" );
3563         ScAddress aPos( (SCCOL)aPosition.Column, (SCROW)aPosition.Row, nTab );
3564 
3565         ScDocFunc aFunc( *pDocShell );
3566         aFunc.ReplaceNote( aPos, rText, 0, 0, sal_True );
3567     }
3568 }
3569 
3570 void SAL_CALL ScAnnotationsObj::removeByIndex( sal_Int32 nIndex ) throw(uno::RuntimeException)
3571 {
3572     ScUnoGuard aGuard;
3573     if (pDocShell)
3574     {
3575         ScAddress aPos;
3576         if ( GetAddressByIndex_Impl( nIndex, aPos ) )
3577         {
3578             ScMarkData aMarkData;
3579             aMarkData.SelectTable( aPos.Tab(), sal_True );
3580             aMarkData.SetMultiMarkArea( ScRange(aPos) );
3581 
3582             ScDocFunc aFunc(*pDocShell);
3583             aFunc.DeleteContents( aMarkData, IDF_NOTE, sal_True, sal_True );
3584         }
3585     }
3586 }
3587 
3588 // XEnumerationAccess
3589 
3590 uno::Reference<container::XEnumeration> SAL_CALL ScAnnotationsObj::createEnumeration()
3591                                                     throw(uno::RuntimeException)
3592 {
3593     //! iterate directly (more efficiently)?
3594 
3595     ScUnoGuard aGuard;
3596     return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.CellAnnotationsEnumeration")));
3597 }
3598 
3599 // XIndexAccess
3600 
3601 sal_Int32 SAL_CALL ScAnnotationsObj::getCount() throw(uno::RuntimeException)
3602 {
3603     ScUnoGuard aGuard;
3604     sal_uLong nCount = 0;
3605     if (pDocShell)
3606     {
3607         ScCellIterator aCellIter( pDocShell->GetDocument(), 0,0, nTab, MAXCOL,MAXROW, nTab );
3608         for( ScBaseCell* pCell = aCellIter.GetFirst(); pCell; pCell = aCellIter.GetNext() )
3609             if (pCell->HasNote())
3610                 ++nCount;
3611     }
3612     return nCount;
3613 }
3614 
3615 uno::Any SAL_CALL ScAnnotationsObj::getByIndex( sal_Int32 nIndex )
3616                             throw(lang::IndexOutOfBoundsException,
3617                                     lang::WrappedTargetException, uno::RuntimeException)
3618 {
3619     ScUnoGuard aGuard;
3620     uno::Reference<sheet::XSheetAnnotation> xAnnotation(GetObjectByIndex_Impl(nIndex));
3621     if (xAnnotation.is())
3622         return uno::makeAny(xAnnotation);
3623     else
3624         throw lang::IndexOutOfBoundsException();
3625 //    return uno::Any();
3626 }
3627 
3628 uno::Type SAL_CALL ScAnnotationsObj::getElementType() throw(uno::RuntimeException)
3629 {
3630     ScUnoGuard aGuard;
3631     return getCppuType((uno::Reference<sheet::XSheetAnnotation>*)0);
3632 }
3633 
3634 sal_Bool SAL_CALL ScAnnotationsObj::hasElements() throw(uno::RuntimeException)
3635 {
3636     ScUnoGuard aGuard;
3637     return ( getCount() != 0 );
3638 }
3639 
3640 //------------------------------------------------------------------------
3641 
3642 ScScenariosObj::ScScenariosObj(ScDocShell* pDocSh, SCTAB nT) :
3643     pDocShell( pDocSh ),
3644     nTab     ( nT )
3645 {
3646     pDocShell->GetDocument()->AddUnoObject(*this);
3647 }
3648 
3649 ScScenariosObj::~ScScenariosObj()
3650 {
3651     if (pDocShell)
3652         pDocShell->GetDocument()->RemoveUnoObject(*this);
3653 }
3654 
3655 void ScScenariosObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
3656 {
3657     if ( rHint.ISA( ScUpdateRefHint ) )
3658     {
3659 //        const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
3660 
3661         //! Referenz-Update fuer Tab und Start/Ende
3662     }
3663     else if ( rHint.ISA( SfxSimpleHint ) &&
3664             ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
3665     {
3666         pDocShell = NULL; // ungültig geworden
3667     }
3668 }
3669 
3670 // XScenarios
3671 
3672 sal_Bool ScScenariosObj::GetScenarioIndex_Impl( const rtl::OUString& rName, SCTAB& rIndex )
3673 {
3674     //! Case-insensitiv ????
3675 
3676     if ( pDocShell )
3677     {
3678         String aString(rName);
3679 
3680         String aTabName;
3681         ScDocument* pDoc = pDocShell->GetDocument();
3682         SCTAB nCount = (SCTAB)getCount();
3683         for (SCTAB i=0; i<nCount; i++)
3684             if (pDoc->GetName( nTab+i+1, aTabName ))
3685                 if ( aTabName == aString )
3686                 {
3687                     rIndex = i;
3688                     return sal_True;
3689                 }
3690     }
3691 
3692     return sal_False;
3693 }
3694 
3695 ScTableSheetObj* ScScenariosObj::GetObjectByIndex_Impl(sal_Int32 nIndex)
3696 {
3697     sal_uInt16 nCount = (sal_uInt16)getCount();
3698     if ( pDocShell && nIndex >= 0 && nIndex < nCount )
3699         return new ScTableSheetObj( pDocShell, nTab+static_cast<SCTAB>(nIndex)+1 );
3700 
3701     return NULL; // kein Dokument oder falscher Index
3702 }
3703 
3704 ScTableSheetObj* ScScenariosObj::GetObjectByName_Impl(const rtl::OUString& aName)
3705 {
3706     SCTAB nIndex;
3707     if ( pDocShell && GetScenarioIndex_Impl( aName, nIndex ) )
3708         return new ScTableSheetObj( pDocShell, nTab+nIndex+1 );
3709 
3710     return NULL; // not found
3711 }
3712 
3713 void SAL_CALL ScScenariosObj::addNewByName( const rtl::OUString& aName,
3714                                 const uno::Sequence<table::CellRangeAddress>& aRanges,
3715                                 const rtl::OUString& aComment )
3716                                     throw(uno::RuntimeException)
3717 {
3718     ScUnoGuard aGuard;
3719     if ( pDocShell )
3720     {
3721         ScMarkData aMarkData;
3722         aMarkData.SelectTable( nTab, sal_True );
3723 
3724         sal_uInt16 nRangeCount = (sal_uInt16)aRanges.getLength();
3725         if (nRangeCount)
3726         {
3727             const table::CellRangeAddress* pAry = aRanges.getConstArray();
3728             for (sal_uInt16 i=0; i<nRangeCount; i++)
3729             {
3730                 DBG_ASSERT( pAry[i].Sheet == nTab, "addScenario mit falscher Tab" );
3731                 ScRange aRange( (SCCOL)pAry[i].StartColumn, (SCROW)pAry[i].StartRow, nTab,
3732                                 (SCCOL)pAry[i].EndColumn,   (SCROW)pAry[i].EndRow,   nTab );
3733 
3734                 aMarkData.SetMultiMarkArea( aRange );
3735             }
3736         }
3737 
3738         String aNameStr(aName);
3739         String aCommStr(aComment);
3740 
3741         Color aColor( COL_LIGHTGRAY ); // Default
3742         sal_uInt16 nFlags = SC_SCENARIO_SHOWFRAME | SC_SCENARIO_PRINTFRAME | SC_SCENARIO_TWOWAY | SC_SCENARIO_PROTECT;
3743 
3744         pDocShell->MakeScenario( nTab, aNameStr, aCommStr, aColor, nFlags, aMarkData );
3745     }
3746 }
3747 
3748 void SAL_CALL ScScenariosObj::removeByName( const rtl::OUString& aName )
3749                                             throw(uno::RuntimeException)
3750 {
3751     ScUnoGuard aGuard;
3752     SCTAB nIndex;
3753     if ( pDocShell && GetScenarioIndex_Impl( aName, nIndex ) )
3754     {
3755         ScDocFunc aFunc(*pDocShell);
3756         aFunc.DeleteTable( nTab+nIndex+1, sal_True, sal_True );
3757     }
3758 }
3759 
3760 // XEnumerationAccess
3761 
3762 uno::Reference<container::XEnumeration> SAL_CALL ScScenariosObj::createEnumeration()
3763                                                     throw(uno::RuntimeException)
3764 {
3765     ScUnoGuard aGuard;
3766     return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.ScenariosEnumeration")));
3767 }
3768 
3769 // XIndexAccess
3770 
3771 sal_Int32 SAL_CALL ScScenariosObj::getCount() throw(uno::RuntimeException)
3772 {
3773     ScUnoGuard aGuard;
3774     SCTAB nCount = 0;
3775     if ( pDocShell )
3776     {
3777         ScDocument* pDoc = pDocShell->GetDocument();
3778         if (!pDoc->IsScenario(nTab))
3779         {
3780             SCTAB nTabCount = pDoc->GetTableCount();
3781             SCTAB nNext = nTab + 1;
3782             while (nNext < nTabCount && pDoc->IsScenario(nNext))
3783             {
3784                 ++nCount;
3785                 ++nNext;
3786             }
3787         }
3788     }
3789     return nCount;
3790 }
3791 
3792 uno::Any SAL_CALL ScScenariosObj::getByIndex( sal_Int32 nIndex )
3793                             throw(lang::IndexOutOfBoundsException,
3794                                     lang::WrappedTargetException, uno::RuntimeException)
3795 {
3796     ScUnoGuard aGuard;
3797     uno::Reference<sheet::XScenario> xScen(GetObjectByIndex_Impl(nIndex));
3798     if (xScen.is())
3799         return uno::makeAny(xScen);
3800     else
3801         throw lang::IndexOutOfBoundsException();
3802 //    return uno::Any();
3803 }
3804 
3805 uno::Type SAL_CALL ScScenariosObj::getElementType() throw(uno::RuntimeException)
3806 {
3807     ScUnoGuard aGuard;
3808     return getCppuType((uno::Reference<sheet::XScenario>*)0);
3809 }
3810 
3811 sal_Bool SAL_CALL ScScenariosObj::hasElements() throw(uno::RuntimeException)
3812 {
3813     ScUnoGuard aGuard;
3814     return ( getCount() != 0 );
3815 }
3816 
3817 uno::Any SAL_CALL ScScenariosObj::getByName( const rtl::OUString& aName )
3818             throw(container::NoSuchElementException,
3819                     lang::WrappedTargetException, uno::RuntimeException)
3820 {
3821     ScUnoGuard aGuard;
3822     uno::Reference<sheet::XScenario> xScen(GetObjectByName_Impl(aName));
3823     if (xScen.is())
3824         return uno::makeAny(xScen);
3825     else
3826         throw container::NoSuchElementException();
3827 //    return uno::Any();
3828 }
3829 
3830 uno::Sequence<rtl::OUString> SAL_CALL ScScenariosObj::getElementNames()
3831                                                 throw(uno::RuntimeException)
3832 {
3833     ScUnoGuard aGuard;
3834     SCTAB nCount = (SCTAB)getCount();
3835     uno::Sequence<rtl::OUString> aSeq(nCount);
3836 
3837     if ( pDocShell ) // sonst ist auch Count = 0
3838     {
3839         String aTabName;
3840         ScDocument* pDoc = pDocShell->GetDocument();
3841         rtl::OUString* pAry = aSeq.getArray();
3842         for (SCTAB i=0; i<nCount; i++)
3843             if (pDoc->GetName( nTab+i+1, aTabName ))
3844                 pAry[i] = aTabName;
3845     }
3846 
3847     return aSeq;
3848 }
3849 
3850 sal_Bool SAL_CALL ScScenariosObj::hasByName( const rtl::OUString& aName )
3851                                         throw(uno::RuntimeException)
3852 {
3853     ScUnoGuard aGuard;
3854     SCTAB nIndex;
3855     return GetScenarioIndex_Impl( aName, nIndex );
3856 }
3857 
3858 /* vim: set noet sw=4 ts=4: */
3859