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