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