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