xref: /aoo41x/main/sc/source/ui/vba/vbarange.cxx (revision 86d5ef3b)
1b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3b3f79822SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4b3f79822SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5b3f79822SAndrew Rist  * distributed with this work for additional information
6b3f79822SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7b3f79822SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8b3f79822SAndrew Rist  * "License"); you may not use this file except in compliance
9b3f79822SAndrew Rist  * with the License.  You may obtain a copy of the License at
10b3f79822SAndrew Rist  *
11b3f79822SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12b3f79822SAndrew Rist  *
13b3f79822SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14b3f79822SAndrew Rist  * software distributed under the License is distributed on an
15b3f79822SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16b3f79822SAndrew Rist  * KIND, either express or implied.  See the License for the
17b3f79822SAndrew Rist  * specific language governing permissions and limitations
18b3f79822SAndrew Rist  * under the License.
19b3f79822SAndrew Rist  *
20b3f79822SAndrew Rist  *************************************************************/
21b3f79822SAndrew Rist 
22b3f79822SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include "vbarange.hxx"
25cdf0e10cSrcweir 
26cdf0e10cSrcweir #include <vbahelper/helperdecl.hxx>
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include <comphelper/unwrapargs.hxx>
29cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
30cdf0e10cSrcweir #include <sfx2/objsh.hxx>
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include <com/sun/star/script/ArrayWrapper.hpp>
33cdf0e10cSrcweir #include <com/sun/star/script/vba/VBAEventId.hpp>
34cdf0e10cSrcweir #include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
35cdf0e10cSrcweir #include <com/sun/star/sheet/XDatabaseRange.hpp>
36cdf0e10cSrcweir #include <com/sun/star/sheet/XDatabaseRanges.hpp>
37cdf0e10cSrcweir #include <com/sun/star/sheet/XGoalSeek.hpp>
38cdf0e10cSrcweir #include <com/sun/star/sheet/XSheetOperation.hpp>
39cdf0e10cSrcweir #include <com/sun/star/sheet/CellFlags.hpp>
40cdf0e10cSrcweir #include <com/sun/star/table/XColumnRowRange.hpp>
41cdf0e10cSrcweir #include <com/sun/star/sheet/XCellAddressable.hpp>
42cdf0e10cSrcweir #include <com/sun/star/table/CellContentType.hpp>
43cdf0e10cSrcweir #include <com/sun/star/sheet/XCellSeries.hpp>
44cdf0e10cSrcweir #include <com/sun/star/text/XTextRange.hpp>
45cdf0e10cSrcweir #include <com/sun/star/sheet/XCellRangeAddressable.hpp>
46cdf0e10cSrcweir #include <com/sun/star/table/CellRangeAddress.hpp>
47cdf0e10cSrcweir #include <com/sun/star/table/CellAddress.hpp>
48cdf0e10cSrcweir #include <com/sun/star/sheet/XSpreadsheetView.hpp>
49cdf0e10cSrcweir #include <com/sun/star/sheet/XCellRangeReferrer.hpp>
50cdf0e10cSrcweir #include <com/sun/star/sheet/XSheetCellRange.hpp>
51cdf0e10cSrcweir #include <com/sun/star/sheet/XSpreadsheet.hpp>
52cdf0e10cSrcweir #include <com/sun/star/sheet/XSheetCellCursor.hpp>
53cdf0e10cSrcweir #include <com/sun/star/sheet/XArrayFormulaRange.hpp>
54cdf0e10cSrcweir #include <com/sun/star/sheet/XNamedRange.hpp>
55cdf0e10cSrcweir #include <com/sun/star/sheet/XPrintAreas.hpp>
56cdf0e10cSrcweir #include <com/sun/star/sheet/XCellRangesQuery.hpp>
57cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
58cdf0e10cSrcweir #include <com/sun/star/sheet/XFunctionAccess.hpp>
59cdf0e10cSrcweir #include <com/sun/star/frame/XModel.hpp>
60cdf0e10cSrcweir #include <com/sun/star/view/XSelectionSupplier.hpp>
61cdf0e10cSrcweir #include <com/sun/star/table/XCellCursor.hpp>
62cdf0e10cSrcweir #include <com/sun/star/table/XTableRows.hpp>
63cdf0e10cSrcweir #include <com/sun/star/table/XTableColumns.hpp>
64cdf0e10cSrcweir #include <com/sun/star/table/TableSortField.hpp>
65cdf0e10cSrcweir #include <com/sun/star/util/XMergeable.hpp>
66cdf0e10cSrcweir #include <com/sun/star/uno/XComponentContext.hpp>
67cdf0e10cSrcweir #include <com/sun/star/lang/XMultiComponentFactory.hpp>
68cdf0e10cSrcweir #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
69cdf0e10cSrcweir #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
70cdf0e10cSrcweir #include <com/sun/star/util/XNumberFormats.hpp>
71cdf0e10cSrcweir #include <com/sun/star/util/NumberFormat.hpp>
72cdf0e10cSrcweir #include <com/sun/star/util/XNumberFormatTypes.hpp>
73cdf0e10cSrcweir #include <com/sun/star/util/XReplaceable.hpp>
74cdf0e10cSrcweir #include <com/sun/star/util/XSortable.hpp>
75cdf0e10cSrcweir #include <com/sun/star/sheet/XCellRangeMovement.hpp>
76cdf0e10cSrcweir #include <com/sun/star/sheet/XCellRangeData.hpp>
77cdf0e10cSrcweir #include <com/sun/star/sheet/FormulaResult.hpp>
78cdf0e10cSrcweir #include <com/sun/star/sheet/FilterOperator2.hpp>
79cdf0e10cSrcweir #include <com/sun/star/sheet/TableFilterField.hpp>
80cdf0e10cSrcweir #include <com/sun/star/sheet/TableFilterField2.hpp>
81cdf0e10cSrcweir #include <com/sun/star/sheet/XSheetFilterDescriptor2.hpp>
82cdf0e10cSrcweir #include <com/sun/star/sheet/XSheetFilterable.hpp>
83cdf0e10cSrcweir #include <com/sun/star/sheet/FilterConnection.hpp>
84cdf0e10cSrcweir #include <com/sun/star/util/CellProtection.hpp>
85cdf0e10cSrcweir #include <com/sun/star/util/TriState.hpp>
86cdf0e10cSrcweir 
87cdf0e10cSrcweir #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
88cdf0e10cSrcweir #include <com/sun/star/awt/XDevice.hpp>
89cdf0e10cSrcweir 
90cdf0e10cSrcweir //#include <com/sun/star/sheet/CellDeleteMode.hpp>
91cdf0e10cSrcweir #include <com/sun/star/sheet/XCellRangeMovement.hpp>
92cdf0e10cSrcweir #include <com/sun/star/sheet/XSubTotalCalculatable.hpp>
93cdf0e10cSrcweir #include <com/sun/star/sheet/XSubTotalDescriptor.hpp>
94cdf0e10cSrcweir #include <com/sun/star/sheet/GeneralFunction.hdl>
95cdf0e10cSrcweir 
96cdf0e10cSrcweir #include <ooo/vba/excel/XlPasteSpecialOperation.hpp>
97cdf0e10cSrcweir #include <ooo/vba/excel/XlPasteType.hpp>
98cdf0e10cSrcweir #include <ooo/vba/excel/Constants.hpp>
99cdf0e10cSrcweir #include <ooo/vba/excel/XlFindLookIn.hpp>
100cdf0e10cSrcweir #include <ooo/vba/excel/XlLookAt.hpp>
101cdf0e10cSrcweir #include <ooo/vba/excel/XlSearchOrder.hpp>
102cdf0e10cSrcweir #include <ooo/vba/excel/XlSortOrder.hpp>
103cdf0e10cSrcweir #include <ooo/vba/excel/XlYesNoGuess.hpp>
104cdf0e10cSrcweir #include <ooo/vba/excel/XlSortOrientation.hpp>
105cdf0e10cSrcweir #include <ooo/vba/excel/XlSortMethod.hpp>
106cdf0e10cSrcweir #include <ooo/vba/excel/XlDirection.hpp>
107cdf0e10cSrcweir #include <ooo/vba/excel/XlSortDataOption.hpp>
108cdf0e10cSrcweir #include <ooo/vba/excel/XlDeleteShiftDirection.hpp>
109cdf0e10cSrcweir #include <ooo/vba/excel/XlInsertShiftDirection.hpp>
110cdf0e10cSrcweir #include <ooo/vba/excel/XlReferenceStyle.hpp>
111cdf0e10cSrcweir #include <ooo/vba/excel/XlBordersIndex.hpp>
112cdf0e10cSrcweir #include <ooo/vba/excel/XlPageBreak.hpp>
113cdf0e10cSrcweir #include <ooo/vba/excel/XlAutoFilterOperator.hpp>
114cdf0e10cSrcweir #include <ooo/vba/excel/XlAutoFillType.hpp>
115cdf0e10cSrcweir #include <ooo/vba/excel/XlTextParsingType.hpp>
116cdf0e10cSrcweir #include <ooo/vba/excel/XlTextQualifier.hpp>
117cdf0e10cSrcweir #include <ooo/vba/excel/XlCellType.hpp>
118cdf0e10cSrcweir #include <ooo/vba/excel/XlSpecialCellsValue.hpp>
119cdf0e10cSrcweir #include <ooo/vba/excel/XlConsolidationFunction.hpp>
120cdf0e10cSrcweir #include <ooo/vba/excel/XlSearchDirection.hpp>
121cdf0e10cSrcweir 
122cdf0e10cSrcweir #include <scitems.hxx>
123cdf0e10cSrcweir #include <svl/srchitem.hxx>
124cdf0e10cSrcweir #include <cellsuno.hxx>
125cdf0e10cSrcweir #include <dbcolect.hxx>
126cdf0e10cSrcweir #include "docfunc.hxx"
127*86d5ef3bSPedro Giffuni #include <docuno.hxx>
128cdf0e10cSrcweir #include "transobj.hxx"
129cdf0e10cSrcweir 
130cdf0e10cSrcweir #include <sfx2/dispatch.hxx>
131cdf0e10cSrcweir #include <sfx2/app.hxx>
132cdf0e10cSrcweir #include <sfx2/bindings.hxx>
133cdf0e10cSrcweir #include <sfx2/request.hxx>
134cdf0e10cSrcweir #include <sfx2/viewfrm.hxx>
135cdf0e10cSrcweir #include <sfx2/itemwrapper.hxx>
136cdf0e10cSrcweir #include <sc.hrc>
137cdf0e10cSrcweir #include <globstr.hrc>
138cdf0e10cSrcweir #include <unonames.hxx>
139cdf0e10cSrcweir 
140cdf0e10cSrcweir #include "vbaapplication.hxx"
141cdf0e10cSrcweir #include "vbafont.hxx"
142cdf0e10cSrcweir #include "vbacomment.hxx"
143cdf0e10cSrcweir #include "vbainterior.hxx"
144cdf0e10cSrcweir #include "vbacharacters.hxx"
145cdf0e10cSrcweir #include "vbaborders.hxx"
146cdf0e10cSrcweir #include "vbaworksheet.hxx"
147cdf0e10cSrcweir #include "vbavalidation.hxx"
148cdf0e10cSrcweir #include "vbahyperlinks.hxx"
149cdf0e10cSrcweir 
150cdf0e10cSrcweir #include "tabvwsh.hxx"
151cdf0e10cSrcweir #include "rangelst.hxx"
152cdf0e10cSrcweir #include "convuno.hxx"
153cdf0e10cSrcweir #include "compiler.hxx"
154cdf0e10cSrcweir #include "attrib.hxx"
155cdf0e10cSrcweir #include "undodat.hxx"
156cdf0e10cSrcweir #include "dbdocfun.hxx"
157cdf0e10cSrcweir #include "patattr.hxx"
158cdf0e10cSrcweir #include "olinetab.hxx"
159cdf0e10cSrcweir #include <comphelper/anytostring.hxx>
160cdf0e10cSrcweir 
161cdf0e10cSrcweir #include <global.hxx>
162cdf0e10cSrcweir 
163cdf0e10cSrcweir #include "vbaglobals.hxx"
164cdf0e10cSrcweir #include "vbastyle.hxx"
165cdf0e10cSrcweir #include <vector>
166cdf0e10cSrcweir #include <vbahelper/vbacollectionimpl.hxx>
167cdf0e10cSrcweir // begin test includes
168cdf0e10cSrcweir #include <com/sun/star/sheet/FunctionArgument.hpp>
169cdf0e10cSrcweir // end test includes
170cdf0e10cSrcweir 
171cdf0e10cSrcweir #include <ooo/vba/excel/Range.hpp>
172cdf0e10cSrcweir #include <com/sun/star/bridge/oleautomation/Date.hpp>
173cdf0e10cSrcweir 
174cdf0e10cSrcweir using namespace ::ooo::vba;
175cdf0e10cSrcweir using namespace ::com::sun::star;
176cdf0e10cSrcweir using ::std::vector;
177cdf0e10cSrcweir 
178cdf0e10cSrcweir // difference between VBA and file format width, in character units
179cdf0e10cSrcweir const double fExtraWidth = 182.0 / 256.0;
180cdf0e10cSrcweir 
181cdf0e10cSrcweir //    * 1 point = 1/72 inch = 20 twips
182cdf0e10cSrcweir //    * 1 inch = 72 points = 1440 twips
183cdf0e10cSrcweir //    * 1 cm = 567 twips
lcl_hmmToPoints(double nVal)184cdf0e10cSrcweir double lcl_hmmToPoints( double nVal ) { return ( (double)((nVal /1000 ) * 567 ) / 20 ); }
185cdf0e10cSrcweir 
186cdf0e10cSrcweir static const sal_Int16 supportedIndexTable[] = {  excel::XlBordersIndex::xlEdgeLeft, excel::XlBordersIndex::xlEdgeTop, excel::XlBordersIndex::xlEdgeBottom, excel::XlBordersIndex::xlEdgeRight, excel::XlBordersIndex::xlDiagonalDown, excel::XlBordersIndex::xlDiagonalUp, excel::XlBordersIndex::xlInsideVertical, excel::XlBordersIndex::xlInsideHorizontal };
187cdf0e10cSrcweir 
lcl_pointsToTwips(double nVal)188cdf0e10cSrcweir sal_uInt16 lcl_pointsToTwips( double nVal )
189cdf0e10cSrcweir {
190cdf0e10cSrcweir 	nVal = nVal * static_cast<double>(20);
191cdf0e10cSrcweir 	short nTwips = static_cast<short>(nVal);
192cdf0e10cSrcweir 	return nTwips;
193cdf0e10cSrcweir }
lcl_TwipsToPoints(sal_uInt16 nVal)194cdf0e10cSrcweir double lcl_TwipsToPoints( sal_uInt16 nVal )
195cdf0e10cSrcweir {
196cdf0e10cSrcweir 	double nPoints = nVal;
197cdf0e10cSrcweir 	return nPoints / 20;
198cdf0e10cSrcweir }
199cdf0e10cSrcweir 
lcl_Round2DecPlaces(double nVal)200cdf0e10cSrcweir double lcl_Round2DecPlaces( double nVal )
201cdf0e10cSrcweir {
202cdf0e10cSrcweir 	nVal  = (nVal * (double)100);
203cdf0e10cSrcweir 	long tmp = static_cast<long>(nVal);
204cdf0e10cSrcweir 	if ( ( ( nVal - tmp ) >= 0.5 ) )
205cdf0e10cSrcweir 		++tmp;
206cdf0e10cSrcweir 	nVal = tmp;
207cdf0e10cSrcweir 	nVal = nVal/100;
208cdf0e10cSrcweir 	return nVal;
209cdf0e10cSrcweir }
210cdf0e10cSrcweir 
lcl_makeRange(const uno::Reference<XHelperInterface> & xParent,const uno::Reference<uno::XComponentContext> & xContext,const uno::Any aAny,bool bIsRows,bool bIsColumns)211cdf0e10cSrcweir uno::Any lcl_makeRange( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Any aAny, bool bIsRows, bool bIsColumns )
212cdf0e10cSrcweir {
213cdf0e10cSrcweir 	uno::Reference< table::XCellRange > xCellRange( aAny, uno::UNO_QUERY_THROW );
214cdf0e10cSrcweir     return uno::makeAny( uno::Reference< excel::XRange >( new ScVbaRange( xParent, xContext, xCellRange, bIsRows, bIsColumns ) ) );
215cdf0e10cSrcweir }
216cdf0e10cSrcweir 
lcl_makeXRangeFromSheetCellRanges(const uno::Reference<XHelperInterface> & xParent,const uno::Reference<uno::XComponentContext> & xContext,const uno::Reference<sheet::XSheetCellRanges> & xLocSheetCellRanges,ScDocShell * pDoc)217cdf0e10cSrcweir uno::Reference< excel::XRange > lcl_makeXRangeFromSheetCellRanges( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< sheet::XSheetCellRanges >& xLocSheetCellRanges, ScDocShell* pDoc )
218cdf0e10cSrcweir {
219cdf0e10cSrcweir 	uno::Reference< excel::XRange > xRange;
220cdf0e10cSrcweir 	uno::Sequence< table::CellRangeAddress  > sAddresses = xLocSheetCellRanges->getRangeAddresses();
221cdf0e10cSrcweir 	ScRangeList aCellRanges;
222cdf0e10cSrcweir 	sal_Int32 nLen = sAddresses.getLength();
223cdf0e10cSrcweir 	if ( nLen )
224cdf0e10cSrcweir        	{
225cdf0e10cSrcweir 	for ( sal_Int32 index = 0; index < nLen; ++index )
226cdf0e10cSrcweir 	{
227cdf0e10cSrcweir 		ScRange refRange;
228cdf0e10cSrcweir 		ScUnoConversion::FillScRange( refRange, sAddresses[ index ] );
229cdf0e10cSrcweir 		aCellRanges.Append( refRange );
230cdf0e10cSrcweir 	}
231cdf0e10cSrcweir 	// Single range
232cdf0e10cSrcweir 	if ( aCellRanges.First() == aCellRanges.Last() )
233cdf0e10cSrcweir 	{
234cdf0e10cSrcweir 		uno::Reference< table::XCellRange > xTmpRange( new ScCellRangeObj( pDoc, *aCellRanges.First() ) );
235cdf0e10cSrcweir 		xRange = new ScVbaRange( xParent, xContext, xTmpRange );
236cdf0e10cSrcweir 	}
237cdf0e10cSrcweir 	else
238cdf0e10cSrcweir 	{
239cdf0e10cSrcweir 		uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDoc, aCellRanges ) );
240cdf0e10cSrcweir 		xRange = new ScVbaRange( xParent, xContext, xRanges );
241cdf0e10cSrcweir 	}
242cdf0e10cSrcweir 	}
243cdf0e10cSrcweir 	return xRange;
244cdf0e10cSrcweir }
245cdf0e10cSrcweir 
getCellRangesBase()246cdf0e10cSrcweir ScCellRangesBase* ScVbaRange::getCellRangesBase() throw ( uno::RuntimeException )
247cdf0e10cSrcweir {
248cdf0e10cSrcweir     if( mxRanges.is() )
249cdf0e10cSrcweir         return ScCellRangesBase::getImplementation( mxRanges );
250cdf0e10cSrcweir     if( mxRange.is() )
251cdf0e10cSrcweir         return ScCellRangesBase::getImplementation( mxRange );
252cdf0e10cSrcweir     throw uno::RuntimeException( rtl::OUString::createFromAscii("General Error creating range - Unknown" ), uno::Reference< uno::XInterface >() );
253cdf0e10cSrcweir }
254cdf0e10cSrcweir 
getCellRangeObj()255cdf0e10cSrcweir ScCellRangeObj* ScVbaRange::getCellRangeObj() throw ( uno::RuntimeException )
256cdf0e10cSrcweir {
257cdf0e10cSrcweir 	return dynamic_cast< ScCellRangeObj* >( getCellRangesBase() );
258cdf0e10cSrcweir }
259cdf0e10cSrcweir 
getCellRangesObj()260cdf0e10cSrcweir ScCellRangesObj* ScVbaRange::getCellRangesObj() throw ( uno::RuntimeException )
261cdf0e10cSrcweir {
262cdf0e10cSrcweir 	return dynamic_cast< ScCellRangesObj* >( getCellRangesBase() );
263cdf0e10cSrcweir }
264cdf0e10cSrcweir 
getCurrentDataSet()265cdf0e10cSrcweir SfxItemSet*  ScVbaRange::getCurrentDataSet( ) throw ( uno::RuntimeException )
266cdf0e10cSrcweir {
267cdf0e10cSrcweir 	SfxItemSet* pDataSet = excel::ScVbaCellRangeAccess::GetDataSet( getCellRangesBase() );
268cdf0e10cSrcweir 	if ( !pDataSet )
269cdf0e10cSrcweir 		throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can't access Itemset for range" ) ), uno::Reference< uno::XInterface >() );
270cdf0e10cSrcweir 	return pDataSet;
271cdf0e10cSrcweir }
272cdf0e10cSrcweir 
fireChangeEvent()273cdf0e10cSrcweir void ScVbaRange::fireChangeEvent()
274cdf0e10cSrcweir {
275cdf0e10cSrcweir     if( ScVbaApplication::getDocumentEventsEnabled() )
276cdf0e10cSrcweir     {
277cdf0e10cSrcweir         if( ScDocument* pDoc = getScDocument() )
278cdf0e10cSrcweir         {
279cdf0e10cSrcweir             uno::Reference< script::vba::XVBAEventProcessor > xVBAEvents = pDoc->GetVbaEventProcessor();
280cdf0e10cSrcweir             if( xVBAEvents.is() ) try
281cdf0e10cSrcweir             {
282cdf0e10cSrcweir                 uno::Sequence< uno::Any > aArgs( 1 );
283cdf0e10cSrcweir                 aArgs[ 0 ] <<= uno::Reference< excel::XRange >( this );
284cdf0e10cSrcweir                 xVBAEvents->processVbaEvent( script::vba::VBAEventId::WORKSHEET_CHANGE, aArgs );
285cdf0e10cSrcweir             }
286cdf0e10cSrcweir             catch( uno::Exception& )
287cdf0e10cSrcweir             {
288cdf0e10cSrcweir             }
289cdf0e10cSrcweir         }
290cdf0e10cSrcweir     }
291cdf0e10cSrcweir }
292cdf0e10cSrcweir 
293cdf0e10cSrcweir class SingleRangeEnumeration : public EnumerationHelper_BASE
294cdf0e10cSrcweir {
295cdf0e10cSrcweir     uno::Reference< XHelperInterface > m_xParent;
296cdf0e10cSrcweir 	uno::Reference< table::XCellRange > m_xRange;
297cdf0e10cSrcweir 	uno::Reference< uno::XComponentContext > mxContext;
298cdf0e10cSrcweir 	bool bHasMore;
299cdf0e10cSrcweir public:
300cdf0e10cSrcweir 
SingleRangeEnumeration(const uno::Reference<XHelperInterface> & xParent,const uno::Reference<css::uno::XComponentContext> & xContext,const uno::Reference<table::XCellRange> & xRange)301cdf0e10cSrcweir     SingleRangeEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< css::uno::XComponentContext >& xContext, const uno::Reference< table::XCellRange >& xRange ) throw ( uno::RuntimeException ) : m_xParent( xParent ), m_xRange( xRange ), mxContext( xContext ), bHasMore( true ) { }
hasMoreElements()302cdf0e10cSrcweir 	virtual ::sal_Bool SAL_CALL hasMoreElements(  ) throw (uno::RuntimeException) { return bHasMore; }
nextElement()303cdf0e10cSrcweir 	virtual uno::Any SAL_CALL nextElement(  ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
304cdf0e10cSrcweir 	{
305cdf0e10cSrcweir 		if ( !bHasMore )
306cdf0e10cSrcweir 			throw container::NoSuchElementException();
307cdf0e10cSrcweir 		bHasMore = false;
308cdf0e10cSrcweir 		return uno::makeAny( m_xRange );
309cdf0e10cSrcweir 	}
310cdf0e10cSrcweir };
311cdf0e10cSrcweir 
312cdf0e10cSrcweir // very simple class to pass to ScVbaCollectionBaseImpl containing
313cdf0e10cSrcweir // just one item
314cdf0e10cSrcweir typedef ::cppu::WeakImplHelper2< container::XIndexAccess, container::XEnumerationAccess > SingleRange_BASE;
315cdf0e10cSrcweir 
316cdf0e10cSrcweir class SingleRangeIndexAccess : public SingleRange_BASE
317cdf0e10cSrcweir {
318cdf0e10cSrcweir private:
319cdf0e10cSrcweir     uno::Reference< XHelperInterface > mxParent;
320cdf0e10cSrcweir 	uno::Reference< table::XCellRange > m_xRange;
321cdf0e10cSrcweir 	uno::Reference< uno::XComponentContext > mxContext;
322cdf0e10cSrcweir 	SingleRangeIndexAccess(); // not defined
323cdf0e10cSrcweir public:
SingleRangeIndexAccess(const uno::Reference<XHelperInterface> & xParent,const uno::Reference<uno::XComponentContext> & xContext,const uno::Reference<table::XCellRange> & xRange)324cdf0e10cSrcweir     SingleRangeIndexAccess( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< table::XCellRange >& xRange ):mxParent( xParent ), m_xRange( xRange ), mxContext( xContext ) {}
325cdf0e10cSrcweir 	// XIndexAccess
getCount()326cdf0e10cSrcweir 	virtual ::sal_Int32 SAL_CALL getCount() throw (::uno::RuntimeException) { return 1; }
getByIndex(::sal_Int32 Index)327cdf0e10cSrcweir 	virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException)
328cdf0e10cSrcweir 	{
329cdf0e10cSrcweir 		if ( Index != 0 )
330cdf0e10cSrcweir 			throw lang::IndexOutOfBoundsException();
331cdf0e10cSrcweir 		return uno::makeAny( m_xRange );
332cdf0e10cSrcweir 	}
333cdf0e10cSrcweir         // XElementAccess
getElementType()334cdf0e10cSrcweir         virtual uno::Type SAL_CALL getElementType() throw (uno::RuntimeException){ return table::XCellRange::static_type(0); }
335cdf0e10cSrcweir 
hasElements()336cdf0e10cSrcweir         virtual ::sal_Bool SAL_CALL hasElements() throw (uno::RuntimeException) { return sal_True; }
337cdf0e10cSrcweir 	// XEnumerationAccess
createEnumeration()338cdf0e10cSrcweir     virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration() throw (uno::RuntimeException) { return new SingleRangeEnumeration( mxParent, mxContext, m_xRange ); }
339cdf0e10cSrcweir 
340cdf0e10cSrcweir };
341cdf0e10cSrcweir 
342cdf0e10cSrcweir 
343cdf0e10cSrcweir 
344cdf0e10cSrcweir class RangesEnumerationImpl : public EnumerationHelperImpl
345cdf0e10cSrcweir {
346cdf0e10cSrcweir 	bool mbIsRows;
347cdf0e10cSrcweir 	bool mbIsColumns;
348cdf0e10cSrcweir public:
349cdf0e10cSrcweir 
RangesEnumerationImpl(const uno::Reference<XHelperInterface> & xParent,const uno::Reference<uno::XComponentContext> & xContext,const uno::Reference<container::XEnumeration> & xEnumeration,bool bIsRows,bool bIsColumns)350cdf0e10cSrcweir     RangesEnumerationImpl( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, bool bIsRows, bool bIsColumns ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), mbIsRows( bIsRows ), mbIsColumns( bIsColumns ) {}
nextElement()351cdf0e10cSrcweir 	virtual uno::Any SAL_CALL nextElement(  ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
352cdf0e10cSrcweir 	{
353cdf0e10cSrcweir         return lcl_makeRange( m_xParent, m_xContext, m_xEnumeration->nextElement(), mbIsRows, mbIsColumns );
354cdf0e10cSrcweir 	}
355cdf0e10cSrcweir };
356cdf0e10cSrcweir 
357cdf0e10cSrcweir 
358cdf0e10cSrcweir class ScVbaRangeAreas : public ScVbaCollectionBaseImpl
359cdf0e10cSrcweir {
360cdf0e10cSrcweir 	bool mbIsRows;
361cdf0e10cSrcweir 	bool mbIsColumns;
362cdf0e10cSrcweir public:
ScVbaRangeAreas(const uno::Reference<XHelperInterface> & xParent,const uno::Reference<uno::XComponentContext> & xContext,const uno::Reference<container::XIndexAccess> & xIndexAccess,bool bIsRows,bool bIsColumns)363cdf0e10cSrcweir     ScVbaRangeAreas( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XIndexAccess >& xIndexAccess, bool bIsRows, bool bIsColumns ) : ScVbaCollectionBaseImpl( xParent, xContext, xIndexAccess ), mbIsRows( bIsRows ), mbIsColumns( bIsColumns ) {}
364cdf0e10cSrcweir 
365cdf0e10cSrcweir 	// XEnumerationAccess
366cdf0e10cSrcweir 	virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration() throw (uno::RuntimeException);
367cdf0e10cSrcweir 
368cdf0e10cSrcweir 	// XElementAccess
getElementType()369cdf0e10cSrcweir 	virtual uno::Type SAL_CALL getElementType() throw (uno::RuntimeException){ return excel::XRange::static_type(0); }
370cdf0e10cSrcweir 
371cdf0e10cSrcweir 	virtual uno::Any createCollectionObject( const uno::Any& aSource );
372cdf0e10cSrcweir 
getServiceImplName()373cdf0e10cSrcweir 	virtual rtl::OUString& getServiceImplName() { static rtl::OUString sDummy; return sDummy; }
374cdf0e10cSrcweir 
getServiceNames()375cdf0e10cSrcweir 	virtual uno::Sequence< rtl::OUString > getServiceNames() { return uno::Sequence< rtl::OUString >(); }
376cdf0e10cSrcweir 
377cdf0e10cSrcweir };
378cdf0e10cSrcweir 
379cdf0e10cSrcweir uno::Reference< container::XEnumeration > SAL_CALL
createEnumeration()380cdf0e10cSrcweir ScVbaRangeAreas::createEnumeration() throw (uno::RuntimeException)
381cdf0e10cSrcweir {
382cdf0e10cSrcweir 	uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
383cdf0e10cSrcweir 	return new RangesEnumerationImpl( mxParent, mxContext, xEnumAccess->createEnumeration(), mbIsRows, mbIsColumns );
384cdf0e10cSrcweir }
385cdf0e10cSrcweir 
386cdf0e10cSrcweir uno::Any
createCollectionObject(const uno::Any & aSource)387cdf0e10cSrcweir ScVbaRangeAreas::createCollectionObject( const uno::Any& aSource )
388cdf0e10cSrcweir {
389cdf0e10cSrcweir 	return lcl_makeRange( mxParent, mxContext, aSource, mbIsRows, mbIsColumns );
390cdf0e10cSrcweir }
391cdf0e10cSrcweir 
392cdf0e10cSrcweir // assume that xIf is infact a ScCellRangesBase
393cdf0e10cSrcweir ScDocShell*
getDocShellFromIf(const uno::Reference<uno::XInterface> & xIf)394cdf0e10cSrcweir getDocShellFromIf( const uno::Reference< uno::XInterface >& xIf ) throw ( uno::RuntimeException )
395cdf0e10cSrcweir {
396cdf0e10cSrcweir 	ScCellRangesBase* pUno = ScCellRangesBase::getImplementation( xIf );
397cdf0e10cSrcweir 	if ( !pUno )
398cdf0e10cSrcweir 		throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to access underlying uno range object" ) ), uno::Reference< uno::XInterface >()  );
399cdf0e10cSrcweir 	return pUno->GetDocShell();
400cdf0e10cSrcweir }
401cdf0e10cSrcweir 
402cdf0e10cSrcweir ScDocShell*
getDocShellFromRange(const uno::Reference<table::XCellRange> & xRange)403cdf0e10cSrcweir getDocShellFromRange( const uno::Reference< table::XCellRange >& xRange ) throw ( uno::RuntimeException )
404cdf0e10cSrcweir {
405cdf0e10cSrcweir 	// need the ScCellRangesBase to get docshell
406cdf0e10cSrcweir     uno::Reference< uno::XInterface > xIf( xRange );
407cdf0e10cSrcweir 	return getDocShellFromIf(xIf );
408cdf0e10cSrcweir }
409cdf0e10cSrcweir 
410cdf0e10cSrcweir ScDocShell*
getDocShellFromRanges(const uno::Reference<sheet::XSheetCellRangeContainer> & xRanges)411cdf0e10cSrcweir getDocShellFromRanges( const uno::Reference< sheet::XSheetCellRangeContainer >& xRanges ) throw ( uno::RuntimeException )
412cdf0e10cSrcweir {
413cdf0e10cSrcweir 	// need the ScCellRangesBase to get docshell
414cdf0e10cSrcweir     uno::Reference< uno::XInterface > xIf( xRanges );
415cdf0e10cSrcweir 	return getDocShellFromIf(xIf );
416cdf0e10cSrcweir }
417cdf0e10cSrcweir 
getModelFromXIf(const uno::Reference<uno::XInterface> & xIf)418cdf0e10cSrcweir uno::Reference< frame::XModel > getModelFromXIf( const uno::Reference< uno::XInterface >& xIf ) throw ( uno::RuntimeException )
419cdf0e10cSrcweir {
420cdf0e10cSrcweir 	ScDocShell* pDocShell = getDocShellFromIf(xIf );
421cdf0e10cSrcweir 	return pDocShell->GetModel();
422cdf0e10cSrcweir }
423cdf0e10cSrcweir 
getModelFromRange(const uno::Reference<table::XCellRange> & xRange)424cdf0e10cSrcweir uno::Reference< frame::XModel > getModelFromRange( const uno::Reference< table::XCellRange >& xRange ) throw ( uno::RuntimeException )
425cdf0e10cSrcweir {
426cdf0e10cSrcweir     // the XInterface for getImplementation can be any derived interface, no need for queryInterface
427cdf0e10cSrcweir     uno::Reference< uno::XInterface > xIf( xRange );
428cdf0e10cSrcweir 	return getModelFromXIf( xIf );
429cdf0e10cSrcweir }
430cdf0e10cSrcweir 
431cdf0e10cSrcweir ScDocument*
getDocumentFromRange(const uno::Reference<table::XCellRange> & xRange)432cdf0e10cSrcweir getDocumentFromRange( const uno::Reference< table::XCellRange >& xRange )
433cdf0e10cSrcweir {
434cdf0e10cSrcweir 	ScDocShell* pDocShell = getDocShellFromRange( xRange );
435cdf0e10cSrcweir 	if ( !pDocShell )
436cdf0e10cSrcweir 		throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to access underlying docshell from uno range object" ) ), uno::Reference< uno::XInterface >() );
437cdf0e10cSrcweir 	ScDocument* pDoc = pDocShell->GetDocument();
438cdf0e10cSrcweir 	return pDoc;
439cdf0e10cSrcweir }
440cdf0e10cSrcweir 
441cdf0e10cSrcweir 
442cdf0e10cSrcweir ScDocument*
getScDocument()443cdf0e10cSrcweir ScVbaRange::getScDocument() throw (uno::RuntimeException)
444cdf0e10cSrcweir {
445cdf0e10cSrcweir 	if ( mxRanges.is() )
446cdf0e10cSrcweir 	{
447cdf0e10cSrcweir 		uno::Reference< container::XIndexAccess > xIndex( mxRanges, uno::UNO_QUERY_THROW );
448cdf0e10cSrcweir 		uno::Reference< table::XCellRange > xRange( xIndex->getByIndex( 0 ), uno::UNO_QUERY_THROW );
449cdf0e10cSrcweir 		return getDocumentFromRange( xRange );
450cdf0e10cSrcweir 	}
451cdf0e10cSrcweir 	return getDocumentFromRange( mxRange );
452cdf0e10cSrcweir }
453cdf0e10cSrcweir 
454cdf0e10cSrcweir ScDocShell*
getScDocShell()455cdf0e10cSrcweir ScVbaRange::getScDocShell() throw (uno::RuntimeException)
456cdf0e10cSrcweir {
457cdf0e10cSrcweir 	if ( mxRanges.is() )
458cdf0e10cSrcweir 	{
459cdf0e10cSrcweir 		uno::Reference< container::XIndexAccess > xIndex( mxRanges, uno::UNO_QUERY_THROW );
460cdf0e10cSrcweir 		uno::Reference< table::XCellRange > xRange( xIndex->getByIndex( 0 ), uno::UNO_QUERY_THROW );
461cdf0e10cSrcweir 		return getDocShellFromRange( xRange );
462cdf0e10cSrcweir 	}
463cdf0e10cSrcweir 	return getDocShellFromRange( mxRange );
464cdf0e10cSrcweir }
465cdf0e10cSrcweir 
getImplementation(const uno::Reference<excel::XRange> & rxRange)466cdf0e10cSrcweir /*static*/ ScVbaRange* ScVbaRange::getImplementation( const uno::Reference< excel::XRange >& rxRange )
467cdf0e10cSrcweir {
468cdf0e10cSrcweir     // FIXME: always save to use dynamic_cast? Or better to (implement and) use XTunnel?
469cdf0e10cSrcweir     return dynamic_cast< ScVbaRange* >( rxRange.get() );
470cdf0e10cSrcweir }
471cdf0e10cSrcweir 
getUnoModel()472cdf0e10cSrcweir uno::Reference< frame::XModel > ScVbaRange::getUnoModel() throw (uno::RuntimeException)
473cdf0e10cSrcweir {
474cdf0e10cSrcweir     if( ScDocShell* pDocShell = getScDocShell() )
475cdf0e10cSrcweir         return pDocShell->GetModel();
476cdf0e10cSrcweir     throw uno::RuntimeException();
477cdf0e10cSrcweir }
478cdf0e10cSrcweir 
getUnoModel(const uno::Reference<excel::XRange> & rxRange)479cdf0e10cSrcweir /*static*/ uno::Reference< frame::XModel > ScVbaRange::getUnoModel( const uno::Reference< excel::XRange >& rxRange ) throw (uno::RuntimeException)
480cdf0e10cSrcweir {
481cdf0e10cSrcweir     if( ScVbaRange* pScVbaRange = getImplementation( rxRange ) )
482cdf0e10cSrcweir         return pScVbaRange->getUnoModel();
483cdf0e10cSrcweir     throw uno::RuntimeException();
484cdf0e10cSrcweir }
485cdf0e10cSrcweir 
getScRangeList()486cdf0e10cSrcweir const ScRangeList& ScVbaRange::getScRangeList() throw (uno::RuntimeException)
487cdf0e10cSrcweir {
488cdf0e10cSrcweir     if( ScCellRangesBase* pScRangesBase = getCellRangesBase() )
489cdf0e10cSrcweir         return pScRangesBase->GetRangeList();
490cdf0e10cSrcweir     throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Cannot obtain UNO range implementation object" ) ), uno::Reference< uno::XInterface >() );
491cdf0e10cSrcweir }
492cdf0e10cSrcweir 
getScRangeList(const uno::Reference<excel::XRange> & rxRange)493cdf0e10cSrcweir /*static*/ const ScRangeList& ScVbaRange::getScRangeList( const uno::Reference< excel::XRange >& rxRange ) throw (uno::RuntimeException)
494cdf0e10cSrcweir {
495cdf0e10cSrcweir     if( ScVbaRange* pScVbaRange = getImplementation( rxRange ) )
496cdf0e10cSrcweir         return pScVbaRange->getScRangeList();
497cdf0e10cSrcweir     throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Cannot obtain VBA range implementation object" ) ), uno::Reference< uno::XInterface >() );
498cdf0e10cSrcweir }
499cdf0e10cSrcweir 
500cdf0e10cSrcweir 
501cdf0e10cSrcweir class NumFormatHelper
502cdf0e10cSrcweir {
503cdf0e10cSrcweir 	uno::Reference< util::XNumberFormatsSupplier > mxSupplier;
504cdf0e10cSrcweir 	uno::Reference< beans::XPropertySet > mxRangeProps;
505cdf0e10cSrcweir 	uno::Reference< util::XNumberFormats > mxFormats;
506cdf0e10cSrcweir public:
NumFormatHelper(const uno::Reference<table::XCellRange> & xRange)507cdf0e10cSrcweir 	NumFormatHelper( const uno::Reference< table::XCellRange >& xRange )
508cdf0e10cSrcweir 	{
509cdf0e10cSrcweir 		mxSupplier.set( getModelFromRange( xRange ), uno::UNO_QUERY_THROW );
510cdf0e10cSrcweir 		mxRangeProps.set( xRange, uno::UNO_QUERY_THROW);
511cdf0e10cSrcweir 		mxFormats = mxSupplier->getNumberFormats();
512cdf0e10cSrcweir 	}
getNumberProps()513cdf0e10cSrcweir 	uno::Reference< beans::XPropertySet > getNumberProps()
514cdf0e10cSrcweir 	{
515cdf0e10cSrcweir 		long nIndexKey = 0;
516cdf0e10cSrcweir 		uno::Any aValue = mxRangeProps->getPropertyValue(rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("NumberFormat")));
517cdf0e10cSrcweir 		aValue >>= nIndexKey;
518cdf0e10cSrcweir 
519cdf0e10cSrcweir 		if ( mxFormats.is() )
520cdf0e10cSrcweir 			return  mxFormats->getByKey( nIndexKey );
521cdf0e10cSrcweir 		return	uno::Reference< beans::XPropertySet > ();
522cdf0e10cSrcweir 	}
523cdf0e10cSrcweir 
isBooleanType()524cdf0e10cSrcweir 	bool isBooleanType()
525cdf0e10cSrcweir 	{
526cdf0e10cSrcweir 
527cdf0e10cSrcweir 		if ( getNumberFormat() & util::NumberFormat::LOGICAL )
528cdf0e10cSrcweir 			return true;
529cdf0e10cSrcweir 		return false;
530cdf0e10cSrcweir 	}
531cdf0e10cSrcweir 
isDateType()532cdf0e10cSrcweir 	bool isDateType()
533cdf0e10cSrcweir 	{
534cdf0e10cSrcweir 		sal_Int16 nType = getNumberFormat();
535cdf0e10cSrcweir 		if(( nType & util::NumberFormat::DATETIME ))
536cdf0e10cSrcweir 		{
537cdf0e10cSrcweir 			return true;
538cdf0e10cSrcweir 		}
539cdf0e10cSrcweir 		return false;
540cdf0e10cSrcweir 	}
541cdf0e10cSrcweir 
getNumberFormatString()542cdf0e10cSrcweir 	rtl::OUString getNumberFormatString()
543cdf0e10cSrcweir 	{
544cdf0e10cSrcweir 		uno::Reference< uno::XInterface > xIf( mxRangeProps, uno::UNO_QUERY_THROW );
545cdf0e10cSrcweir 		ScCellRangesBase* pUnoCellRange = ScCellRangesBase::getImplementation( xIf );
546cdf0e10cSrcweir 		if ( pUnoCellRange )
547cdf0e10cSrcweir 		{
548cdf0e10cSrcweir 
549cdf0e10cSrcweir 			SfxItemSet* pDataSet = 	excel::ScVbaCellRangeAccess::GetDataSet( pUnoCellRange );
550cdf0e10cSrcweir 			SfxItemState eState = pDataSet->GetItemState( ATTR_VALUE_FORMAT, sal_True, NULL);
551cdf0e10cSrcweir 			// one of the cells in the range is not like the other ;-)
552cdf0e10cSrcweir 			// so return a zero length format to indicate that
553cdf0e10cSrcweir 			if ( eState == SFX_ITEM_DONTCARE )
554cdf0e10cSrcweir 				return rtl::OUString();
555cdf0e10cSrcweir 		}
556cdf0e10cSrcweir 
557cdf0e10cSrcweir 
558cdf0e10cSrcweir 		uno::Reference< beans::XPropertySet > xNumberProps( getNumberProps(), uno::UNO_QUERY_THROW );
559cdf0e10cSrcweir 		::rtl::OUString aFormatString;
560cdf0e10cSrcweir 		uno::Any aString = xNumberProps->getPropertyValue(rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("FormatString")));
561cdf0e10cSrcweir 		aString >>= aFormatString;
562cdf0e10cSrcweir 		return aFormatString;
563cdf0e10cSrcweir 	}
564cdf0e10cSrcweir 
getNumberFormat()565cdf0e10cSrcweir 	sal_Int16 getNumberFormat()
566cdf0e10cSrcweir 	{
567cdf0e10cSrcweir 		uno::Reference< beans::XPropertySet > xNumberProps = getNumberProps();
568cdf0e10cSrcweir 		sal_Int16 nType = ::comphelper::getINT16(
569cdf0e10cSrcweir         	xNumberProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Type" ) ) ) );
570cdf0e10cSrcweir 		return nType;
571cdf0e10cSrcweir 	}
572cdf0e10cSrcweir 
setNumberFormat(const rtl::OUString & rFormat)573cdf0e10cSrcweir 	bool setNumberFormat( const rtl::OUString& rFormat )
574cdf0e10cSrcweir 	{
575cdf0e10cSrcweir         // #163288# treat "General" as "Standard" format
576cdf0e10cSrcweir         sal_Int32 nNewIndex = 0;
577cdf0e10cSrcweir         if( !rFormat.equalsIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( "General" ) ) )
578cdf0e10cSrcweir         {
579cdf0e10cSrcweir     		lang::Locale aLocale;
580cdf0e10cSrcweir     		uno::Reference< beans::XPropertySet > xNumProps = getNumberProps();
581cdf0e10cSrcweir     		xNumProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Locale" ) ) ) >>= aLocale;
582cdf0e10cSrcweir     		nNewIndex = mxFormats->queryKey( rFormat, aLocale, false );
583cdf0e10cSrcweir     		if ( nNewIndex == -1 ) // format not defined
584cdf0e10cSrcweir     			nNewIndex = mxFormats->addNew( rFormat, aLocale );
585cdf0e10cSrcweir         }
586cdf0e10cSrcweir 		mxRangeProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("NumberFormat") ), uno::makeAny( nNewIndex ) );
587cdf0e10cSrcweir 		return true;
588cdf0e10cSrcweir 	}
589cdf0e10cSrcweir 
setNumberFormat(sal_Int16 nType)590cdf0e10cSrcweir 	bool setNumberFormat( sal_Int16 nType )
591cdf0e10cSrcweir 	{
592cdf0e10cSrcweir 		uno::Reference< beans::XPropertySet > xNumberProps = getNumberProps();
593cdf0e10cSrcweir 		lang::Locale aLocale;
594cdf0e10cSrcweir 		xNumberProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Locale" ) ) ) >>= aLocale;
595cdf0e10cSrcweir 		uno::Reference<util::XNumberFormatTypes> xTypes( mxFormats, uno::UNO_QUERY );
596cdf0e10cSrcweir 		if ( xTypes.is() )
597cdf0e10cSrcweir 		{
598cdf0e10cSrcweir 			sal_Int32 nNewIndex = xTypes->getStandardFormat( nType, aLocale );
599cdf0e10cSrcweir        		mxRangeProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("NumberFormat") ), uno::makeAny( nNewIndex ) );
600cdf0e10cSrcweir 			return true;
601cdf0e10cSrcweir 		}
602cdf0e10cSrcweir 		return false;
603cdf0e10cSrcweir 	}
604cdf0e10cSrcweir 
605cdf0e10cSrcweir };
606cdf0e10cSrcweir 
607cdf0e10cSrcweir struct CellPos
608cdf0e10cSrcweir {
CellPosCellPos609cdf0e10cSrcweir 	CellPos():m_nRow(-1), m_nCol(-1), m_nArea(0) {};
CellPosCellPos610cdf0e10cSrcweir 	CellPos( sal_Int32 nRow, sal_Int32 nCol, sal_Int32 nArea ):m_nRow(nRow), m_nCol(nCol), m_nArea( nArea ) {};
611cdf0e10cSrcweir sal_Int32 m_nRow;
612cdf0e10cSrcweir sal_Int32 m_nCol;
613cdf0e10cSrcweir sal_Int32 m_nArea;
614cdf0e10cSrcweir };
615cdf0e10cSrcweir 
616cdf0e10cSrcweir typedef ::cppu::WeakImplHelper1< container::XEnumeration > CellsEnumeration_BASE;
617cdf0e10cSrcweir typedef ::std::vector< CellPos > vCellPos;
618cdf0e10cSrcweir 
619cdf0e10cSrcweir // #FIXME - QUICK
620cdf0e10cSrcweir // we could probably could and should modify CellsEnumeration below
621cdf0e10cSrcweir // to handle rows and columns ( but I do this seperately for now
622cdf0e10cSrcweir // and.. this class only handles singe areas ( does it have to handle
623cdf0e10cSrcweir // multi area ranges?? )
624cdf0e10cSrcweir class ColumnsRowEnumeration: public CellsEnumeration_BASE
625cdf0e10cSrcweir {
626cdf0e10cSrcweir 	uno::Reference< uno::XComponentContext > mxContext;
627cdf0e10cSrcweir         uno::Reference< excel::XRange > mxRange;
628cdf0e10cSrcweir 	sal_Int32 mMaxElems;
629cdf0e10cSrcweir 	sal_Int32 mCurElem;
630cdf0e10cSrcweir 
631cdf0e10cSrcweir public:
ColumnsRowEnumeration(const uno::Reference<uno::XComponentContext> & xContext,const uno::Reference<excel::XRange> & xRange,sal_Int32 nElems)632cdf0e10cSrcweir 	ColumnsRowEnumeration( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< excel::XRange >& xRange, sal_Int32 nElems ) : mxContext( xContext ), mxRange( xRange ), mMaxElems( nElems ), mCurElem( 0 )
633cdf0e10cSrcweir         {
634cdf0e10cSrcweir 	}
635cdf0e10cSrcweir 
hasMoreElements()636cdf0e10cSrcweir 	virtual ::sal_Bool SAL_CALL hasMoreElements() throw (::uno::RuntimeException){ return mCurElem < mMaxElems; }
637cdf0e10cSrcweir 
nextElement()638cdf0e10cSrcweir 	virtual uno::Any SAL_CALL nextElement() throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
639cdf0e10cSrcweir 	{
640cdf0e10cSrcweir 		if ( !hasMoreElements() )
641cdf0e10cSrcweir 			throw container::NoSuchElementException();
642cdf0e10cSrcweir 		sal_Int32 vbaIndex = 1 + mCurElem++;
643cdf0e10cSrcweir 		return uno::makeAny( mxRange->Item( uno::makeAny( vbaIndex ), uno::Any() ) );
644cdf0e10cSrcweir 	}
645cdf0e10cSrcweir };
646cdf0e10cSrcweir 
647cdf0e10cSrcweir class CellsEnumeration : public CellsEnumeration_BASE
648cdf0e10cSrcweir {
649cdf0e10cSrcweir     uno::WeakReference< XHelperInterface > mxParent;
650cdf0e10cSrcweir 	uno::Reference< uno::XComponentContext > mxContext;
651cdf0e10cSrcweir 	uno::Reference< XCollection > m_xAreas;
652cdf0e10cSrcweir 	vCellPos m_CellPositions;
653cdf0e10cSrcweir 	vCellPos::const_iterator m_it;
654cdf0e10cSrcweir 
getArea(sal_Int32 nVBAIndex)655cdf0e10cSrcweir 	uno::Reference< table::XCellRange > getArea( sal_Int32 nVBAIndex ) throw ( uno::RuntimeException )
656cdf0e10cSrcweir 	{
657cdf0e10cSrcweir 		if ( nVBAIndex < 1 || nVBAIndex > m_xAreas->getCount() )
658cdf0e10cSrcweir 			throw uno::RuntimeException();
659cdf0e10cSrcweir 		uno::Reference< excel::XRange > xRange( m_xAreas->Item( uno::makeAny(nVBAIndex), uno::Any() ), uno::UNO_QUERY_THROW );
660cdf0e10cSrcweir 		uno::Reference< table::XCellRange > xCellRange( ScVbaRange::getCellRange( xRange ), uno::UNO_QUERY_THROW );
661cdf0e10cSrcweir 		return xCellRange;
662cdf0e10cSrcweir 	}
663cdf0e10cSrcweir 
populateArea(sal_Int32 nVBAIndex)664cdf0e10cSrcweir     void populateArea( sal_Int32 nVBAIndex )
665cdf0e10cSrcweir 	{
666cdf0e10cSrcweir 		uno::Reference< table::XCellRange > xRange = getArea( nVBAIndex );
667cdf0e10cSrcweir 		uno::Reference< table::XColumnRowRange > xColumnRowRange(xRange, uno::UNO_QUERY_THROW );
668cdf0e10cSrcweir 		sal_Int32 nRowCount =  xColumnRowRange->getRows()->getCount();
669cdf0e10cSrcweir 		sal_Int32 nColCount = xColumnRowRange->getColumns()->getCount();
670cdf0e10cSrcweir 		for ( sal_Int32 i=0; i<nRowCount; ++i )
671cdf0e10cSrcweir 		{
672cdf0e10cSrcweir 			for ( sal_Int32 j=0; j<nColCount; ++j )
673cdf0e10cSrcweir 				m_CellPositions.push_back( CellPos( i,j,nVBAIndex ) );
674cdf0e10cSrcweir 		}
675cdf0e10cSrcweir 	}
676cdf0e10cSrcweir public:
CellsEnumeration(const uno::Reference<XHelperInterface> & xParent,const uno::Reference<uno::XComponentContext> & xContext,const uno::Reference<XCollection> & xAreas)677cdf0e10cSrcweir     CellsEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< XCollection >& xAreas ): mxParent( xParent ), mxContext( xContext ), m_xAreas( xAreas )
678cdf0e10cSrcweir 	{
679cdf0e10cSrcweir 		sal_Int32 nItems = m_xAreas->getCount();
680cdf0e10cSrcweir 		for ( sal_Int32 index=1; index <= nItems; ++index )
681cdf0e10cSrcweir 		{
682cdf0e10cSrcweir         		populateArea( index );
683cdf0e10cSrcweir 		}
684cdf0e10cSrcweir 		m_it = m_CellPositions.begin();
685cdf0e10cSrcweir 	}
hasMoreElements()686cdf0e10cSrcweir 	virtual ::sal_Bool SAL_CALL hasMoreElements() throw (::uno::RuntimeException){ return m_it != m_CellPositions.end(); }
687cdf0e10cSrcweir 
nextElement()688cdf0e10cSrcweir 	virtual uno::Any SAL_CALL nextElement() throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
689cdf0e10cSrcweir 	{
690cdf0e10cSrcweir 		if ( !hasMoreElements() )
691cdf0e10cSrcweir 			throw container::NoSuchElementException();
692cdf0e10cSrcweir 		CellPos aPos = *(m_it)++;
693cdf0e10cSrcweir 
694cdf0e10cSrcweir 		uno::Reference< table::XCellRange > xRangeArea = getArea( aPos.m_nArea );
695cdf0e10cSrcweir 		uno::Reference< table::XCellRange > xCellRange( xRangeArea->getCellByPosition(  aPos.m_nCol, aPos.m_nRow ), uno::UNO_QUERY_THROW );
696cdf0e10cSrcweir         return uno::makeAny( uno::Reference< excel::XRange >( new ScVbaRange( mxParent, mxContext, xCellRange ) ) );
697cdf0e10cSrcweir 
698cdf0e10cSrcweir 	}
699cdf0e10cSrcweir };
700cdf0e10cSrcweir 
701cdf0e10cSrcweir 
702cdf0e10cSrcweir const static ::rtl::OUString ISVISIBLE(  RTL_CONSTASCII_USTRINGPARAM( "IsVisible"));
703cdf0e10cSrcweir const static ::rtl::OUString WIDTH(  RTL_CONSTASCII_USTRINGPARAM( "Width"));
704cdf0e10cSrcweir const static ::rtl::OUString HEIGHT(  RTL_CONSTASCII_USTRINGPARAM( "Height"));
705cdf0e10cSrcweir const static ::rtl::OUString POSITION(  RTL_CONSTASCII_USTRINGPARAM( "Position"));
706cdf0e10cSrcweir const static rtl::OUString EQUALS( RTL_CONSTASCII_USTRINGPARAM("=") );
707cdf0e10cSrcweir const static rtl::OUString NOTEQUALS( RTL_CONSTASCII_USTRINGPARAM("<>") );
708cdf0e10cSrcweir const static rtl::OUString GREATERTHAN( RTL_CONSTASCII_USTRINGPARAM(">") );
709cdf0e10cSrcweir const static rtl::OUString GREATERTHANEQUALS( RTL_CONSTASCII_USTRINGPARAM(">=") );
710cdf0e10cSrcweir const static rtl::OUString LESSTHAN( RTL_CONSTASCII_USTRINGPARAM("<") );
711cdf0e10cSrcweir const static rtl::OUString LESSTHANEQUALS( RTL_CONSTASCII_USTRINGPARAM("<=") );
712cdf0e10cSrcweir const static rtl::OUString CONTS_HEADER( RTL_CONSTASCII_USTRINGPARAM("ContainsHeader" ));
713cdf0e10cSrcweir const static rtl::OUString INSERTPAGEBREAKS( RTL_CONSTASCII_USTRINGPARAM("InsertPageBreaks" ));
714cdf0e10cSrcweir const static rtl::OUString STR_ERRORMESSAGE_APPLIESTOSINGLERANGEONLY( RTL_CONSTASCII_USTRINGPARAM("The command you chose cannot be performed with multiple selections.\nSelect a single range and click the command again") );
715cdf0e10cSrcweir const static rtl::OUString STR_ERRORMESSAGE_NOCELLSWEREFOUND( RTL_CONSTASCII_USTRINGPARAM("No cells were found") );
716cdf0e10cSrcweir const static rtl::OUString STR_ERRORMESSAGE_APPLIESTOROWCOLUMNSONLY( RTL_CONSTASCII_USTRINGPARAM("Property only applicable for Columns and Rows") );
717cdf0e10cSrcweir const static rtl::OUString CELLSTYLE( RTL_CONSTASCII_USTRINGPARAM("CellStyle") );
718cdf0e10cSrcweir 
719cdf0e10cSrcweir class CellValueSetter : public ValueSetter
720cdf0e10cSrcweir {
721cdf0e10cSrcweir protected:
722cdf0e10cSrcweir 	uno::Any maValue;
723cdf0e10cSrcweir 	uno::TypeClass mTypeClass;
724cdf0e10cSrcweir public:
725cdf0e10cSrcweir 	CellValueSetter( const uno::Any& aValue );
726cdf0e10cSrcweir 	virtual bool processValue( const uno::Any& aValue,  const uno::Reference< table::XCell >& xCell );
727cdf0e10cSrcweir 	virtual void visitNode( sal_Int32 x, sal_Int32 y, const uno::Reference< table::XCell >& xCell );
728cdf0e10cSrcweir 
729cdf0e10cSrcweir };
730cdf0e10cSrcweir 
CellValueSetter(const uno::Any & aValue)731cdf0e10cSrcweir CellValueSetter::CellValueSetter( const uno::Any& aValue ): maValue( aValue ), mTypeClass( aValue.getValueTypeClass() ) {}
732cdf0e10cSrcweir 
733cdf0e10cSrcweir void
visitNode(sal_Int32,sal_Int32,const uno::Reference<table::XCell> & xCell)734cdf0e10cSrcweir CellValueSetter::visitNode( sal_Int32 /*i*/, sal_Int32 /*j*/, const uno::Reference< table::XCell >& xCell )
735cdf0e10cSrcweir {
736cdf0e10cSrcweir 	processValue( maValue, xCell );
737cdf0e10cSrcweir }
738cdf0e10cSrcweir 
739cdf0e10cSrcweir bool
processValue(const uno::Any & aValue,const uno::Reference<table::XCell> & xCell)740cdf0e10cSrcweir CellValueSetter::processValue( const uno::Any& aValue, const uno::Reference< table::XCell >& xCell )
741cdf0e10cSrcweir {
742cdf0e10cSrcweir 
743cdf0e10cSrcweir 	bool isExtracted = false;
744cdf0e10cSrcweir 	switch ( aValue.getValueTypeClass() )
745cdf0e10cSrcweir 	{
746cdf0e10cSrcweir 		case  uno::TypeClass_BOOLEAN:
747cdf0e10cSrcweir 		{
748cdf0e10cSrcweir 			sal_Bool bState = sal_False;
749cdf0e10cSrcweir 			if ( aValue >>= bState 	 )
750cdf0e10cSrcweir 			{
751cdf0e10cSrcweir 				uno::Reference< table::XCellRange > xRange( xCell, uno::UNO_QUERY_THROW );
752cdf0e10cSrcweir 				if ( bState )
753cdf0e10cSrcweir 					xCell->setValue( (double) 1 );
754cdf0e10cSrcweir 				else
755cdf0e10cSrcweir 					xCell->setValue( (double) 0 );
756cdf0e10cSrcweir 				NumFormatHelper cellNumFormat( xRange );
757cdf0e10cSrcweir 				cellNumFormat.setNumberFormat( util::NumberFormat::LOGICAL );
758cdf0e10cSrcweir 			}
759cdf0e10cSrcweir 			break;
760cdf0e10cSrcweir 		}
761cdf0e10cSrcweir 		case uno::TypeClass_STRING:
762cdf0e10cSrcweir 		{
763cdf0e10cSrcweir 			rtl::OUString aString;
764cdf0e10cSrcweir 			if ( aValue >>= aString )
765cdf0e10cSrcweir 			{
766cdf0e10cSrcweir                 // The required behavior for a string value is:
767cdf0e10cSrcweir                 // 1. If the first character is a single quote, use the rest as a string cell, regardless of the cell's number format.
768cdf0e10cSrcweir                 // 2. Otherwise, if the cell's number format is "text", use the string value as a string cell.
769cdf0e10cSrcweir                 // 3. Otherwise, parse the string value in English locale, and apply a corresponding number format with the cell's locale
770cdf0e10cSrcweir                 //    if the cell's number format was "General".
771cdf0e10cSrcweir                 // Case 1 is handled here, the rest in ScCellObj::InputEnglishString
772cdf0e10cSrcweir 
773cdf0e10cSrcweir                 if ( aString.toChar() == '\'' )     // case 1 - handle with XTextRange
774cdf0e10cSrcweir                 {
775cdf0e10cSrcweir                     rtl::OUString aRemainder( aString.copy(1) );    // strip the quote
776cdf0e10cSrcweir                     uno::Reference< text::XTextRange > xTextRange( xCell, uno::UNO_QUERY_THROW );
777cdf0e10cSrcweir                     xTextRange->setString( aRemainder );
778cdf0e10cSrcweir                 }
779cdf0e10cSrcweir                 else
780cdf0e10cSrcweir                 {
781cdf0e10cSrcweir                     // call implementation method InputEnglishString
782cdf0e10cSrcweir                     ScCellObj* pCellObj = dynamic_cast< ScCellObj* >( xCell.get() );
783cdf0e10cSrcweir                     if ( pCellObj )
784cdf0e10cSrcweir                         pCellObj->InputEnglishString( aString );
785cdf0e10cSrcweir                 }
786cdf0e10cSrcweir 			}
787cdf0e10cSrcweir 			else
788cdf0e10cSrcweir 				isExtracted = false;
789cdf0e10cSrcweir 			break;
790cdf0e10cSrcweir 		}
791cdf0e10cSrcweir 		default:
792cdf0e10cSrcweir 		{
793cdf0e10cSrcweir 			double nDouble = 0.0;
794cdf0e10cSrcweir 			if ( aValue >>= nDouble )
795cdf0e10cSrcweir 				xCell->setValue( nDouble );
796cdf0e10cSrcweir 			else
797cdf0e10cSrcweir 				isExtracted = false;
798cdf0e10cSrcweir 			break;
799cdf0e10cSrcweir 		}
800cdf0e10cSrcweir 	}
801cdf0e10cSrcweir 	return isExtracted;
802cdf0e10cSrcweir 
803cdf0e10cSrcweir }
804cdf0e10cSrcweir 
805cdf0e10cSrcweir 
806cdf0e10cSrcweir class CellValueGetter : public ValueGetter
807cdf0e10cSrcweir {
808cdf0e10cSrcweir protected:
809cdf0e10cSrcweir 	uno::Any maValue;
810cdf0e10cSrcweir 	uno::TypeClass mTypeClass;
811cdf0e10cSrcweir public:
CellValueGetter()812cdf0e10cSrcweir 	CellValueGetter() {}
813cdf0e10cSrcweir 	virtual void visitNode( sal_Int32 x, sal_Int32 y, const uno::Reference< table::XCell >& xCell );
814cdf0e10cSrcweir 	virtual void processValue( sal_Int32 x, sal_Int32 y, const uno::Any& aValue );
getValue() const815cdf0e10cSrcweir 	const uno::Any& getValue() const { return maValue; }
816cdf0e10cSrcweir 
817cdf0e10cSrcweir };
818cdf0e10cSrcweir 
819cdf0e10cSrcweir void
processValue(sal_Int32,sal_Int32,const uno::Any & aValue)820cdf0e10cSrcweir CellValueGetter::processValue(  sal_Int32 /*x*/, sal_Int32 /*y*/, const uno::Any& aValue )
821cdf0e10cSrcweir {
822cdf0e10cSrcweir 	maValue = aValue;
823cdf0e10cSrcweir }
visitNode(sal_Int32 x,sal_Int32 y,const uno::Reference<table::XCell> & xCell)824cdf0e10cSrcweir void CellValueGetter::visitNode( sal_Int32 x, sal_Int32 y, const uno::Reference< table::XCell >& xCell )
825cdf0e10cSrcweir {
826cdf0e10cSrcweir 	uno::Any aValue;
827cdf0e10cSrcweir 	table::CellContentType eType = xCell->getType();
828cdf0e10cSrcweir 	if( eType == table::CellContentType_VALUE || eType == table::CellContentType_FORMULA )
829cdf0e10cSrcweir 	{
830cdf0e10cSrcweir 		if ( eType == table::CellContentType_FORMULA )
831cdf0e10cSrcweir 		{
832cdf0e10cSrcweir 
833cdf0e10cSrcweir 			rtl::OUString sFormula = xCell->getFormula();
834cdf0e10cSrcweir 			if ( sFormula.equals( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("=TRUE()") ) ) )
835cdf0e10cSrcweir 				aValue <<= sal_True;
836cdf0e10cSrcweir 			else if ( sFormula.equals( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("=FALSE()") ) ) )
837cdf0e10cSrcweir 				aValue <<= sal_False;
838cdf0e10cSrcweir 			else
839cdf0e10cSrcweir 			{
840cdf0e10cSrcweir 				uno::Reference< beans::XPropertySet > xProp( xCell, uno::UNO_QUERY_THROW );
841cdf0e10cSrcweir 
842cdf0e10cSrcweir 				table::CellContentType eFormulaType = table::CellContentType_VALUE;
843cdf0e10cSrcweir 				// some formulas give textual results
844cdf0e10cSrcweir 				xProp->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("FormulaResultType" ) ) ) >>= eFormulaType;
845cdf0e10cSrcweir 
846cdf0e10cSrcweir 				if ( eFormulaType == table::CellContentType_TEXT )
847cdf0e10cSrcweir 				{
848cdf0e10cSrcweir 					uno::Reference< text::XTextRange > xTextRange(xCell, ::uno::UNO_QUERY_THROW);
849cdf0e10cSrcweir 					aValue <<= xTextRange->getString();
850cdf0e10cSrcweir 				}
851cdf0e10cSrcweir 				else
852cdf0e10cSrcweir 					aValue <<= xCell->getValue();
853cdf0e10cSrcweir 			}
854cdf0e10cSrcweir 		}
855cdf0e10cSrcweir 		else
856cdf0e10cSrcweir 		{
857cdf0e10cSrcweir 			uno::Reference< table::XCellRange > xRange( xCell, uno::UNO_QUERY_THROW );
858cdf0e10cSrcweir 			NumFormatHelper cellFormat( xRange );
859cdf0e10cSrcweir 			if ( cellFormat.isBooleanType() )
860cdf0e10cSrcweir 				aValue = uno::makeAny( ( xCell->getValue() != 0.0 ) );
861cdf0e10cSrcweir 			else if ( cellFormat.isDateType() )
862cdf0e10cSrcweir 				aValue = uno::makeAny( bridge::oleautomation::Date( xCell->getValue() ) );
863cdf0e10cSrcweir 			else
864cdf0e10cSrcweir 				aValue <<= xCell->getValue();
865cdf0e10cSrcweir 		}
866cdf0e10cSrcweir 	}
867cdf0e10cSrcweir 	if( eType == table::CellContentType_TEXT )
868cdf0e10cSrcweir 	{
869cdf0e10cSrcweir 		uno::Reference< text::XTextRange > xTextRange(xCell, ::uno::UNO_QUERY_THROW);
870cdf0e10cSrcweir 		aValue <<= xTextRange->getString();
871cdf0e10cSrcweir 	}
872cdf0e10cSrcweir 	processValue( x,y,aValue );
873cdf0e10cSrcweir }
874cdf0e10cSrcweir 
875cdf0e10cSrcweir class CellFormulaValueSetter : public CellValueSetter
876cdf0e10cSrcweir {
877cdf0e10cSrcweir private:
878cdf0e10cSrcweir 	ScDocument*  m_pDoc;
879cdf0e10cSrcweir     formula::FormulaGrammar::Grammar m_eGrammar;
880cdf0e10cSrcweir public:
CellFormulaValueSetter(const uno::Any & aValue,ScDocument * pDoc,formula::FormulaGrammar::Grammar eGram)881cdf0e10cSrcweir 	CellFormulaValueSetter( const uno::Any& aValue, ScDocument* pDoc, formula::FormulaGrammar::Grammar eGram ):CellValueSetter( aValue ),  m_pDoc( pDoc ), m_eGrammar( eGram ){}
882cdf0e10cSrcweir protected:
processValue(const uno::Any & aValue,const uno::Reference<table::XCell> & xCell)883cdf0e10cSrcweir 	bool processValue( const uno::Any& aValue, const uno::Reference< table::XCell >& xCell )
884cdf0e10cSrcweir 	{
885cdf0e10cSrcweir 		rtl::OUString sFormula;
886cdf0e10cSrcweir 		double aDblValue = 0.0;
887cdf0e10cSrcweir 		if ( aValue >>= sFormula )
888cdf0e10cSrcweir 		{
889cdf0e10cSrcweir             // convert to CONV_OOO style formula string because XCell::setFormula
890cdf0e10cSrcweir             // always compile it in CONV_OOO style.  Perhaps css.sheet.FormulaParser
891cdf0e10cSrcweir             // should be used in future to directly pass formula tokens.
892cdf0e10cSrcweir             if ( m_eGrammar != formula::FormulaGrammar::GRAM_PODF_A1 && ( sFormula.trim().indexOf('=') == 0 ) )
893cdf0e10cSrcweir 			{
894cdf0e10cSrcweir 				uno::Reference< uno::XInterface > xIf( xCell, uno::UNO_QUERY_THROW );
895cdf0e10cSrcweir 				ScCellRangesBase* pUnoRangesBase = dynamic_cast< ScCellRangesBase* >( xIf.get() );
896cdf0e10cSrcweir 				if ( pUnoRangesBase )
897cdf0e10cSrcweir 				{
898cdf0e10cSrcweir 					ScRangeList aCellRanges = pUnoRangesBase->GetRangeList();
899cdf0e10cSrcweir 					ScCompiler aCompiler( m_pDoc, aCellRanges.First()->aStart );
900cdf0e10cSrcweir                     aCompiler.SetGrammar(m_eGrammar);
901cdf0e10cSrcweir 					// compile the string in the format passed in
902cdf0e10cSrcweir 					aCompiler.CompileString( sFormula );
903cdf0e10cSrcweir 					// set desired convention to that of the document
904cdf0e10cSrcweir                     aCompiler.SetGrammar( formula::FormulaGrammar::GRAM_PODF_A1 );
905cdf0e10cSrcweir 					String sConverted;
906cdf0e10cSrcweir 					aCompiler.CreateStringFromTokenArray(sConverted);
907cdf0e10cSrcweir 					sFormula = EQUALS + sConverted;
908cdf0e10cSrcweir 				}
909cdf0e10cSrcweir 			}
910cdf0e10cSrcweir 
911cdf0e10cSrcweir 			xCell->setFormula( sFormula );
912cdf0e10cSrcweir 			return true;
913cdf0e10cSrcweir 		}
914cdf0e10cSrcweir 		else if ( aValue >>= aDblValue )
915cdf0e10cSrcweir 		{
916cdf0e10cSrcweir 			xCell->setValue( aDblValue );
917cdf0e10cSrcweir 			return true;
918cdf0e10cSrcweir 		}
919cdf0e10cSrcweir 		return false;
920cdf0e10cSrcweir 	}
921cdf0e10cSrcweir 
922cdf0e10cSrcweir };
923cdf0e10cSrcweir 
924cdf0e10cSrcweir class CellFormulaValueGetter : public CellValueGetter
925cdf0e10cSrcweir {
926cdf0e10cSrcweir private:
927cdf0e10cSrcweir 	ScDocument*  m_pDoc;
928cdf0e10cSrcweir     formula::FormulaGrammar::Grammar m_eGrammar;
929cdf0e10cSrcweir public:
CellFormulaValueGetter(ScDocument * pDoc,formula::FormulaGrammar::Grammar eGram)930cdf0e10cSrcweir 	CellFormulaValueGetter(ScDocument* pDoc, formula::FormulaGrammar::Grammar eGram ) : CellValueGetter( ), m_pDoc( pDoc ), m_eGrammar( eGram ) {}
visitNode(sal_Int32 x,sal_Int32 y,const uno::Reference<table::XCell> & xCell)931cdf0e10cSrcweir 	virtual void visitNode( sal_Int32 x, sal_Int32 y, const uno::Reference< table::XCell >& xCell )
932cdf0e10cSrcweir 	{
933cdf0e10cSrcweir 		uno::Any aValue;
934cdf0e10cSrcweir 		aValue <<= xCell->getFormula();
935cdf0e10cSrcweir 		rtl::OUString sVal;
936cdf0e10cSrcweir 		aValue >>= sVal;
937cdf0e10cSrcweir 		uno::Reference< uno::XInterface > xIf( xCell, uno::UNO_QUERY_THROW );
938cdf0e10cSrcweir 		ScCellRangesBase* pUnoRangesBase = dynamic_cast< ScCellRangesBase* >( xIf.get() );
939cdf0e10cSrcweir 		if ( ( xCell->getType() == table::CellContentType_FORMULA ) &&
940cdf0e10cSrcweir 			pUnoRangesBase )
941cdf0e10cSrcweir 		{
942cdf0e10cSrcweir 			ScRangeList aCellRanges = pUnoRangesBase->GetRangeList();
943cdf0e10cSrcweir 			ScCompiler aCompiler( m_pDoc, aCellRanges.First()->aStart );
944cdf0e10cSrcweir             aCompiler.SetGrammar(formula::FormulaGrammar::GRAM_DEFAULT);
945cdf0e10cSrcweir 			aCompiler.CompileString( sVal );
946cdf0e10cSrcweir 			// set desired convention
947cdf0e10cSrcweir             aCompiler.SetGrammar( m_eGrammar );
948cdf0e10cSrcweir 			String sConverted;
949cdf0e10cSrcweir 			aCompiler.CreateStringFromTokenArray(sConverted);
950cdf0e10cSrcweir 			sVal = EQUALS + sConverted;
951cdf0e10cSrcweir 			aValue <<= sVal;
952cdf0e10cSrcweir 		}
953cdf0e10cSrcweir 
954cdf0e10cSrcweir 		processValue( x,y,aValue );
955cdf0e10cSrcweir 	}
956cdf0e10cSrcweir 
957cdf0e10cSrcweir };
958cdf0e10cSrcweir 
959cdf0e10cSrcweir 
960cdf0e10cSrcweir class Dim2ArrayValueGetter : public ArrayVisitor
961cdf0e10cSrcweir {
962cdf0e10cSrcweir protected:
963cdf0e10cSrcweir 	uno::Any maValue;
964cdf0e10cSrcweir 	ValueGetter& mValueGetter;
processValue(sal_Int32 x,sal_Int32 y,const uno::Any & aValue)965cdf0e10cSrcweir 	virtual void processValue( sal_Int32 x, sal_Int32 y, const uno::Any& aValue )
966cdf0e10cSrcweir 	{
967cdf0e10cSrcweir 		uno::Sequence< uno::Sequence< uno::Any > >& aMatrix = *( uno::Sequence< uno::Sequence< uno::Any > >* )( maValue.getValue() );
968cdf0e10cSrcweir 		aMatrix[x][y] = aValue;
969cdf0e10cSrcweir 	}
970cdf0e10cSrcweir 
971cdf0e10cSrcweir public:
Dim2ArrayValueGetter(sal_Int32 nRowCount,sal_Int32 nColCount,ValueGetter & rValueGetter)972cdf0e10cSrcweir 	Dim2ArrayValueGetter(sal_Int32 nRowCount, sal_Int32 nColCount, ValueGetter& rValueGetter ): mValueGetter(rValueGetter)
973cdf0e10cSrcweir 	{
974cdf0e10cSrcweir 		uno::Sequence< uno::Sequence< uno::Any > > aMatrix;
975cdf0e10cSrcweir 		aMatrix.realloc( nRowCount );
976cdf0e10cSrcweir 		for ( sal_Int32 index = 0; index < nRowCount; ++index )
977cdf0e10cSrcweir 			aMatrix[index].realloc( nColCount );
978cdf0e10cSrcweir 		maValue <<= aMatrix;
979cdf0e10cSrcweir 	}
visitNode(sal_Int32 x,sal_Int32 y,const uno::Reference<table::XCell> & xCell)980cdf0e10cSrcweir 	void visitNode( sal_Int32 x, sal_Int32 y, const uno::Reference< table::XCell >& xCell )
981cdf0e10cSrcweir 
982cdf0e10cSrcweir 	{
983cdf0e10cSrcweir 		mValueGetter.visitNode( x, y, xCell );
984cdf0e10cSrcweir 		processValue( x, y, mValueGetter.getValue() );
985cdf0e10cSrcweir 	}
getValue() const986cdf0e10cSrcweir 	const uno::Any& getValue() const { return maValue; }
987cdf0e10cSrcweir 
988cdf0e10cSrcweir };
989cdf0e10cSrcweir 
990cdf0e10cSrcweir const static rtl::OUString sNA = rtl::OUString::createFromAscii("#N/A");
991cdf0e10cSrcweir 
992cdf0e10cSrcweir class Dim1ArrayValueSetter : public ArrayVisitor
993cdf0e10cSrcweir {
994cdf0e10cSrcweir 	uno::Sequence< uno::Any > aMatrix;
995cdf0e10cSrcweir 	sal_Int32 nColCount;
996cdf0e10cSrcweir 	ValueSetter& mCellValueSetter;
997cdf0e10cSrcweir public:
Dim1ArrayValueSetter(const uno::Any & aValue,ValueSetter & rCellValueSetter)998cdf0e10cSrcweir 	Dim1ArrayValueSetter( const uno::Any& aValue, ValueSetter& rCellValueSetter ):mCellValueSetter( rCellValueSetter )
999cdf0e10cSrcweir 	{
1000cdf0e10cSrcweir 		aValue >>= aMatrix;
1001cdf0e10cSrcweir 		nColCount = aMatrix.getLength();
1002cdf0e10cSrcweir 	}
visitNode(sal_Int32,sal_Int32 y,const uno::Reference<table::XCell> & xCell)1003cdf0e10cSrcweir 	virtual void visitNode( sal_Int32 /*x*/, sal_Int32 y, const uno::Reference< table::XCell >& xCell )
1004cdf0e10cSrcweir 	{
1005cdf0e10cSrcweir 		if ( y < nColCount )
1006cdf0e10cSrcweir 			mCellValueSetter.processValue( aMatrix[ y ], xCell );
1007cdf0e10cSrcweir 		else
1008cdf0e10cSrcweir 			mCellValueSetter.processValue( uno::makeAny( sNA ), xCell );
1009cdf0e10cSrcweir 	}
1010cdf0e10cSrcweir };
1011cdf0e10cSrcweir 
1012cdf0e10cSrcweir 
1013cdf0e10cSrcweir 
1014cdf0e10cSrcweir class Dim2ArrayValueSetter : public ArrayVisitor
1015cdf0e10cSrcweir {
1016cdf0e10cSrcweir 	uno::Sequence< uno::Sequence< uno::Any > > aMatrix;
1017cdf0e10cSrcweir 	ValueSetter& mCellValueSetter;
1018cdf0e10cSrcweir 	sal_Int32 nRowCount;
1019cdf0e10cSrcweir 	sal_Int32 nColCount;
1020cdf0e10cSrcweir public:
Dim2ArrayValueSetter(const uno::Any & aValue,ValueSetter & rCellValueSetter)1021cdf0e10cSrcweir 	Dim2ArrayValueSetter( const uno::Any& aValue, ValueSetter& rCellValueSetter ) : mCellValueSetter( rCellValueSetter )
1022cdf0e10cSrcweir 	{
1023cdf0e10cSrcweir 		aValue >>= aMatrix;
1024cdf0e10cSrcweir 		nRowCount = aMatrix.getLength();
1025cdf0e10cSrcweir 		nColCount = aMatrix[0].getLength();
1026cdf0e10cSrcweir 	}
1027cdf0e10cSrcweir 
visitNode(sal_Int32 x,sal_Int32 y,const uno::Reference<table::XCell> & xCell)1028cdf0e10cSrcweir 	virtual void visitNode( sal_Int32 x, sal_Int32 y, const uno::Reference< table::XCell >& xCell )
1029cdf0e10cSrcweir 	{
1030cdf0e10cSrcweir 		if ( x < nRowCount && y < nColCount )
1031cdf0e10cSrcweir 			mCellValueSetter.processValue( aMatrix[ x ][ y ], xCell );
1032cdf0e10cSrcweir 		else
1033cdf0e10cSrcweir 			mCellValueSetter.processValue( uno::makeAny( sNA ), xCell );
1034cdf0e10cSrcweir 
1035cdf0e10cSrcweir 	}
1036cdf0e10cSrcweir };
1037cdf0e10cSrcweir 
1038cdf0e10cSrcweir class RangeProcessor
1039cdf0e10cSrcweir {
1040cdf0e10cSrcweir public:
1041cdf0e10cSrcweir 	virtual void process( const uno::Reference< excel::XRange >& xRange ) = 0;
1042cdf0e10cSrcweir };
1043cdf0e10cSrcweir 
1044cdf0e10cSrcweir class RangeValueProcessor : public RangeProcessor
1045cdf0e10cSrcweir {
1046cdf0e10cSrcweir 	const uno::Any& m_aVal;
1047cdf0e10cSrcweir public:
RangeValueProcessor(const uno::Any & rVal)1048cdf0e10cSrcweir 	RangeValueProcessor( const uno::Any& rVal ):m_aVal( rVal ) {}
process(const uno::Reference<excel::XRange> & xRange)1049cdf0e10cSrcweir 	virtual void process( const uno::Reference< excel::XRange >& xRange )
1050cdf0e10cSrcweir 	{
1051cdf0e10cSrcweir 		xRange->setValue( m_aVal );
1052cdf0e10cSrcweir 	}
1053cdf0e10cSrcweir };
1054cdf0e10cSrcweir 
1055cdf0e10cSrcweir class RangeFormulaProcessor : public RangeProcessor
1056cdf0e10cSrcweir {
1057cdf0e10cSrcweir 	const uno::Any& m_aVal;
1058cdf0e10cSrcweir public:
RangeFormulaProcessor(const uno::Any & rVal)1059cdf0e10cSrcweir 	RangeFormulaProcessor( const uno::Any& rVal ):m_aVal( rVal ) {}
process(const uno::Reference<excel::XRange> & xRange)1060cdf0e10cSrcweir 	virtual void process( const uno::Reference< excel::XRange >& xRange )
1061cdf0e10cSrcweir 	{
1062cdf0e10cSrcweir 		xRange->setFormula( m_aVal );
1063cdf0e10cSrcweir 	}
1064cdf0e10cSrcweir };
1065cdf0e10cSrcweir 
1066cdf0e10cSrcweir class RangeCountProcessor : public RangeProcessor
1067cdf0e10cSrcweir {
1068cdf0e10cSrcweir 	sal_Int32 nCount;
1069cdf0e10cSrcweir public:
RangeCountProcessor()1070cdf0e10cSrcweir 	RangeCountProcessor():nCount(0){}
process(const uno::Reference<excel::XRange> & xRange)1071cdf0e10cSrcweir 	virtual void process( const uno::Reference< excel::XRange >& xRange )
1072cdf0e10cSrcweir 	{
1073cdf0e10cSrcweir 		nCount = nCount + xRange->getCount();
1074cdf0e10cSrcweir 	}
value()1075cdf0e10cSrcweir 	sal_Int32 value() { return nCount; }
1076cdf0e10cSrcweir };
1077cdf0e10cSrcweir class AreasVisitor
1078cdf0e10cSrcweir {
1079cdf0e10cSrcweir private:
1080cdf0e10cSrcweir 	uno::Reference< XCollection > m_Areas;
1081cdf0e10cSrcweir public:
AreasVisitor(const uno::Reference<XCollection> & rAreas)1082cdf0e10cSrcweir 	AreasVisitor( const uno::Reference< XCollection >& rAreas ):m_Areas( rAreas ){}
1083cdf0e10cSrcweir 
visit(RangeProcessor & processor)1084cdf0e10cSrcweir 	void visit( RangeProcessor& processor )
1085cdf0e10cSrcweir 	{
1086cdf0e10cSrcweir 		if ( m_Areas.is() )
1087cdf0e10cSrcweir 		{
1088cdf0e10cSrcweir 			sal_Int32 nItems = m_Areas->getCount();
1089cdf0e10cSrcweir 			for ( sal_Int32 index=1; index <= nItems; ++index )
1090cdf0e10cSrcweir 			{
1091cdf0e10cSrcweir 				uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW );
1092cdf0e10cSrcweir 				processor.process( xRange );
1093cdf0e10cSrcweir 			}
1094cdf0e10cSrcweir 		}
1095cdf0e10cSrcweir 	}
1096cdf0e10cSrcweir };
1097cdf0e10cSrcweir 
1098cdf0e10cSrcweir class RangeHelper
1099cdf0e10cSrcweir {
1100cdf0e10cSrcweir 	uno::Reference< table::XCellRange > m_xCellRange;
1101cdf0e10cSrcweir 
1102cdf0e10cSrcweir public:
RangeHelper(const uno::Reference<table::XCellRange> & xCellRange)1103cdf0e10cSrcweir 	RangeHelper( const uno::Reference< table::XCellRange >& xCellRange ) throw (uno::RuntimeException) : m_xCellRange( xCellRange )
1104cdf0e10cSrcweir 	{
1105cdf0e10cSrcweir 		if ( !m_xCellRange.is() )
1106cdf0e10cSrcweir 			throw uno::RuntimeException();
1107cdf0e10cSrcweir 	}
RangeHelper(const uno::Any aCellRange)1108cdf0e10cSrcweir 	RangeHelper( const uno::Any aCellRange ) throw (uno::RuntimeException)
1109cdf0e10cSrcweir 	{
1110cdf0e10cSrcweir 		m_xCellRange.set( aCellRange, uno::UNO_QUERY_THROW );
1111cdf0e10cSrcweir 	}
getSheetCellRange()1112cdf0e10cSrcweir 	uno::Reference< sheet::XSheetCellRange > getSheetCellRange() throw (uno::RuntimeException)
1113cdf0e10cSrcweir 	{
1114cdf0e10cSrcweir 		return uno::Reference< sheet::XSheetCellRange >(m_xCellRange, uno::UNO_QUERY_THROW);
1115cdf0e10cSrcweir 	}
getSpreadSheet()1116cdf0e10cSrcweir 	uno::Reference< sheet::XSpreadsheet >  getSpreadSheet() throw (uno::RuntimeException)
1117cdf0e10cSrcweir 	{
1118cdf0e10cSrcweir 		return getSheetCellRange()->getSpreadsheet();
1119cdf0e10cSrcweir 	}
1120cdf0e10cSrcweir 
getCellRangeFromSheet()1121cdf0e10cSrcweir 	uno::Reference< table::XCellRange > getCellRangeFromSheet() throw (uno::RuntimeException)
1122cdf0e10cSrcweir 	{
1123cdf0e10cSrcweir 		return uno::Reference< table::XCellRange >(getSpreadSheet(), uno::UNO_QUERY_THROW );
1124cdf0e10cSrcweir 	}
1125cdf0e10cSrcweir 
getCellRangeAddressable()1126cdf0e10cSrcweir 	uno::Reference< sheet::XCellRangeAddressable >  getCellRangeAddressable() throw (uno::RuntimeException)
1127cdf0e10cSrcweir 	{
1128cdf0e10cSrcweir 		return uno::Reference< sheet::XCellRangeAddressable >(m_xCellRange, ::uno::UNO_QUERY_THROW);
1129cdf0e10cSrcweir 
1130cdf0e10cSrcweir 	}
1131cdf0e10cSrcweir 
getSheetCellCursor()1132cdf0e10cSrcweir 	uno::Reference< sheet::XSheetCellCursor > getSheetCellCursor() throw ( uno::RuntimeException )
1133cdf0e10cSrcweir 	{
1134cdf0e10cSrcweir 		return 	uno::Reference< sheet::XSheetCellCursor >( getSpreadSheet()->createCursorByRange( getSheetCellRange() ), uno::UNO_QUERY_THROW );
1135cdf0e10cSrcweir 	}
1136cdf0e10cSrcweir 
createRangeFromRange(const uno::Reference<XHelperInterface> & xParent,const uno::Reference<uno::XComponentContext> & xContext,const uno::Reference<table::XCellRange> & xRange,const uno::Reference<sheet::XCellRangeAddressable> & xCellRangeAddressable,sal_Int32 nStartColOffset=0,sal_Int32 nStartRowOffset=0,sal_Int32 nEndColOffset=0,sal_Int32 nEndRowOffset=0)1137cdf0e10cSrcweir 	static uno::Reference< excel::XRange > createRangeFromRange( const uno::Reference< XHelperInterface >& xParent, const uno::Reference<uno::XComponentContext >& xContext,
1138cdf0e10cSrcweir 		const uno::Reference< table::XCellRange >& xRange, const uno::Reference< sheet::XCellRangeAddressable >& xCellRangeAddressable,
1139cdf0e10cSrcweir 		sal_Int32 nStartColOffset = 0, sal_Int32 nStartRowOffset = 0, sal_Int32 nEndColOffset = 0, sal_Int32 nEndRowOffset = 0 )
1140cdf0e10cSrcweir 	{
1141cdf0e10cSrcweir 		return uno::Reference< excel::XRange >( new ScVbaRange( xParent, xContext,
1142cdf0e10cSrcweir 			xRange->getCellRangeByPosition(
1143cdf0e10cSrcweir 				xCellRangeAddressable->getRangeAddress().StartColumn + nStartColOffset,
1144cdf0e10cSrcweir 				xCellRangeAddressable->getRangeAddress().StartRow + nStartRowOffset,
1145cdf0e10cSrcweir 				xCellRangeAddressable->getRangeAddress().EndColumn + nEndColOffset,
1146cdf0e10cSrcweir 				xCellRangeAddressable->getRangeAddress().EndRow + nEndRowOffset ) ) );
1147cdf0e10cSrcweir 	}
1148cdf0e10cSrcweir 
1149cdf0e10cSrcweir };
1150cdf0e10cSrcweir 
1151cdf0e10cSrcweir bool
getCellRangesForAddress(sal_uInt16 & rResFlags,const rtl::OUString & sAddress,ScDocShell * pDocSh,ScRangeList & rCellRanges,formula::FormulaGrammar::AddressConvention & eConv)1152cdf0e10cSrcweir getCellRangesForAddress( sal_uInt16& rResFlags, const rtl::OUString& sAddress, ScDocShell* pDocSh, ScRangeList& rCellRanges, formula::FormulaGrammar::AddressConvention& eConv )
1153cdf0e10cSrcweir {
1154cdf0e10cSrcweir 
1155cdf0e10cSrcweir 	ScDocument* pDoc = NULL;
1156cdf0e10cSrcweir 	if ( pDocSh )
1157cdf0e10cSrcweir 	{
1158cdf0e10cSrcweir 		pDoc = pDocSh->GetDocument();
1159cdf0e10cSrcweir 		String aString(sAddress);
1160cdf0e10cSrcweir 		sal_uInt16 nMask = SCA_VALID;
1161cdf0e10cSrcweir 		//sal_uInt16 nParse = rCellRanges.Parse( sAddress, pDoc, nMask, formula::FormulaGrammar::CONV_XL_A1 );
1162cdf0e10cSrcweir 		rResFlags = rCellRanges.Parse( sAddress, pDoc, nMask, eConv, 0 );
1163cdf0e10cSrcweir 		if ( rResFlags & SCA_VALID )
1164cdf0e10cSrcweir 		{
1165cdf0e10cSrcweir 			return true;
1166cdf0e10cSrcweir 		}
1167cdf0e10cSrcweir 	}
1168cdf0e10cSrcweir 	return false;
1169cdf0e10cSrcweir }
1170cdf0e10cSrcweir 
getScRangeListForAddress(const rtl::OUString & sName,ScDocShell * pDocSh,ScRange & refRange,ScRangeList & aCellRanges,formula::FormulaGrammar::AddressConvention aConv=formula::FormulaGrammar::CONV_XL_A1)1171cdf0e10cSrcweir bool getScRangeListForAddress( const rtl::OUString& sName, ScDocShell* pDocSh, ScRange& refRange, ScRangeList& aCellRanges, formula::FormulaGrammar::AddressConvention aConv = formula::FormulaGrammar::CONV_XL_A1 ) throw ( uno::RuntimeException )
1172cdf0e10cSrcweir {
1173cdf0e10cSrcweir 	// see if there is a match with a named range
1174cdf0e10cSrcweir 	uno::Reference< beans::XPropertySet > xProps( pDocSh->GetModel(), uno::UNO_QUERY_THROW );
1175cdf0e10cSrcweir 	uno::Reference< container::XNameAccess > xNameAccess( xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("NamedRanges") ) ), uno::UNO_QUERY_THROW );
1176cdf0e10cSrcweir 	// Strangly enough you can have Range( "namedRange1, namedRange2, etc," )
1177cdf0e10cSrcweir 	// loop around each ',' seperated name
1178cdf0e10cSrcweir 	std::vector< rtl::OUString > vNames;
1179cdf0e10cSrcweir 	sal_Int32 nIndex = 0;
1180cdf0e10cSrcweir 	do
1181cdf0e10cSrcweir 	{
1182cdf0e10cSrcweir 		rtl::OUString aToken = sName.getToken( 0, ',', nIndex );
1183cdf0e10cSrcweir 		vNames.push_back( aToken );
1184cdf0e10cSrcweir 	} while ( nIndex >= 0 );
1185cdf0e10cSrcweir 
1186cdf0e10cSrcweir 	if ( !vNames.size() )
1187cdf0e10cSrcweir 		vNames.push_back( sName );
1188cdf0e10cSrcweir 
1189cdf0e10cSrcweir 	std::vector< rtl::OUString >::iterator it = vNames.begin();
1190cdf0e10cSrcweir 	std::vector< rtl::OUString >::iterator it_end = vNames.end();
1191cdf0e10cSrcweir 	for ( ; it != it_end; ++it )
1192cdf0e10cSrcweir 	{
1193cdf0e10cSrcweir 
1194cdf0e10cSrcweir 		formula::FormulaGrammar::AddressConvention eConv = aConv;
1195cdf0e10cSrcweir 		// spaces are illegal ( but the user of course can enter them )
1196cdf0e10cSrcweir 		rtl::OUString sAddress = (*it).trim();
1197cdf0e10cSrcweir 		if ( xNameAccess->hasByName( sAddress ) )
1198cdf0e10cSrcweir 		{
1199cdf0e10cSrcweir 			uno::Reference< sheet::XNamedRange > xNamed( xNameAccess->getByName( sAddress ), uno::UNO_QUERY_THROW );
1200cdf0e10cSrcweir 			sAddress = xNamed->getContent();
1201cdf0e10cSrcweir 			// As the address comes from OOO, the addressing
1202cdf0e10cSrcweir 			// style is may not be XL_A1
1203cdf0e10cSrcweir 			eConv = pDocSh->GetDocument()->GetAddressConvention();
1204cdf0e10cSrcweir 		}
1205cdf0e10cSrcweir 
1206cdf0e10cSrcweir 		sal_uInt16 nFlags = 0;
1207cdf0e10cSrcweir 		if ( !getCellRangesForAddress( nFlags, sAddress, pDocSh, aCellRanges, eConv ) )
1208cdf0e10cSrcweir 			return false;
1209cdf0e10cSrcweir 
1210cdf0e10cSrcweir 		bool bTabFromReferrer = !( nFlags & SCA_TAB_3D );
1211cdf0e10cSrcweir 
1212cdf0e10cSrcweir 		for ( ScRange* pRange = aCellRanges.First() ; pRange; pRange = aCellRanges.Next() )
1213cdf0e10cSrcweir 		{
1214cdf0e10cSrcweir 			pRange->aStart.SetCol( refRange.aStart.Col() + pRange->aStart.Col() );
1215cdf0e10cSrcweir 			pRange->aStart.SetRow( refRange.aStart.Row() + pRange->aStart.Row() );
1216cdf0e10cSrcweir 			pRange->aStart.SetTab( bTabFromReferrer ? refRange.aStart.Tab()  : pRange->aStart.Tab() );
1217cdf0e10cSrcweir 			pRange->aEnd.SetCol( refRange.aStart.Col() + pRange->aEnd.Col() );
1218cdf0e10cSrcweir 			pRange->aEnd.SetRow( refRange.aStart.Row() + pRange->aEnd.Row() );
1219cdf0e10cSrcweir 			pRange->aEnd.SetTab( bTabFromReferrer ? refRange.aEnd.Tab()  : pRange->aEnd.Tab() );
1220cdf0e10cSrcweir 		}
1221cdf0e10cSrcweir 	}
1222cdf0e10cSrcweir 	return true;
1223cdf0e10cSrcweir }
1224cdf0e10cSrcweir 
1225cdf0e10cSrcweir 
1226cdf0e10cSrcweir ScVbaRange*
getRangeForName(const uno::Reference<uno::XComponentContext> & xContext,const rtl::OUString & sName,ScDocShell * pDocSh,table::CellRangeAddress & pAddr,formula::FormulaGrammar::AddressConvention eConv=formula::FormulaGrammar::CONV_XL_A1)1227cdf0e10cSrcweir getRangeForName( const uno::Reference< uno::XComponentContext >& xContext, const rtl::OUString& sName, ScDocShell* pDocSh, table::CellRangeAddress& pAddr, formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_XL_A1 ) throw ( uno::RuntimeException )
1228cdf0e10cSrcweir {
1229cdf0e10cSrcweir 	ScRangeList aCellRanges;
1230cdf0e10cSrcweir 	ScRange refRange;
1231cdf0e10cSrcweir 	ScUnoConversion::FillScRange( refRange, pAddr );
1232cdf0e10cSrcweir 	if ( !getScRangeListForAddress ( sName, pDocSh, refRange, aCellRanges, eConv ) )
1233cdf0e10cSrcweir 		throw uno::RuntimeException();
1234cdf0e10cSrcweir 	// Single range
1235cdf0e10cSrcweir 	if ( aCellRanges.First() == aCellRanges.Last() )
1236cdf0e10cSrcweir 	{
1237cdf0e10cSrcweir 		uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pDocSh, *aCellRanges.First() ) );
1238cdf0e10cSrcweir 		uno::Reference< XHelperInterface > xFixThisParent = excel::getUnoSheetModuleObj( xRange );
1239cdf0e10cSrcweir 		return new ScVbaRange( xFixThisParent, xContext, xRange );
1240cdf0e10cSrcweir 	}
1241cdf0e10cSrcweir 	uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDocSh, aCellRanges ) );
1242cdf0e10cSrcweir 
1243cdf0e10cSrcweir 	uno::Reference< XHelperInterface > xFixThisParent = excel::getUnoSheetModuleObj( xRanges );
1244cdf0e10cSrcweir 	return new ScVbaRange( xFixThisParent, xContext, xRanges );
1245cdf0e10cSrcweir }
1246cdf0e10cSrcweir 
1247cdf0e10cSrcweir // ----------------------------------------------------------------------------
1248cdf0e10cSrcweir 
1249cdf0e10cSrcweir namespace {
1250cdf0e10cSrcweir 
1251cdf0e10cSrcweir template< typename RangeType >
lclGetRangeAddress(const uno::Reference<RangeType> & rxCellRange)1252cdf0e10cSrcweir inline table::CellRangeAddress lclGetRangeAddress( const uno::Reference< RangeType >& rxCellRange ) throw (uno::RuntimeException)
1253cdf0e10cSrcweir {
1254cdf0e10cSrcweir     return uno::Reference< sheet::XCellRangeAddressable >( rxCellRange, uno::UNO_QUERY_THROW )->getRangeAddress();
1255cdf0e10cSrcweir }
1256cdf0e10cSrcweir 
lclClearRange(const uno::Reference<table::XCellRange> & rxCellRange)1257cdf0e10cSrcweir void lclClearRange( const uno::Reference< table::XCellRange >& rxCellRange ) throw (uno::RuntimeException)
1258cdf0e10cSrcweir {
1259cdf0e10cSrcweir     using namespace ::com::sun::star::sheet::CellFlags;
1260cdf0e10cSrcweir 	sal_Int32 nFlags = VALUE | DATETIME | STRING | ANNOTATION | FORMULA | HARDATTR | STYLES | EDITATTR | FORMATTED;
1261cdf0e10cSrcweir 	uno::Reference< sheet::XSheetOperation > xSheetOperation( rxCellRange, uno::UNO_QUERY_THROW );
1262cdf0e10cSrcweir 	xSheetOperation->clearContents( nFlags );
1263cdf0e10cSrcweir }
1264cdf0e10cSrcweir 
lclExpandToMerged(const uno::Reference<table::XCellRange> & rxCellRange,bool bRecursive)1265cdf0e10cSrcweir uno::Reference< sheet::XSheetCellRange > lclExpandToMerged( const uno::Reference< table::XCellRange >& rxCellRange, bool bRecursive ) throw (uno::RuntimeException)
1266cdf0e10cSrcweir {
1267cdf0e10cSrcweir     uno::Reference< sheet::XSheetCellRange > xNewCellRange( rxCellRange, uno::UNO_QUERY_THROW );
1268cdf0e10cSrcweir     uno::Reference< sheet::XSpreadsheet > xSheet( xNewCellRange->getSpreadsheet(), uno::UNO_SET_THROW );
1269cdf0e10cSrcweir     table::CellRangeAddress aNewAddress = lclGetRangeAddress( xNewCellRange );
1270cdf0e10cSrcweir     table::CellRangeAddress aOldAddress;
1271cdf0e10cSrcweir     // expand as long as there are new merged ranges included
1272cdf0e10cSrcweir     do
1273cdf0e10cSrcweir     {
1274cdf0e10cSrcweir         aOldAddress = aNewAddress;
1275cdf0e10cSrcweir         uno::Reference< sheet::XSheetCellCursor > xCursor( xSheet->createCursorByRange( xNewCellRange ), uno::UNO_SET_THROW );
1276cdf0e10cSrcweir         xCursor->collapseToMergedArea();
1277cdf0e10cSrcweir         xNewCellRange.set( xCursor, uno::UNO_QUERY_THROW );
1278cdf0e10cSrcweir         aNewAddress = lclGetRangeAddress( xNewCellRange );
1279cdf0e10cSrcweir     }
1280cdf0e10cSrcweir     while( bRecursive && (aOldAddress != aNewAddress) );
1281cdf0e10cSrcweir     return xNewCellRange;
1282cdf0e10cSrcweir }
1283cdf0e10cSrcweir 
lclExpandToMerged(const uno::Reference<sheet::XSheetCellRangeContainer> & rxCellRanges,bool bRecursive)1284cdf0e10cSrcweir uno::Reference< sheet::XSheetCellRangeContainer > lclExpandToMerged( const uno::Reference< sheet::XSheetCellRangeContainer >& rxCellRanges, bool bRecursive ) throw (uno::RuntimeException)
1285cdf0e10cSrcweir {
1286cdf0e10cSrcweir     if( !rxCellRanges.is() )
1287cdf0e10cSrcweir 		throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Missing cell ranges object" ) ), uno::Reference< uno::XInterface >() );
1288cdf0e10cSrcweir     sal_Int32 nCount = rxCellRanges->getCount();
1289cdf0e10cSrcweir     if( nCount < 1 )
1290cdf0e10cSrcweir 		throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Missing cell ranges object" ) ), uno::Reference< uno::XInterface >() );
1291cdf0e10cSrcweir 
1292cdf0e10cSrcweir     ScRangeList aScRanges;
1293cdf0e10cSrcweir     for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
1294cdf0e10cSrcweir     {
1295cdf0e10cSrcweir         uno::Reference< table::XCellRange > xRange( rxCellRanges->getByIndex( nIndex ), uno::UNO_QUERY_THROW );
1296cdf0e10cSrcweir         table::CellRangeAddress aRangeAddr = lclGetRangeAddress( lclExpandToMerged( xRange, bRecursive ) );
1297cdf0e10cSrcweir     	ScRange aScRange;
1298cdf0e10cSrcweir     	ScUnoConversion::FillScRange( aScRange, aRangeAddr );
1299cdf0e10cSrcweir     	aScRanges.Append( aScRange );
1300cdf0e10cSrcweir     }
1301cdf0e10cSrcweir 	return new ScCellRangesObj( getDocShellFromRanges( rxCellRanges ), aScRanges );
1302cdf0e10cSrcweir }
1303cdf0e10cSrcweir 
lclExpandAndMerge(const uno::Reference<table::XCellRange> & rxCellRange,bool bMerge)1304cdf0e10cSrcweir void lclExpandAndMerge( const uno::Reference< table::XCellRange >& rxCellRange, bool bMerge ) throw (uno::RuntimeException)
1305cdf0e10cSrcweir {
1306cdf0e10cSrcweir     uno::Reference< util::XMergeable > xMerge( lclExpandToMerged( rxCellRange, true ), uno::UNO_QUERY_THROW );
1307cdf0e10cSrcweir     // Calc cannot merge over merged ranges, always unmerge first
1308cdf0e10cSrcweir     xMerge->merge( sal_False );
1309cdf0e10cSrcweir     if( bMerge )
1310cdf0e10cSrcweir     {
1311cdf0e10cSrcweir         // clear all contents of the covered cells (not the top-left cell)
1312cdf0e10cSrcweir         table::CellRangeAddress aRangeAddr = lclGetRangeAddress( rxCellRange );
1313cdf0e10cSrcweir         sal_Int32 nLastColIdx = aRangeAddr.EndColumn - aRangeAddr.StartColumn;
1314cdf0e10cSrcweir         sal_Int32 nLastRowIdx = aRangeAddr.EndRow - aRangeAddr.StartRow;
1315cdf0e10cSrcweir         // clear cells of top row, right of top-left cell
1316cdf0e10cSrcweir         if( nLastColIdx > 0 )
1317cdf0e10cSrcweir             lclClearRange( rxCellRange->getCellRangeByPosition( 1, 0, nLastColIdx, 0 ) );
1318cdf0e10cSrcweir         // clear all rows below top row
1319cdf0e10cSrcweir         if( nLastRowIdx > 0 )
1320cdf0e10cSrcweir             lclClearRange( rxCellRange->getCellRangeByPosition( 0, 1, nLastColIdx, nLastRowIdx ) );
1321cdf0e10cSrcweir         // merge the range
1322cdf0e10cSrcweir         xMerge->merge( sal_True );
1323cdf0e10cSrcweir     }
1324cdf0e10cSrcweir }
1325cdf0e10cSrcweir 
lclGetMergedState(const uno::Reference<table::XCellRange> & rxCellRange)1326cdf0e10cSrcweir util::TriState lclGetMergedState( const uno::Reference< table::XCellRange >& rxCellRange ) throw (uno::RuntimeException)
1327cdf0e10cSrcweir {
1328cdf0e10cSrcweir     /*  1) Check if range is completely inside one single merged range. To do
1329cdf0e10cSrcweir         this, try to extend from top-left cell only (not from entire range).
1330cdf0e10cSrcweir         This will exclude cases where this range consists of several merged
1331cdf0e10cSrcweir         ranges (or parts of them). */
1332cdf0e10cSrcweir     table::CellRangeAddress aRangeAddr = lclGetRangeAddress( rxCellRange );
1333cdf0e10cSrcweir     uno::Reference< table::XCellRange > xTopLeft( rxCellRange->getCellRangeByPosition( 0, 0, 0, 0 ), uno::UNO_SET_THROW );
1334cdf0e10cSrcweir     uno::Reference< sheet::XSheetCellRange > xExpanded( lclExpandToMerged( xTopLeft, false ), uno::UNO_SET_THROW );
1335cdf0e10cSrcweir     table::CellRangeAddress aExpAddr = lclGetRangeAddress( xExpanded );
1336cdf0e10cSrcweir     // check that expanded range has more than one cell (really merged)
1337cdf0e10cSrcweir     if( ((aExpAddr.StartColumn < aExpAddr.EndColumn) || (aExpAddr.StartRow < aExpAddr.EndRow)) && ScUnoConversion::Contains( aExpAddr, aRangeAddr ) )
1338cdf0e10cSrcweir         return util::TriState_YES;
1339cdf0e10cSrcweir 
1340cdf0e10cSrcweir     /*  2) Check if this range contains any merged cells (completely or
1341cdf0e10cSrcweir         partly). This seems to be hardly possible via API, as
1342cdf0e10cSrcweir         XMergeable::getIsMerged() returns only true, if the top-left cell of a
1343cdf0e10cSrcweir         merged range is part of this range, so cases where just the lower part
1344cdf0e10cSrcweir         of a merged range is part of this range are not covered. */
1345cdf0e10cSrcweir 	ScRange aScRange;
1346cdf0e10cSrcweir 	ScUnoConversion::FillScRange( aScRange, aRangeAddr );
1347cdf0e10cSrcweir     bool bHasMerged = getDocumentFromRange( rxCellRange )->HasAttrib( aScRange, HASATTR_MERGED | HASATTR_OVERLAPPED );
1348cdf0e10cSrcweir 	return bHasMerged ? util::TriState_INDETERMINATE : util::TriState_NO;
1349cdf0e10cSrcweir }
1350cdf0e10cSrcweir 
1351cdf0e10cSrcweir } // namespace
1352cdf0e10cSrcweir 
1353cdf0e10cSrcweir // ----------------------------------------------------------------------------
1354cdf0e10cSrcweir 
1355cdf0e10cSrcweir css::uno::Reference< excel::XRange >
getRangeObjectForName(const uno::Reference<uno::XComponentContext> & xContext,const rtl::OUString & sRangeName,ScDocShell * pDocSh,formula::FormulaGrammar::AddressConvention eConv)1356cdf0e10cSrcweir ScVbaRange::getRangeObjectForName(
1357cdf0e10cSrcweir         const uno::Reference< uno::XComponentContext >& xContext, const rtl::OUString& sRangeName,
1358cdf0e10cSrcweir         ScDocShell* pDocSh, formula::FormulaGrammar::AddressConvention eConv ) throw ( uno::RuntimeException )
1359cdf0e10cSrcweir {
1360cdf0e10cSrcweir 	table::CellRangeAddress refAddr;
1361cdf0e10cSrcweir 	return getRangeForName( xContext, sRangeName, pDocSh, refAddr, eConv );
1362cdf0e10cSrcweir }
1363cdf0e10cSrcweir 
1364cdf0e10cSrcweir 
getCellRangeAddressForVBARange(const uno::Any & aParam,ScDocShell * pDocSh,formula::FormulaGrammar::AddressConvention aConv=formula::FormulaGrammar::CONV_XL_A1)1365cdf0e10cSrcweir table::CellRangeAddress getCellRangeAddressForVBARange( const uno::Any& aParam, ScDocShell* pDocSh,  formula::FormulaGrammar::AddressConvention aConv = formula::FormulaGrammar::CONV_XL_A1) throw ( uno::RuntimeException )
1366cdf0e10cSrcweir {
1367cdf0e10cSrcweir 	uno::Reference< table::XCellRange > xRangeParam;
1368cdf0e10cSrcweir 	switch ( aParam.getValueTypeClass() )
1369cdf0e10cSrcweir 	{
1370cdf0e10cSrcweir 		case uno::TypeClass_STRING:
1371cdf0e10cSrcweir 		{
1372cdf0e10cSrcweir 			rtl::OUString rString;
1373cdf0e10cSrcweir 			aParam >>= rString;
1374cdf0e10cSrcweir 			ScRangeList aCellRanges;
1375cdf0e10cSrcweir 			ScRange refRange;
1376cdf0e10cSrcweir 			if ( getScRangeListForAddress ( rString, pDocSh, refRange, aCellRanges, aConv ) )
1377cdf0e10cSrcweir 			{
1378cdf0e10cSrcweir 				if ( aCellRanges.First() == aCellRanges.Last() )
1379cdf0e10cSrcweir 				{
1380cdf0e10cSrcweir 					table::CellRangeAddress aRangeAddress;
1381cdf0e10cSrcweir 					ScUnoConversion::FillApiRange( aRangeAddress, *aCellRanges.First() );
1382cdf0e10cSrcweir 					return aRangeAddress;
1383cdf0e10cSrcweir 				}
1384cdf0e10cSrcweir 			}
1385cdf0e10cSrcweir 		}
1386cdf0e10cSrcweir 		case uno::TypeClass_INTERFACE:
1387cdf0e10cSrcweir 		{
1388cdf0e10cSrcweir 			uno::Reference< excel::XRange > xRange;
1389cdf0e10cSrcweir 			aParam >>= xRange;
1390cdf0e10cSrcweir 			if ( xRange.is() )
1391cdf0e10cSrcweir 				xRange->getCellRange() >>= xRangeParam;
1392cdf0e10cSrcweir 			break;
1393cdf0e10cSrcweir 		}
1394cdf0e10cSrcweir 		default:
1395cdf0e10cSrcweir 			throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Can't extact CellRangeAddress from type" ) ), uno::Reference< uno::XInterface >() );
1396cdf0e10cSrcweir 	}
1397cdf0e10cSrcweir     return lclGetRangeAddress( xRangeParam );
1398cdf0e10cSrcweir }
1399cdf0e10cSrcweir 
1400cdf0e10cSrcweir uno::Reference< XCollection >
lcl_setupBorders(const uno::Reference<excel::XRange> & xParentRange,const uno::Reference<uno::XComponentContext> & xContext,const uno::Reference<table::XCellRange> & xRange)1401cdf0e10cSrcweir lcl_setupBorders( const uno::Reference< excel::XRange >& xParentRange, const uno::Reference<uno::XComponentContext>& xContext,  const uno::Reference< table::XCellRange >& xRange  ) throw( uno::RuntimeException )
1402cdf0e10cSrcweir {
1403cdf0e10cSrcweir 	uno::Reference< XHelperInterface > xParent( xParentRange, uno::UNO_QUERY_THROW );
1404cdf0e10cSrcweir 	ScDocument* pDoc = getDocumentFromRange(xRange);
1405cdf0e10cSrcweir 	if ( !pDoc )
1406cdf0e10cSrcweir 		throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to access document from shell" ) ), uno::Reference< uno::XInterface >() );
1407cdf0e10cSrcweir 	ScVbaPalette aPalette( pDoc->GetDocumentShell() );
1408cdf0e10cSrcweir  	uno::Reference< XCollection > borders( new ScVbaBorders( xParent, xContext, xRange, aPalette ) );
1409cdf0e10cSrcweir 	return borders;
1410cdf0e10cSrcweir }
1411cdf0e10cSrcweir 
lcl_NotifyRangeChanges(const uno::Reference<frame::XModel> & xModel,ScCellRangesBase * pUnoRangesBase)1412*86d5ef3bSPedro Giffuni void lcl_NotifyRangeChanges( const uno::Reference< frame::XModel >& xModel, ScCellRangesBase* pUnoRangesBase ) // i108874
1413*86d5ef3bSPedro Giffuni {
1414*86d5ef3bSPedro Giffuni 	if ( xModel.is() && pUnoRangesBase )
1415*86d5ef3bSPedro Giffuni 	{
1416*86d5ef3bSPedro Giffuni 		ScModelObj* pModelObj = ScModelObj::getImplementation( xModel );
1417*86d5ef3bSPedro Giffuni 		const ScRangeList& aCellRanges = pUnoRangesBase->GetRangeList();
1418*86d5ef3bSPedro Giffuni 		if ( pModelObj && pModelObj->HasChangesListeners() )
1419*86d5ef3bSPedro Giffuni 		{
1420*86d5ef3bSPedro Giffuni 			pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aCellRanges );
1421*86d5ef3bSPedro Giffuni 		}
1422*86d5ef3bSPedro Giffuni 	}
1423*86d5ef3bSPedro Giffuni }
1424*86d5ef3bSPedro Giffuni 
ScVbaRange(uno::Sequence<uno::Any> const & args,uno::Reference<uno::XComponentContext> const & xContext)1425cdf0e10cSrcweir ScVbaRange::ScVbaRange( uno::Sequence< uno::Any> const & args,
1426cdf0e10cSrcweir     uno::Reference< uno::XComponentContext> const & xContext )  throw ( lang::IllegalArgumentException ) : ScVbaRange_BASE( getXSomethingFromArgs< XHelperInterface >( args, 0 ), xContext, getXSomethingFromArgs< beans::XPropertySet >( args, 1, false ), getModelFromXIf( getXSomethingFromArgs< uno::XInterface >( args, 1 ) ), true ), mbIsRows( sal_False ), mbIsColumns( sal_False )
1427cdf0e10cSrcweir {
1428cdf0e10cSrcweir 	mxRange.set( mxPropertySet, uno::UNO_QUERY );
1429cdf0e10cSrcweir 	mxRanges.set( mxPropertySet, uno::UNO_QUERY );
1430cdf0e10cSrcweir 	uno::Reference< container::XIndexAccess >  xIndex;
1431cdf0e10cSrcweir 	if ( mxRange.is() )
1432cdf0e10cSrcweir 	{
1433cdf0e10cSrcweir         xIndex = new SingleRangeIndexAccess( mxParent, mxContext, mxRange );
1434cdf0e10cSrcweir 	}
1435cdf0e10cSrcweir 	else if ( mxRanges.is() )
1436cdf0e10cSrcweir 	{
1437cdf0e10cSrcweir 		xIndex.set( mxRanges, uno::UNO_QUERY_THROW );
1438cdf0e10cSrcweir 	}
1439cdf0e10cSrcweir     m_Areas = new ScVbaRangeAreas( mxParent, mxContext, xIndex, mbIsRows, mbIsColumns );
1440cdf0e10cSrcweir }
1441cdf0e10cSrcweir 
ScVbaRange(const uno::Reference<XHelperInterface> & xParent,const uno::Reference<uno::XComponentContext> & xContext,const uno::Reference<table::XCellRange> & xRange,sal_Bool bIsRows,sal_Bool bIsColumns)1442cdf0e10cSrcweir ScVbaRange::ScVbaRange( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< table::XCellRange >& xRange, sal_Bool bIsRows, sal_Bool bIsColumns ) throw( lang::IllegalArgumentException )
1443cdf0e10cSrcweir : ScVbaRange_BASE( xParent, xContext, uno::Reference< beans::XPropertySet >( xRange, uno::UNO_QUERY_THROW ), getModelFromRange( xRange), true ), mxRange( xRange ),
1444cdf0e10cSrcweir                 mbIsRows( bIsRows ),
1445cdf0e10cSrcweir                 mbIsColumns( bIsColumns )
1446cdf0e10cSrcweir {
1447cdf0e10cSrcweir 	if  ( !xContext.is() )
1448cdf0e10cSrcweir 		throw lang::IllegalArgumentException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "context is not set " ) ), uno::Reference< uno::XInterface >() , 1 );
1449cdf0e10cSrcweir 	if  ( !xRange.is() )
1450cdf0e10cSrcweir 		throw lang::IllegalArgumentException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "range is not set " ) ), uno::Reference< uno::XInterface >() , 1 );
1451cdf0e10cSrcweir 
1452cdf0e10cSrcweir     uno::Reference< container::XIndexAccess > xIndex( new SingleRangeIndexAccess( mxParent, mxContext, xRange ) );
1453cdf0e10cSrcweir     m_Areas = new ScVbaRangeAreas( mxParent, mxContext, xIndex, mbIsRows, mbIsColumns );
1454cdf0e10cSrcweir 
1455cdf0e10cSrcweir }
1456cdf0e10cSrcweir 
ScVbaRange(const uno::Reference<XHelperInterface> & xParent,const uno::Reference<uno::XComponentContext> & xContext,const uno::Reference<sheet::XSheetCellRangeContainer> & xRanges,sal_Bool bIsRows,sal_Bool bIsColumns)1457cdf0e10cSrcweir ScVbaRange::ScVbaRange( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< sheet::XSheetCellRangeContainer >& xRanges,  sal_Bool bIsRows, sal_Bool bIsColumns  ) throw ( lang::IllegalArgumentException )
1458cdf0e10cSrcweir : ScVbaRange_BASE( xParent, xContext, uno::Reference< beans::XPropertySet >( xRanges, uno::UNO_QUERY_THROW ), getModelFromXIf( uno::Reference< uno::XInterface >( xRanges, uno::UNO_QUERY_THROW ) ), true ), mxRanges( xRanges ),mbIsRows( bIsRows ), mbIsColumns( bIsColumns )
1459cdf0e10cSrcweir 
1460cdf0e10cSrcweir {
1461cdf0e10cSrcweir 	uno::Reference< container::XIndexAccess >  xIndex( mxRanges, uno::UNO_QUERY_THROW );
1462cdf0e10cSrcweir     m_Areas	 = new ScVbaRangeAreas( xParent, mxContext, xIndex, mbIsRows, mbIsColumns );
1463cdf0e10cSrcweir 
1464cdf0e10cSrcweir }
1465cdf0e10cSrcweir 
~ScVbaRange()1466cdf0e10cSrcweir ScVbaRange::~ScVbaRange()
1467cdf0e10cSrcweir {
1468cdf0e10cSrcweir }
1469cdf0e10cSrcweir 
getBorders()1470cdf0e10cSrcweir uno::Reference< XCollection >& ScVbaRange::getBorders()
1471cdf0e10cSrcweir {
1472cdf0e10cSrcweir 	if ( !m_Borders.is() )
1473cdf0e10cSrcweir 	{
1474cdf0e10cSrcweir 		uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny( sal_Int32(1) ), uno::Any() ), uno::UNO_QUERY_THROW );
1475cdf0e10cSrcweir 		m_Borders = lcl_setupBorders( this, mxContext, uno::Reference< table::XCellRange >( xRange->getCellRange(), uno::UNO_QUERY_THROW ) );
1476cdf0e10cSrcweir 	}
1477cdf0e10cSrcweir 	return m_Borders;
1478cdf0e10cSrcweir }
1479cdf0e10cSrcweir 
1480cdf0e10cSrcweir void
visitArray(ArrayVisitor & visitor)1481cdf0e10cSrcweir ScVbaRange::visitArray( ArrayVisitor& visitor )
1482cdf0e10cSrcweir {
1483cdf0e10cSrcweir     table::CellRangeAddress aRangeAddr = lclGetRangeAddress( mxRange );
1484cdf0e10cSrcweir     sal_Int32 nRowCount = aRangeAddr.EndRow - aRangeAddr.StartRow + 1;
1485cdf0e10cSrcweir     sal_Int32 nColCount = aRangeAddr.EndColumn - aRangeAddr.StartColumn + 1;
1486cdf0e10cSrcweir 	for ( sal_Int32 i=0; i<nRowCount; ++i )
1487cdf0e10cSrcweir 	{
1488cdf0e10cSrcweir 		for ( sal_Int32 j=0; j<nColCount; ++j )
1489cdf0e10cSrcweir 		{
1490cdf0e10cSrcweir 			uno::Reference< table::XCell > xCell( mxRange->getCellByPosition( j, i ), uno::UNO_QUERY_THROW );
1491cdf0e10cSrcweir 
1492cdf0e10cSrcweir 			visitor.visitNode( i, j, xCell );
1493cdf0e10cSrcweir 		}
1494cdf0e10cSrcweir 	}
1495cdf0e10cSrcweir }
1496cdf0e10cSrcweir 
1497cdf0e10cSrcweir 
1498cdf0e10cSrcweir 
1499cdf0e10cSrcweir uno::Any
getValue(ValueGetter & valueGetter)1500cdf0e10cSrcweir ScVbaRange::getValue( ValueGetter& valueGetter) throw (uno::RuntimeException)
1501cdf0e10cSrcweir {
1502cdf0e10cSrcweir 	uno::Reference< table::XColumnRowRange > xColumnRowRange(mxRange, uno::UNO_QUERY_THROW );
1503cdf0e10cSrcweir 	// single cell range
1504cdf0e10cSrcweir 	if ( isSingleCellRange() )
1505cdf0e10cSrcweir 	{
1506cdf0e10cSrcweir 		visitArray( valueGetter );
1507cdf0e10cSrcweir 		return valueGetter.getValue();
1508cdf0e10cSrcweir 	}
1509cdf0e10cSrcweir 	sal_Int32 nRowCount = xColumnRowRange->getRows()->getCount();
1510cdf0e10cSrcweir 	sal_Int32 nColCount = xColumnRowRange->getColumns()->getCount();
1511cdf0e10cSrcweir 	// multi cell range ( return array )
1512cdf0e10cSrcweir 	Dim2ArrayValueGetter arrayGetter( nRowCount, nColCount, valueGetter );
1513cdf0e10cSrcweir 	visitArray( arrayGetter );
1514cdf0e10cSrcweir 	return uno::makeAny( script::ArrayWrapper( sal_False, arrayGetter.getValue() ) );
1515cdf0e10cSrcweir }
1516cdf0e10cSrcweir 
1517cdf0e10cSrcweir uno::Any SAL_CALL
getValue()1518cdf0e10cSrcweir ScVbaRange::getValue() throw (uno::RuntimeException)
1519cdf0e10cSrcweir {
1520cdf0e10cSrcweir 	// #TODO code within the test below "if ( m_Areas.... " can be removed
1521cdf0e10cSrcweir 	// Test is performed only because m_xRange is NOT set to be
1522cdf0e10cSrcweir 	// the first range in m_Areas ( to force failure while
1523cdf0e10cSrcweir 	// the implementations for each method are being updated )
1524cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
1525cdf0e10cSrcweir 	{
1526cdf0e10cSrcweir 		uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_QUERY_THROW );
1527cdf0e10cSrcweir 		return xRange->getValue();
1528cdf0e10cSrcweir 	}
1529cdf0e10cSrcweir 
1530cdf0e10cSrcweir 	CellValueGetter valueGetter;
1531cdf0e10cSrcweir 	return getValue( valueGetter );
1532cdf0e10cSrcweir 
1533cdf0e10cSrcweir }
1534cdf0e10cSrcweir 
1535cdf0e10cSrcweir 
1536cdf0e10cSrcweir void
setValue(const uno::Any & aValue,ValueSetter & valueSetter,bool bFireEvent)1537cdf0e10cSrcweir ScVbaRange::setValue( const uno::Any& aValue, ValueSetter& valueSetter, bool bFireEvent ) throw (uno::RuntimeException)
1538cdf0e10cSrcweir {
1539cdf0e10cSrcweir 	uno::TypeClass aClass = aValue.getValueTypeClass();
1540cdf0e10cSrcweir 	if ( aClass == uno::TypeClass_SEQUENCE )
1541cdf0e10cSrcweir 	{
1542cdf0e10cSrcweir 		uno::Reference< script::XTypeConverter > xConverter = getTypeConverter( mxContext );
1543cdf0e10cSrcweir 		uno::Any aConverted;
1544cdf0e10cSrcweir 		try
1545cdf0e10cSrcweir 		{
1546cdf0e10cSrcweir 			// test for single dimension, could do
1547cdf0e10cSrcweir 			// with a better test than this
1548cdf0e10cSrcweir 			if ( aValue.getValueTypeName().indexOf('[') ==  aValue.getValueTypeName().lastIndexOf('[') )
1549cdf0e10cSrcweir 			{
1550cdf0e10cSrcweir 				aConverted = xConverter->convertTo( aValue, getCppuType((uno::Sequence< uno::Any >*)0) );
1551cdf0e10cSrcweir 				Dim1ArrayValueSetter setter( aConverted, valueSetter );
1552cdf0e10cSrcweir 				visitArray( setter );
1553cdf0e10cSrcweir 			}
1554cdf0e10cSrcweir 			else
1555cdf0e10cSrcweir 			{
1556cdf0e10cSrcweir 				aConverted = xConverter->convertTo( aValue, getCppuType((uno::Sequence< uno::Sequence< uno::Any > >*)0) );
1557cdf0e10cSrcweir 				Dim2ArrayValueSetter setter( aConverted, valueSetter );
1558cdf0e10cSrcweir 				visitArray( setter );
1559cdf0e10cSrcweir 			}
1560cdf0e10cSrcweir 		}
1561cdf0e10cSrcweir 		catch ( uno::Exception& e )
1562cdf0e10cSrcweir 		{
1563cdf0e10cSrcweir 			OSL_TRACE("Bahhh, caught exception %s",
1564cdf0e10cSrcweir 				rtl::OUStringToOString( e.Message,
1565cdf0e10cSrcweir 					RTL_TEXTENCODING_UTF8 ).getStr() );
1566cdf0e10cSrcweir 		}
1567cdf0e10cSrcweir 	}
1568cdf0e10cSrcweir 	else
1569cdf0e10cSrcweir 	{
1570cdf0e10cSrcweir 		visitArray( valueSetter );
1571cdf0e10cSrcweir 	}
1572cdf0e10cSrcweir     if( bFireEvent ) fireChangeEvent();
1573cdf0e10cSrcweir }
1574cdf0e10cSrcweir 
1575cdf0e10cSrcweir void SAL_CALL
setValue(const uno::Any & aValue)1576cdf0e10cSrcweir ScVbaRange::setValue( const uno::Any  &aValue ) throw (uno::RuntimeException)
1577cdf0e10cSrcweir {
1578cdf0e10cSrcweir 	// If this is a multiple selection apply setValue over all areas
1579cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
1580cdf0e10cSrcweir 	{
1581cdf0e10cSrcweir 		AreasVisitor aVisitor( m_Areas );
1582cdf0e10cSrcweir 		RangeValueProcessor valueProcessor( aValue );
1583cdf0e10cSrcweir 		aVisitor.visit( valueProcessor );
1584cdf0e10cSrcweir 		return;
1585cdf0e10cSrcweir 	}
1586cdf0e10cSrcweir 	CellValueSetter valueSetter( aValue );
1587cdf0e10cSrcweir 	setValue( aValue, valueSetter, true );
1588*86d5ef3bSPedro Giffuni 	// Fire the range change event.
1589*86d5ef3bSPedro Giffuni 	lcl_NotifyRangeChanges( getScDocShell()->GetModel(), getCellRangesBase() );
1590cdf0e10cSrcweir }
1591cdf0e10cSrcweir 
1592cdf0e10cSrcweir void SAL_CALL
Clear()1593cdf0e10cSrcweir ScVbaRange::Clear() throw (uno::RuntimeException)
1594cdf0e10cSrcweir {
1595cdf0e10cSrcweir     using namespace ::com::sun::star::sheet::CellFlags;
1596cdf0e10cSrcweir 	sal_Int32 nFlags = VALUE | DATETIME | STRING | FORMULA | HARDATTR | EDITATTR | FORMATTED;
1597cdf0e10cSrcweir 	ClearContents( nFlags, true );
1598*86d5ef3bSPedro Giffuni 	// Fire the range change event
1599*86d5ef3bSPedro Giffuni 	lcl_NotifyRangeChanges( getScDocShell()->GetModel(), getCellRangesBase() );
1600cdf0e10cSrcweir }
1601cdf0e10cSrcweir 
1602cdf0e10cSrcweir //helper ClearContent
1603cdf0e10cSrcweir void
ClearContents(sal_Int32 nFlags,bool bFireEvent)1604cdf0e10cSrcweir ScVbaRange::ClearContents( sal_Int32 nFlags, bool bFireEvent ) throw (uno::RuntimeException)
1605cdf0e10cSrcweir {
1606cdf0e10cSrcweir 	// #TODO code within the test below "if ( m_Areas.... " can be removed
1607cdf0e10cSrcweir 	// Test is performed only because m_xRange is NOT set to be
1608cdf0e10cSrcweir 	// the first range in m_Areas ( to force failure while
1609cdf0e10cSrcweir 	// the implementations for each method are being updated )
1610cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
1611cdf0e10cSrcweir 	{
1612cdf0e10cSrcweir 		sal_Int32 nItems = m_Areas->getCount();
1613cdf0e10cSrcweir 		for ( sal_Int32 index=1; index <= nItems; ++index )
1614cdf0e10cSrcweir 		{
1615cdf0e10cSrcweir 			uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW );
1616cdf0e10cSrcweir 			ScVbaRange* pRange = getImplementation( xRange );
1617cdf0e10cSrcweir 			if ( pRange )
1618cdf0e10cSrcweir 				pRange->ClearContents( nFlags, false ); // do not fire for single ranges
1619cdf0e10cSrcweir 		}
1620cdf0e10cSrcweir         // fire change event for the entire range list
1621cdf0e10cSrcweir         if( bFireEvent ) fireChangeEvent();
1622cdf0e10cSrcweir 		return;
1623cdf0e10cSrcweir 	}
1624cdf0e10cSrcweir 
1625cdf0e10cSrcweir 
1626cdf0e10cSrcweir 	uno::Reference< sheet::XSheetOperation > xSheetOperation(mxRange, uno::UNO_QUERY_THROW);
1627cdf0e10cSrcweir 	xSheetOperation->clearContents( nFlags );
1628cdf0e10cSrcweir     if( bFireEvent ) fireChangeEvent();
1629cdf0e10cSrcweir }
1630cdf0e10cSrcweir 
1631cdf0e10cSrcweir void SAL_CALL
ClearComments()1632cdf0e10cSrcweir ScVbaRange::ClearComments() throw (uno::RuntimeException)
1633cdf0e10cSrcweir {
1634cdf0e10cSrcweir 	ClearContents( sheet::CellFlags::ANNOTATION, false );
1635cdf0e10cSrcweir }
1636cdf0e10cSrcweir 
1637cdf0e10cSrcweir void SAL_CALL
ClearContents()1638cdf0e10cSrcweir ScVbaRange::ClearContents() throw (uno::RuntimeException)
1639cdf0e10cSrcweir {
1640cdf0e10cSrcweir     using namespace ::com::sun::star::sheet::CellFlags;
1641cdf0e10cSrcweir 	sal_Int32 nFlags = VALUE | STRING |  DATETIME | FORMULA;
1642cdf0e10cSrcweir 	ClearContents( nFlags, true );
1643cdf0e10cSrcweir }
1644cdf0e10cSrcweir 
1645cdf0e10cSrcweir void SAL_CALL
ClearFormats()1646cdf0e10cSrcweir ScVbaRange::ClearFormats() throw (uno::RuntimeException)
1647cdf0e10cSrcweir {
1648cdf0e10cSrcweir 	//FIXME: need to check if we need to combine FORMATTED
1649cdf0e10cSrcweir     using namespace ::com::sun::star::sheet::CellFlags;
1650cdf0e10cSrcweir 	sal_Int32 nFlags = HARDATTR | FORMATTED | EDITATTR;
1651cdf0e10cSrcweir 	ClearContents( nFlags, false );
1652*86d5ef3bSPedro Giffuni 	// Fire the range change event.
1653*86d5ef3bSPedro Giffuni 	lcl_NotifyRangeChanges( getScDocShell()->GetModel(), getCellRangesBase() );
1654cdf0e10cSrcweir }
1655cdf0e10cSrcweir 
1656cdf0e10cSrcweir void
setFormulaValue(const uno::Any & rFormula,formula::FormulaGrammar::Grammar eGram,bool bFireEvent)1657cdf0e10cSrcweir ScVbaRange::setFormulaValue( const uno::Any& rFormula, formula::FormulaGrammar::Grammar eGram, bool bFireEvent ) throw (uno::RuntimeException)
1658cdf0e10cSrcweir {
1659cdf0e10cSrcweir 	// If this is a multiple selection apply setFormula over all areas
1660cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
1661cdf0e10cSrcweir 	{
1662cdf0e10cSrcweir 		AreasVisitor aVisitor( m_Areas );
1663cdf0e10cSrcweir 		RangeFormulaProcessor valueProcessor( rFormula );
1664cdf0e10cSrcweir 		aVisitor.visit( valueProcessor );
1665cdf0e10cSrcweir 		return;
1666cdf0e10cSrcweir 	}
1667cdf0e10cSrcweir 	CellFormulaValueSetter formulaValueSetter( rFormula, getScDocument(), eGram );
1668cdf0e10cSrcweir 	setValue( rFormula, formulaValueSetter, bFireEvent );
1669*86d5ef3bSPedro Giffuni 	// Fire the range change event.
1670*86d5ef3bSPedro Giffuni 	lcl_NotifyRangeChanges( getScDocShell()->GetModel(), getCellRangesBase() );
1671cdf0e10cSrcweir }
1672cdf0e10cSrcweir 
1673cdf0e10cSrcweir uno::Any
getFormulaValue(formula::FormulaGrammar::Grammar eGram)1674cdf0e10cSrcweir ScVbaRange::getFormulaValue( formula::FormulaGrammar::Grammar eGram ) throw (uno::RuntimeException)
1675cdf0e10cSrcweir {
1676cdf0e10cSrcweir 	// #TODO code within the test below "if ( m_Areas.... " can be removed
1677cdf0e10cSrcweir 	// Test is performed only because m_xRange is NOT set to be
1678cdf0e10cSrcweir 	// the first range in m_Areas ( to force failure while
1679cdf0e10cSrcweir 	// the implementations for each method are being updated )
1680cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
1681cdf0e10cSrcweir 	{
1682cdf0e10cSrcweir 		uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_QUERY_THROW );
1683cdf0e10cSrcweir 		return xRange->getFormula();
1684cdf0e10cSrcweir 	}
1685cdf0e10cSrcweir 	CellFormulaValueGetter valueGetter( getScDocument(), eGram );
1686cdf0e10cSrcweir 	return getValue( valueGetter );
1687cdf0e10cSrcweir 
1688cdf0e10cSrcweir }
1689cdf0e10cSrcweir 
1690cdf0e10cSrcweir void
setFormula(const uno::Any & rFormula)1691cdf0e10cSrcweir ScVbaRange::setFormula(const uno::Any &rFormula ) throw (uno::RuntimeException)
1692cdf0e10cSrcweir {
1693cdf0e10cSrcweir 	// #FIXME converting "=$a$1" e.g. CONV_XL_A1 -> CONV_OOO                        	// results in "=$a$1:a1", temporalily disable conversion
1694cdf0e10cSrcweir 	setFormulaValue( rFormula,formula::FormulaGrammar::GRAM_NATIVE_XL_A1, true );
1695cdf0e10cSrcweir }
1696cdf0e10cSrcweir 
1697cdf0e10cSrcweir uno::Any
getFormulaR1C1()1698cdf0e10cSrcweir ScVbaRange::getFormulaR1C1() throw (::com::sun::star::uno::RuntimeException)
1699cdf0e10cSrcweir {
1700cdf0e10cSrcweir 	return getFormulaValue( formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1 );
1701cdf0e10cSrcweir }
1702cdf0e10cSrcweir 
1703cdf0e10cSrcweir void
setFormulaR1C1(const uno::Any & rFormula)1704cdf0e10cSrcweir ScVbaRange::setFormulaR1C1(const uno::Any& rFormula ) throw (uno::RuntimeException)
1705cdf0e10cSrcweir {
1706cdf0e10cSrcweir 	setFormulaValue( rFormula,formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1, true );
1707cdf0e10cSrcweir }
1708cdf0e10cSrcweir 
1709cdf0e10cSrcweir uno::Any
getFormula()1710cdf0e10cSrcweir ScVbaRange::getFormula() throw (::com::sun::star::uno::RuntimeException)
1711cdf0e10cSrcweir {
1712cdf0e10cSrcweir 	return getFormulaValue( formula::FormulaGrammar::GRAM_NATIVE_XL_A1 );
1713cdf0e10cSrcweir }
1714cdf0e10cSrcweir 
1715cdf0e10cSrcweir sal_Int32
getCount()1716cdf0e10cSrcweir ScVbaRange::getCount() throw (uno::RuntimeException)
1717cdf0e10cSrcweir {
1718cdf0e10cSrcweir 	// If this is a multiple selection apply setValue over all areas
1719cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
1720cdf0e10cSrcweir 	{
1721cdf0e10cSrcweir 		AreasVisitor aVisitor( m_Areas );
1722cdf0e10cSrcweir 		RangeCountProcessor valueProcessor;
1723cdf0e10cSrcweir 		aVisitor.visit( valueProcessor );
1724cdf0e10cSrcweir 		return valueProcessor.value();
1725cdf0e10cSrcweir 	}
1726cdf0e10cSrcweir 	sal_Int32 rowCount = 0;
1727cdf0e10cSrcweir 	sal_Int32 colCount = 0;
1728cdf0e10cSrcweir 	uno::Reference< table::XColumnRowRange > xColumnRowRange(mxRange, uno::UNO_QUERY_THROW );
1729cdf0e10cSrcweir 	rowCount = xColumnRowRange->getRows()->getCount();
1730cdf0e10cSrcweir 	colCount = xColumnRowRange->getColumns()->getCount();
1731cdf0e10cSrcweir 
1732cdf0e10cSrcweir 	if( IsRows() )
1733cdf0e10cSrcweir 		return rowCount;
1734cdf0e10cSrcweir 	if( IsColumns() )
1735cdf0e10cSrcweir 		return colCount;
1736cdf0e10cSrcweir 	return rowCount * colCount;
1737cdf0e10cSrcweir }
1738cdf0e10cSrcweir 
1739cdf0e10cSrcweir sal_Int32
getRow()1740cdf0e10cSrcweir ScVbaRange::getRow() throw (uno::RuntimeException)
1741cdf0e10cSrcweir {
1742cdf0e10cSrcweir 	// #TODO code within the test below "if ( m_Areas.... " can be removed
1743cdf0e10cSrcweir 	// Test is performed only because m_xRange is NOT set to be
1744cdf0e10cSrcweir 	// the first range in m_Areas ( to force failure while
1745cdf0e10cSrcweir 	// the implementations for each method are being updated )
1746cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
1747cdf0e10cSrcweir 	{
1748cdf0e10cSrcweir 		uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_QUERY_THROW );
1749cdf0e10cSrcweir 		return xRange->getRow();
1750cdf0e10cSrcweir 	}
1751cdf0e10cSrcweir 	uno::Reference< sheet::XCellAddressable > xCellAddressable(mxRange->getCellByPosition(0, 0), uno::UNO_QUERY_THROW );
1752cdf0e10cSrcweir 	return xCellAddressable->getCellAddress().Row + 1; // Zero value indexing
1753cdf0e10cSrcweir }
1754cdf0e10cSrcweir 
1755cdf0e10cSrcweir sal_Int32
getColumn()1756cdf0e10cSrcweir ScVbaRange::getColumn() throw (uno::RuntimeException)
1757cdf0e10cSrcweir {
1758cdf0e10cSrcweir 	// #TODO code within the test below "if ( m_Areas.... " can be removed
1759cdf0e10cSrcweir 	// Test is performed only because m_xRange is NOT set to be
1760cdf0e10cSrcweir 	// the first range in m_Areas ( to force failure while
1761cdf0e10cSrcweir 	// the implementations for each method are being updated )
1762cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
1763cdf0e10cSrcweir 	{
1764cdf0e10cSrcweir 		uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_QUERY_THROW );
1765cdf0e10cSrcweir 		return xRange->getColumn();
1766cdf0e10cSrcweir 	}
1767cdf0e10cSrcweir 	uno::Reference< sheet::XCellAddressable > xCellAddressable(mxRange->getCellByPosition(0, 0), uno::UNO_QUERY_THROW );
1768cdf0e10cSrcweir 	return xCellAddressable->getCellAddress().Column + 1; // Zero value indexing
1769cdf0e10cSrcweir }
1770cdf0e10cSrcweir 
1771cdf0e10cSrcweir uno::Any
HasFormula()1772cdf0e10cSrcweir ScVbaRange::HasFormula() throw (uno::RuntimeException)
1773cdf0e10cSrcweir {
1774cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
1775cdf0e10cSrcweir 	{
1776cdf0e10cSrcweir 		sal_Int32 nItems = m_Areas->getCount();
1777cdf0e10cSrcweir 		uno::Any aResult = aNULL();
1778cdf0e10cSrcweir 		for ( sal_Int32 index=1; index <= nItems; ++index )
1779cdf0e10cSrcweir 		{
1780cdf0e10cSrcweir 			uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW );
1781cdf0e10cSrcweir 			// if the HasFormula for any area is different to another
1782cdf0e10cSrcweir 			// return null
1783cdf0e10cSrcweir 			if ( index > 1 )
1784cdf0e10cSrcweir 				if ( aResult != xRange->HasFormula() )
1785cdf0e10cSrcweir 					return aNULL();
1786cdf0e10cSrcweir 			aResult = xRange->HasFormula();
1787cdf0e10cSrcweir 			if ( aNULL() == aResult )
1788cdf0e10cSrcweir 				return aNULL();
1789cdf0e10cSrcweir 		}
1790cdf0e10cSrcweir 		return aResult;
1791cdf0e10cSrcweir 	}
1792cdf0e10cSrcweir 	uno::Reference< uno::XInterface > xIf( mxRange, uno::UNO_QUERY_THROW );
1793cdf0e10cSrcweir 	ScCellRangesBase* pThisRanges = dynamic_cast< ScCellRangesBase * > ( xIf.get() );
1794cdf0e10cSrcweir 	if ( pThisRanges )
1795cdf0e10cSrcweir 	{
1796cdf0e10cSrcweir 		uno::Reference<uno::XInterface>  xRanges( pThisRanges->queryFormulaCells( ( sheet::FormulaResult::ERROR | sheet::FormulaResult::VALUE |  sheet::FormulaResult::STRING ) ), uno::UNO_QUERY_THROW );
1797cdf0e10cSrcweir 		ScCellRangesBase* pFormulaRanges = dynamic_cast< ScCellRangesBase * > ( xRanges.get() );
1798cdf0e10cSrcweir 		// check if there are no formula cell, return false
1799cdf0e10cSrcweir 		if ( pFormulaRanges->GetRangeList().Count() == 0 )
1800cdf0e10cSrcweir 			return uno::makeAny(sal_False);
1801cdf0e10cSrcweir 
1802cdf0e10cSrcweir 		// chech if there are holes (where some cells are not formulas)
1803cdf0e10cSrcweir 		// or returned range is not equal to this range
1804cdf0e10cSrcweir 		if ( ( pFormulaRanges->GetRangeList().Count() > 1 )
1805cdf0e10cSrcweir 		|| ( pFormulaRanges->GetRangeList().GetObject(0)->aStart != pThisRanges->GetRangeList().GetObject(0)->aStart )
1806cdf0e10cSrcweir 		|| ( pFormulaRanges->GetRangeList().GetObject(0)->aEnd != pThisRanges->GetRangeList().GetObject(0)->aEnd ) )
1807cdf0e10cSrcweir 			return aNULL(); // should return aNULL;
1808cdf0e10cSrcweir 	}
1809cdf0e10cSrcweir 	return uno::makeAny( sal_True );
1810cdf0e10cSrcweir }
1811cdf0e10cSrcweir void
fillSeries(sheet::FillDirection nFillDirection,sheet::FillMode nFillMode,sheet::FillDateMode nFillDateMode,double fStep,double fEndValue)1812cdf0e10cSrcweir ScVbaRange::fillSeries( sheet::FillDirection nFillDirection, sheet::FillMode nFillMode, sheet::FillDateMode nFillDateMode, double fStep, double fEndValue ) throw( uno::RuntimeException )
1813cdf0e10cSrcweir {
1814cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
1815cdf0e10cSrcweir 	{
1816cdf0e10cSrcweir 		// Multi-Area Range
1817cdf0e10cSrcweir 		uno::Reference< XCollection > xCollection( m_Areas, uno::UNO_QUERY_THROW );
1818cdf0e10cSrcweir 		for ( sal_Int32 index = 1; index <= xCollection->getCount(); ++index )
1819cdf0e10cSrcweir 		{
1820cdf0e10cSrcweir 			uno::Reference< excel::XRange > xRange( xCollection->Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW );
1821cdf0e10cSrcweir 			ScVbaRange* pThisRange = getImplementation( xRange );
1822cdf0e10cSrcweir 			pThisRange->fillSeries( nFillDirection, nFillMode, nFillDateMode, fStep, fEndValue );
1823cdf0e10cSrcweir 
1824cdf0e10cSrcweir 		}
1825cdf0e10cSrcweir 		return;
1826cdf0e10cSrcweir 	}
1827cdf0e10cSrcweir 
1828cdf0e10cSrcweir 	uno::Reference< sheet::XCellSeries > xCellSeries(mxRange, uno::UNO_QUERY_THROW );
1829cdf0e10cSrcweir 	xCellSeries->fillSeries( nFillDirection, nFillMode, nFillDateMode, fStep, fEndValue );
1830*86d5ef3bSPedro Giffuni 
1831*86d5ef3bSPedro Giffuni 	// Fire the range change event.
1832*86d5ef3bSPedro Giffuni 	lcl_NotifyRangeChanges( getScDocShell()->GetModel(), getCellRangesBase() );
1833cdf0e10cSrcweir }
1834cdf0e10cSrcweir 
1835cdf0e10cSrcweir void
FillLeft()1836cdf0e10cSrcweir ScVbaRange::FillLeft() throw (uno::RuntimeException)
1837cdf0e10cSrcweir {
1838cdf0e10cSrcweir 	fillSeries(sheet::FillDirection_TO_LEFT,
1839cdf0e10cSrcweir 		sheet::FillMode_SIMPLE, sheet::FillDateMode_FILL_DATE_DAY, 0, 0x7FFFFFFF);
1840cdf0e10cSrcweir }
1841cdf0e10cSrcweir 
1842cdf0e10cSrcweir void
FillRight()1843cdf0e10cSrcweir ScVbaRange::FillRight() throw (uno::RuntimeException)
1844cdf0e10cSrcweir {
1845cdf0e10cSrcweir 	fillSeries(sheet::FillDirection_TO_RIGHT,
1846cdf0e10cSrcweir 		sheet::FillMode_SIMPLE, sheet::FillDateMode_FILL_DATE_DAY, 0, 0x7FFFFFFF);
1847cdf0e10cSrcweir }
1848cdf0e10cSrcweir 
1849cdf0e10cSrcweir void
FillUp()1850cdf0e10cSrcweir ScVbaRange::FillUp() throw (uno::RuntimeException)
1851cdf0e10cSrcweir {
1852cdf0e10cSrcweir 	fillSeries(sheet::FillDirection_TO_TOP,
1853cdf0e10cSrcweir 		sheet::FillMode_SIMPLE, sheet::FillDateMode_FILL_DATE_DAY, 0, 0x7FFFFFFF);
1854cdf0e10cSrcweir }
1855cdf0e10cSrcweir 
1856cdf0e10cSrcweir void
FillDown()1857cdf0e10cSrcweir ScVbaRange::FillDown() throw (uno::RuntimeException)
1858cdf0e10cSrcweir {
1859cdf0e10cSrcweir 	fillSeries(sheet::FillDirection_TO_BOTTOM,
1860cdf0e10cSrcweir 		sheet::FillMode_SIMPLE, sheet::FillDateMode_FILL_DATE_DAY, 0, 0x7FFFFFFF);
1861cdf0e10cSrcweir }
1862cdf0e10cSrcweir 
1863cdf0e10cSrcweir ::rtl::OUString
getText()1864cdf0e10cSrcweir ScVbaRange::getText() throw (uno::RuntimeException)
1865cdf0e10cSrcweir {
1866cdf0e10cSrcweir 	// #TODO code within the test below "if ( m_Areas.... " can be removed
1867cdf0e10cSrcweir 	// Test is performed only because m_xRange is NOT set to be
1868cdf0e10cSrcweir 	// the first range in m_Areas ( to force failure while
1869cdf0e10cSrcweir 	// the implementations for each method are being updated )
1870cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
1871cdf0e10cSrcweir 	{
1872cdf0e10cSrcweir 		uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_QUERY_THROW );
1873cdf0e10cSrcweir 		return xRange->getText();
1874cdf0e10cSrcweir 	}
1875cdf0e10cSrcweir 	uno::Reference< text::XTextRange > xTextRange(mxRange->getCellByPosition(0,0), uno::UNO_QUERY_THROW );
1876cdf0e10cSrcweir 	return xTextRange->getString();
1877cdf0e10cSrcweir }
1878cdf0e10cSrcweir 
1879cdf0e10cSrcweir uno::Reference< excel::XRange >
Offset(const::uno::Any & nRowOff,const uno::Any & nColOff)1880cdf0e10cSrcweir ScVbaRange::Offset( const ::uno::Any &nRowOff, const uno::Any &nColOff ) throw (uno::RuntimeException)
1881cdf0e10cSrcweir {
1882cdf0e10cSrcweir 	SCROW nRowOffset = 0;
1883cdf0e10cSrcweir 	SCCOL nColOffset = 0;
1884cdf0e10cSrcweir 	sal_Bool bIsRowOffset = ( nRowOff >>= nRowOffset );
1885cdf0e10cSrcweir 	sal_Bool bIsColumnOffset = ( nColOff >>= nColOffset );
1886cdf0e10cSrcweir 	ScCellRangesBase* pUnoRangesBase = getCellRangesBase();
1887cdf0e10cSrcweir 
1888cdf0e10cSrcweir 	ScRangeList aCellRanges = pUnoRangesBase->GetRangeList();
1889cdf0e10cSrcweir 
1890cdf0e10cSrcweir 
1891cdf0e10cSrcweir 	for ( ScRange* pRange = aCellRanges.First() ; pRange; pRange = aCellRanges.Next() )
1892cdf0e10cSrcweir 	{
1893cdf0e10cSrcweir 		if ( bIsColumnOffset )
1894cdf0e10cSrcweir 		{
1895cdf0e10cSrcweir 			pRange->aStart.SetCol( pRange->aStart.Col() + nColOffset );
1896cdf0e10cSrcweir 			pRange->aEnd.SetCol( pRange->aEnd.Col() + nColOffset );
1897cdf0e10cSrcweir 		}
1898cdf0e10cSrcweir 		if ( bIsRowOffset )
1899cdf0e10cSrcweir 		{
1900cdf0e10cSrcweir 			pRange->aStart.SetRow( pRange->aStart.Row() + nRowOffset );
1901cdf0e10cSrcweir 			pRange->aEnd.SetRow( pRange->aEnd.Row() + nRowOffset );
1902cdf0e10cSrcweir 		}
1903cdf0e10cSrcweir 	}
1904cdf0e10cSrcweir 
1905cdf0e10cSrcweir 	if ( aCellRanges.Count() > 1 ) // Multi-Area
1906cdf0e10cSrcweir 	{
1907cdf0e10cSrcweir 		uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pUnoRangesBase->GetDocShell(), aCellRanges ) );
1908cdf0e10cSrcweir 		return new ScVbaRange( mxParent, mxContext, xRanges );
1909cdf0e10cSrcweir 	}
1910cdf0e10cSrcweir 	// normal range
1911cdf0e10cSrcweir 	uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pUnoRangesBase->GetDocShell(), *aCellRanges.First() ) );
1912cdf0e10cSrcweir 	return new ScVbaRange( mxParent, mxContext, xRange  );
1913cdf0e10cSrcweir }
1914cdf0e10cSrcweir 
1915cdf0e10cSrcweir uno::Reference< excel::XRange >
CurrentRegion()1916cdf0e10cSrcweir ScVbaRange::CurrentRegion() throw (uno::RuntimeException)
1917cdf0e10cSrcweir {
1918cdf0e10cSrcweir 	// #TODO code within the test below "if ( m_Areas.... " can be removed
1919cdf0e10cSrcweir 	// Test is performed only because m_xRange is NOT set to be
1920cdf0e10cSrcweir 	// the first range in m_Areas ( to force failure while
1921cdf0e10cSrcweir 	// the implementations for each method are being updated )
1922cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
1923cdf0e10cSrcweir 	{
1924cdf0e10cSrcweir 		uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_QUERY_THROW );
1925cdf0e10cSrcweir 		return xRange->CurrentRegion();
1926cdf0e10cSrcweir 	}
1927cdf0e10cSrcweir 
1928cdf0e10cSrcweir 	RangeHelper helper( mxRange );
1929cdf0e10cSrcweir 	uno::Reference< sheet::XSheetCellCursor > xSheetCellCursor =
1930cdf0e10cSrcweir 		helper.getSheetCellCursor();
1931cdf0e10cSrcweir 	xSheetCellCursor->collapseToCurrentRegion();
1932cdf0e10cSrcweir 	uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable(xSheetCellCursor, uno::UNO_QUERY_THROW);
1933cdf0e10cSrcweir     return RangeHelper::createRangeFromRange( mxParent, mxContext, helper.getCellRangeFromSheet(), xCellRangeAddressable );
1934cdf0e10cSrcweir }
1935cdf0e10cSrcweir 
1936cdf0e10cSrcweir uno::Reference< excel::XRange >
CurrentArray()1937cdf0e10cSrcweir ScVbaRange::CurrentArray() throw (uno::RuntimeException)
1938cdf0e10cSrcweir {
1939cdf0e10cSrcweir 	// #TODO code within the test below "if ( m_Areas.... " can be removed
1940cdf0e10cSrcweir 	// Test is performed only because m_xRange is NOT set to be
1941cdf0e10cSrcweir 	// the first range in m_Areas ( to force failure while
1942cdf0e10cSrcweir 	// the implementations for each method are being updated )
1943cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
1944cdf0e10cSrcweir 	{
1945cdf0e10cSrcweir 		uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_QUERY_THROW );
1946cdf0e10cSrcweir 		return xRange->CurrentArray();
1947cdf0e10cSrcweir 	}
1948cdf0e10cSrcweir 	RangeHelper helper( mxRange );
1949cdf0e10cSrcweir 	uno::Reference< sheet::XSheetCellCursor > xSheetCellCursor =
1950cdf0e10cSrcweir 		helper.getSheetCellCursor();
1951cdf0e10cSrcweir 	xSheetCellCursor->collapseToCurrentArray();
1952cdf0e10cSrcweir 	uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable(xSheetCellCursor, uno::UNO_QUERY_THROW);
1953cdf0e10cSrcweir     return RangeHelper::createRangeFromRange( mxParent, mxContext, helper.getCellRangeFromSheet(), xCellRangeAddressable );
1954cdf0e10cSrcweir }
1955cdf0e10cSrcweir 
1956cdf0e10cSrcweir uno::Any
getFormulaArray()1957cdf0e10cSrcweir ScVbaRange::getFormulaArray() throw (uno::RuntimeException)
1958cdf0e10cSrcweir {
1959cdf0e10cSrcweir 	// #TODO code within the test below "if ( m_Areas.... " can be removed
1960cdf0e10cSrcweir 	// Test is performed only because m_xRange is NOT set to be
1961cdf0e10cSrcweir 	// the first range in m_Areas ( to force failure while
1962cdf0e10cSrcweir 	// the implementations for each method are being updated )
1963cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
1964cdf0e10cSrcweir 	{
1965cdf0e10cSrcweir 		uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_QUERY_THROW );
1966cdf0e10cSrcweir 		return xRange->getFormulaArray();
1967cdf0e10cSrcweir 	}
1968cdf0e10cSrcweir 
1969cdf0e10cSrcweir 	uno::Reference< sheet::XCellRangeFormula> xCellRangeFormula( mxRange, uno::UNO_QUERY_THROW );
1970cdf0e10cSrcweir 	uno::Reference< script::XTypeConverter > xConverter = getTypeConverter( mxContext );
1971cdf0e10cSrcweir 	uno::Any aMatrix;
1972cdf0e10cSrcweir 	aMatrix = xConverter->convertTo( uno::makeAny( xCellRangeFormula->getFormulaArray() ) , getCppuType((uno::Sequence< uno::Sequence< uno::Any > >*)0)  ) ;
1973cdf0e10cSrcweir 	return aMatrix;
1974cdf0e10cSrcweir }
1975cdf0e10cSrcweir 
1976cdf0e10cSrcweir void
setFormulaArray(const uno::Any & rFormula)1977cdf0e10cSrcweir ScVbaRange::setFormulaArray(const uno::Any& rFormula) throw (uno::RuntimeException)
1978cdf0e10cSrcweir {
1979cdf0e10cSrcweir 	// #TODO code within the test below "if ( m_Areas.... " can be removed
1980cdf0e10cSrcweir 	// Test is performed only because m_xRange is NOT set to be
1981cdf0e10cSrcweir 	// the first range in m_Areas ( to force failure while
1982cdf0e10cSrcweir 	// the implementations for each method are being updated )
1983cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
1984cdf0e10cSrcweir 	{
1985cdf0e10cSrcweir 		uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_QUERY_THROW );
1986cdf0e10cSrcweir 		return xRange->setFormulaArray( rFormula );
1987cdf0e10cSrcweir 	}
1988cdf0e10cSrcweir 	// #TODO need to distinguish between getFormula and getFormulaArray e.g. (R1C1)
1989cdf0e10cSrcweir 	// but for the moment its just easier to treat them the same for setting
1990cdf0e10cSrcweir 
1991cdf0e10cSrcweir 	setFormula( rFormula );
1992cdf0e10cSrcweir }
1993cdf0e10cSrcweir 
1994cdf0e10cSrcweir ::rtl::OUString
Characters(const uno::Any & Start,const uno::Any & Length)1995cdf0e10cSrcweir ScVbaRange::Characters(const uno::Any& Start, const uno::Any& Length) throw (uno::RuntimeException)
1996cdf0e10cSrcweir {
1997cdf0e10cSrcweir 	// #TODO code within the test below "if ( m_Areas.... " can be removed
1998cdf0e10cSrcweir 	// Test is performed only because m_xRange is NOT set to be
1999cdf0e10cSrcweir 	// the first range in m_Areas ( to force failure while
2000cdf0e10cSrcweir 	// the implementations for each method are being updated )
2001cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
2002cdf0e10cSrcweir 	{
2003cdf0e10cSrcweir 		uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_QUERY_THROW );
2004cdf0e10cSrcweir 		return xRange->Characters( Start, Length );
2005cdf0e10cSrcweir 	}
2006cdf0e10cSrcweir 
2007cdf0e10cSrcweir 	long nIndex = 0, nCount = 0;
2008cdf0e10cSrcweir 	::rtl::OUString rString;
2009cdf0e10cSrcweir 	uno::Reference< text::XTextRange > xTextRange(mxRange, ::uno::UNO_QUERY_THROW );
2010cdf0e10cSrcweir 	rString = xTextRange->getString();
2011cdf0e10cSrcweir 	if( !( Start >>= nIndex ) && !( Length >>= nCount ) )
2012cdf0e10cSrcweir 		return rString;
2013cdf0e10cSrcweir 	if(!( Start >>= nIndex ) )
2014cdf0e10cSrcweir 		nIndex = 1;
2015cdf0e10cSrcweir 	if(!( Length >>= nCount ) )
2016cdf0e10cSrcweir 		nIndex = rString.getLength();
2017cdf0e10cSrcweir 	return rString.copy( --nIndex, nCount ); // Zero value indexing
2018cdf0e10cSrcweir }
2019cdf0e10cSrcweir 
2020cdf0e10cSrcweir ::rtl::OUString
Address(const uno::Any & RowAbsolute,const uno::Any & ColumnAbsolute,const uno::Any & ReferenceStyle,const uno::Any & External,const uno::Any & RelativeTo)2021cdf0e10cSrcweir ScVbaRange::Address(  const uno::Any& RowAbsolute, const uno::Any& ColumnAbsolute, const uno::Any& ReferenceStyle, const uno::Any& External, const uno::Any& RelativeTo ) throw (uno::RuntimeException)
2022cdf0e10cSrcweir {
2023cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
2024cdf0e10cSrcweir 	{
2025cdf0e10cSrcweir 		// Multi-Area Range
2026cdf0e10cSrcweir 		rtl::OUString sAddress;
2027cdf0e10cSrcweir 		uno::Reference< XCollection > xCollection( m_Areas, uno::UNO_QUERY_THROW );
2028cdf0e10cSrcweir                 uno::Any aExternalCopy = External;
2029cdf0e10cSrcweir 		for ( sal_Int32 index = 1; index <= xCollection->getCount(); ++index )
2030cdf0e10cSrcweir 		{
2031cdf0e10cSrcweir 			uno::Reference< excel::XRange > xRange( xCollection->Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW );
2032cdf0e10cSrcweir 			if ( index > 1 )
2033cdf0e10cSrcweir 			{
2034cdf0e10cSrcweir 				sAddress += rtl::OUString( ',' );
2035cdf0e10cSrcweir                                 // force external to be false
2036cdf0e10cSrcweir                                 // only first address should have the
2037cdf0e10cSrcweir                                 // document and sheet specifications
2038cdf0e10cSrcweir                                 aExternalCopy = uno::makeAny(sal_False);
2039cdf0e10cSrcweir 			}
2040cdf0e10cSrcweir 			sAddress += xRange->Address( RowAbsolute, ColumnAbsolute, ReferenceStyle, aExternalCopy, RelativeTo );
2041cdf0e10cSrcweir 		}
2042cdf0e10cSrcweir 		return sAddress;
2043cdf0e10cSrcweir 
2044cdf0e10cSrcweir 	}
2045cdf0e10cSrcweir 	ScAddress::Details dDetails( formula::FormulaGrammar::CONV_XL_A1, 0, 0 );
2046cdf0e10cSrcweir 	if ( ReferenceStyle.hasValue() )
2047cdf0e10cSrcweir 	{
2048cdf0e10cSrcweir 		sal_Int32 refStyle = excel::XlReferenceStyle::xlA1;
2049cdf0e10cSrcweir 		ReferenceStyle >>= refStyle;
2050cdf0e10cSrcweir 		if ( refStyle == excel::XlReferenceStyle::xlR1C1 )
2051cdf0e10cSrcweir 			dDetails = ScAddress::Details( formula::FormulaGrammar::CONV_XL_R1C1, 0, 0 );
2052cdf0e10cSrcweir 	}
2053cdf0e10cSrcweir 	sal_uInt16 nFlags = SCA_VALID;
2054cdf0e10cSrcweir 	ScDocShell* pDocShell =  getScDocShell();
2055cdf0e10cSrcweir 	ScDocument* pDoc =  pDocShell->GetDocument();
2056cdf0e10cSrcweir 
2057cdf0e10cSrcweir 	RangeHelper thisRange( mxRange );
2058cdf0e10cSrcweir 	table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
2059cdf0e10cSrcweir 	ScRange aRange( static_cast< SCCOL >( thisAddress.StartColumn ), static_cast< SCROW >( thisAddress.StartRow ), static_cast< SCTAB >( thisAddress.Sheet ), static_cast< SCCOL >( thisAddress.EndColumn ), static_cast< SCROW >( thisAddress.EndRow ), static_cast< SCTAB >( thisAddress.Sheet ) );
2060cdf0e10cSrcweir 	String sRange;
2061cdf0e10cSrcweir 	sal_uInt16 ROW_ABSOLUTE = ( SCA_ROW_ABSOLUTE | SCA_ROW2_ABSOLUTE );
2062cdf0e10cSrcweir 	sal_uInt16 COL_ABSOLUTE = ( SCA_COL_ABSOLUTE | SCA_COL2_ABSOLUTE );
2063cdf0e10cSrcweir 	// default
2064cdf0e10cSrcweir 	nFlags |= ( SCA_TAB_ABSOLUTE | SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB2_ABSOLUTE | SCA_COL2_ABSOLUTE | SCA_ROW2_ABSOLUTE );
2065cdf0e10cSrcweir 	if ( RowAbsolute.hasValue() )
2066cdf0e10cSrcweir 	{
2067cdf0e10cSrcweir 		sal_Bool bVal = sal_True;
2068cdf0e10cSrcweir 		RowAbsolute >>= bVal;
2069cdf0e10cSrcweir 		if ( !bVal )
2070cdf0e10cSrcweir 			nFlags &= ~ROW_ABSOLUTE;
2071cdf0e10cSrcweir 	}
2072cdf0e10cSrcweir 	if ( ColumnAbsolute.hasValue() )
2073cdf0e10cSrcweir 	{
2074cdf0e10cSrcweir 		sal_Bool bVal = sal_True;
2075cdf0e10cSrcweir 		ColumnAbsolute >>= bVal;
2076cdf0e10cSrcweir 		if ( !bVal )
2077cdf0e10cSrcweir 			nFlags &= ~COL_ABSOLUTE;
2078cdf0e10cSrcweir 	}
2079cdf0e10cSrcweir 	sal_Bool bLocal = sal_False;
2080cdf0e10cSrcweir 	if ( External.hasValue() )
2081cdf0e10cSrcweir 	{
2082cdf0e10cSrcweir 		External >>= bLocal;
2083cdf0e10cSrcweir 		if (  bLocal )
2084cdf0e10cSrcweir 			nFlags |= SCA_TAB_3D | SCA_FORCE_DOC;
2085cdf0e10cSrcweir 	}
2086cdf0e10cSrcweir 	if ( RelativeTo.hasValue() )
2087cdf0e10cSrcweir 	{
2088cdf0e10cSrcweir 		// #TODO should I throw an error if R1C1 is not set?
2089cdf0e10cSrcweir 
2090cdf0e10cSrcweir 		table::CellRangeAddress refAddress = getCellRangeAddressForVBARange( RelativeTo, pDocShell );
2091cdf0e10cSrcweir 		dDetails = ScAddress::Details( formula::FormulaGrammar::CONV_XL_R1C1, static_cast< SCROW >( refAddress.StartRow ), static_cast< SCCOL >( refAddress.StartColumn ) );
2092cdf0e10cSrcweir 	}
2093cdf0e10cSrcweir 	aRange.Format( sRange,  nFlags, pDoc, dDetails );
2094cdf0e10cSrcweir 	return sRange;
2095cdf0e10cSrcweir }
2096cdf0e10cSrcweir 
2097cdf0e10cSrcweir uno::Reference < excel::XFont >
Font()2098cdf0e10cSrcweir ScVbaRange::Font() throw ( script::BasicErrorException, uno::RuntimeException)
2099cdf0e10cSrcweir {
2100cdf0e10cSrcweir 	uno::Reference< beans::XPropertySet > xProps(mxRange, ::uno::UNO_QUERY );
2101cdf0e10cSrcweir 	ScDocument* pDoc = getScDocument();
2102cdf0e10cSrcweir 	if ( mxRange.is() )
2103cdf0e10cSrcweir 		xProps.set(mxRange, ::uno::UNO_QUERY );
2104cdf0e10cSrcweir 	else if ( mxRanges.is() )
2105cdf0e10cSrcweir 		xProps.set(mxRanges, ::uno::UNO_QUERY );
2106cdf0e10cSrcweir 	if ( !pDoc )
2107cdf0e10cSrcweir 		throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to access document from shell" ) ), uno::Reference< uno::XInterface >() );
2108cdf0e10cSrcweir 
2109cdf0e10cSrcweir 	ScVbaPalette aPalette( pDoc->GetDocumentShell() );
2110cdf0e10cSrcweir 	ScCellRangeObj* pRangeObj = NULL;
2111cdf0e10cSrcweir 	try
2112cdf0e10cSrcweir 	{
2113cdf0e10cSrcweir 		pRangeObj = getCellRangeObj();
2114cdf0e10cSrcweir 	}
2115cdf0e10cSrcweir 	catch( uno::Exception& )
2116cdf0e10cSrcweir 	{
2117cdf0e10cSrcweir 	}
2118cdf0e10cSrcweir 	return  new ScVbaFont( this, mxContext, aPalette, xProps, pRangeObj );
2119cdf0e10cSrcweir }
2120cdf0e10cSrcweir 
2121cdf0e10cSrcweir uno::Reference< excel::XRange >
Cells(const uno::Any & nRowIndex,const uno::Any & nColumnIndex)2122cdf0e10cSrcweir ScVbaRange::Cells( const uno::Any &nRowIndex, const uno::Any &nColumnIndex ) throw(uno::RuntimeException)
2123cdf0e10cSrcweir {
2124cdf0e10cSrcweir 	// #TODO code within the test below "if ( m_Areas.... " can be removed
2125cdf0e10cSrcweir 	// Test is performed only because m_xRange is NOT set to be
2126cdf0e10cSrcweir 	// the first range in m_Areas ( to force failure while
2127cdf0e10cSrcweir 	// the implementations for each method are being updated )
2128cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
2129cdf0e10cSrcweir 	{
2130cdf0e10cSrcweir 		uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_QUERY_THROW );
2131cdf0e10cSrcweir 		return xRange->Cells( nRowIndex, nColumnIndex );
2132cdf0e10cSrcweir 	}
2133cdf0e10cSrcweir 
2134cdf0e10cSrcweir     // Performance: Use a common helper method for ScVbaRange::Cells and ScVbaWorksheet::Cells,
2135cdf0e10cSrcweir     // instead of creating a new ScVbaRange object in often-called ScVbaWorksheet::Cells
2136cdf0e10cSrcweir     return CellsHelper( mxParent, mxContext, mxRange, nRowIndex, nColumnIndex );
2137cdf0e10cSrcweir }
2138cdf0e10cSrcweir 
2139cdf0e10cSrcweir // static
2140cdf0e10cSrcweir uno::Reference< excel::XRange >
CellsHelper(const uno::Reference<ov::XHelperInterface> & xParent,const uno::Reference<uno::XComponentContext> & xContext,const uno::Reference<css::table::XCellRange> & xRange,const uno::Any & nRowIndex,const uno::Any & nColumnIndex)2141cdf0e10cSrcweir ScVbaRange::CellsHelper( const uno::Reference< ov::XHelperInterface >& xParent,
2142cdf0e10cSrcweir                          const uno::Reference< uno::XComponentContext >& xContext,
2143cdf0e10cSrcweir                          const uno::Reference< css::table::XCellRange >& xRange,
2144cdf0e10cSrcweir                          const uno::Any &nRowIndex, const uno::Any &nColumnIndex ) throw(uno::RuntimeException)
2145cdf0e10cSrcweir {
2146cdf0e10cSrcweir 	sal_Int32 nRow = 0, nColumn = 0;
2147cdf0e10cSrcweir 
2148cdf0e10cSrcweir 	sal_Bool bIsIndex = nRowIndex.hasValue();
2149cdf0e10cSrcweir 	sal_Bool bIsColumnIndex = nColumnIndex.hasValue();
2150cdf0e10cSrcweir 
2151cdf0e10cSrcweir 	// Sometimes we might get a float or a double or whatever
2152cdf0e10cSrcweir 	// set in the Any, we should convert as appropriate
2153cdf0e10cSrcweir 	// #FIXME - perhaps worth turning this into some sort of
2154cdf0e10cSrcweir 	// convertion routine e.g. bSuccess = getValueFromAny( nRow, nRowIndex, getCppuType((sal_Int32*)0) )
2155cdf0e10cSrcweir 	if ( nRowIndex.hasValue() && !( nRowIndex >>= nRow ) )
2156cdf0e10cSrcweir 	{
2157cdf0e10cSrcweir 		uno::Reference< script::XTypeConverter > xConverter = getTypeConverter( xContext );
2158cdf0e10cSrcweir 		uno::Any aConverted;
2159cdf0e10cSrcweir 		try
2160cdf0e10cSrcweir 		{
2161cdf0e10cSrcweir 			aConverted = xConverter->convertTo( nRowIndex, getCppuType((sal_Int32*)0) );
2162cdf0e10cSrcweir 			bIsIndex = ( aConverted >>= nRow );
2163cdf0e10cSrcweir 		}
2164cdf0e10cSrcweir 		catch( uno::Exception& ) {} // silence any errors
2165cdf0e10cSrcweir 	}
2166cdf0e10cSrcweir 	if ( bIsColumnIndex && !( nColumnIndex >>= nColumn ) )
2167cdf0e10cSrcweir 	{
2168cdf0e10cSrcweir 		uno::Reference< script::XTypeConverter > xConverter = getTypeConverter( xContext );
2169cdf0e10cSrcweir 		uno::Any aConverted;
2170cdf0e10cSrcweir 		try
2171cdf0e10cSrcweir 		{
2172cdf0e10cSrcweir 			aConverted = xConverter->convertTo( nColumnIndex, getCppuType((sal_Int32*)0) );
2173cdf0e10cSrcweir 			bIsColumnIndex = ( aConverted >>= nColumn );
2174cdf0e10cSrcweir 		}
2175cdf0e10cSrcweir 		catch( uno::Exception& ) {} // silence any errors
2176cdf0e10cSrcweir 	}
2177cdf0e10cSrcweir 
2178cdf0e10cSrcweir 	RangeHelper thisRange( xRange );
2179cdf0e10cSrcweir 	table::CellRangeAddress thisRangeAddress =  thisRange.getCellRangeAddressable()->getRangeAddress();
2180cdf0e10cSrcweir 	uno::Reference< table::XCellRange > xSheetRange = thisRange.getCellRangeFromSheet();
2181cdf0e10cSrcweir 	if( !bIsIndex && !bIsColumnIndex ) // .Cells
2182cdf0e10cSrcweir 		// #FIXE needs proper parent ( Worksheet )
2183cdf0e10cSrcweir 		return uno::Reference< excel::XRange >( new ScVbaRange( xParent, xContext, xRange ) );
2184cdf0e10cSrcweir 
2185cdf0e10cSrcweir 	sal_Int32 nIndex = --nRow;
2186cdf0e10cSrcweir 	if( bIsIndex && !bIsColumnIndex ) // .Cells(n)
2187cdf0e10cSrcweir 	{
2188cdf0e10cSrcweir 		uno::Reference< table::XColumnRowRange > xColumnRowRange(xRange, ::uno::UNO_QUERY_THROW);
2189cdf0e10cSrcweir 		sal_Int32 nColCount = xColumnRowRange->getColumns()->getCount();
2190cdf0e10cSrcweir 
2191cdf0e10cSrcweir 		if ( !nIndex || nIndex < 0 )
2192cdf0e10cSrcweir 			nRow = 0;
2193cdf0e10cSrcweir 		else
2194cdf0e10cSrcweir 			nRow = nIndex / nColCount;
2195cdf0e10cSrcweir 		nColumn = nIndex % nColCount;
2196cdf0e10cSrcweir 	}
2197cdf0e10cSrcweir 	else
2198cdf0e10cSrcweir 		--nColumn;
2199cdf0e10cSrcweir 	nRow = nRow + thisRangeAddress.StartRow;
2200cdf0e10cSrcweir 	nColumn =  nColumn + thisRangeAddress.StartColumn;
2201cdf0e10cSrcweir 	return new ScVbaRange( xParent, xContext, xSheetRange->getCellRangeByPosition( nColumn, nRow,                                        nColumn, nRow ) );
2202cdf0e10cSrcweir }
2203cdf0e10cSrcweir 
2204cdf0e10cSrcweir void
Select()2205cdf0e10cSrcweir ScVbaRange::Select() throw (uno::RuntimeException)
2206cdf0e10cSrcweir {
2207cdf0e10cSrcweir 	ScCellRangesBase* pUnoRangesBase = getCellRangesBase();
2208cdf0e10cSrcweir 	if ( !pUnoRangesBase )
2209cdf0e10cSrcweir 		throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to access underlying uno range object" ) ), uno::Reference< uno::XInterface >()  );
2210cdf0e10cSrcweir 	ScDocShell* pShell = pUnoRangesBase->GetDocShell();
2211cdf0e10cSrcweir 	if ( pShell )
2212cdf0e10cSrcweir 	{
2213cdf0e10cSrcweir 		uno::Reference< frame::XModel > xModel( pShell->GetModel(), uno::UNO_QUERY_THROW );
2214cdf0e10cSrcweir 		uno::Reference< view::XSelectionSupplier > xSelection( xModel->getCurrentController(), uno::UNO_QUERY_THROW );
2215cdf0e10cSrcweir 		if ( mxRanges.is() )
2216cdf0e10cSrcweir 			xSelection->select( uno::Any( lclExpandToMerged( mxRanges, true ) ) );
2217cdf0e10cSrcweir 		else
2218cdf0e10cSrcweir 			xSelection->select( uno::Any( lclExpandToMerged( mxRange, true ) ) );
2219cdf0e10cSrcweir 		// set focus on document e.g.
2220cdf0e10cSrcweir 		// ThisComponent.CurrentController.Frame.getContainerWindow.SetFocus
2221cdf0e10cSrcweir 		try
2222cdf0e10cSrcweir 		{
2223cdf0e10cSrcweir 			uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_QUERY_THROW );
2224cdf0e10cSrcweir 			uno::Reference< frame::XFrame > xFrame( xController->getFrame(), uno::UNO_QUERY_THROW );
2225cdf0e10cSrcweir 			uno::Reference< awt::XWindow > xWin( xFrame->getContainerWindow(), uno::UNO_QUERY_THROW );
2226cdf0e10cSrcweir 			xWin->setFocus();
2227cdf0e10cSrcweir 		}
2228cdf0e10cSrcweir 		catch( uno::Exception& )
2229cdf0e10cSrcweir 		{
2230cdf0e10cSrcweir 		}
2231cdf0e10cSrcweir 	}
2232cdf0e10cSrcweir }
2233cdf0e10cSrcweir 
cellInRange(const table::CellRangeAddress & rAddr,const sal_Int32 & nCol,const sal_Int32 & nRow)2234cdf0e10cSrcweir bool cellInRange( const table::CellRangeAddress& rAddr, const sal_Int32& nCol, const sal_Int32& nRow )
2235cdf0e10cSrcweir {
2236cdf0e10cSrcweir 	if ( nCol >= rAddr.StartColumn && nCol <= rAddr.EndColumn &&
2237cdf0e10cSrcweir 		nRow >= rAddr.StartRow && nRow <= rAddr.EndRow )
2238cdf0e10cSrcweir 		return true;
2239cdf0e10cSrcweir 	return false;
2240cdf0e10cSrcweir }
2241cdf0e10cSrcweir 
setCursor(const SCCOL & nCol,const SCROW & nRow,const uno::Reference<frame::XModel> & xModel,bool bInSel=true)2242cdf0e10cSrcweir void setCursor(  const SCCOL& nCol, const SCROW& nRow, const uno::Reference< frame::XModel >& xModel,  bool bInSel = true )
2243cdf0e10cSrcweir {
2244cdf0e10cSrcweir 	ScTabViewShell* pShell = excel::getBestViewShell( xModel );
2245cdf0e10cSrcweir 	if ( pShell )
2246cdf0e10cSrcweir 	{
2247cdf0e10cSrcweir 		if ( bInSel )
2248cdf0e10cSrcweir 			pShell->SetCursor( nCol, nRow );
2249cdf0e10cSrcweir 		else
2250cdf0e10cSrcweir 			pShell->MoveCursorAbs( nCol, nRow, SC_FOLLOW_NONE, sal_False, sal_False, sal_True, sal_False );
2251cdf0e10cSrcweir 	}
2252cdf0e10cSrcweir }
2253cdf0e10cSrcweir 
2254cdf0e10cSrcweir void
Activate()2255cdf0e10cSrcweir ScVbaRange::Activate() throw (uno::RuntimeException)
2256cdf0e10cSrcweir {
2257cdf0e10cSrcweir 	// get first cell of current range
2258cdf0e10cSrcweir 	uno::Reference< table::XCellRange > xCellRange;
2259cdf0e10cSrcweir 	if ( mxRanges.is() )
2260cdf0e10cSrcweir 	{
2261cdf0e10cSrcweir 		uno::Reference< container::XIndexAccess > xIndex( mxRanges, uno::UNO_QUERY_THROW  );
2262cdf0e10cSrcweir 		xCellRange.set( xIndex->getByIndex( 0 ), uno::UNO_QUERY_THROW );
2263cdf0e10cSrcweir 	}
2264cdf0e10cSrcweir 	else
2265cdf0e10cSrcweir 		xCellRange.set( mxRange, uno::UNO_QUERY_THROW );
2266cdf0e10cSrcweir 
2267cdf0e10cSrcweir 	RangeHelper thisRange( xCellRange );
2268cdf0e10cSrcweir 	uno::Reference< sheet::XCellRangeAddressable > xThisRangeAddress = thisRange.getCellRangeAddressable();
2269cdf0e10cSrcweir 	table::CellRangeAddress thisRangeAddress = xThisRangeAddress->getRangeAddress();
2270cdf0e10cSrcweir         uno::Reference< frame::XModel > xModel;
2271cdf0e10cSrcweir         ScDocShell* pShell = getScDocShell();
2272cdf0e10cSrcweir 
2273cdf0e10cSrcweir         if ( pShell )
2274cdf0e10cSrcweir             xModel = pShell->GetModel();
2275cdf0e10cSrcweir 
2276cdf0e10cSrcweir         if ( !xModel.is() )
2277cdf0e10cSrcweir             throw uno::RuntimeException();
2278cdf0e10cSrcweir 
2279cdf0e10cSrcweir 	// get current selection
2280cdf0e10cSrcweir 	uno::Reference< sheet::XCellRangeAddressable > xRange( xModel->getCurrentSelection(), ::uno::UNO_QUERY);
2281cdf0e10cSrcweir 
2282cdf0e10cSrcweir 	uno::Reference< sheet::XSheetCellRanges > xRanges( xModel->getCurrentSelection(), ::uno::UNO_QUERY);
2283cdf0e10cSrcweir 
2284cdf0e10cSrcweir 	if ( xRanges.is() )
2285cdf0e10cSrcweir 	{
2286cdf0e10cSrcweir 		uno::Sequence< table::CellRangeAddress > nAddrs = xRanges->getRangeAddresses();
2287cdf0e10cSrcweir 		for ( sal_Int32 index = 0; index < nAddrs.getLength(); ++index )
2288cdf0e10cSrcweir 		{
2289cdf0e10cSrcweir 			if ( cellInRange( nAddrs[index], thisRangeAddress.StartColumn, thisRangeAddress.StartRow ) )
2290cdf0e10cSrcweir 			{
2291cdf0e10cSrcweir 				setCursor( static_cast< SCCOL >( thisRangeAddress.StartColumn ), static_cast< SCROW >( thisRangeAddress.StartRow ), xModel );
2292cdf0e10cSrcweir 				return;
2293cdf0e10cSrcweir 			}
2294cdf0e10cSrcweir 
2295cdf0e10cSrcweir 		}
2296cdf0e10cSrcweir 	}
2297cdf0e10cSrcweir 
2298cdf0e10cSrcweir 	if ( xRange.is() && cellInRange( xRange->getRangeAddress(), thisRangeAddress.StartColumn, thisRangeAddress.StartRow ) )
2299cdf0e10cSrcweir 		setCursor( static_cast< SCCOL >( thisRangeAddress.StartColumn ), static_cast< SCROW >( thisRangeAddress.StartRow ), xModel );
2300cdf0e10cSrcweir 	else
2301cdf0e10cSrcweir 	{
2302cdf0e10cSrcweir 		// if this range is multi cell select the range other
2303cdf0e10cSrcweir 		// wise just position the cell at this single range position
2304cdf0e10cSrcweir 		if ( isSingleCellRange() )
2305cdf0e10cSrcweir 			// This top-leftmost cell of this Range is not in the current
2306cdf0e10cSrcweir 			// selection so just select this range
2307cdf0e10cSrcweir 			setCursor( static_cast< SCCOL >( thisRangeAddress.StartColumn ), static_cast< SCROW >( thisRangeAddress.StartRow ), xModel, false  );
2308cdf0e10cSrcweir 		else
2309cdf0e10cSrcweir 			Select();
2310cdf0e10cSrcweir 	}
2311cdf0e10cSrcweir 
2312cdf0e10cSrcweir }
2313cdf0e10cSrcweir 
2314cdf0e10cSrcweir uno::Reference< excel::XRange >
Rows(const uno::Any & aIndex)2315cdf0e10cSrcweir ScVbaRange::Rows(const uno::Any& aIndex ) throw (uno::RuntimeException)
2316cdf0e10cSrcweir {
2317cdf0e10cSrcweir 	SCROW nStartRow = 0;
2318cdf0e10cSrcweir 	SCROW nEndRow = 0;
2319cdf0e10cSrcweir 
2320cdf0e10cSrcweir 	sal_Int32 nValue = 0;
2321cdf0e10cSrcweir 	rtl::OUString sAddress;
2322cdf0e10cSrcweir 
2323cdf0e10cSrcweir 	if ( aIndex.hasValue() )
2324cdf0e10cSrcweir 	{
2325cdf0e10cSrcweir 		ScCellRangesBase* pUnoRangesBase = getCellRangesBase();
2326cdf0e10cSrcweir 		ScRangeList aCellRanges = pUnoRangesBase->GetRangeList();
2327cdf0e10cSrcweir 
2328cdf0e10cSrcweir 		ScRange aRange = *aCellRanges.First();
2329cdf0e10cSrcweir 		if( aIndex >>= nValue )
2330cdf0e10cSrcweir 		{
2331cdf0e10cSrcweir 			aRange.aStart.SetRow( aRange.aStart.Row() + --nValue );
2332cdf0e10cSrcweir 			aRange.aEnd.SetRow( aRange.aStart.Row() );
2333cdf0e10cSrcweir 		}
2334cdf0e10cSrcweir 
2335cdf0e10cSrcweir 		else if ( aIndex >>= sAddress )
2336cdf0e10cSrcweir 		{
2337cdf0e10cSrcweir 			ScAddress::Details dDetails( formula::FormulaGrammar::CONV_XL_A1, 0, 0 );
2338cdf0e10cSrcweir 			ScRange tmpRange;
2339cdf0e10cSrcweir 			tmpRange.ParseRows( sAddress, getDocumentFromRange( mxRange ), dDetails );
2340cdf0e10cSrcweir 			nStartRow = tmpRange.aStart.Row();
2341cdf0e10cSrcweir 			nEndRow = tmpRange.aEnd.Row();
2342cdf0e10cSrcweir 
2343cdf0e10cSrcweir 			aRange.aStart.SetRow( aRange.aStart.Row() + nStartRow );
2344cdf0e10cSrcweir 			aRange.aEnd.SetRow( aRange.aStart.Row() + ( nEndRow  - nStartRow ));
2345cdf0e10cSrcweir 		}
2346cdf0e10cSrcweir 		else
2347cdf0e10cSrcweir 			throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Illegal param" ) ), uno::Reference< uno::XInterface >() );
2348cdf0e10cSrcweir 
2349cdf0e10cSrcweir 		if ( aRange.aStart.Row() < 0 || aRange.aEnd.Row() < 0 )
2350cdf0e10cSrcweir 			throw uno::RuntimeException( rtl::OUString::createFromAscii("Internal failure, illegal param"), uno::Reference< uno::XInterface >() );
2351cdf0e10cSrcweir 		// return a normal range ( even for multi-selection
2352cdf0e10cSrcweir 		uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pUnoRangesBase->GetDocShell(), aRange ) );
2353cdf0e10cSrcweir 		return new ScVbaRange( mxParent, mxContext, xRange, true  );
2354cdf0e10cSrcweir 	}
2355cdf0e10cSrcweir 	// Rows() - no params
2356cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
2357cdf0e10cSrcweir 		return new ScVbaRange(  mxParent, mxContext, mxRanges, true );
2358cdf0e10cSrcweir 	return new ScVbaRange(  mxParent, mxContext, mxRange, true );
2359cdf0e10cSrcweir }
2360cdf0e10cSrcweir 
2361cdf0e10cSrcweir uno::Reference< excel::XRange >
Columns(const uno::Any & aIndex)2362cdf0e10cSrcweir ScVbaRange::Columns(const uno::Any& aIndex ) throw (uno::RuntimeException)
2363cdf0e10cSrcweir {
2364cdf0e10cSrcweir 	SCCOL nStartCol = 0;
2365cdf0e10cSrcweir 	SCCOL nEndCol = 0;
2366cdf0e10cSrcweir 
2367cdf0e10cSrcweir 	sal_Int32 nValue = 0;
2368cdf0e10cSrcweir 	rtl::OUString sAddress;
2369cdf0e10cSrcweir 
2370cdf0e10cSrcweir 	ScCellRangesBase* pUnoRangesBase = getCellRangesBase();
2371cdf0e10cSrcweir 	ScRangeList aCellRanges = pUnoRangesBase->GetRangeList();
2372cdf0e10cSrcweir 
2373cdf0e10cSrcweir 	ScRange aRange = *aCellRanges.First();
2374cdf0e10cSrcweir 	if ( aIndex.hasValue() )
2375cdf0e10cSrcweir 	{
2376cdf0e10cSrcweir 		if ( aIndex >>= nValue )
2377cdf0e10cSrcweir 		{
2378cdf0e10cSrcweir 			aRange.aStart.SetCol( aRange.aStart.Col() + static_cast< SCCOL > ( --nValue ) );
2379cdf0e10cSrcweir 			aRange.aEnd.SetCol( aRange.aStart.Col() );
2380cdf0e10cSrcweir 		}
2381cdf0e10cSrcweir 
2382cdf0e10cSrcweir 		else if ( aIndex >>= sAddress )
2383cdf0e10cSrcweir 		{
2384cdf0e10cSrcweir 			ScAddress::Details dDetails( formula::FormulaGrammar::CONV_XL_A1, 0, 0 );
2385cdf0e10cSrcweir 			ScRange tmpRange;
2386cdf0e10cSrcweir 			tmpRange.ParseCols( sAddress, getDocumentFromRange( mxRange ), dDetails );
2387cdf0e10cSrcweir 			nStartCol = tmpRange.aStart.Col();
2388cdf0e10cSrcweir 			nEndCol = tmpRange.aEnd.Col();
2389cdf0e10cSrcweir 
2390cdf0e10cSrcweir 			aRange.aStart.SetCol( aRange.aStart.Col() + nStartCol );
2391cdf0e10cSrcweir 			aRange.aEnd.SetCol( aRange.aStart.Col() + ( nEndCol  - nStartCol ));
2392cdf0e10cSrcweir 		}
2393cdf0e10cSrcweir 		else
2394cdf0e10cSrcweir 			throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Illegal param" ) ), uno::Reference< uno::XInterface >() );
2395cdf0e10cSrcweir 
2396cdf0e10cSrcweir 		if ( aRange.aStart.Col() < 0 || aRange.aEnd.Col() < 0 )
2397cdf0e10cSrcweir 			throw uno::RuntimeException( rtl::OUString::createFromAscii("Internal failure, illegal param"), uno::Reference< uno::XInterface >() );
2398cdf0e10cSrcweir 	}
2399cdf0e10cSrcweir 	// Columns() - no params
2400cdf0e10cSrcweir 	uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pUnoRangesBase->GetDocShell(), aRange ) );
2401cdf0e10cSrcweir 	return new ScVbaRange( mxParent, mxContext, xRange, false, true  );
2402cdf0e10cSrcweir }
2403cdf0e10cSrcweir 
2404cdf0e10cSrcweir void
setMergeCells(const uno::Any & aIsMerged)2405cdf0e10cSrcweir ScVbaRange::setMergeCells( const uno::Any& aIsMerged ) throw (script::BasicErrorException, uno::RuntimeException)
2406cdf0e10cSrcweir {
2407cdf0e10cSrcweir     bool bMerge = extractBoolFromAny( aIsMerged );
2408cdf0e10cSrcweir 
2409cdf0e10cSrcweir     if( mxRanges.is() )
2410cdf0e10cSrcweir     {
2411cdf0e10cSrcweir         sal_Int32 nCount = mxRanges->getCount();
2412cdf0e10cSrcweir 
2413cdf0e10cSrcweir         // VBA does nothing (no error) if the own ranges overlap somehow
2414cdf0e10cSrcweir         ::std::vector< table::CellRangeAddress > aList;
2415cdf0e10cSrcweir         for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
2416cdf0e10cSrcweir         {
2417cdf0e10cSrcweir             uno::Reference< sheet::XCellRangeAddressable > xRangeAddr( mxRanges->getByIndex( nIndex ), uno::UNO_QUERY_THROW );
2418cdf0e10cSrcweir             table::CellRangeAddress aAddress = xRangeAddr->getRangeAddress();
2419cdf0e10cSrcweir             for( ::std::vector< table::CellRangeAddress >::const_iterator aIt = aList.begin(), aEnd = aList.end(); aIt != aEnd; ++aIt )
2420cdf0e10cSrcweir                 if( ScUnoConversion::Intersects( *aIt, aAddress ) )
2421cdf0e10cSrcweir                     return;
2422cdf0e10cSrcweir             aList.push_back( aAddress );
2423cdf0e10cSrcweir         }
2424cdf0e10cSrcweir 
2425cdf0e10cSrcweir         // (un)merge every range after it has been extended to intersecting merged ranges from sheet
2426cdf0e10cSrcweir         for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
2427cdf0e10cSrcweir         {
2428cdf0e10cSrcweir             uno::Reference< table::XCellRange > xRange( mxRanges->getByIndex( nIndex ), uno::UNO_QUERY_THROW );
2429cdf0e10cSrcweir             lclExpandAndMerge( xRange, bMerge );
2430cdf0e10cSrcweir         }
2431cdf0e10cSrcweir         return;
2432cdf0e10cSrcweir     }
2433cdf0e10cSrcweir 
2434cdf0e10cSrcweir     // otherwise, merge single range
2435cdf0e10cSrcweir     lclExpandAndMerge( mxRange, bMerge );
2436cdf0e10cSrcweir }
2437cdf0e10cSrcweir 
2438cdf0e10cSrcweir uno::Any
getMergeCells()2439cdf0e10cSrcweir ScVbaRange::getMergeCells() throw (script::BasicErrorException, uno::RuntimeException)
2440cdf0e10cSrcweir {
2441cdf0e10cSrcweir     if( mxRanges.is() )
2442cdf0e10cSrcweir     {
2443cdf0e10cSrcweir         sal_Int32 nCount = mxRanges->getCount();
2444cdf0e10cSrcweir         for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
2445cdf0e10cSrcweir         {
2446cdf0e10cSrcweir             uno::Reference< table::XCellRange > xRange( mxRanges->getByIndex( nIndex ), uno::UNO_QUERY_THROW );
2447cdf0e10cSrcweir             util::TriState eMerged = lclGetMergedState( xRange );
2448cdf0e10cSrcweir             /*  Excel always returns NULL, if one range of the range list is
2449cdf0e10cSrcweir                 partly or completely merged. Even if all ranges are completely
2450cdf0e10cSrcweir                 merged, the return value is still NULL. */
2451cdf0e10cSrcweir             if( eMerged != util::TriState_NO )
2452cdf0e10cSrcweir                 return aNULL();
2453cdf0e10cSrcweir         }
2454cdf0e10cSrcweir         // no range is merged anyhow, return false
2455cdf0e10cSrcweir         return uno::Any( false );
2456cdf0e10cSrcweir     }
2457cdf0e10cSrcweir 
2458cdf0e10cSrcweir     // otherwise, check single range
2459cdf0e10cSrcweir     switch( lclGetMergedState( mxRange ) )
2460cdf0e10cSrcweir     {
2461cdf0e10cSrcweir         case util::TriState_YES:    return uno::Any( true );
2462cdf0e10cSrcweir         case util::TriState_NO:     return uno::Any( false );
2463cdf0e10cSrcweir         default:                    return aNULL();
2464cdf0e10cSrcweir     }
2465cdf0e10cSrcweir }
2466cdf0e10cSrcweir 
2467cdf0e10cSrcweir void
Copy(const::uno::Any & Destination)2468cdf0e10cSrcweir ScVbaRange::Copy(const ::uno::Any& Destination) throw (uno::RuntimeException)
2469cdf0e10cSrcweir {
2470cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
2471cdf0e10cSrcweir 		throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("That command cannot be used on multiple selections" ) ), uno::Reference< uno::XInterface >() );
2472cdf0e10cSrcweir 	if ( Destination.hasValue() )
2473cdf0e10cSrcweir 	{
2474cdf0e10cSrcweir 		uno::Reference< excel::XRange > xRange( Destination, uno::UNO_QUERY_THROW );
2475cdf0e10cSrcweir 		uno::Any aRange = xRange->getCellRange();
2476cdf0e10cSrcweir 		uno::Reference< table::XCellRange > xCellRange;
2477cdf0e10cSrcweir 		aRange >>= xCellRange;
2478cdf0e10cSrcweir 		uno::Reference< sheet::XSheetCellRange > xSheetCellRange(xCellRange, ::uno::UNO_QUERY_THROW);
2479cdf0e10cSrcweir 		uno::Reference< sheet::XSpreadsheet > xSheet = xSheetCellRange->getSpreadsheet();
2480cdf0e10cSrcweir 		uno::Reference< table::XCellRange > xDest( xSheet, uno::UNO_QUERY_THROW );
2481cdf0e10cSrcweir 		uno::Reference< sheet::XCellRangeMovement > xMover( xSheet, uno::UNO_QUERY_THROW);
2482cdf0e10cSrcweir 		uno::Reference< sheet::XCellAddressable > xDestination( xDest->getCellByPosition(
2483cdf0e10cSrcweir 												xRange->getColumn()-1,xRange->getRow()-1), uno::UNO_QUERY_THROW );
2484cdf0e10cSrcweir 		uno::Reference< sheet::XCellRangeAddressable > xSource( mxRange, uno::UNO_QUERY);
2485cdf0e10cSrcweir 		xMover->copyRange( xDestination->getCellAddress(), xSource->getRangeAddress() );
2486cdf0e10cSrcweir 	}
2487cdf0e10cSrcweir 	else
2488cdf0e10cSrcweir 	{
2489cdf0e10cSrcweir 		uno::Reference< frame::XModel > xModel = getModelFromRange( mxRange );
2490cdf0e10cSrcweir 		Select();
2491cdf0e10cSrcweir 		excel::implnCopy( xModel );
2492cdf0e10cSrcweir 	}
2493cdf0e10cSrcweir }
2494cdf0e10cSrcweir 
2495cdf0e10cSrcweir void
Cut(const::uno::Any & Destination)2496cdf0e10cSrcweir ScVbaRange::Cut(const ::uno::Any& Destination) throw (uno::RuntimeException)
2497cdf0e10cSrcweir {
2498cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
2499cdf0e10cSrcweir 		throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("That command cannot be used on multiple selections" ) ), uno::Reference< uno::XInterface >() );
2500cdf0e10cSrcweir 	if (Destination.hasValue())
2501cdf0e10cSrcweir 	{
2502cdf0e10cSrcweir 		uno::Reference< excel::XRange > xRange( Destination, uno::UNO_QUERY_THROW );
2503cdf0e10cSrcweir 		uno::Reference< table::XCellRange > xCellRange( xRange->getCellRange(), uno::UNO_QUERY_THROW );
2504cdf0e10cSrcweir 		uno::Reference< sheet::XSheetCellRange > xSheetCellRange(xCellRange, ::uno::UNO_QUERY_THROW );
2505cdf0e10cSrcweir 		uno::Reference< sheet::XSpreadsheet > xSheet = xSheetCellRange->getSpreadsheet();
2506cdf0e10cSrcweir 		uno::Reference< table::XCellRange > xDest( xSheet, uno::UNO_QUERY_THROW );
2507cdf0e10cSrcweir 		uno::Reference< sheet::XCellRangeMovement > xMover( xSheet, uno::UNO_QUERY_THROW);
2508cdf0e10cSrcweir 		uno::Reference< sheet::XCellAddressable > xDestination( xDest->getCellByPosition(
2509cdf0e10cSrcweir 												xRange->getColumn()-1,xRange->getRow()-1), uno::UNO_QUERY);
2510cdf0e10cSrcweir 		uno::Reference< sheet::XCellRangeAddressable > xSource( mxRange, uno::UNO_QUERY);
2511cdf0e10cSrcweir 		xMover->moveRange( xDestination->getCellAddress(), xSource->getRangeAddress() );
2512cdf0e10cSrcweir 	}
2513cdf0e10cSrcweir 	{
2514cdf0e10cSrcweir 		uno::Reference< frame::XModel > xModel = getModelFromRange( mxRange );
2515cdf0e10cSrcweir 		Select();
2516cdf0e10cSrcweir 		excel::implnCut( xModel );
2517cdf0e10cSrcweir 	}
2518cdf0e10cSrcweir }
2519cdf0e10cSrcweir 
2520cdf0e10cSrcweir void
setNumberFormat(const uno::Any & aFormat)2521cdf0e10cSrcweir ScVbaRange::setNumberFormat( const uno::Any& aFormat ) throw ( script::BasicErrorException, uno::RuntimeException)
2522cdf0e10cSrcweir {
2523cdf0e10cSrcweir 	rtl::OUString sFormat;
2524cdf0e10cSrcweir 	aFormat >>= sFormat;
2525cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
2526cdf0e10cSrcweir 	{
2527cdf0e10cSrcweir 		sal_Int32 nItems = m_Areas->getCount();
2528cdf0e10cSrcweir 		for ( sal_Int32 index=1; index <= nItems; ++index )
2529cdf0e10cSrcweir 		{
2530cdf0e10cSrcweir 			uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW );
2531cdf0e10cSrcweir 			xRange->setNumberFormat( aFormat );
2532cdf0e10cSrcweir 		}
2533cdf0e10cSrcweir 		return;
2534cdf0e10cSrcweir 	}
2535cdf0e10cSrcweir 	NumFormatHelper numFormat( mxRange );
2536cdf0e10cSrcweir 	numFormat.setNumberFormat( sFormat );
2537cdf0e10cSrcweir }
2538cdf0e10cSrcweir 
2539cdf0e10cSrcweir uno::Any
getNumberFormat()2540cdf0e10cSrcweir ScVbaRange::getNumberFormat() throw ( script::BasicErrorException, uno::RuntimeException)
2541cdf0e10cSrcweir {
2542cdf0e10cSrcweir 
2543cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
2544cdf0e10cSrcweir 	{
2545cdf0e10cSrcweir 		sal_Int32 nItems = m_Areas->getCount();
2546cdf0e10cSrcweir 		uno::Any aResult = aNULL();
2547cdf0e10cSrcweir 		for ( sal_Int32 index=1; index <= nItems; ++index )
2548cdf0e10cSrcweir 		{
2549cdf0e10cSrcweir 			uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW );
2550cdf0e10cSrcweir 			// if the numberformat of one area is different to another
2551cdf0e10cSrcweir 			// return null
2552cdf0e10cSrcweir 			if ( index > 1 )
2553cdf0e10cSrcweir 				if ( aResult != xRange->getNumberFormat() )
2554cdf0e10cSrcweir 					return aNULL();
2555cdf0e10cSrcweir 			aResult = xRange->getNumberFormat();
2556cdf0e10cSrcweir 			if ( aNULL() == aResult )
2557cdf0e10cSrcweir 				return aNULL();
2558cdf0e10cSrcweir 		}
2559cdf0e10cSrcweir 		return aResult;
2560cdf0e10cSrcweir 	}
2561cdf0e10cSrcweir 	NumFormatHelper numFormat( mxRange );
2562cdf0e10cSrcweir 	rtl::OUString sFormat = numFormat.getNumberFormatString();
2563cdf0e10cSrcweir 	if ( sFormat.getLength() > 0 )
2564cdf0e10cSrcweir 		return uno::makeAny( sFormat );
2565cdf0e10cSrcweir 	return aNULL();
2566cdf0e10cSrcweir }
2567cdf0e10cSrcweir 
2568cdf0e10cSrcweir uno::Reference< excel::XRange >
Resize(const uno::Any & RowSize,const uno::Any & ColumnSize)2569cdf0e10cSrcweir ScVbaRange::Resize( const uno::Any &RowSize, const uno::Any &ColumnSize ) throw (uno::RuntimeException)
2570cdf0e10cSrcweir {
2571cdf0e10cSrcweir 	long nRowSize = 0, nColumnSize = 0;
2572cdf0e10cSrcweir 	sal_Bool bIsRowChanged = ( RowSize >>= nRowSize ), bIsColumnChanged = ( ColumnSize >>= nColumnSize );
2573cdf0e10cSrcweir 	uno::Reference< table::XColumnRowRange > xColumnRowRange(mxRange, ::uno::UNO_QUERY_THROW);
2574cdf0e10cSrcweir 	uno::Reference< sheet::XSheetCellRange > xSheetRange(mxRange, ::uno::UNO_QUERY_THROW);
2575cdf0e10cSrcweir 	uno::Reference< sheet::XSheetCellCursor > xCursor( xSheetRange->getSpreadsheet()->createCursorByRange(xSheetRange), ::uno::UNO_QUERY_THROW );
2576cdf0e10cSrcweir 
2577cdf0e10cSrcweir 	if( !bIsRowChanged )
2578cdf0e10cSrcweir 		nRowSize = xColumnRowRange->getRows()->getCount();
2579cdf0e10cSrcweir 	if( !bIsColumnChanged )
2580cdf0e10cSrcweir 		nColumnSize = xColumnRowRange->getColumns()->getCount();
2581cdf0e10cSrcweir 
2582cdf0e10cSrcweir 	xCursor->collapseToSize( nColumnSize, nRowSize );
2583cdf0e10cSrcweir 	uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable(xCursor, ::uno::UNO_QUERY_THROW );
2584cdf0e10cSrcweir 	uno::Reference< table::XCellRange > xRange( xSheetRange->getSpreadsheet(), ::uno::UNO_QUERY_THROW );
2585cdf0e10cSrcweir 	return new ScVbaRange( mxParent, mxContext,xRange->getCellRangeByPosition(
2586cdf0e10cSrcweir 										xCellRangeAddressable->getRangeAddress().StartColumn,
2587cdf0e10cSrcweir 										xCellRangeAddressable->getRangeAddress().StartRow,
2588cdf0e10cSrcweir 										xCellRangeAddressable->getRangeAddress().EndColumn,
2589cdf0e10cSrcweir 										xCellRangeAddressable->getRangeAddress().EndRow ) );
2590cdf0e10cSrcweir }
2591cdf0e10cSrcweir 
2592cdf0e10cSrcweir void
setWrapText(const uno::Any & aIsWrapped)2593cdf0e10cSrcweir ScVbaRange::setWrapText( const uno::Any& aIsWrapped ) throw (script::BasicErrorException, uno::RuntimeException)
2594cdf0e10cSrcweir {
2595cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
2596cdf0e10cSrcweir 	{
2597cdf0e10cSrcweir 		sal_Int32 nItems = m_Areas->getCount();
2598cdf0e10cSrcweir 		uno::Any aResult;
2599cdf0e10cSrcweir 		for ( sal_Int32 index=1; index <= nItems; ++index )
2600cdf0e10cSrcweir 		{
2601cdf0e10cSrcweir 			uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW );
2602cdf0e10cSrcweir 			xRange->setWrapText( aIsWrapped );
2603cdf0e10cSrcweir 		}
2604cdf0e10cSrcweir 		return;
2605cdf0e10cSrcweir 	}
2606cdf0e10cSrcweir 
2607cdf0e10cSrcweir 	uno::Reference< beans::XPropertySet > xProps(mxRange, ::uno::UNO_QUERY_THROW );
2608cdf0e10cSrcweir 	bool bIsWrapped = extractBoolFromAny( aIsWrapped );
2609cdf0e10cSrcweir 	xProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsTextWrapped" ) ), uno::Any( bIsWrapped ) );
2610cdf0e10cSrcweir }
2611cdf0e10cSrcweir 
2612cdf0e10cSrcweir uno::Any
getWrapText()2613cdf0e10cSrcweir ScVbaRange::getWrapText() throw (script::BasicErrorException, uno::RuntimeException)
2614cdf0e10cSrcweir {
2615cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
2616cdf0e10cSrcweir 	{
2617cdf0e10cSrcweir 		sal_Int32 nItems = m_Areas->getCount();
2618cdf0e10cSrcweir 		uno::Any aResult;
2619cdf0e10cSrcweir 		for ( sal_Int32 index=1; index <= nItems; ++index )
2620cdf0e10cSrcweir 		{
2621cdf0e10cSrcweir 				uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW );
2622cdf0e10cSrcweir 				if ( index > 1 )
2623cdf0e10cSrcweir 				if ( aResult != xRange->getWrapText() )
2624cdf0e10cSrcweir 					return aNULL();
2625cdf0e10cSrcweir 			aResult = xRange->getWrapText();
2626cdf0e10cSrcweir 		}
2627cdf0e10cSrcweir 		return aResult;
2628cdf0e10cSrcweir 	}
2629cdf0e10cSrcweir 
2630cdf0e10cSrcweir 	SfxItemSet* pDataSet = getCurrentDataSet();
2631cdf0e10cSrcweir 
2632cdf0e10cSrcweir 	SfxItemState eState = pDataSet->GetItemState( ATTR_LINEBREAK, sal_True, NULL);
2633cdf0e10cSrcweir 	if ( eState == SFX_ITEM_DONTCARE )
2634cdf0e10cSrcweir 		return aNULL();
2635cdf0e10cSrcweir 
2636cdf0e10cSrcweir 	uno::Reference< beans::XPropertySet > xProps(mxRange, ::uno::UNO_QUERY_THROW );
2637cdf0e10cSrcweir 	uno::Any aValue = xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsTextWrapped" ) ) );
2638cdf0e10cSrcweir 	return aValue;
2639cdf0e10cSrcweir }
2640cdf0e10cSrcweir 
Interior()2641cdf0e10cSrcweir uno::Reference< excel::XInterior > ScVbaRange::Interior( ) throw ( script::BasicErrorException, uno::RuntimeException)
2642cdf0e10cSrcweir {
2643cdf0e10cSrcweir 	uno::Reference< beans::XPropertySet > xProps( mxRange, uno::UNO_QUERY_THROW );
2644cdf0e10cSrcweir         return new ScVbaInterior ( this, mxContext, xProps, getScDocument() );
2645cdf0e10cSrcweir }
2646cdf0e10cSrcweir uno::Reference< excel::XRange >
Range(const uno::Any & Cell1,const uno::Any & Cell2)2647cdf0e10cSrcweir ScVbaRange::Range( const uno::Any &Cell1, const uno::Any &Cell2 ) throw (uno::RuntimeException)
2648cdf0e10cSrcweir {
2649cdf0e10cSrcweir     return Range( Cell1, Cell2, false );
2650cdf0e10cSrcweir }
2651cdf0e10cSrcweir uno::Reference< excel::XRange >
Range(const uno::Any & Cell1,const uno::Any & Cell2,bool bForceUseInpuRangeTab)2652cdf0e10cSrcweir ScVbaRange::Range( const uno::Any &Cell1, const uno::Any &Cell2, bool bForceUseInpuRangeTab ) throw (uno::RuntimeException)
2653cdf0e10cSrcweir 
2654cdf0e10cSrcweir {
2655cdf0e10cSrcweir 	uno::Reference< table::XCellRange > xCellRange = mxRange;
2656cdf0e10cSrcweir 
2657cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
2658cdf0e10cSrcweir 	{
2659cdf0e10cSrcweir 		uno::Reference< container::XIndexAccess > xIndex( mxRanges, uno::UNO_QUERY_THROW );
2660cdf0e10cSrcweir 		xCellRange.set( xIndex->getByIndex( 0 ), uno::UNO_QUERY_THROW );
2661cdf0e10cSrcweir 	}
2662cdf0e10cSrcweir 	else
2663cdf0e10cSrcweir 		xCellRange.set( mxRange );
2664cdf0e10cSrcweir 
2665cdf0e10cSrcweir 	RangeHelper thisRange( xCellRange );
2666cdf0e10cSrcweir 	uno::Reference< table::XCellRange > xRanges = thisRange.getCellRangeFromSheet();
2667cdf0e10cSrcweir 	uno::Reference< sheet::XCellRangeAddressable > xAddressable( xRanges, uno::UNO_QUERY_THROW );
2668cdf0e10cSrcweir 
2669cdf0e10cSrcweir 	uno::Reference< table::XCellRange > xReferrer =
2670cdf0e10cSrcweir 		xRanges->getCellRangeByPosition( getColumn()-1, getRow()-1,
2671cdf0e10cSrcweir 				xAddressable->getRangeAddress().EndColumn,
2672cdf0e10cSrcweir 				xAddressable->getRangeAddress().EndRow );
2673cdf0e10cSrcweir 	// xAddressable now for this range
2674cdf0e10cSrcweir 	xAddressable.set( xReferrer, uno::UNO_QUERY_THROW );
2675cdf0e10cSrcweir 
2676cdf0e10cSrcweir 	if( !Cell1.hasValue() )
2677cdf0e10cSrcweir 		throw uno::RuntimeException(
2678cdf0e10cSrcweir 			rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " Invalid Argument " ) ),
2679cdf0e10cSrcweir 			uno::Reference< XInterface >() );
2680cdf0e10cSrcweir 
2681cdf0e10cSrcweir 	table::CellRangeAddress resultAddress;
2682cdf0e10cSrcweir 	table::CellRangeAddress parentRangeAddress = xAddressable->getRangeAddress();
2683cdf0e10cSrcweir 
2684cdf0e10cSrcweir 	ScRange aRange;
2685cdf0e10cSrcweir 	// Cell1 defined only
2686cdf0e10cSrcweir 	if ( !Cell2.hasValue() )
2687cdf0e10cSrcweir 	{
2688cdf0e10cSrcweir 		rtl::OUString sName;
2689cdf0e10cSrcweir 		Cell1 >>= sName;
2690cdf0e10cSrcweir 		RangeHelper referRange( xReferrer );
2691cdf0e10cSrcweir 		table::CellRangeAddress referAddress = referRange.getCellRangeAddressable()->getRangeAddress();
2692cdf0e10cSrcweir 		return getRangeForName( mxContext, sName, getScDocShell(), referAddress );
2693cdf0e10cSrcweir 
2694cdf0e10cSrcweir 	}
2695cdf0e10cSrcweir 	else
2696cdf0e10cSrcweir 	{
2697cdf0e10cSrcweir 		table::CellRangeAddress  cell1, cell2;
2698cdf0e10cSrcweir 		cell1 = getCellRangeAddressForVBARange( Cell1, getScDocShell() );
2699cdf0e10cSrcweir 		// Cell1 & Cell2 defined
2700cdf0e10cSrcweir 		// Excel seems to combine the range as the range defined by
2701cdf0e10cSrcweir 		// the combination of Cell1 & Cell2
2702cdf0e10cSrcweir 
2703cdf0e10cSrcweir 		cell2 = getCellRangeAddressForVBARange( Cell2, getScDocShell() );
2704cdf0e10cSrcweir 
2705cdf0e10cSrcweir 		resultAddress.StartColumn = ( cell1.StartColumn <  cell2.StartColumn ) ? cell1.StartColumn : cell2.StartColumn;
2706cdf0e10cSrcweir 		resultAddress.StartRow = ( cell1.StartRow <  cell2.StartRow ) ? cell1.StartRow : cell2.StartRow;
2707cdf0e10cSrcweir 		resultAddress.EndColumn = ( cell1.EndColumn >  cell2.EndColumn ) ? cell1.EndColumn : cell2.EndColumn;
2708cdf0e10cSrcweir 		resultAddress.EndRow = ( cell1.EndRow >  cell2.EndRow ) ? cell1.EndRow : cell2.EndRow;
2709cdf0e10cSrcweir 		if ( bForceUseInpuRangeTab )
2710cdf0e10cSrcweir 		{
2711cdf0e10cSrcweir 			// this is a call from Application.Range( x,y )
2712cdf0e10cSrcweir 			// its possiblefor x or y to specify a different sheet from
2713cdf0e10cSrcweir 			// the current or active on ( but they must be the same )
2714cdf0e10cSrcweir 			if ( cell1.Sheet != cell2.Sheet )
2715cdf0e10cSrcweir 				throw uno::RuntimeException();
2716cdf0e10cSrcweir 			parentRangeAddress.Sheet = cell1.Sheet;
2717cdf0e10cSrcweir 		}
2718cdf0e10cSrcweir 		else
2719cdf0e10cSrcweir 		{
2720cdf0e10cSrcweir 			// this is not a call from Application.Range( x,y )
2721cdf0e10cSrcweir 			// if a different sheet from this range is specified it's
2722cdf0e10cSrcweir 			// an error
2723cdf0e10cSrcweir 			if ( parentRangeAddress.Sheet != cell1.Sheet
2724cdf0e10cSrcweir 			|| parentRangeAddress.Sheet != cell2.Sheet
2725cdf0e10cSrcweir 			)
2726cdf0e10cSrcweir 				throw uno::RuntimeException();
2727cdf0e10cSrcweir 
2728cdf0e10cSrcweir 		}
2729cdf0e10cSrcweir 		ScUnoConversion::FillScRange( aRange, resultAddress );
2730cdf0e10cSrcweir 	}
2731cdf0e10cSrcweir 	ScRange parentAddress;
2732cdf0e10cSrcweir 	ScUnoConversion::FillScRange( parentAddress, parentRangeAddress);
2733cdf0e10cSrcweir 	if ( aRange.aStart.Col() >= 0 && aRange.aStart.Row() >= 0 && aRange.aEnd.Col() >= 0 && aRange.aEnd.Row() >= 0 )
2734cdf0e10cSrcweir 	{
2735cdf0e10cSrcweir 		sal_Int32 nStartX = parentAddress.aStart.Col() + aRange.aStart.Col();
2736cdf0e10cSrcweir 		sal_Int32 nStartY = parentAddress.aStart.Row() + aRange.aStart.Row();
2737cdf0e10cSrcweir 		sal_Int32 nEndX = parentAddress.aStart.Col() + aRange.aEnd.Col();
2738cdf0e10cSrcweir 		sal_Int32 nEndY = parentAddress.aStart.Row() + aRange.aEnd.Row();
2739cdf0e10cSrcweir 
2740cdf0e10cSrcweir 		if ( nStartX <= nEndX && nEndX <= parentAddress.aEnd.Col() &&
2741cdf0e10cSrcweir 			 nStartY <= nEndY && nEndY <= parentAddress.aEnd.Row() )
2742cdf0e10cSrcweir 		{
2743cdf0e10cSrcweir 			ScRange aNew( (SCCOL)nStartX, (SCROW)nStartY, parentAddress.aStart.Tab(),
2744cdf0e10cSrcweir 						  (SCCOL)nEndX, (SCROW)nEndY, parentAddress.aEnd.Tab() );
2745cdf0e10cSrcweir 			xCellRange = new ScCellRangeObj( getScDocShell(), aNew );
2746cdf0e10cSrcweir 		}
2747cdf0e10cSrcweir 	}
2748cdf0e10cSrcweir 
2749cdf0e10cSrcweir 	return new ScVbaRange( mxParent, mxContext, xCellRange );
2750cdf0e10cSrcweir 
2751cdf0e10cSrcweir }
2752cdf0e10cSrcweir 
2753cdf0e10cSrcweir // Allow access to underlying openoffice uno api ( useful for debugging
2754cdf0e10cSrcweir // with openoffice basic )
getCellRange()2755cdf0e10cSrcweir uno::Any SAL_CALL ScVbaRange::getCellRange(  ) throw (uno::RuntimeException)
2756cdf0e10cSrcweir {
2757cdf0e10cSrcweir 	uno::Any aAny;
2758cdf0e10cSrcweir 	if ( mxRanges.is() )
2759cdf0e10cSrcweir 		aAny <<= mxRanges;
2760cdf0e10cSrcweir 	else if ( mxRange.is() )
2761cdf0e10cSrcweir 		aAny <<= mxRange;
2762cdf0e10cSrcweir 	return aAny;
2763cdf0e10cSrcweir }
2764cdf0e10cSrcweir 
getCellRange(const uno::Reference<excel::XRange> & rxRange)2765cdf0e10cSrcweir /*static*/ uno::Any ScVbaRange::getCellRange( const uno::Reference< excel::XRange >& rxRange ) throw (uno::RuntimeException)
2766cdf0e10cSrcweir {
2767cdf0e10cSrcweir     if( ScVbaRange* pVbaRange = getImplementation( rxRange ) )
2768cdf0e10cSrcweir         return pVbaRange->getCellRange();
2769cdf0e10cSrcweir     throw uno::RuntimeException();
2770cdf0e10cSrcweir }
2771cdf0e10cSrcweir 
2772cdf0e10cSrcweir static sal_uInt16
getPasteFlags(sal_Int32 Paste)2773cdf0e10cSrcweir getPasteFlags (sal_Int32 Paste)
2774cdf0e10cSrcweir {
2775cdf0e10cSrcweir 	sal_uInt16 nFlags = IDF_NONE;
2776cdf0e10cSrcweir 	switch (Paste) {
2777cdf0e10cSrcweir         case excel::XlPasteType::xlPasteComments:
2778cdf0e10cSrcweir 		nFlags = IDF_NOTE;break;
2779cdf0e10cSrcweir         case excel::XlPasteType::xlPasteFormats:
2780cdf0e10cSrcweir 		nFlags = IDF_ATTRIB;break;
2781cdf0e10cSrcweir         case excel::XlPasteType::xlPasteFormulas:
2782cdf0e10cSrcweir 		nFlags = IDF_FORMULA;break;
2783cdf0e10cSrcweir         case excel::XlPasteType::xlPasteFormulasAndNumberFormats :
2784cdf0e10cSrcweir         case excel::XlPasteType::xlPasteValues:
2785cdf0e10cSrcweir #ifdef VBA_OOBUILD_HACK
2786cdf0e10cSrcweir 		nFlags = ( IDF_VALUE | IDF_DATETIME | IDF_STRING | IDF_SPECIAL_BOOLEAN ); break;
2787cdf0e10cSrcweir #else
2788cdf0e10cSrcweir 		nFlags = ( IDF_VALUE | IDF_DATETIME | IDF_STRING ); break;
2789cdf0e10cSrcweir #endif
2790cdf0e10cSrcweir         case excel::XlPasteType::xlPasteValuesAndNumberFormats:
2791cdf0e10cSrcweir 		nFlags = IDF_VALUE | IDF_ATTRIB; break;
2792cdf0e10cSrcweir         case excel::XlPasteType::xlPasteColumnWidths:
2793cdf0e10cSrcweir         case excel::XlPasteType::xlPasteValidation:
2794cdf0e10cSrcweir 		nFlags = IDF_NONE;break;
2795cdf0e10cSrcweir 	case excel::XlPasteType::xlPasteAll:
2796cdf0e10cSrcweir         case excel::XlPasteType::xlPasteAllExceptBorders:
2797cdf0e10cSrcweir 	default:
2798cdf0e10cSrcweir 		nFlags = IDF_ALL;break;
2799cdf0e10cSrcweir 	};
2800cdf0e10cSrcweir return nFlags;
2801cdf0e10cSrcweir }
2802cdf0e10cSrcweir 
2803cdf0e10cSrcweir static sal_uInt16
getPasteFormulaBits(sal_Int32 Operation)2804cdf0e10cSrcweir getPasteFormulaBits( sal_Int32 Operation)
2805cdf0e10cSrcweir {
2806cdf0e10cSrcweir 	sal_uInt16 nFormulaBits = PASTE_NOFUNC ;
2807cdf0e10cSrcweir 	switch (Operation)
2808cdf0e10cSrcweir 	{
2809cdf0e10cSrcweir 	case excel::XlPasteSpecialOperation::xlPasteSpecialOperationAdd:
2810cdf0e10cSrcweir 		nFormulaBits = PASTE_ADD;break;
2811cdf0e10cSrcweir 	case excel::XlPasteSpecialOperation::xlPasteSpecialOperationSubtract:
2812cdf0e10cSrcweir 		nFormulaBits = PASTE_SUB;break;
2813cdf0e10cSrcweir 	case excel::XlPasteSpecialOperation::xlPasteSpecialOperationMultiply:
2814cdf0e10cSrcweir 		nFormulaBits = PASTE_MUL;break;
2815cdf0e10cSrcweir 	case excel::XlPasteSpecialOperation::xlPasteSpecialOperationDivide:
2816cdf0e10cSrcweir 		nFormulaBits = PASTE_DIV;break;
2817cdf0e10cSrcweir 
2818cdf0e10cSrcweir 	case excel::XlPasteSpecialOperation::xlPasteSpecialOperationNone:
2819cdf0e10cSrcweir 	default:
2820cdf0e10cSrcweir 		nFormulaBits = PASTE_NOFUNC; break;
2821cdf0e10cSrcweir 	};
2822cdf0e10cSrcweir 
2823cdf0e10cSrcweir return nFormulaBits;
2824cdf0e10cSrcweir }
2825cdf0e10cSrcweir void SAL_CALL
PasteSpecial(const uno::Any & Paste,const uno::Any & Operation,const uno::Any & SkipBlanks,const uno::Any & Transpose)2826cdf0e10cSrcweir ScVbaRange::PasteSpecial( const uno::Any& Paste, const uno::Any& Operation, const uno::Any& SkipBlanks, const uno::Any& Transpose ) throw (::com::sun::star::uno::RuntimeException)
2827cdf0e10cSrcweir {
2828cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
2829cdf0e10cSrcweir 		throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("That command cannot be used on multiple selections" ) ), uno::Reference< uno::XInterface >() );
2830cdf0e10cSrcweir         ScDocShell* pShell = getScDocShell();
2831cdf0e10cSrcweir 
2832cdf0e10cSrcweir         uno::Reference< frame::XModel > xModel( ( pShell ? pShell->GetModel() : NULL ), uno::UNO_QUERY_THROW );
2833cdf0e10cSrcweir 	uno::Reference< view::XSelectionSupplier > xSelection( xModel->getCurrentController(), uno::UNO_QUERY_THROW );
2834cdf0e10cSrcweir 	// save old selection
2835cdf0e10cSrcweir 	uno::Reference< uno::XInterface > xSel( xModel->getCurrentSelection() );
2836cdf0e10cSrcweir 	// select this range
2837cdf0e10cSrcweir 	xSelection->select( uno::makeAny( mxRange ) );
2838cdf0e10cSrcweir 	// set up defaults
2839cdf0e10cSrcweir 	sal_Int32 nPaste = excel::XlPasteType::xlPasteAll;
2840cdf0e10cSrcweir 	sal_Int32 nOperation = excel::XlPasteSpecialOperation::xlPasteSpecialOperationNone;
2841cdf0e10cSrcweir 	sal_Bool bTranspose = sal_False;
2842cdf0e10cSrcweir 	sal_Bool bSkipBlanks = sal_False;
2843cdf0e10cSrcweir 
2844cdf0e10cSrcweir 	if ( Paste.hasValue() )
2845cdf0e10cSrcweir 		Paste >>= nPaste;
2846cdf0e10cSrcweir 	if ( Operation.hasValue() )
2847cdf0e10cSrcweir 		Operation >>= nOperation;
2848cdf0e10cSrcweir 	if ( SkipBlanks.hasValue() )
2849cdf0e10cSrcweir 		SkipBlanks >>= bSkipBlanks;
2850cdf0e10cSrcweir 	if ( Transpose.hasValue() )
2851cdf0e10cSrcweir 		Transpose >>= bTranspose;
2852cdf0e10cSrcweir 
2853cdf0e10cSrcweir 	sal_uInt16 nFlags = getPasteFlags(nPaste);
2854cdf0e10cSrcweir 	sal_uInt16 nFormulaBits = getPasteFormulaBits(nOperation);
2855cdf0e10cSrcweir 	excel::implnPasteSpecial(pShell->GetModel(), nFlags,nFormulaBits,bSkipBlanks,bTranspose);
2856cdf0e10cSrcweir 	// restore selection
2857cdf0e10cSrcweir 	xSelection->select( uno::makeAny( xSel ) );
2858cdf0e10cSrcweir }
2859cdf0e10cSrcweir 
2860cdf0e10cSrcweir uno::Reference< excel::XRange >
getEntireColumnOrRow(bool bColumn)2861cdf0e10cSrcweir ScVbaRange::getEntireColumnOrRow( bool bColumn ) throw (uno::RuntimeException)
2862cdf0e10cSrcweir {
2863cdf0e10cSrcweir 	ScCellRangesBase* pUnoRangesBase = getCellRangesBase();
2864cdf0e10cSrcweir 	// copy the range list
2865cdf0e10cSrcweir 	ScRangeList aCellRanges = pUnoRangesBase->GetRangeList();
2866cdf0e10cSrcweir 
2867cdf0e10cSrcweir 	for ( ScRange* pRange = aCellRanges.First() ; pRange; pRange = aCellRanges.Next() )
2868cdf0e10cSrcweir 	{
2869cdf0e10cSrcweir 		if ( bColumn )
2870cdf0e10cSrcweir 		{
2871cdf0e10cSrcweir 			pRange->aStart.SetRow( 0 );
2872cdf0e10cSrcweir 			pRange->aEnd.SetRow( MAXROW );
2873cdf0e10cSrcweir 		}
2874cdf0e10cSrcweir 		else
2875cdf0e10cSrcweir 		{
2876cdf0e10cSrcweir 			pRange->aStart.SetCol( 0 );
2877cdf0e10cSrcweir 			pRange->aEnd.SetCol( MAXCOL );
2878cdf0e10cSrcweir 		}
2879cdf0e10cSrcweir 	}
2880cdf0e10cSrcweir 	if ( aCellRanges.Count() > 1 ) // Multi-Area
2881cdf0e10cSrcweir 	{
2882cdf0e10cSrcweir 		uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pUnoRangesBase->GetDocShell(), aCellRanges ) );
2883cdf0e10cSrcweir 
2884cdf0e10cSrcweir 		return new ScVbaRange( mxParent, mxContext, xRanges, !bColumn, bColumn );
2885cdf0e10cSrcweir 	}
2886cdf0e10cSrcweir 	uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pUnoRangesBase->GetDocShell(), *aCellRanges.First() ) );
2887cdf0e10cSrcweir 	return new ScVbaRange( mxParent, mxContext, xRange, !bColumn, bColumn  );
2888cdf0e10cSrcweir }
2889cdf0e10cSrcweir 
2890cdf0e10cSrcweir uno::Reference< excel::XRange > SAL_CALL
getEntireRow()2891cdf0e10cSrcweir ScVbaRange::getEntireRow() throw (uno::RuntimeException)
2892cdf0e10cSrcweir {
2893cdf0e10cSrcweir 	return getEntireColumnOrRow(false);
2894cdf0e10cSrcweir }
2895cdf0e10cSrcweir 
2896cdf0e10cSrcweir uno::Reference< excel::XRange > SAL_CALL
getEntireColumn()2897cdf0e10cSrcweir ScVbaRange::getEntireColumn() throw (uno::RuntimeException)
2898cdf0e10cSrcweir {
2899cdf0e10cSrcweir 	return getEntireColumnOrRow();
2900cdf0e10cSrcweir }
2901cdf0e10cSrcweir 
2902cdf0e10cSrcweir uno::Reference< excel::XComment > SAL_CALL
AddComment(const uno::Any & Text)2903cdf0e10cSrcweir ScVbaRange::AddComment( const uno::Any& Text ) throw (uno::RuntimeException)
2904cdf0e10cSrcweir {
2905cdf0e10cSrcweir     // if there is already a comment in the top-left cell then throw
2906cdf0e10cSrcweir     if( getComment().is() )
2907cdf0e10cSrcweir         throw uno::RuntimeException();
2908cdf0e10cSrcweir 
2909cdf0e10cSrcweir 	// workaround: Excel allows to create empty comment, Calc does not
2910cdf0e10cSrcweir 	::rtl::OUString aNoteText;
2911cdf0e10cSrcweir 	if( Text.hasValue() && !(Text >>= aNoteText) )
2912cdf0e10cSrcweir         throw uno::RuntimeException();
2913cdf0e10cSrcweir     if( aNoteText.getLength() == 0 )
2914cdf0e10cSrcweir         aNoteText = ::rtl::OUString( sal_Unicode( ' ' ) );
2915cdf0e10cSrcweir 
2916cdf0e10cSrcweir     // try to create a new annotation
2917cdf0e10cSrcweir     table::CellRangeAddress aRangePos = lclGetRangeAddress( mxRange );
2918cdf0e10cSrcweir     table::CellAddress aNotePos( aRangePos.Sheet, aRangePos.StartColumn, aRangePos.StartRow );
2919cdf0e10cSrcweir     uno::Reference< sheet::XSheetCellRange > xCellRange( mxRange, uno::UNO_QUERY_THROW );
2920cdf0e10cSrcweir     uno::Reference< sheet::XSheetAnnotationsSupplier > xAnnosSupp( xCellRange->getSpreadsheet(), uno::UNO_QUERY_THROW );
2921cdf0e10cSrcweir     uno::Reference< sheet::XSheetAnnotations > xAnnos( xAnnosSupp->getAnnotations(), uno::UNO_SET_THROW );
2922cdf0e10cSrcweir     xAnnos->insertNew( aNotePos, aNoteText );
2923cdf0e10cSrcweir 	return new ScVbaComment( this, mxContext, getUnoModel(), mxRange );
2924cdf0e10cSrcweir }
2925cdf0e10cSrcweir 
2926cdf0e10cSrcweir uno::Reference< excel::XComment > SAL_CALL
getComment()2927cdf0e10cSrcweir ScVbaRange::getComment() throw (uno::RuntimeException)
2928cdf0e10cSrcweir {
2929cdf0e10cSrcweir 	// intentional behavior to return a null object if no
2930cdf0e10cSrcweir 	// comment defined
2931cdf0e10cSrcweir 	uno::Reference< excel::XComment > xComment( new ScVbaComment( this, mxContext, getUnoModel(), mxRange ) );
2932cdf0e10cSrcweir 	if ( !xComment->Text( uno::Any(), uno::Any(), uno::Any() ).getLength() )
2933cdf0e10cSrcweir 		return NULL;
2934cdf0e10cSrcweir 	return xComment;
2935cdf0e10cSrcweir 
2936cdf0e10cSrcweir }
2937cdf0e10cSrcweir 
2938cdf0e10cSrcweir uno::Reference< beans::XPropertySet >
getRowOrColumnProps(const uno::Reference<table::XCellRange> & xCellRange,bool bRows)2939cdf0e10cSrcweir getRowOrColumnProps( const uno::Reference< table::XCellRange >& xCellRange, bool bRows ) throw ( uno::RuntimeException )
2940cdf0e10cSrcweir {
2941cdf0e10cSrcweir 	uno::Reference< table::XColumnRowRange > xColRow( xCellRange, uno::UNO_QUERY_THROW );
2942cdf0e10cSrcweir 	uno::Reference< beans::XPropertySet > xProps;
2943cdf0e10cSrcweir 	if ( bRows )
2944cdf0e10cSrcweir 		xProps.set( xColRow->getRows(), uno::UNO_QUERY_THROW );
2945cdf0e10cSrcweir 	else
2946cdf0e10cSrcweir 		xProps.set( xColRow->getColumns(), uno::UNO_QUERY_THROW );
2947cdf0e10cSrcweir 	return xProps;
2948cdf0e10cSrcweir }
2949cdf0e10cSrcweir 
2950cdf0e10cSrcweir uno::Any SAL_CALL
getHidden()2951cdf0e10cSrcweir ScVbaRange::getHidden() throw (uno::RuntimeException)
2952cdf0e10cSrcweir {
2953cdf0e10cSrcweir 	// if multi-area result is the result of the
2954cdf0e10cSrcweir 	// first area
2955cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
2956cdf0e10cSrcweir 	{
2957cdf0e10cSrcweir 		uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(sal_Int32(1)), uno::Any() ), uno::UNO_QUERY_THROW );
2958cdf0e10cSrcweir 		return xRange->getHidden();
2959cdf0e10cSrcweir 	}
2960cdf0e10cSrcweir 	bool bIsVisible = false;
2961cdf0e10cSrcweir 	try
2962cdf0e10cSrcweir 	{
2963cdf0e10cSrcweir 		uno::Reference< beans::XPropertySet > xProps = getRowOrColumnProps( mxRange, mbIsRows );
2964cdf0e10cSrcweir 		if ( !( xProps->getPropertyValue( ISVISIBLE ) >>= bIsVisible ) )
2965cdf0e10cSrcweir 			throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to get IsVisible property")), uno::Reference< uno::XInterface >() );
2966cdf0e10cSrcweir 	}
2967cdf0e10cSrcweir 	catch( uno::Exception& e )
2968cdf0e10cSrcweir 	{
2969cdf0e10cSrcweir 		throw uno::RuntimeException( e.Message, uno::Reference< uno::XInterface >() );
2970cdf0e10cSrcweir 	}
2971cdf0e10cSrcweir 	return uno::makeAny( !bIsVisible );
2972cdf0e10cSrcweir }
2973cdf0e10cSrcweir 
2974cdf0e10cSrcweir void SAL_CALL
setHidden(const uno::Any & _hidden)2975cdf0e10cSrcweir ScVbaRange::setHidden( const uno::Any& _hidden ) throw (uno::RuntimeException)
2976cdf0e10cSrcweir {
2977cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
2978cdf0e10cSrcweir 	{
2979cdf0e10cSrcweir 		sal_Int32 nItems = m_Areas->getCount();
2980cdf0e10cSrcweir 		for ( sal_Int32 index=1; index <= nItems; ++index )
2981cdf0e10cSrcweir 		{
2982cdf0e10cSrcweir 			uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW );
2983cdf0e10cSrcweir 			xRange->setHidden( _hidden );
2984cdf0e10cSrcweir 		}
2985cdf0e10cSrcweir 		return;
2986cdf0e10cSrcweir 	}
2987cdf0e10cSrcweir 
2988cdf0e10cSrcweir     bool bHidden = extractBoolFromAny( _hidden );
2989cdf0e10cSrcweir 	try
2990cdf0e10cSrcweir 	{
2991cdf0e10cSrcweir 		uno::Reference< beans::XPropertySet > xProps = getRowOrColumnProps( mxRange, mbIsRows );
2992cdf0e10cSrcweir 		xProps->setPropertyValue( ISVISIBLE, uno::Any( !bHidden ) );
2993cdf0e10cSrcweir 	}
2994cdf0e10cSrcweir 	catch( uno::Exception& e )
2995cdf0e10cSrcweir 	{
2996cdf0e10cSrcweir 		throw uno::RuntimeException( e.Message, uno::Reference< uno::XInterface >() );
2997cdf0e10cSrcweir 	}
2998cdf0e10cSrcweir }
2999cdf0e10cSrcweir 
3000cdf0e10cSrcweir ::sal_Bool SAL_CALL
Replace(const::rtl::OUString & What,const::rtl::OUString & Replacement,const uno::Any & LookAt,const uno::Any & SearchOrder,const uno::Any & MatchCase,const uno::Any & MatchByte,const uno::Any & SearchFormat,const uno::Any & ReplaceFormat)3001cdf0e10cSrcweir ScVbaRange::Replace( const ::rtl::OUString& What, const ::rtl::OUString& Replacement, const uno::Any& LookAt, const uno::Any& SearchOrder, const uno::Any& MatchCase, const uno::Any& MatchByte, const uno::Any& SearchFormat, const uno::Any& ReplaceFormat  ) throw (uno::RuntimeException)
3002cdf0e10cSrcweir {
3003cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
3004cdf0e10cSrcweir 	{
3005cdf0e10cSrcweir 		for ( sal_Int32 index = 1; index <= m_Areas->getCount(); ++index )
3006cdf0e10cSrcweir 		{
3007cdf0e10cSrcweir 			uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW );
3008cdf0e10cSrcweir 			xRange->Replace( What, Replacement,  LookAt, SearchOrder, MatchCase, MatchByte, SearchFormat, ReplaceFormat );
3009cdf0e10cSrcweir 		}
3010cdf0e10cSrcweir 		return sal_True; // seems to return true always ( or at least I haven't found the trick of
3011cdf0e10cSrcweir 	}
3012cdf0e10cSrcweir 
3013cdf0e10cSrcweir 	// sanity check required params
3014cdf0e10cSrcweir 	if ( !What.getLength() /*|| !Replacement.getLength()*/ )
3015cdf0e10cSrcweir 		throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Range::Replace, missing params" )) , uno::Reference< uno::XInterface >() );
3016cdf0e10cSrcweir 	rtl::OUString sWhat = VBAToRegexp( What);
3017cdf0e10cSrcweir 	// #TODO #FIXME SearchFormat & ReplacesFormat are not processed
3018cdf0e10cSrcweir 	// What do we do about MatchByte.. we don't seem to support that
3019cdf0e10cSrcweir 	const SvxSearchItem& globalSearchOptions = ScGlobal::GetSearchItem();
3020cdf0e10cSrcweir 	SvxSearchItem newOptions( globalSearchOptions );
3021cdf0e10cSrcweir 
3022cdf0e10cSrcweir 	sal_Int16 nLook =  globalSearchOptions.GetWordOnly() ?  excel::XlLookAt::xlPart : excel::XlLookAt::xlWhole;
3023cdf0e10cSrcweir 	sal_Int16 nSearchOrder = globalSearchOptions.GetRowDirection() ? excel::XlSearchOrder::xlByRows : excel::XlSearchOrder::xlByColumns;
3024cdf0e10cSrcweir 
3025cdf0e10cSrcweir 	sal_Bool bMatchCase = sal_False;
3026cdf0e10cSrcweir 	uno::Reference< util::XReplaceable > xReplace( mxRange, uno::UNO_QUERY );
3027cdf0e10cSrcweir 	if ( xReplace.is() )
3028cdf0e10cSrcweir 	{
3029cdf0e10cSrcweir 		uno::Reference< util::XReplaceDescriptor > xDescriptor =
3030cdf0e10cSrcweir 			xReplace->createReplaceDescriptor();
3031cdf0e10cSrcweir 
3032cdf0e10cSrcweir 		xDescriptor->setSearchString( sWhat);
3033cdf0e10cSrcweir 		xDescriptor->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SRCHREGEXP ) ), uno::makeAny( sal_True ) );
3034cdf0e10cSrcweir 		xDescriptor->setReplaceString( Replacement);
3035cdf0e10cSrcweir 		if ( LookAt.hasValue() )
3036cdf0e10cSrcweir 		{
3037cdf0e10cSrcweir 			// sets SearchWords ( true is Cell match )
3038cdf0e10cSrcweir 			nLook =  ::comphelper::getINT16( LookAt );
3039cdf0e10cSrcweir 			sal_Bool bSearchWords = sal_False;
3040cdf0e10cSrcweir 			if ( nLook == excel::XlLookAt::xlPart )
3041cdf0e10cSrcweir 				bSearchWords = sal_False;
3042cdf0e10cSrcweir 			else if ( nLook == excel::XlLookAt::xlWhole )
3043cdf0e10cSrcweir 				bSearchWords = sal_True;
3044cdf0e10cSrcweir 			else
3045cdf0e10cSrcweir 				throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Range::Replace, illegal value for LookAt" )) , uno::Reference< uno::XInterface >() );
3046cdf0e10cSrcweir 			// set global search props ( affects the find dialog
3047cdf0e10cSrcweir 			// and of course the defaults for this method
3048cdf0e10cSrcweir 			newOptions.SetWordOnly( bSearchWords );
3049cdf0e10cSrcweir 			xDescriptor->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SRCHWORDS ) ), uno::makeAny( bSearchWords ) );
3050cdf0e10cSrcweir 		}
3051cdf0e10cSrcweir 		// sets SearchByRow ( true for Rows )
3052cdf0e10cSrcweir 		if ( SearchOrder.hasValue() )
3053cdf0e10cSrcweir 		{
3054cdf0e10cSrcweir 			nSearchOrder =  ::comphelper::getINT16( SearchOrder );
3055cdf0e10cSrcweir 			sal_Bool bSearchByRow = sal_False;
3056cdf0e10cSrcweir 			if ( nSearchOrder == excel::XlSearchOrder::xlByColumns )
3057cdf0e10cSrcweir 				bSearchByRow = sal_False;
3058cdf0e10cSrcweir 			else if ( nSearchOrder == excel::XlSearchOrder::xlByRows )
3059cdf0e10cSrcweir 				bSearchByRow = sal_True;
3060cdf0e10cSrcweir 			else
3061cdf0e10cSrcweir 				throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Range::Replace, illegal value for SearchOrder" )) , uno::Reference< uno::XInterface >() );
3062cdf0e10cSrcweir 
3063cdf0e10cSrcweir 			newOptions.SetRowDirection( bSearchByRow );
3064cdf0e10cSrcweir 			xDescriptor->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SRCHBYROW ) ), uno::makeAny( bSearchByRow ) );
3065cdf0e10cSrcweir 		}
3066cdf0e10cSrcweir 		if ( MatchCase.hasValue() )
3067cdf0e10cSrcweir 		{
3068cdf0e10cSrcweir 			// SearchCaseSensitive
3069cdf0e10cSrcweir 			MatchCase >>= bMatchCase;
3070cdf0e10cSrcweir 			xDescriptor->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SRCHCASE ) ), uno::makeAny( bMatchCase ) );
3071cdf0e10cSrcweir 		}
3072cdf0e10cSrcweir 
3073cdf0e10cSrcweir 		ScGlobal::SetSearchItem( newOptions );
3074cdf0e10cSrcweir 		// ignore MatchByte for the moment, its not supported in
3075cdf0e10cSrcweir 		// OOo.org afaik
3076cdf0e10cSrcweir 
3077cdf0e10cSrcweir 		uno::Reference< util::XSearchDescriptor > xSearch( xDescriptor, uno::UNO_QUERY );
3078*86d5ef3bSPedro Giffuni 		// Find all cells that being replaced, used to fire the range changed event.
3079*86d5ef3bSPedro Giffuni 		uno::Reference< container::XIndexAccess > xIndexAccess = xReplace->findAll( xSearch );
3080cdf0e10cSrcweir 		xReplace->replaceAll( xSearch );
3081*86d5ef3bSPedro Giffuni 
3082*86d5ef3bSPedro Giffuni 		if ( xIndexAccess.is() && xIndexAccess->getCount() > 0 )
3083*86d5ef3bSPedro Giffuni 		{
3084*86d5ef3bSPedro Giffuni 			// Fire the range change event.
3085*86d5ef3bSPedro Giffuni 			ScCellRangesBase* pScCellRangesBase = ScCellRangesBase::getImplementation( xIndexAccess );
3086*86d5ef3bSPedro Giffuni 			// i108874 - the original convert method will fail in SUSE
3087*86d5ef3bSPedro Giffuni 			lcl_NotifyRangeChanges( getScDocShell()->GetModel(), pScCellRangesBase );
3088*86d5ef3bSPedro Giffuni 		}
3089cdf0e10cSrcweir 	}
3090cdf0e10cSrcweir 	return sal_True; // always
3091cdf0e10cSrcweir }
3092cdf0e10cSrcweir 
3093cdf0e10cSrcweir uno::Reference< excel::XRange > SAL_CALL
Find(const uno::Any & What,const uno::Any & After,const uno::Any & LookIn,const uno::Any & LookAt,const uno::Any & SearchOrder,const uno::Any & SearchDirection,const uno::Any & MatchCase,const uno::Any &,const uno::Any &)3094cdf0e10cSrcweir ScVbaRange::Find( const uno::Any& What, const uno::Any& After, const uno::Any& LookIn, const uno::Any& LookAt, const uno::Any& SearchOrder, const uno::Any& SearchDirection, const uno::Any& MatchCase, const uno::Any& /*MatchByte*/, const uno::Any& /*SearchFormat*/ ) throw (uno::RuntimeException)
3095cdf0e10cSrcweir {
3096cdf0e10cSrcweir     // return a Range object that represents the first cell where that information is found.
3097cdf0e10cSrcweir     rtl::OUString sWhat;
3098cdf0e10cSrcweir     sal_Int32 nWhat = 0;
3099cdf0e10cSrcweir     double fWhat = 0.0;
3100cdf0e10cSrcweir 
3101cdf0e10cSrcweir     // string.
3102cdf0e10cSrcweir     if( What >>= sWhat )
3103cdf0e10cSrcweir     {
3104cdf0e10cSrcweir         if( !sWhat.getLength() )
3105cdf0e10cSrcweir 		    throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Range::Find, missing params" )) , uno::Reference< uno::XInterface >() );
3106cdf0e10cSrcweir     }
3107cdf0e10cSrcweir     else if( What >>= nWhat )
3108cdf0e10cSrcweir     {
3109cdf0e10cSrcweir         sWhat = rtl::OUString::valueOf( nWhat );
3110cdf0e10cSrcweir     }
3111cdf0e10cSrcweir     else if( What >>= fWhat )
3112cdf0e10cSrcweir     {
3113cdf0e10cSrcweir         sWhat = rtl::OUString::valueOf( fWhat );
3114cdf0e10cSrcweir     }
3115cdf0e10cSrcweir     else
3116cdf0e10cSrcweir 	    throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Range::Find, missing params" )) , uno::Reference< uno::XInterface >() );
3117cdf0e10cSrcweir 
3118cdf0e10cSrcweir     rtl::OUString sSearch = VBAToRegexp( sWhat );
3119cdf0e10cSrcweir 
3120cdf0e10cSrcweir 	const SvxSearchItem& globalSearchOptions = ScGlobal::GetSearchItem();
3121cdf0e10cSrcweir 	SvxSearchItem newOptions( globalSearchOptions );
3122cdf0e10cSrcweir 
3123cdf0e10cSrcweir 	sal_Int16 nLookAt =  globalSearchOptions.GetWordOnly() ?  excel::XlLookAt::xlPart : excel::XlLookAt::xlWhole;
3124cdf0e10cSrcweir 	sal_Int16 nSearchOrder = globalSearchOptions.GetRowDirection() ? excel::XlSearchOrder::xlByRows : excel::XlSearchOrder::xlByColumns;
3125cdf0e10cSrcweir 
3126cdf0e10cSrcweir 	uno::Reference< util::XSearchable > xSearch( mxRange, uno::UNO_QUERY );
3127cdf0e10cSrcweir     if( xSearch.is() )
3128cdf0e10cSrcweir     {
3129cdf0e10cSrcweir         uno::Reference< util::XSearchDescriptor > xDescriptor = xSearch->createSearchDescriptor();
3130cdf0e10cSrcweir         xDescriptor->setSearchString( sSearch );
3131cdf0e10cSrcweir         xDescriptor->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SRCHREGEXP ) ), uno::Any( true ) );
3132cdf0e10cSrcweir 
3133cdf0e10cSrcweir         uno::Reference< excel::XRange > xAfterRange;
3134cdf0e10cSrcweir         uno::Reference< table::XCellRange > xStartCell;
3135cdf0e10cSrcweir         if( After >>= xAfterRange )
3136cdf0e10cSrcweir         {
3137cdf0e10cSrcweir             // After must be a single cell in the range
3138cdf0e10cSrcweir             if( xAfterRange->getCount() > 1 )
3139cdf0e10cSrcweir 		        throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("After must be a single cell." )) , uno::Reference< uno::XInterface >() );
3140cdf0e10cSrcweir             uno::Reference< excel::XRange > xCell( Cells( uno::makeAny( xAfterRange->getRow() ), uno::makeAny( xAfterRange->getColumn() ) ), uno::UNO_QUERY );
3141cdf0e10cSrcweir             if( !xCell.is() )
3142cdf0e10cSrcweir 		        throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("After must be in range." )) , uno::Reference< uno::XInterface >() );
3143cdf0e10cSrcweir             xStartCell.set( xAfterRange->getCellRange(), uno::UNO_QUERY_THROW );
3144cdf0e10cSrcweir         }
3145cdf0e10cSrcweir 
3146cdf0e10cSrcweir         // LookIn
3147cdf0e10cSrcweir         if( LookIn.hasValue() )
3148cdf0e10cSrcweir         {
3149cdf0e10cSrcweir             sal_Int32 nLookIn = 0;
3150cdf0e10cSrcweir             if( LookIn >>= nLookIn )
3151cdf0e10cSrcweir             {
3152cdf0e10cSrcweir                 sal_Int16 nSearchType = 0;
3153cdf0e10cSrcweir                 switch( nLookIn )
3154cdf0e10cSrcweir                 {
3155cdf0e10cSrcweir                     case excel::XlFindLookIn::xlComments :
3156cdf0e10cSrcweir                         nSearchType = SVX_SEARCHIN_NOTE; // Notes
3157cdf0e10cSrcweir                     break;
3158cdf0e10cSrcweir                     case excel::XlFindLookIn::xlFormulas :
3159cdf0e10cSrcweir                         nSearchType = SVX_SEARCHIN_FORMULA;
3160cdf0e10cSrcweir                     break;
3161cdf0e10cSrcweir                     case excel::XlFindLookIn::xlValues :
3162cdf0e10cSrcweir                         nSearchType = SVX_SEARCHIN_VALUE;
3163cdf0e10cSrcweir                     break;
3164cdf0e10cSrcweir                     default:
3165cdf0e10cSrcweir 		                throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Range::Replace, illegal value for LookIn." )) , uno::Reference< uno::XInterface >() );
3166cdf0e10cSrcweir                 }
3167cdf0e10cSrcweir                 newOptions.SetCellType( nSearchType );
3168cdf0e10cSrcweir                 xDescriptor->setPropertyValue( rtl::OUString::createFromAscii( "SearchType" ), uno::makeAny( nSearchType ) );
3169cdf0e10cSrcweir             }
3170cdf0e10cSrcweir         }
3171cdf0e10cSrcweir 
3172cdf0e10cSrcweir         // LookAt
3173cdf0e10cSrcweir 		if ( LookAt.hasValue() )
3174cdf0e10cSrcweir 		{
3175cdf0e10cSrcweir 			nLookAt =  ::comphelper::getINT16( LookAt );
3176cdf0e10cSrcweir 			sal_Bool bSearchWords = sal_False;
3177cdf0e10cSrcweir 			if ( nLookAt == excel::XlLookAt::xlPart )
3178cdf0e10cSrcweir 				bSearchWords = sal_False;
3179cdf0e10cSrcweir 			else if ( nLookAt == excel::XlLookAt::xlWhole )
3180cdf0e10cSrcweir 				bSearchWords = sal_True;
3181cdf0e10cSrcweir 			else
3182cdf0e10cSrcweir 				throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Range::Replace, illegal value for LookAt" )) , uno::Reference< uno::XInterface >() );
3183cdf0e10cSrcweir 			newOptions.SetWordOnly( bSearchWords );
3184cdf0e10cSrcweir 			xDescriptor->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SRCHWORDS ) ), uno::makeAny( bSearchWords ) );
3185cdf0e10cSrcweir         }
3186cdf0e10cSrcweir 
3187cdf0e10cSrcweir         // SearchOrder
3188cdf0e10cSrcweir 		if ( SearchOrder.hasValue() )
3189cdf0e10cSrcweir 		{
3190cdf0e10cSrcweir 			nSearchOrder =  ::comphelper::getINT16( SearchOrder );
3191cdf0e10cSrcweir 			sal_Bool bSearchByRow = sal_False;
3192cdf0e10cSrcweir 			if ( nSearchOrder == excel::XlSearchOrder::xlByColumns )
3193cdf0e10cSrcweir 				bSearchByRow = sal_False;
3194cdf0e10cSrcweir 			else if ( nSearchOrder == excel::XlSearchOrder::xlByRows )
3195cdf0e10cSrcweir 				bSearchByRow = sal_True;
3196cdf0e10cSrcweir 			else
3197cdf0e10cSrcweir 				throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Range::Replace, illegal value for SearchOrder" )) , uno::Reference< uno::XInterface >() );
3198cdf0e10cSrcweir 
3199cdf0e10cSrcweir 			newOptions.SetRowDirection( bSearchByRow );
3200cdf0e10cSrcweir 			xDescriptor->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SRCHBYROW ) ), uno::makeAny( bSearchByRow ) );
3201cdf0e10cSrcweir 		}
3202cdf0e10cSrcweir 
3203cdf0e10cSrcweir         // SearchDirection
3204cdf0e10cSrcweir         if ( SearchDirection.hasValue() )
3205cdf0e10cSrcweir         {
3206cdf0e10cSrcweir             sal_Int32 nSearchDirection = 0;
3207cdf0e10cSrcweir             if( SearchDirection >>= nSearchDirection )
3208cdf0e10cSrcweir             {
3209cdf0e10cSrcweir                 sal_Bool bSearchBackwards = sal_False;
3210cdf0e10cSrcweir                 if ( nSearchDirection == excel::XlSearchDirection::xlNext )
3211cdf0e10cSrcweir                     bSearchBackwards = sal_False;
3212cdf0e10cSrcweir                 else if( nSearchDirection == excel::XlSearchDirection::xlPrevious )
3213cdf0e10cSrcweir                     bSearchBackwards = sal_True;
3214cdf0e10cSrcweir                 else
3215cdf0e10cSrcweir 				    throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Range::Replace, illegal value for SearchDirection" )) , uno::Reference< uno::XInterface >() );
3216cdf0e10cSrcweir                 newOptions.SetBackward( bSearchBackwards );
3217cdf0e10cSrcweir                 xDescriptor->setPropertyValue( rtl::OUString::createFromAscii( "SearchBackwards" ), uno::makeAny( bSearchBackwards ) );
3218cdf0e10cSrcweir             }
3219cdf0e10cSrcweir         }
3220cdf0e10cSrcweir 
3221cdf0e10cSrcweir         // MatchCase
3222cdf0e10cSrcweir         sal_Bool bMatchCase = sal_False;
3223cdf0e10cSrcweir 		if ( MatchCase.hasValue() )
3224cdf0e10cSrcweir 		{
3225cdf0e10cSrcweir 			// SearchCaseSensitive
3226cdf0e10cSrcweir 			if( !( MatchCase >>= bMatchCase ) )
3227cdf0e10cSrcweir 			    throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Range::Replace, illegal value for MatchCase" )) , uno::Reference< uno::XInterface >() );
3228cdf0e10cSrcweir 		}
3229cdf0e10cSrcweir         xDescriptor->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SRCHCASE ) ), uno::makeAny( bMatchCase ) );
3230cdf0e10cSrcweir 
3231cdf0e10cSrcweir         // MatchByte
3232cdf0e10cSrcweir         // SearchFormat
3233cdf0e10cSrcweir         // ignore
3234cdf0e10cSrcweir 
3235cdf0e10cSrcweir 		ScGlobal::SetSearchItem( newOptions );
3236cdf0e10cSrcweir 
3237cdf0e10cSrcweir 		uno::Reference< uno::XInterface > xInterface = xStartCell.is() ? xSearch->findNext( xStartCell, xDescriptor) : xSearch->findFirst( xDescriptor );
3238cdf0e10cSrcweir 		uno::Reference< table::XCellRange > xCellRange( xInterface, uno::UNO_QUERY );
3239cdf0e10cSrcweir         if ( xCellRange.is() )
3240cdf0e10cSrcweir         {
3241cdf0e10cSrcweir             uno::Reference< excel::XRange > xResultRange = new ScVbaRange( mxParent, mxContext, xCellRange );
3242cdf0e10cSrcweir             if( xResultRange.is() )
3243cdf0e10cSrcweir             {
3244cdf0e10cSrcweir                 xResultRange->Select();
3245cdf0e10cSrcweir                 return xResultRange;
3246cdf0e10cSrcweir             }
3247cdf0e10cSrcweir         }
3248cdf0e10cSrcweir 
3249cdf0e10cSrcweir     }
3250cdf0e10cSrcweir 
3251cdf0e10cSrcweir     return uno::Reference< excel::XRange >();
3252cdf0e10cSrcweir }
3253cdf0e10cSrcweir 
processKey(const uno::Any & Key,uno::Reference<uno::XComponentContext> & xContext,ScDocShell * pDocSh)3254cdf0e10cSrcweir uno::Reference< table::XCellRange > processKey( const uno::Any& Key, uno::Reference<  uno::XComponentContext >& xContext, ScDocShell* pDocSh )
3255cdf0e10cSrcweir {
3256cdf0e10cSrcweir 	uno::Reference< excel::XRange > xKeyRange;
3257cdf0e10cSrcweir 	if ( Key.getValueType() == excel::XRange::static_type() )
3258cdf0e10cSrcweir 	{
3259cdf0e10cSrcweir 		xKeyRange.set( Key, uno::UNO_QUERY_THROW );
3260cdf0e10cSrcweir 	}
3261cdf0e10cSrcweir 	else if ( Key.getValueType() == ::getCppuType( static_cast< const rtl::OUString* >(0) )  )
3262cdf0e10cSrcweir 
3263cdf0e10cSrcweir 	{
3264cdf0e10cSrcweir 		rtl::OUString sRangeName = ::comphelper::getString( Key );
3265cdf0e10cSrcweir 		table::CellRangeAddress  aRefAddr;
3266cdf0e10cSrcweir 		if ( !pDocSh )
3267cdf0e10cSrcweir 			throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Range::Sort no docshell to calculate key param")), uno::Reference< uno::XInterface >() );
3268cdf0e10cSrcweir 		xKeyRange = getRangeForName( xContext, sRangeName, pDocSh, aRefAddr );
3269cdf0e10cSrcweir 	}
3270cdf0e10cSrcweir 	else
3271cdf0e10cSrcweir 		throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Range::Sort illegal type value for key param")), uno::Reference< uno::XInterface >() );
3272cdf0e10cSrcweir 	uno::Reference< table::XCellRange > xKey;
3273cdf0e10cSrcweir 	xKey.set( xKeyRange->getCellRange(), uno::UNO_QUERY_THROW );
3274cdf0e10cSrcweir 	return xKey;
3275cdf0e10cSrcweir }
3276cdf0e10cSrcweir 
3277cdf0e10cSrcweir // helper method for Sort
findSortPropertyIndex(const uno::Sequence<beans::PropertyValue> & props,const rtl::OUString & sPropName)3278cdf0e10cSrcweir sal_Int32 findSortPropertyIndex( const uno::Sequence< beans::PropertyValue >& props,
3279cdf0e10cSrcweir const rtl::OUString& sPropName ) throw( uno::RuntimeException )
3280cdf0e10cSrcweir {
3281cdf0e10cSrcweir 	const beans::PropertyValue* pProp = props.getConstArray();
3282cdf0e10cSrcweir 	sal_Int32 nItems = props.getLength();
3283cdf0e10cSrcweir 
3284cdf0e10cSrcweir 	 sal_Int32 count=0;
3285cdf0e10cSrcweir 	for ( ; count < nItems; ++count, ++pProp )
3286cdf0e10cSrcweir 		if ( pProp->Name.equals( sPropName ) )
3287cdf0e10cSrcweir 			return count;
3288cdf0e10cSrcweir 	if ( count == nItems )
3289cdf0e10cSrcweir 		throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Range::Sort unknown sort property")), uno::Reference< uno::XInterface >() );
3290cdf0e10cSrcweir 	return -1; //should never reach here ( satisfy compiler )
3291cdf0e10cSrcweir }
3292cdf0e10cSrcweir 
3293cdf0e10cSrcweir // helper method for Sort
updateTableSortField(const uno::Reference<table::XCellRange> & xParentRange,const uno::Reference<table::XCellRange> & xColRowKey,sal_Int16 nOrder,table::TableSortField & aTableField,sal_Bool bIsSortColumn,sal_Bool bMatchCase)3294cdf0e10cSrcweir void updateTableSortField( const uno::Reference< table::XCellRange >& xParentRange,
3295cdf0e10cSrcweir 	const uno::Reference< table::XCellRange >& xColRowKey, sal_Int16 nOrder,
3296cdf0e10cSrcweir 	table::TableSortField& aTableField, sal_Bool bIsSortColumn, sal_Bool bMatchCase ) throw ( uno::RuntimeException )
3297cdf0e10cSrcweir {
3298cdf0e10cSrcweir 		RangeHelper parentRange( xParentRange );
3299cdf0e10cSrcweir 		RangeHelper colRowRange( xColRowKey );
3300cdf0e10cSrcweir 
3301cdf0e10cSrcweir 		table::CellRangeAddress parentRangeAddress = parentRange.getCellRangeAddressable()->getRangeAddress();
3302cdf0e10cSrcweir 
3303cdf0e10cSrcweir 		table::CellRangeAddress colRowKeyAddress = colRowRange.getCellRangeAddressable()->getRangeAddress();
3304cdf0e10cSrcweir 
3305cdf0e10cSrcweir 		// make sure that upper left poing of key range is within the
3306cdf0e10cSrcweir 		// parent range
3307cdf0e10cSrcweir 		if (  ( !bIsSortColumn && colRowKeyAddress.StartColumn >= parentRangeAddress.StartColumn &&
3308cdf0e10cSrcweir 			colRowKeyAddress.StartColumn <= parentRangeAddress.EndColumn ) || ( bIsSortColumn &&
3309cdf0e10cSrcweir 			colRowKeyAddress.StartRow >= parentRangeAddress.StartRow &&
3310cdf0e10cSrcweir 			colRowKeyAddress.StartRow <= parentRangeAddress.EndRow  ) )
3311cdf0e10cSrcweir 		{
3312cdf0e10cSrcweir 			//determine col/row index
3313cdf0e10cSrcweir 			if ( bIsSortColumn )
3314cdf0e10cSrcweir 				aTableField.Field = colRowKeyAddress.StartRow - parentRangeAddress.StartRow;
3315cdf0e10cSrcweir 			else
3316cdf0e10cSrcweir 				aTableField.Field = colRowKeyAddress.StartColumn - parentRangeAddress.StartColumn;
3317cdf0e10cSrcweir 			aTableField.IsCaseSensitive = bMatchCase;
3318cdf0e10cSrcweir 
3319cdf0e10cSrcweir 			if ( nOrder ==  excel::XlSortOrder::xlAscending )
3320cdf0e10cSrcweir 				aTableField.IsAscending = sal_True;
3321cdf0e10cSrcweir 			else
3322cdf0e10cSrcweir 				aTableField.IsAscending = sal_False;
3323cdf0e10cSrcweir 		}
3324cdf0e10cSrcweir 		else
3325cdf0e10cSrcweir 			throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Illegal Key param" ) ), uno::Reference< uno::XInterface >() );
3326cdf0e10cSrcweir 
3327cdf0e10cSrcweir 
3328cdf0e10cSrcweir }
3329cdf0e10cSrcweir 
3330cdf0e10cSrcweir void SAL_CALL
Sort(const uno::Any & Key1,const uno::Any & Order1,const uno::Any & Key2,const uno::Any &,const uno::Any & Order2,const uno::Any & Key3,const uno::Any & Order3,const uno::Any & Header,const uno::Any & OrderCustom,const uno::Any & MatchCase,const uno::Any & Orientation,const uno::Any & SortMethod,const uno::Any & DataOption1,const uno::Any & DataOption2,const uno::Any & DataOption3)3331cdf0e10cSrcweir ScVbaRange::Sort( const uno::Any& Key1, const uno::Any& Order1, const uno::Any& Key2, const uno::Any& /*Type*/, const uno::Any& Order2, const uno::Any& Key3, const uno::Any& Order3, const uno::Any& Header, const uno::Any& OrderCustom, const uno::Any& MatchCase, const uno::Any& Orientation, const uno::Any& SortMethod,  const uno::Any& DataOption1, const uno::Any& DataOption2, const uno::Any& DataOption3  ) throw (uno::RuntimeException)
3332cdf0e10cSrcweir {
3333cdf0e10cSrcweir 	// #TODO# #FIXME# can we do something with Type
3334cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
3335cdf0e10cSrcweir 		throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("That command cannot be used on multiple selections" ) ), uno::Reference< uno::XInterface >() );
3336cdf0e10cSrcweir 
3337cdf0e10cSrcweir 	sal_Int16 nDataOption1 = excel::XlSortDataOption::xlSortNormal;
3338cdf0e10cSrcweir 	sal_Int16 nDataOption2 = excel::XlSortDataOption::xlSortNormal;
3339cdf0e10cSrcweir 	sal_Int16 nDataOption3 = excel::XlSortDataOption::xlSortNormal;
3340cdf0e10cSrcweir 
3341cdf0e10cSrcweir 	ScDocument* pDoc = getScDocument();
3342cdf0e10cSrcweir 	if ( !pDoc )
3343cdf0e10cSrcweir 		throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to access document from shell" ) ), uno::Reference< uno::XInterface >() );
3344cdf0e10cSrcweir 
3345cdf0e10cSrcweir 	RangeHelper thisRange( mxRange );
3346cdf0e10cSrcweir 	table::CellRangeAddress thisRangeAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
3347cdf0e10cSrcweir 	ScSortParam aSortParam;
3348cdf0e10cSrcweir 	SCTAB nTab = thisRangeAddress.Sheet;
3349cdf0e10cSrcweir 	pDoc->GetSortParam( aSortParam, nTab );
3350cdf0e10cSrcweir 
3351cdf0e10cSrcweir 	if ( DataOption1.hasValue() )
3352cdf0e10cSrcweir 		DataOption1 >>= nDataOption1;
3353cdf0e10cSrcweir 	if ( DataOption2.hasValue() )
3354cdf0e10cSrcweir 		DataOption2 >>= nDataOption2;
3355cdf0e10cSrcweir 	if ( DataOption3.hasValue() )
3356cdf0e10cSrcweir 		DataOption3 >>= nDataOption3;
3357cdf0e10cSrcweir 
3358cdf0e10cSrcweir 	// 1) #TODO #FIXME need to process DataOption[1..3] not used currently
3359cdf0e10cSrcweir 	// 2) #TODO #FIXME need to refactor this ( below ) into a IsSingleCell() method
3360cdf0e10cSrcweir 	uno::Reference< table::XColumnRowRange > xColumnRowRange(mxRange, uno::UNO_QUERY_THROW );
3361cdf0e10cSrcweir 
3362cdf0e10cSrcweir 	// 'Fraid I don't remember what I was trying to achieve here ???
3363cdf0e10cSrcweir /*
3364cdf0e10cSrcweir 	if (  isSingleCellRange() )
3365cdf0e10cSrcweir 	{
3366cdf0e10cSrcweir 		uno::Reference< XRange > xCurrent = CurrentRegion();
3367cdf0e10cSrcweir 		xCurrent->Sort( Key1, Order1, Key2, Type, Order2, Key3, Order3, Header, OrderCustom, MatchCase, Orientation, SortMethod, DataOption1, DataOption2, DataOption3 );
3368cdf0e10cSrcweir 		return;
3369cdf0e10cSrcweir 	}
3370cdf0e10cSrcweir */
3371cdf0e10cSrcweir 	// set up defaults
3372cdf0e10cSrcweir 
3373cdf0e10cSrcweir 	sal_Int16 nOrder1 = aSortParam.bAscending[0] ? excel::XlSortOrder::xlAscending : excel::XlSortOrder::xlDescending;
3374cdf0e10cSrcweir 	sal_Int16 nOrder2 = aSortParam.bAscending[1] ? excel::XlSortOrder::xlAscending : excel::XlSortOrder::xlDescending;
3375cdf0e10cSrcweir 	sal_Int16 nOrder3 = aSortParam.bAscending[2] ? excel::XlSortOrder::xlAscending : excel::XlSortOrder::xlDescending;
3376cdf0e10cSrcweir 
3377cdf0e10cSrcweir 	sal_Int16 nCustom = aSortParam.nUserIndex;
3378cdf0e10cSrcweir 	sal_Int16 nSortMethod = excel::XlSortMethod::xlPinYin;
3379cdf0e10cSrcweir 	sal_Bool bMatchCase = aSortParam.bCaseSens;
3380cdf0e10cSrcweir 
3381cdf0e10cSrcweir 	// seems to work opposite to expected, see below
3382cdf0e10cSrcweir 	sal_Int16 nOrientation = aSortParam.bByRow ?  excel::XlSortOrientation::xlSortColumns :  excel::XlSortOrientation::xlSortRows;
3383cdf0e10cSrcweir 
3384cdf0e10cSrcweir 	if ( Orientation.hasValue() )
3385cdf0e10cSrcweir 	{
3386cdf0e10cSrcweir 		// Documentation says xlSortRows is default but that doesn't appear to be
3387cdf0e10cSrcweir 		// the case. Also it appears that xlSortColumns is the default which
3388cdf0e10cSrcweir 		// strangely enought sorts by Row
3389cdf0e10cSrcweir 		nOrientation = ::comphelper::getINT16( Orientation );
3390cdf0e10cSrcweir 		// persist new option to be next calls default
3391cdf0e10cSrcweir 		if ( nOrientation == excel::XlSortOrientation::xlSortRows )
3392cdf0e10cSrcweir 			aSortParam.bByRow = sal_False;
3393cdf0e10cSrcweir 		else
3394cdf0e10cSrcweir 			aSortParam.bByRow = sal_True;
3395cdf0e10cSrcweir 
3396cdf0e10cSrcweir 	}
3397cdf0e10cSrcweir 
3398cdf0e10cSrcweir 	sal_Bool bIsSortColumns=sal_False; // sort by row
3399cdf0e10cSrcweir 
3400cdf0e10cSrcweir 	if ( nOrientation == excel::XlSortOrientation::xlSortRows )
3401cdf0e10cSrcweir 		bIsSortColumns = sal_True;
3402cdf0e10cSrcweir 	sal_Int16 nHeader = 0;
3403cdf0e10cSrcweir #ifdef VBA_OOBUILD_HACK
3404cdf0e10cSrcweir 	nHeader = aSortParam.nCompatHeader;
3405cdf0e10cSrcweir #endif
3406cdf0e10cSrcweir 	sal_Bool bContainsHeader = sal_False;
3407cdf0e10cSrcweir 
3408cdf0e10cSrcweir 	if ( Header.hasValue() )
3409cdf0e10cSrcweir 	{
3410cdf0e10cSrcweir 		nHeader = ::comphelper::getINT16( Header );
3411cdf0e10cSrcweir #ifdef VBA_OOBUILD_HACK
3412cdf0e10cSrcweir 		aSortParam.nCompatHeader = nHeader;
3413cdf0e10cSrcweir #endif
3414cdf0e10cSrcweir 	}
3415cdf0e10cSrcweir 
3416cdf0e10cSrcweir 	if ( nHeader == excel::XlYesNoGuess::xlGuess )
3417cdf0e10cSrcweir 	{
3418cdf0e10cSrcweir 		bool bHasColHeader = pDoc->HasColHeader(  static_cast< SCCOL >( thisRangeAddress.StartColumn ), static_cast< SCROW >( thisRangeAddress.StartRow ), static_cast< SCCOL >( thisRangeAddress.EndColumn ), static_cast< SCROW >( thisRangeAddress.EndRow ), static_cast< SCTAB >( thisRangeAddress.Sheet ));
3419cdf0e10cSrcweir 		bool bHasRowHeader = pDoc->HasRowHeader(  static_cast< SCCOL >( thisRangeAddress.StartColumn ), static_cast< SCROW >( thisRangeAddress.StartRow ), static_cast< SCCOL >( thisRangeAddress.EndColumn ), static_cast< SCROW >( thisRangeAddress.EndRow ), static_cast< SCTAB >( thisRangeAddress.Sheet ) );
3420cdf0e10cSrcweir 		if ( bHasColHeader || bHasRowHeader )
3421cdf0e10cSrcweir 			nHeader =  excel::XlYesNoGuess::xlYes;
3422cdf0e10cSrcweir 		else
3423cdf0e10cSrcweir 			nHeader =  excel::XlYesNoGuess::xlNo;
3424cdf0e10cSrcweir #ifdef VBA_OOBUILD_HACK
3425cdf0e10cSrcweir 		aSortParam.nCompatHeader = nHeader;
3426cdf0e10cSrcweir #endif
3427cdf0e10cSrcweir 	}
3428cdf0e10cSrcweir 
3429cdf0e10cSrcweir 	if ( nHeader == excel::XlYesNoGuess::xlYes )
3430cdf0e10cSrcweir 		bContainsHeader = sal_True;
3431cdf0e10cSrcweir 
3432cdf0e10cSrcweir 	if ( SortMethod.hasValue() )
3433cdf0e10cSrcweir 	{
3434cdf0e10cSrcweir 		nSortMethod = ::comphelper::getINT16( SortMethod );
3435cdf0e10cSrcweir 	}
3436cdf0e10cSrcweir 
3437cdf0e10cSrcweir 	if ( OrderCustom.hasValue() )
3438cdf0e10cSrcweir 	{
3439cdf0e10cSrcweir 		OrderCustom >>= nCustom;
3440cdf0e10cSrcweir 		--nCustom; // 0-based in OOo
3441cdf0e10cSrcweir 		aSortParam.nUserIndex = nCustom;
3442cdf0e10cSrcweir 	}
3443cdf0e10cSrcweir 
3444cdf0e10cSrcweir 	if ( MatchCase.hasValue() )
3445cdf0e10cSrcweir 	{
3446cdf0e10cSrcweir 		MatchCase >>= bMatchCase;
3447cdf0e10cSrcweir 		aSortParam.bCaseSens = bMatchCase;
3448cdf0e10cSrcweir 	}
3449cdf0e10cSrcweir 
3450cdf0e10cSrcweir 	if ( Order1.hasValue() )
3451cdf0e10cSrcweir 	{
3452cdf0e10cSrcweir 		nOrder1 = ::comphelper::getINT16(Order1);
3453cdf0e10cSrcweir 		if (  nOrder1 == excel::XlSortOrder::xlAscending )
3454cdf0e10cSrcweir 			aSortParam.bAscending[0]  = sal_True;
3455cdf0e10cSrcweir 		else
3456cdf0e10cSrcweir 			aSortParam.bAscending[0]  = sal_False;
3457cdf0e10cSrcweir 
3458cdf0e10cSrcweir 	}
3459cdf0e10cSrcweir 	if ( Order2.hasValue() )
3460cdf0e10cSrcweir 	{
3461cdf0e10cSrcweir 		nOrder2 = ::comphelper::getINT16(Order2);
3462cdf0e10cSrcweir 		if ( nOrder2 == excel::XlSortOrder::xlAscending )
3463cdf0e10cSrcweir 			aSortParam.bAscending[1]  = sal_True;
3464cdf0e10cSrcweir 		else
3465cdf0e10cSrcweir 			aSortParam.bAscending[1]  = sal_False;
3466cdf0e10cSrcweir 	}
3467cdf0e10cSrcweir 	if ( Order3.hasValue() )
3468cdf0e10cSrcweir 	{
3469cdf0e10cSrcweir 		nOrder3 = ::comphelper::getINT16(Order3);
3470cdf0e10cSrcweir 		if ( nOrder3 == excel::XlSortOrder::xlAscending )
3471cdf0e10cSrcweir 			aSortParam.bAscending[2]  = sal_True;
3472cdf0e10cSrcweir 		else
3473cdf0e10cSrcweir 			aSortParam.bAscending[2]  = sal_False;
3474cdf0e10cSrcweir 	}
3475cdf0e10cSrcweir 
3476cdf0e10cSrcweir 	uno::Reference< table::XCellRange > xKey1;
3477cdf0e10cSrcweir 	uno::Reference< table::XCellRange > xKey2;
3478cdf0e10cSrcweir 	uno::Reference< table::XCellRange > xKey3;
3479cdf0e10cSrcweir 	ScDocShell* pDocShell = getScDocShell();
3480cdf0e10cSrcweir 	xKey1 = processKey( Key1, mxContext, pDocShell );
3481cdf0e10cSrcweir 	if ( !xKey1.is() )
3482cdf0e10cSrcweir 		throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Range::Sort needs a key1 param")), uno::Reference< uno::XInterface >() );
3483cdf0e10cSrcweir 
3484cdf0e10cSrcweir 	if ( Key2.hasValue() )
3485cdf0e10cSrcweir 		xKey2 = processKey( Key2, mxContext, pDocShell );
3486cdf0e10cSrcweir 	if ( Key3.hasValue() )
3487cdf0e10cSrcweir 		xKey3 = processKey( Key3, mxContext, pDocShell );
3488cdf0e10cSrcweir 
3489cdf0e10cSrcweir 	uno::Reference< util::XSortable > xSort( mxRange, uno::UNO_QUERY_THROW );
3490cdf0e10cSrcweir 	uno::Sequence< beans::PropertyValue > sortDescriptor = xSort->createSortDescriptor();
3491cdf0e10cSrcweir 	sal_Int32 nTableSortFieldIndex = findSortPropertyIndex( sortDescriptor, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SortFields") ) );
3492cdf0e10cSrcweir 
3493cdf0e10cSrcweir 	uno::Sequence< table::TableSortField > sTableFields(1);
3494cdf0e10cSrcweir 	sal_Int32 nTableIndex = 0;
3495cdf0e10cSrcweir 	updateTableSortField(  mxRange, xKey1, nOrder1, sTableFields[ nTableIndex++ ], bIsSortColumns, bMatchCase );
3496cdf0e10cSrcweir 
3497cdf0e10cSrcweir 	if ( xKey2.is() )
3498cdf0e10cSrcweir 	{
3499cdf0e10cSrcweir 		sTableFields.realloc( sTableFields.getLength() + 1 );
3500cdf0e10cSrcweir 		updateTableSortField(  mxRange, xKey2, nOrder2, sTableFields[ nTableIndex++ ], bIsSortColumns, bMatchCase );
3501cdf0e10cSrcweir 	}
3502cdf0e10cSrcweir 	if ( xKey3.is()  )
3503cdf0e10cSrcweir 	{
3504cdf0e10cSrcweir 		sTableFields.realloc( sTableFields.getLength() + 1 );
3505cdf0e10cSrcweir 		updateTableSortField(  mxRange, xKey3, nOrder3, sTableFields[ nTableIndex++ ], bIsSortColumns, bMatchCase );
3506cdf0e10cSrcweir 	}
3507cdf0e10cSrcweir 	sortDescriptor[ nTableSortFieldIndex ].Value <<= sTableFields;
3508cdf0e10cSrcweir 
3509cdf0e10cSrcweir 	sal_Int32 nIndex = 	findSortPropertyIndex( sortDescriptor,  rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IsSortColumns")) );
3510cdf0e10cSrcweir 	sortDescriptor[ nIndex ].Value <<= bIsSortColumns;
3511cdf0e10cSrcweir 
3512cdf0e10cSrcweir 	nIndex = 	findSortPropertyIndex( sortDescriptor, CONTS_HEADER );
3513cdf0e10cSrcweir 	sortDescriptor[ nIndex ].Value <<= bContainsHeader;
3514cdf0e10cSrcweir 
3515cdf0e10cSrcweir 	pDoc->SetSortParam( aSortParam, nTab );
3516cdf0e10cSrcweir 	xSort->sort( sortDescriptor );
3517cdf0e10cSrcweir 
3518cdf0e10cSrcweir 	// #FIXME #TODO
3519cdf0e10cSrcweir 	// The SortMethod param is not processed ( not sure what its all about, need to
3520cdf0e10cSrcweir 
3521cdf0e10cSrcweir }
3522cdf0e10cSrcweir 
3523cdf0e10cSrcweir uno::Reference< excel::XRange > SAL_CALL
End(::sal_Int32 Direction)3524cdf0e10cSrcweir ScVbaRange::End( ::sal_Int32 Direction )  throw (uno::RuntimeException)
3525cdf0e10cSrcweir {
3526cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
3527cdf0e10cSrcweir 	{
3528cdf0e10cSrcweir 		uno::Reference< excel::XRange > xRange( getArea( 0 ), uno::UNO_QUERY_THROW );
3529cdf0e10cSrcweir 		return xRange->End( Direction );
3530cdf0e10cSrcweir 	}
3531cdf0e10cSrcweir 
3532cdf0e10cSrcweir 
3533cdf0e10cSrcweir 	// #FIXME #TODO
3534cdf0e10cSrcweir 	// euch! found my orig implementation sucked, so
3535cdf0e10cSrcweir 	// trying this even suckier one ( really need to use/expose code in
3536cdf0e10cSrcweir 	// around  ScTabView::MoveCursorArea(), thats the bit that calcutes
3537cdf0e10cSrcweir 	// where the cursor should go )
3538cdf0e10cSrcweir 	// Main problem with this method is the ultra hacky attempt to preserve
3539cdf0e10cSrcweir 	// the ActiveCell, there should be no need to go to these extreems
3540cdf0e10cSrcweir 
3541cdf0e10cSrcweir 	// Save ActiveCell pos ( to restore later )
3542cdf0e10cSrcweir 	uno::Any aDft;
3543cdf0e10cSrcweir 	uno::Reference< excel::XApplication > xApplication( Application(), uno::UNO_QUERY_THROW );
3544cdf0e10cSrcweir 	rtl::OUString sActiveCell = xApplication->getActiveCell()->Address(aDft, aDft, aDft, aDft, aDft );
3545cdf0e10cSrcweir 
3546cdf0e10cSrcweir 	// position current cell upper left of this range
3547cdf0e10cSrcweir 	Cells( uno::makeAny( (sal_Int32) 1 ), uno::makeAny( (sal_Int32) 1 ) )->Select();
3548cdf0e10cSrcweir 
3549cdf0e10cSrcweir         uno::Reference< frame::XModel > xModel = getModelFromRange( mxRange );
3550cdf0e10cSrcweir 
3551cdf0e10cSrcweir 	SfxViewFrame* pViewFrame = excel::getViewFrame( xModel );
3552cdf0e10cSrcweir 	if ( pViewFrame )
3553cdf0e10cSrcweir 	{
3554cdf0e10cSrcweir 		SfxAllItemSet aArgs( SFX_APP()->GetPool() );
3555cdf0e10cSrcweir 		// Hoping this will make sure this slot is called
3556cdf0e10cSrcweir 		// synchronously
3557cdf0e10cSrcweir 		SfxBoolItem sfxAsync( SID_ASYNCHRON, sal_False );
3558cdf0e10cSrcweir 		aArgs.Put( sfxAsync, sfxAsync.Which() );
3559cdf0e10cSrcweir 		SfxDispatcher* pDispatcher = pViewFrame->GetDispatcher();
3560cdf0e10cSrcweir 
3561cdf0e10cSrcweir 		sal_uInt16 nSID = 0;
3562cdf0e10cSrcweir 
3563cdf0e10cSrcweir 		switch( Direction )
3564cdf0e10cSrcweir 		{
3565cdf0e10cSrcweir 			case excel::XlDirection::xlDown:
3566cdf0e10cSrcweir 				nSID = SID_CURSORBLKDOWN;
3567cdf0e10cSrcweir 				break;
3568cdf0e10cSrcweir 			case excel::XlDirection::xlUp:
3569cdf0e10cSrcweir 				nSID = SID_CURSORBLKUP;
3570cdf0e10cSrcweir 				break;
3571cdf0e10cSrcweir 			case excel::XlDirection::xlToLeft:
3572cdf0e10cSrcweir 				nSID = SID_CURSORBLKLEFT;
3573cdf0e10cSrcweir 				break;
3574cdf0e10cSrcweir 			case excel::XlDirection::xlToRight:
3575cdf0e10cSrcweir 				nSID = SID_CURSORBLKRIGHT;
3576cdf0e10cSrcweir 				break;
3577cdf0e10cSrcweir 			default:
3578cdf0e10cSrcweir 				throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ": Invalid ColumnIndex" ) ), uno::Reference< uno::XInterface >() );
3579cdf0e10cSrcweir 		}
3580cdf0e10cSrcweir 		if ( pDispatcher )
3581cdf0e10cSrcweir 		{
3582cdf0e10cSrcweir 			pDispatcher->Execute( nSID, (SfxCallMode)SFX_CALLMODE_SYNCHRON, aArgs );
3583cdf0e10cSrcweir 		}
3584cdf0e10cSrcweir 	}
3585cdf0e10cSrcweir 
3586cdf0e10cSrcweir 	// result is the ActiveCell
3587cdf0e10cSrcweir 	rtl::OUString sMoved =	xApplication->getActiveCell()->Address(aDft, aDft, aDft, aDft, aDft );
3588cdf0e10cSrcweir 
3589cdf0e10cSrcweir 	// restore old ActiveCell
3590cdf0e10cSrcweir 	uno::Any aVoid;
3591cdf0e10cSrcweir 
3592cdf0e10cSrcweir 	uno::Reference< excel::XRange > xOldActiveCell( xApplication->getActiveSheet()->Range( uno::makeAny( sActiveCell ), aVoid ), uno::UNO_QUERY_THROW );
3593cdf0e10cSrcweir 	xOldActiveCell->Select();
3594cdf0e10cSrcweir 
3595cdf0e10cSrcweir 	uno::Reference< excel::XRange > resultCell;
3596cdf0e10cSrcweir 
3597cdf0e10cSrcweir 	resultCell.set( xApplication->getActiveSheet()->Range( uno::makeAny( sMoved ), aVoid ), uno::UNO_QUERY_THROW );
3598cdf0e10cSrcweir 
3599cdf0e10cSrcweir 	// return result
3600cdf0e10cSrcweir 
3601cdf0e10cSrcweir 	return resultCell;
3602cdf0e10cSrcweir }
3603cdf0e10cSrcweir 
3604cdf0e10cSrcweir bool
isSingleCellRange()3605cdf0e10cSrcweir ScVbaRange::isSingleCellRange()
3606cdf0e10cSrcweir {
3607cdf0e10cSrcweir     uno::Reference< sheet::XCellRangeAddressable > xAddressable( mxRange, uno::UNO_QUERY );
3608cdf0e10cSrcweir     if ( xAddressable.is() )
3609cdf0e10cSrcweir     {
3610cdf0e10cSrcweir         table::CellRangeAddress aRangeAddr = xAddressable->getRangeAddress();
3611cdf0e10cSrcweir         return ( aRangeAddr.EndColumn == aRangeAddr.StartColumn && aRangeAddr.EndRow == aRangeAddr.StartRow );
3612cdf0e10cSrcweir     }
3613cdf0e10cSrcweir     return false;
3614cdf0e10cSrcweir }
3615cdf0e10cSrcweir 
3616cdf0e10cSrcweir uno::Reference< excel::XCharacters > SAL_CALL
characters(const uno::Any & Start,const uno::Any & Length)3617cdf0e10cSrcweir ScVbaRange::characters( const uno::Any& Start, const uno::Any& Length ) throw (uno::RuntimeException)
3618cdf0e10cSrcweir {
3619cdf0e10cSrcweir 	if ( !isSingleCellRange() )
3620cdf0e10cSrcweir 		throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Can't create Characters property for multicell range ") ), uno::Reference< uno::XInterface >() );
3621cdf0e10cSrcweir 	uno::Reference< text::XSimpleText > xSimple(mxRange->getCellByPosition(0,0) , uno::UNO_QUERY_THROW );
3622cdf0e10cSrcweir 	ScDocument* pDoc = getDocumentFromRange(mxRange);
3623cdf0e10cSrcweir 	if ( !pDoc )
3624cdf0e10cSrcweir 		throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to access document from shell" ) ), uno::Reference< uno::XInterface >() );
3625cdf0e10cSrcweir 
3626cdf0e10cSrcweir 	ScVbaPalette aPalette( pDoc->GetDocumentShell() );
3627cdf0e10cSrcweir 	return  new ScVbaCharacters( this, mxContext, aPalette, xSimple, Start, Length );
3628cdf0e10cSrcweir }
3629cdf0e10cSrcweir 
3630cdf0e10cSrcweir  void SAL_CALL
Delete(const uno::Any & Shift)3631cdf0e10cSrcweir ScVbaRange::Delete( const uno::Any& Shift ) throw (uno::RuntimeException)
3632cdf0e10cSrcweir {
3633cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
3634cdf0e10cSrcweir 	{
3635cdf0e10cSrcweir 		sal_Int32 nItems = m_Areas->getCount();
3636cdf0e10cSrcweir 		for ( sal_Int32 index=1; index <= nItems; ++index )
3637cdf0e10cSrcweir 		{
3638cdf0e10cSrcweir 			uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW );
3639cdf0e10cSrcweir 			xRange->Delete( Shift );
3640cdf0e10cSrcweir 		}
3641cdf0e10cSrcweir 		return;
3642cdf0e10cSrcweir 	}
3643cdf0e10cSrcweir 	sheet::CellDeleteMode mode = sheet::CellDeleteMode_NONE ;
3644cdf0e10cSrcweir 	RangeHelper thisRange( mxRange );
3645cdf0e10cSrcweir 	table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
3646cdf0e10cSrcweir 	if ( Shift.hasValue() )
3647cdf0e10cSrcweir 	{
3648cdf0e10cSrcweir 		sal_Int32 nShift = 0;
3649cdf0e10cSrcweir 		Shift >>= nShift;
3650cdf0e10cSrcweir 		switch ( nShift )
3651cdf0e10cSrcweir 		{
3652cdf0e10cSrcweir 			case excel::XlDeleteShiftDirection::xlShiftUp:
3653cdf0e10cSrcweir 				mode = sheet::CellDeleteMode_UP;
3654cdf0e10cSrcweir 				break;
3655cdf0e10cSrcweir 			case excel::XlDeleteShiftDirection::xlShiftToLeft:
3656cdf0e10cSrcweir 				mode = sheet::CellDeleteMode_LEFT;
3657cdf0e10cSrcweir 				break;
3658cdf0e10cSrcweir 			default:
3659cdf0e10cSrcweir 				throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ("Illegal paramater ") ), uno::Reference< uno::XInterface >() );
3660cdf0e10cSrcweir 		}
3661cdf0e10cSrcweir 	}
3662cdf0e10cSrcweir 	else
3663cdf0e10cSrcweir         {
3664cdf0e10cSrcweir 		bool bFullRow = ( thisAddress.StartColumn == 0 && thisAddress.EndColumn == MAXCOL );
3665cdf0e10cSrcweir 	        sal_Int32 nCols = thisAddress.EndColumn - thisAddress.StartColumn;
3666cdf0e10cSrcweir 	        sal_Int32 nRows = thisAddress.EndRow - thisAddress.StartRow;
3667cdf0e10cSrcweir 		if ( mbIsRows || bFullRow || ( nCols >=  nRows ) )
3668cdf0e10cSrcweir 			mode = sheet::CellDeleteMode_UP;
3669cdf0e10cSrcweir 		else
3670cdf0e10cSrcweir 			mode = sheet::CellDeleteMode_LEFT;
3671cdf0e10cSrcweir 	}
3672cdf0e10cSrcweir 	uno::Reference< sheet::XCellRangeMovement > xCellRangeMove( thisRange.getSpreadSheet(), uno::UNO_QUERY_THROW );
3673cdf0e10cSrcweir 	xCellRangeMove->removeRange( thisAddress, mode );
3674cdf0e10cSrcweir 
3675cdf0e10cSrcweir }
3676cdf0e10cSrcweir 
3677cdf0e10cSrcweir //XElementAccess
3678cdf0e10cSrcweir sal_Bool SAL_CALL
hasElements()3679cdf0e10cSrcweir ScVbaRange::hasElements() throw (uno::RuntimeException)
3680cdf0e10cSrcweir {
3681cdf0e10cSrcweir 	uno::Reference< table::XColumnRowRange > xColumnRowRange(mxRange, uno::UNO_QUERY );
3682cdf0e10cSrcweir 	if ( xColumnRowRange.is() )
3683cdf0e10cSrcweir 		if ( xColumnRowRange->getRows()->getCount() ||
3684cdf0e10cSrcweir 			xColumnRowRange->getColumns()->getCount() )
3685cdf0e10cSrcweir 			return sal_True;
3686cdf0e10cSrcweir 	return sal_False;
3687cdf0e10cSrcweir }
3688cdf0e10cSrcweir 
3689cdf0e10cSrcweir // XEnumerationAccess
3690cdf0e10cSrcweir uno::Reference< container::XEnumeration > SAL_CALL
createEnumeration()3691cdf0e10cSrcweir ScVbaRange::createEnumeration() throw (uno::RuntimeException)
3692cdf0e10cSrcweir {
3693cdf0e10cSrcweir 	if ( mbIsColumns || mbIsRows )
3694cdf0e10cSrcweir 	{
3695cdf0e10cSrcweir 		uno::Reference< table::XColumnRowRange > xColumnRowRange(mxRange, uno::UNO_QUERY );
3696cdf0e10cSrcweir 		uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny( sal_Int32(1) ), uno::Any() ), uno::UNO_QUERY_THROW );
3697cdf0e10cSrcweir                 sal_Int32 nElems = 0;
3698cdf0e10cSrcweir 		if ( mbIsColumns )
3699cdf0e10cSrcweir 			nElems = xColumnRowRange->getColumns()->getCount();
3700cdf0e10cSrcweir 		else
3701cdf0e10cSrcweir 			nElems = xColumnRowRange->getRows()->getCount();
3702cdf0e10cSrcweir                 return new ColumnsRowEnumeration( mxContext, xRange, nElems );
3703cdf0e10cSrcweir 
3704cdf0e10cSrcweir 	}
3705cdf0e10cSrcweir     return new CellsEnumeration( mxParent, mxContext, m_Areas );
3706cdf0e10cSrcweir }
3707cdf0e10cSrcweir 
3708cdf0e10cSrcweir ::rtl::OUString SAL_CALL
getDefaultMethodName()3709cdf0e10cSrcweir ScVbaRange::getDefaultMethodName(  ) throw (uno::RuntimeException)
3710cdf0e10cSrcweir {
3711cdf0e10cSrcweir 	const static rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM("Item") );
3712cdf0e10cSrcweir 	return sName;
3713cdf0e10cSrcweir }
3714cdf0e10cSrcweir 
3715cdf0e10cSrcweir 
3716cdf0e10cSrcweir // returns calc internal col. width ( in points )
3717cdf0e10cSrcweir double
getCalcColWidth(const table::CellRangeAddress & rAddress)3718cdf0e10cSrcweir ScVbaRange::getCalcColWidth( const table::CellRangeAddress& rAddress) throw (uno::RuntimeException)
3719cdf0e10cSrcweir {
3720cdf0e10cSrcweir 	ScDocument* pDoc = getScDocument();
3721cdf0e10cSrcweir 	sal_uInt16 nWidth = pDoc->GetOriginalWidth( static_cast< SCCOL >( rAddress.StartColumn ), static_cast< SCTAB >( rAddress.Sheet ) );
3722cdf0e10cSrcweir 	double nPoints = lcl_TwipsToPoints( nWidth );
3723cdf0e10cSrcweir 	nPoints = lcl_Round2DecPlaces( nPoints );
3724cdf0e10cSrcweir 	return nPoints;
3725cdf0e10cSrcweir }
3726cdf0e10cSrcweir 
3727cdf0e10cSrcweir double
getCalcRowHeight(const table::CellRangeAddress & rAddress)3728cdf0e10cSrcweir ScVbaRange::getCalcRowHeight( const table::CellRangeAddress& rAddress ) throw (uno::RuntimeException)
3729cdf0e10cSrcweir {
3730cdf0e10cSrcweir 	ScDocument* pDoc = getDocumentFromRange( mxRange );
3731cdf0e10cSrcweir 	sal_uInt16 nWidth = pDoc->GetOriginalHeight( rAddress.StartRow, rAddress.Sheet );
3732cdf0e10cSrcweir 	double nPoints = lcl_TwipsToPoints( nWidth );
3733cdf0e10cSrcweir 	nPoints = lcl_Round2DecPlaces( nPoints );
3734cdf0e10cSrcweir 	return nPoints;
3735cdf0e10cSrcweir }
3736cdf0e10cSrcweir 
3737cdf0e10cSrcweir // return Char Width in points
getDefaultCharWidth(ScDocShell * pDocShell)3738cdf0e10cSrcweir double getDefaultCharWidth( ScDocShell* pDocShell )
3739cdf0e10cSrcweir {
3740cdf0e10cSrcweir     ScDocument* pDoc = pDocShell->GetDocument();
3741cdf0e10cSrcweir     OutputDevice* pRefDevice = pDoc->GetRefDevice();
3742cdf0e10cSrcweir     ScPatternAttr* pAttr = pDoc->GetDefPattern();
3743cdf0e10cSrcweir     ::Font aDefFont;
3744cdf0e10cSrcweir     pAttr->GetFont( aDefFont, SC_AUTOCOL_BLACK, pRefDevice );
3745cdf0e10cSrcweir     pRefDevice->SetFont( aDefFont );
3746cdf0e10cSrcweir     long nCharWidth = pRefDevice->GetTextWidth( String( '0' ) );        // 1/100th mm
3747cdf0e10cSrcweir     return lcl_hmmToPoints( nCharWidth );
3748cdf0e10cSrcweir }
3749cdf0e10cSrcweir 
3750cdf0e10cSrcweir uno::Any SAL_CALL
getColumnWidth()3751cdf0e10cSrcweir ScVbaRange::getColumnWidth() throw (uno::RuntimeException)
3752cdf0e10cSrcweir {
3753cdf0e10cSrcweir 	sal_Int32 nLen = m_Areas->getCount();
3754cdf0e10cSrcweir 	if ( nLen > 1 )
3755cdf0e10cSrcweir 	{
3756cdf0e10cSrcweir 		uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny( sal_Int32(1) ), uno::Any() ), uno::UNO_QUERY_THROW );
3757cdf0e10cSrcweir 		return xRange->getColumnWidth();
3758cdf0e10cSrcweir 	}
3759cdf0e10cSrcweir 
3760cdf0e10cSrcweir 	double nColWidth = 	0;
3761cdf0e10cSrcweir 	ScDocShell* pShell = getScDocShell();
3762cdf0e10cSrcweir 	if ( pShell )
3763cdf0e10cSrcweir 	{
3764cdf0e10cSrcweir 		uno::Reference< frame::XModel > xModel = pShell->GetModel();
3765cdf0e10cSrcweir 		double defaultCharWidth = getDefaultCharWidth( pShell );
3766cdf0e10cSrcweir 		RangeHelper thisRange( mxRange );
3767cdf0e10cSrcweir 		table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
3768cdf0e10cSrcweir 		sal_Int32 nStartCol = thisAddress.StartColumn;
3769cdf0e10cSrcweir 		sal_Int32 nEndCol = thisAddress.EndColumn;
3770cdf0e10cSrcweir 		sal_uInt16 nColTwips = 0;
3771cdf0e10cSrcweir 		for( sal_Int32 nCol = nStartCol ; nCol <= nEndCol; ++nCol )
3772cdf0e10cSrcweir 		{
3773cdf0e10cSrcweir 			thisAddress.StartColumn = nCol;
3774cdf0e10cSrcweir 			sal_uInt16 nCurTwips = pShell->GetDocument()->GetOriginalWidth( static_cast< SCCOL >( thisAddress.StartColumn ), static_cast< SCTAB >( thisAddress.Sheet ) );
3775cdf0e10cSrcweir 			if ( nCol == nStartCol )
3776cdf0e10cSrcweir 				nColTwips =  nCurTwips;
3777cdf0e10cSrcweir 			if ( nColTwips != nCurTwips )
3778cdf0e10cSrcweir 				return aNULL();
3779cdf0e10cSrcweir 		}
3780cdf0e10cSrcweir         nColWidth = lcl_TwipsToPoints( nColTwips );
3781cdf0e10cSrcweir         if ( nColWidth != 0.0 )
3782cdf0e10cSrcweir             nColWidth = ( nColWidth / defaultCharWidth ) - fExtraWidth;
3783cdf0e10cSrcweir 	}
3784cdf0e10cSrcweir 	nColWidth = lcl_Round2DecPlaces( nColWidth );
3785cdf0e10cSrcweir 	return uno::makeAny( nColWidth );
3786cdf0e10cSrcweir }
3787cdf0e10cSrcweir 
3788cdf0e10cSrcweir void SAL_CALL
setColumnWidth(const uno::Any & _columnwidth)3789cdf0e10cSrcweir ScVbaRange::setColumnWidth( const uno::Any& _columnwidth ) throw (uno::RuntimeException)
3790cdf0e10cSrcweir {
3791cdf0e10cSrcweir 	sal_Int32 nLen = m_Areas->getCount();
3792cdf0e10cSrcweir 	if ( nLen > 1 )
3793cdf0e10cSrcweir 	{
3794cdf0e10cSrcweir 		for ( sal_Int32 index = 1; index != nLen; ++index )
3795cdf0e10cSrcweir 		{
3796cdf0e10cSrcweir 			uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny( sal_Int32(index) ), uno::Any() ), uno::UNO_QUERY_THROW );
3797cdf0e10cSrcweir 			xRange->setColumnWidth( _columnwidth );
3798cdf0e10cSrcweir 		}
3799cdf0e10cSrcweir 		return;
3800cdf0e10cSrcweir 	}
3801cdf0e10cSrcweir 	double nColWidth = 0;
3802cdf0e10cSrcweir 	_columnwidth >>= nColWidth;
3803cdf0e10cSrcweir 	nColWidth = lcl_Round2DecPlaces( nColWidth );
3804cdf0e10cSrcweir         ScDocShell* pDocShell = getScDocShell();
3805cdf0e10cSrcweir         if ( pDocShell )
3806cdf0e10cSrcweir         {
3807cdf0e10cSrcweir             if ( nColWidth != 0.0 )
3808cdf0e10cSrcweir                 nColWidth = ( nColWidth + fExtraWidth ) * getDefaultCharWidth( pDocShell );
3809cdf0e10cSrcweir 			RangeHelper thisRange( mxRange );
3810cdf0e10cSrcweir 			table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
3811cdf0e10cSrcweir 			sal_uInt16 nTwips = lcl_pointsToTwips( nColWidth );
3812cdf0e10cSrcweir 
3813cdf0e10cSrcweir 			ScDocFunc aFunc(*pDocShell);
3814cdf0e10cSrcweir 			SCCOLROW nColArr[2];
3815cdf0e10cSrcweir 			nColArr[0] = thisAddress.StartColumn;
3816cdf0e10cSrcweir 			nColArr[1] = thisAddress.EndColumn;
3817cdf0e10cSrcweir             // #163561# use mode SC_SIZE_DIRECT: hide for width 0, show for other values
3818cdf0e10cSrcweir             aFunc.SetWidthOrHeight( sal_True, 1, nColArr, thisAddress.Sheet, SC_SIZE_DIRECT,
3819cdf0e10cSrcweir 		                                                                        nTwips, sal_True, sal_True );
3820cdf0e10cSrcweir 
3821cdf0e10cSrcweir 		}
3822cdf0e10cSrcweir }
3823cdf0e10cSrcweir 
3824cdf0e10cSrcweir uno::Any SAL_CALL
getWidth()3825cdf0e10cSrcweir ScVbaRange::getWidth() throw (uno::RuntimeException)
3826cdf0e10cSrcweir {
3827cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
3828cdf0e10cSrcweir 	{
3829cdf0e10cSrcweir 		uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny( sal_Int32(1) ), uno::Any() ), uno::UNO_QUERY_THROW );
3830cdf0e10cSrcweir 		return xRange->getWidth();
3831cdf0e10cSrcweir 	}
3832cdf0e10cSrcweir 	uno::Reference< table::XColumnRowRange > xColRowRange( mxRange, uno::UNO_QUERY_THROW );
3833cdf0e10cSrcweir 	uno::Reference< container::XIndexAccess > xIndexAccess( xColRowRange->getColumns(), uno::UNO_QUERY_THROW );
3834cdf0e10cSrcweir 	sal_Int32 nElems = xIndexAccess->getCount();
3835cdf0e10cSrcweir 	double nWidth = 0;
3836cdf0e10cSrcweir 	for ( sal_Int32 index=0; index<nElems; ++index )
3837cdf0e10cSrcweir 	{
3838cdf0e10cSrcweir 		uno::Reference< sheet::XCellRangeAddressable > xAddressable( xIndexAccess->getByIndex( index ), uno::UNO_QUERY_THROW );
3839cdf0e10cSrcweir 		double nTmpWidth = getCalcColWidth( xAddressable->getRangeAddress() );
3840cdf0e10cSrcweir 		nWidth += nTmpWidth;
3841cdf0e10cSrcweir 	}
3842cdf0e10cSrcweir 	return uno::makeAny( nWidth );
3843cdf0e10cSrcweir }
3844cdf0e10cSrcweir 
3845cdf0e10cSrcweir uno::Any SAL_CALL
Areas(const uno::Any & item)3846cdf0e10cSrcweir ScVbaRange::Areas( const uno::Any& item) throw (uno::RuntimeException)
3847cdf0e10cSrcweir {
3848cdf0e10cSrcweir 	if ( !item.hasValue() )
3849cdf0e10cSrcweir 		return uno::makeAny( m_Areas );
3850cdf0e10cSrcweir 	return m_Areas->Item( item, uno::Any() );
3851cdf0e10cSrcweir }
3852cdf0e10cSrcweir 
3853cdf0e10cSrcweir uno::Reference< excel::XRange >
getArea(sal_Int32 nIndex)3854cdf0e10cSrcweir ScVbaRange::getArea( sal_Int32 nIndex ) throw( css::uno::RuntimeException )
3855cdf0e10cSrcweir {
3856cdf0e10cSrcweir 	if ( !m_Areas.is() )
3857cdf0e10cSrcweir 		throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("No areas available")), uno::Reference< uno::XInterface >() );
3858cdf0e10cSrcweir 	uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny( ++nIndex ), uno::Any() ), uno::UNO_QUERY_THROW );
3859cdf0e10cSrcweir 	return xRange;
3860cdf0e10cSrcweir }
3861cdf0e10cSrcweir 
3862cdf0e10cSrcweir uno::Any
Borders(const uno::Any & item)3863cdf0e10cSrcweir ScVbaRange::Borders( const uno::Any& item ) throw( script::BasicErrorException, uno::RuntimeException )
3864cdf0e10cSrcweir {
3865cdf0e10cSrcweir 	if ( !item.hasValue() )
3866cdf0e10cSrcweir 		return uno::makeAny( getBorders() );
3867cdf0e10cSrcweir 	return getBorders()->Item( item, uno::Any() );
3868cdf0e10cSrcweir }
3869cdf0e10cSrcweir 
3870cdf0e10cSrcweir uno::Any SAL_CALL
BorderAround(const css::uno::Any & LineStyle,const css::uno::Any & Weight,const css::uno::Any & ColorIndex,const css::uno::Any & Color)3871cdf0e10cSrcweir ScVbaRange::BorderAround( const css::uno::Any& LineStyle, const css::uno::Any& Weight,
3872cdf0e10cSrcweir                 const css::uno::Any& ColorIndex, const css::uno::Any& Color ) throw (css::uno::RuntimeException)
3873cdf0e10cSrcweir {
3874cdf0e10cSrcweir     sal_Int32 nCount = getBorders()->getCount();
3875cdf0e10cSrcweir 
3876cdf0e10cSrcweir     for( sal_Int32 i = 0; i < nCount; i++ )
3877cdf0e10cSrcweir     {
3878cdf0e10cSrcweir         const sal_Int32 nLineType = supportedIndexTable[i];
3879cdf0e10cSrcweir         switch( nLineType )
3880cdf0e10cSrcweir         {
3881cdf0e10cSrcweir             case excel::XlBordersIndex::xlEdgeLeft:
3882cdf0e10cSrcweir             case excel::XlBordersIndex::xlEdgeTop:
3883cdf0e10cSrcweir             case excel::XlBordersIndex::xlEdgeBottom:
3884cdf0e10cSrcweir             case excel::XlBordersIndex::xlEdgeRight:
3885cdf0e10cSrcweir             {
3886cdf0e10cSrcweir                 uno::Reference< excel::XBorder > xBorder( m_Borders->Item( uno::makeAny( nLineType ), uno::Any() ), uno::UNO_QUERY_THROW );
3887cdf0e10cSrcweir                 if( LineStyle.hasValue() )
3888cdf0e10cSrcweir                 {
3889cdf0e10cSrcweir                     xBorder->setLineStyle( LineStyle );
3890cdf0e10cSrcweir                 }
3891cdf0e10cSrcweir                 if( Weight.hasValue() )
3892cdf0e10cSrcweir                 {
3893cdf0e10cSrcweir                     xBorder->setWeight( Weight );
3894cdf0e10cSrcweir                 }
3895cdf0e10cSrcweir                 if( ColorIndex.hasValue() )
3896cdf0e10cSrcweir                 {
3897cdf0e10cSrcweir                     xBorder->setColorIndex( ColorIndex );
3898cdf0e10cSrcweir                 }
3899cdf0e10cSrcweir                 if( Color.hasValue() )
3900cdf0e10cSrcweir                 {
3901cdf0e10cSrcweir                     xBorder->setColor( Color );
3902cdf0e10cSrcweir                 }
3903cdf0e10cSrcweir                 break;
3904cdf0e10cSrcweir             }
3905cdf0e10cSrcweir             case excel::XlBordersIndex::xlInsideVertical:
3906cdf0e10cSrcweir             case excel::XlBordersIndex::xlInsideHorizontal:
3907cdf0e10cSrcweir             case excel::XlBordersIndex::xlDiagonalDown:
3908cdf0e10cSrcweir             case excel::XlBordersIndex::xlDiagonalUp:
3909cdf0e10cSrcweir                 break;
3910cdf0e10cSrcweir             default:
3911cdf0e10cSrcweir                 return uno::makeAny( sal_False );
3912cdf0e10cSrcweir         }
3913cdf0e10cSrcweir     }
3914cdf0e10cSrcweir     return uno::makeAny( sal_True );
3915cdf0e10cSrcweir }
3916cdf0e10cSrcweir 
3917cdf0e10cSrcweir uno::Any SAL_CALL
getRowHeight()3918cdf0e10cSrcweir ScVbaRange::getRowHeight() throw (uno::RuntimeException)
3919cdf0e10cSrcweir {
3920cdf0e10cSrcweir 	sal_Int32 nLen = m_Areas->getCount();
3921cdf0e10cSrcweir 	if ( nLen > 1 )
3922cdf0e10cSrcweir 	{
3923cdf0e10cSrcweir 		uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny( sal_Int32(1) ), uno::Any() ), uno::UNO_QUERY_THROW );
3924cdf0e10cSrcweir 		return xRange->getRowHeight();
3925cdf0e10cSrcweir 	}
3926cdf0e10cSrcweir 
3927cdf0e10cSrcweir 	// if any row's RowHeight in the
3928cdf0e10cSrcweir 	// range is different from any other then return NULL
3929cdf0e10cSrcweir 	RangeHelper thisRange( mxRange );
3930cdf0e10cSrcweir 	table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
3931cdf0e10cSrcweir 
3932cdf0e10cSrcweir 	sal_Int32 nStartRow = thisAddress.StartRow;
3933cdf0e10cSrcweir 	sal_Int32 nEndRow = thisAddress.EndRow;
3934cdf0e10cSrcweir         sal_uInt16 nRowTwips = 0;
3935cdf0e10cSrcweir 	// #TODO probably possible to use the SfxItemSet ( and see if
3936cdf0e10cSrcweir 	//  SFX_ITEM_DONTCARE is set ) to improve performance
3937cdf0e10cSrcweir // #CHECKME looks like this is general behaviour not just row Range specific
3938cdf0e10cSrcweir //	if ( mbIsRows )
3939cdf0e10cSrcweir 	ScDocShell* pShell = getScDocShell();
3940cdf0e10cSrcweir 	if ( pShell )
3941cdf0e10cSrcweir 	{
3942cdf0e10cSrcweir 		for ( sal_Int32 nRow = nStartRow ; nRow <= nEndRow; ++nRow )
3943cdf0e10cSrcweir 		{
3944cdf0e10cSrcweir 			thisAddress.StartRow = nRow;
3945cdf0e10cSrcweir 			sal_uInt16 nCurTwips = pShell->GetDocument()->GetOriginalHeight( thisAddress.StartRow, thisAddress.Sheet );
3946cdf0e10cSrcweir 			if ( nRow == nStartRow )
3947cdf0e10cSrcweir 				nRowTwips = nCurTwips;
3948cdf0e10cSrcweir 			if ( nRowTwips != nCurTwips )
3949cdf0e10cSrcweir 				return aNULL();
3950cdf0e10cSrcweir 		}
3951cdf0e10cSrcweir 	}
3952cdf0e10cSrcweir 	double nHeight = lcl_Round2DecPlaces( lcl_TwipsToPoints( nRowTwips ) );
3953cdf0e10cSrcweir 	return uno::makeAny( nHeight );
3954cdf0e10cSrcweir }
3955cdf0e10cSrcweir 
3956cdf0e10cSrcweir void SAL_CALL
setRowHeight(const uno::Any & _rowheight)3957cdf0e10cSrcweir ScVbaRange::setRowHeight( const uno::Any& _rowheight) throw (uno::RuntimeException)
3958cdf0e10cSrcweir {
3959cdf0e10cSrcweir 	sal_Int32 nLen = m_Areas->getCount();
3960cdf0e10cSrcweir 	if ( nLen > 1 )
3961cdf0e10cSrcweir 	{
3962cdf0e10cSrcweir 		for ( sal_Int32 index = 1; index != nLen; ++index )
3963cdf0e10cSrcweir 		{
3964cdf0e10cSrcweir 			uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny( sal_Int32(index) ), uno::Any() ), uno::UNO_QUERY_THROW );
3965cdf0e10cSrcweir 			xRange->setRowHeight( _rowheight );
3966cdf0e10cSrcweir 		}
3967cdf0e10cSrcweir 		return;
3968cdf0e10cSrcweir 	}
3969cdf0e10cSrcweir 	double nHeight = 0; // Incomming height is in points
3970cdf0e10cSrcweir         _rowheight >>= nHeight;
3971cdf0e10cSrcweir 	nHeight = lcl_Round2DecPlaces( nHeight );
3972cdf0e10cSrcweir 	RangeHelper thisRange( mxRange );
3973cdf0e10cSrcweir 	table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
3974cdf0e10cSrcweir 	sal_uInt16 nTwips = lcl_pointsToTwips( nHeight );
3975cdf0e10cSrcweir 
3976cdf0e10cSrcweir 	ScDocShell* pDocShell = getDocShellFromRange( mxRange );
3977cdf0e10cSrcweir 	ScDocFunc aFunc(*pDocShell);
3978cdf0e10cSrcweir 	SCCOLROW nRowArr[2];
3979cdf0e10cSrcweir 	nRowArr[0] = thisAddress.StartRow;
3980cdf0e10cSrcweir 	nRowArr[1] = thisAddress.EndRow;
3981cdf0e10cSrcweir     // #163561# use mode SC_SIZE_DIRECT: hide for height 0, show for other values
3982cdf0e10cSrcweir     aFunc.SetWidthOrHeight( sal_False, 1, nRowArr, thisAddress.Sheet, SC_SIZE_DIRECT,
3983cdf0e10cSrcweir                                                                         nTwips, sal_True, sal_True );
3984cdf0e10cSrcweir }
3985cdf0e10cSrcweir 
3986cdf0e10cSrcweir uno::Any SAL_CALL
getPageBreak()3987cdf0e10cSrcweir ScVbaRange::getPageBreak() throw (uno::RuntimeException)
3988cdf0e10cSrcweir {
3989cdf0e10cSrcweir 	sal_Int32 nPageBreak = excel::XlPageBreak::xlPageBreakNone;
3990cdf0e10cSrcweir 	ScDocShell* pShell = getDocShellFromRange( mxRange );
3991cdf0e10cSrcweir 	if ( pShell )
3992cdf0e10cSrcweir 	{
3993cdf0e10cSrcweir 		RangeHelper thisRange( mxRange );
3994cdf0e10cSrcweir 		table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
3995cdf0e10cSrcweir 		sal_Bool bColumn = sal_False;
3996cdf0e10cSrcweir 
3997cdf0e10cSrcweir 		if (thisAddress.StartRow==0)
3998cdf0e10cSrcweir 		    bColumn = sal_True;
3999cdf0e10cSrcweir 
4000cdf0e10cSrcweir 		uno::Reference< frame::XModel > xModel = pShell->GetModel();
4001cdf0e10cSrcweir 		if ( xModel.is() )
4002cdf0e10cSrcweir 		{
4003cdf0e10cSrcweir 	        ScDocument* pDoc =  getDocumentFromRange( mxRange );
4004cdf0e10cSrcweir 
4005cdf0e10cSrcweir             ScBreakType nBreak = BREAK_NONE;
4006cdf0e10cSrcweir 			if ( !bColumn )
4007cdf0e10cSrcweir                 nBreak = pDoc->HasRowBreak(thisAddress.StartRow, thisAddress.Sheet);
4008cdf0e10cSrcweir 			else
4009cdf0e10cSrcweir                 nBreak = pDoc->HasColBreak(thisAddress.StartColumn, thisAddress.Sheet);
4010cdf0e10cSrcweir 
4011cdf0e10cSrcweir             if (nBreak & BREAK_PAGE)
4012cdf0e10cSrcweir 			    nPageBreak = excel::XlPageBreak::xlPageBreakAutomatic;
4013cdf0e10cSrcweir 
4014cdf0e10cSrcweir             if (nBreak & BREAK_MANUAL)
4015cdf0e10cSrcweir 			    nPageBreak = excel::XlPageBreak::xlPageBreakManual;
4016cdf0e10cSrcweir 		}
4017cdf0e10cSrcweir 	}
4018cdf0e10cSrcweir 
4019cdf0e10cSrcweir 	return uno::makeAny( nPageBreak );
4020cdf0e10cSrcweir }
4021cdf0e10cSrcweir 
4022cdf0e10cSrcweir void SAL_CALL
setPageBreak(const uno::Any & _pagebreak)4023cdf0e10cSrcweir ScVbaRange::setPageBreak( const uno::Any& _pagebreak) throw (uno::RuntimeException)
4024cdf0e10cSrcweir {
4025cdf0e10cSrcweir 	sal_Int32 nPageBreak = 0;
4026cdf0e10cSrcweir     _pagebreak >>= nPageBreak;
4027cdf0e10cSrcweir 
4028cdf0e10cSrcweir 	ScDocShell* pShell = getDocShellFromRange( mxRange );
4029cdf0e10cSrcweir 	if ( pShell )
4030cdf0e10cSrcweir 	{
4031cdf0e10cSrcweir 		RangeHelper thisRange( mxRange );
4032cdf0e10cSrcweir 		table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
4033cdf0e10cSrcweir 		if ((thisAddress.StartColumn==0) && (thisAddress.StartRow==0))
4034cdf0e10cSrcweir 		    return;
4035cdf0e10cSrcweir 		sal_Bool bColumn = sal_False;
4036cdf0e10cSrcweir 
4037cdf0e10cSrcweir 		if (thisAddress.StartRow==0)
4038cdf0e10cSrcweir 		    bColumn = sal_True;
4039cdf0e10cSrcweir 
4040cdf0e10cSrcweir 		ScAddress aAddr( static_cast<SCCOL>(thisAddress.StartColumn), thisAddress.StartRow, thisAddress.Sheet );
4041cdf0e10cSrcweir 		uno::Reference< frame::XModel > xModel = pShell->GetModel();
4042cdf0e10cSrcweir 		if ( xModel.is() )
4043cdf0e10cSrcweir 		{
4044cdf0e10cSrcweir 			ScTabViewShell* pViewShell = excel::getBestViewShell( xModel );
4045cdf0e10cSrcweir 			if ( nPageBreak == excel::XlPageBreak::xlPageBreakManual )
4046cdf0e10cSrcweir 			    pViewShell->InsertPageBreak( bColumn, sal_True, &aAddr);
4047cdf0e10cSrcweir 			else if ( nPageBreak == excel::XlPageBreak::xlPageBreakNone )
4048cdf0e10cSrcweir 			    pViewShell->DeletePageBreak( bColumn, sal_True, &aAddr);
4049cdf0e10cSrcweir 		}
4050cdf0e10cSrcweir 	}
4051cdf0e10cSrcweir }
4052cdf0e10cSrcweir 
4053cdf0e10cSrcweir uno::Any SAL_CALL
getHeight()4054cdf0e10cSrcweir ScVbaRange::getHeight() throw (uno::RuntimeException)
4055cdf0e10cSrcweir {
4056cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
4057cdf0e10cSrcweir 	{
4058cdf0e10cSrcweir 		uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny( sal_Int32(1) ), uno::Any() ), uno::UNO_QUERY_THROW );
4059cdf0e10cSrcweir 		return xRange->getHeight();
4060cdf0e10cSrcweir 	}
4061cdf0e10cSrcweir 
4062cdf0e10cSrcweir 	uno::Reference< table::XColumnRowRange > xColRowRange( mxRange, uno::UNO_QUERY_THROW );
4063cdf0e10cSrcweir 	uno::Reference< container::XIndexAccess > xIndexAccess( xColRowRange->getRows(), uno::UNO_QUERY_THROW );
4064cdf0e10cSrcweir 	sal_Int32 nElems = xIndexAccess->getCount();
4065cdf0e10cSrcweir 	double nHeight = 0;
4066cdf0e10cSrcweir 	for ( sal_Int32 index=0; index<nElems; ++index )
4067cdf0e10cSrcweir 	{
4068cdf0e10cSrcweir         	uno::Reference< sheet::XCellRangeAddressable > xAddressable( xIndexAccess->getByIndex( index ), uno::UNO_QUERY_THROW );
4069cdf0e10cSrcweir 		nHeight += getCalcRowHeight(xAddressable->getRangeAddress() );
4070cdf0e10cSrcweir 	}
4071cdf0e10cSrcweir 	return uno::makeAny( nHeight );
4072cdf0e10cSrcweir }
4073cdf0e10cSrcweir 
4074cdf0e10cSrcweir awt::Point
getPosition()4075cdf0e10cSrcweir ScVbaRange::getPosition() throw ( uno::RuntimeException )
4076cdf0e10cSrcweir {
4077cdf0e10cSrcweir         awt::Point aPoint;
4078cdf0e10cSrcweir 	uno::Reference< beans::XPropertySet > xProps;
4079cdf0e10cSrcweir 	if ( mxRange.is() )
4080cdf0e10cSrcweir 		xProps.set( mxRange, uno::UNO_QUERY_THROW );
4081cdf0e10cSrcweir 	else
4082cdf0e10cSrcweir 		xProps.set( mxRanges, uno::UNO_QUERY_THROW );
4083cdf0e10cSrcweir 	xProps->getPropertyValue(POSITION) >>= aPoint;
4084cdf0e10cSrcweir 	return aPoint;
4085cdf0e10cSrcweir }
4086cdf0e10cSrcweir uno::Any SAL_CALL
getLeft()4087cdf0e10cSrcweir ScVbaRange::getLeft() throw (uno::RuntimeException)
4088cdf0e10cSrcweir {
4089cdf0e10cSrcweir 	// helperapi returns the first ranges left ( and top below )
4090cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
4091cdf0e10cSrcweir 		return getArea( 0 )->getLeft();
4092cdf0e10cSrcweir         awt::Point aPoint = getPosition();
4093cdf0e10cSrcweir 	return uno::makeAny( lcl_hmmToPoints( aPoint.X ) );
4094cdf0e10cSrcweir }
4095cdf0e10cSrcweir 
4096cdf0e10cSrcweir 
4097cdf0e10cSrcweir uno::Any SAL_CALL
getTop()4098cdf0e10cSrcweir ScVbaRange::getTop() throw (uno::RuntimeException)
4099cdf0e10cSrcweir {
4100cdf0e10cSrcweir 	// helperapi returns the first ranges top
4101cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
4102cdf0e10cSrcweir 		return getArea( 0 )->getTop();
4103cdf0e10cSrcweir         awt::Point aPoint= getPosition();
4104cdf0e10cSrcweir 	return uno::makeAny( lcl_hmmToPoints( aPoint.Y ) );
4105cdf0e10cSrcweir }
4106cdf0e10cSrcweir 
4107cdf0e10cSrcweir uno::Reference< excel::XWorksheet >
getWorksheet()4108cdf0e10cSrcweir ScVbaRange::getWorksheet() throw (uno::RuntimeException)
4109cdf0e10cSrcweir {
4110cdf0e10cSrcweir 	// #TODO #FIXME parent should always be set up ( currently thats not
4111cdf0e10cSrcweir 	// the case )
4112cdf0e10cSrcweir 	uno::Reference< excel::XWorksheet > xSheet( getParent(), uno::UNO_QUERY );
4113cdf0e10cSrcweir 	if ( !xSheet.is() )
4114cdf0e10cSrcweir 	{
4115cdf0e10cSrcweir 		uno::Reference< table::XCellRange > xRange = mxRange;
4116cdf0e10cSrcweir 
4117cdf0e10cSrcweir 		if ( mxRanges.is() ) // assign xRange to first range
4118cdf0e10cSrcweir 		{
4119cdf0e10cSrcweir 			uno::Reference< container::XIndexAccess > xIndex( mxRanges, uno::UNO_QUERY_THROW );
4120cdf0e10cSrcweir 			xRange.set( xIndex->getByIndex( 0 ), uno::UNO_QUERY_THROW );
4121cdf0e10cSrcweir 		}
4122cdf0e10cSrcweir 		ScDocShell* pDocShell = getDocShellFromRange(xRange);
4123cdf0e10cSrcweir 		RangeHelper rHelper(xRange);
4124cdf0e10cSrcweir 		// parent should be Thisworkbook
4125cdf0e10cSrcweir        	xSheet.set( new ScVbaWorksheet( uno::Reference< XHelperInterface >(), mxContext,rHelper.getSpreadSheet(),pDocShell->GetModel()) );
4126cdf0e10cSrcweir 	}
4127cdf0e10cSrcweir 	return xSheet;
4128cdf0e10cSrcweir }
4129cdf0e10cSrcweir 
4130cdf0e10cSrcweir // #TODO remove this ugly application processing
4131cdf0e10cSrcweir // Process an application Range request e.g. 'Range("a1,b2,a4:b6")
4132cdf0e10cSrcweir uno::Reference< excel::XRange >
ApplicationRange(const uno::Reference<uno::XComponentContext> & xContext,const css::uno::Any & Cell1,const css::uno::Any & Cell2)4133cdf0e10cSrcweir ScVbaRange::ApplicationRange( const uno::Reference< uno::XComponentContext >& xContext, const css::uno::Any &Cell1, const css::uno::Any &Cell2 ) throw (css::uno::RuntimeException)
4134cdf0e10cSrcweir {
4135cdf0e10cSrcweir 	// Althought the documentation seems clear that Range without a
4136cdf0e10cSrcweir 	// qualifier then its a shortcut for ActiveSheet.Range
4137cdf0e10cSrcweir 	// however, similarly Application.Range is apparently also a
4138cdf0e10cSrcweir 	// shortcut for ActiveSheet.Range
4139cdf0e10cSrcweir 	// The is however a subtle behavioural difference I've come across
4140cdf0e10cSrcweir 	// wrt to named ranges.
4141cdf0e10cSrcweir 	// If a named range "test" exists { Sheet1!$A1 } and the active sheet
4142cdf0e10cSrcweir 	// is Sheet2 then the following will fail
4143cdf0e10cSrcweir 	// msgbox ActiveSheet.Range("test").Address ' failes
4144cdf0e10cSrcweir 	// msgbox WorkSheets("Sheet2").Range("test").Address
4145cdf0e10cSrcweir 	// but !!!
4146cdf0e10cSrcweir 	// msgbox Range("test").Address ' works
4147cdf0e10cSrcweir 	// msgbox Application.Range("test").Address ' works
4148cdf0e10cSrcweir 
4149cdf0e10cSrcweir 	// Single param Range
4150cdf0e10cSrcweir 	rtl::OUString sRangeName;
4151cdf0e10cSrcweir 	Cell1 >>= sRangeName;
4152cdf0e10cSrcweir 	if ( Cell1.hasValue() && !Cell2.hasValue() && sRangeName.getLength() )
4153cdf0e10cSrcweir 	{
4154cdf0e10cSrcweir 		const static rtl::OUString sNamedRanges( RTL_CONSTASCII_USTRINGPARAM("NamedRanges"));
4155cdf0e10cSrcweir 		uno::Reference< beans::XPropertySet > xPropSet( getCurrentExcelDoc(xContext), uno::UNO_QUERY_THROW );
4156cdf0e10cSrcweir 
4157cdf0e10cSrcweir 		uno::Reference< container::XNameAccess > xNamed( xPropSet->getPropertyValue( sNamedRanges ), uno::UNO_QUERY_THROW );
4158cdf0e10cSrcweir 		uno::Reference< sheet::XCellRangeReferrer > xReferrer;
4159cdf0e10cSrcweir 		try
4160cdf0e10cSrcweir 		{
4161cdf0e10cSrcweir 			xReferrer.set ( xNamed->getByName( sRangeName ), uno::UNO_QUERY );
4162cdf0e10cSrcweir 		}
4163cdf0e10cSrcweir 		catch( uno::Exception& /*e*/ )
4164cdf0e10cSrcweir 		{
4165cdf0e10cSrcweir 			// do nothing
4166cdf0e10cSrcweir 		}
4167cdf0e10cSrcweir 		if ( xReferrer.is() )
4168cdf0e10cSrcweir 		{
4169cdf0e10cSrcweir 			uno::Reference< table::XCellRange > xRange = xReferrer->getReferredCells();
4170cdf0e10cSrcweir 			if ( xRange.is() )
4171cdf0e10cSrcweir 			{
4172cdf0e10cSrcweir 				uno::Reference< excel::XRange > xVbRange =  new ScVbaRange( excel::getUnoSheetModuleObj( xRange ), xContext, xRange );
4173cdf0e10cSrcweir 				return xVbRange;
4174cdf0e10cSrcweir 			}
4175cdf0e10cSrcweir 		}
4176cdf0e10cSrcweir 	}
4177cdf0e10cSrcweir 	uno::Reference< sheet::XSpreadsheetView > xView( getCurrentExcelDoc(xContext)->getCurrentController(), uno::UNO_QUERY );
4178cdf0e10cSrcweir 	uno::Reference< table::XCellRange > xSheetRange( xView->getActiveSheet(), uno::UNO_QUERY_THROW );
4179cdf0e10cSrcweir 	ScVbaRange* pRange = new ScVbaRange( excel::getUnoSheetModuleObj( xSheetRange ), xContext, xSheetRange );
4180cdf0e10cSrcweir 	uno::Reference< excel::XRange > xVbSheetRange( pRange );
4181cdf0e10cSrcweir 	return pRange->Range( Cell1, Cell2, true );
4182cdf0e10cSrcweir }
4183cdf0e10cSrcweir 
4184cdf0e10cSrcweir uno::Reference< sheet::XDatabaseRanges >
lcl_GetDataBaseRanges(ScDocShell * pShell)4185cdf0e10cSrcweir lcl_GetDataBaseRanges( ScDocShell* pShell ) throw ( uno::RuntimeException )
4186cdf0e10cSrcweir {
4187cdf0e10cSrcweir 	uno::Reference< frame::XModel > xModel;
4188cdf0e10cSrcweir 	if ( pShell )
4189cdf0e10cSrcweir 		xModel.set( pShell->GetModel(), uno::UNO_QUERY_THROW );
4190cdf0e10cSrcweir 	uno::Reference< beans::XPropertySet > xModelProps( xModel, uno::UNO_QUERY_THROW );
4191cdf0e10cSrcweir 	uno::Reference< sheet::XDatabaseRanges > xDBRanges( xModelProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DatabaseRanges") ) ), uno::UNO_QUERY_THROW );
4192cdf0e10cSrcweir 	return xDBRanges;
4193cdf0e10cSrcweir }
4194cdf0e10cSrcweir // returns the XDatabaseRange for the autofilter on sheet (nSheet)
4195cdf0e10cSrcweir // also populates sName with the name of range
4196cdf0e10cSrcweir uno::Reference< sheet::XDatabaseRange >
lcl_GetAutoFiltRange(ScDocShell * pShell,sal_Int16 nSheet,rtl::OUString & sName)4197cdf0e10cSrcweir lcl_GetAutoFiltRange( ScDocShell* pShell, sal_Int16 nSheet, rtl::OUString& sName )
4198cdf0e10cSrcweir {
4199cdf0e10cSrcweir 	uno::Reference< container::XIndexAccess > xIndexAccess( lcl_GetDataBaseRanges( pShell ), uno::UNO_QUERY_THROW );
4200cdf0e10cSrcweir 	uno::Reference< sheet::XDatabaseRange > xDataBaseRange;
4201cdf0e10cSrcweir 	table::CellRangeAddress dbAddress;
4202cdf0e10cSrcweir 	for ( sal_Int32 index=0; index < xIndexAccess->getCount(); ++index )
4203cdf0e10cSrcweir 	{
4204cdf0e10cSrcweir 		uno::Reference< sheet::XDatabaseRange > xDBRange( xIndexAccess->getByIndex( index ), uno::UNO_QUERY_THROW );
4205cdf0e10cSrcweir 		uno::Reference< container::XNamed > xNamed( xDBRange, uno::UNO_QUERY_THROW );
4206cdf0e10cSrcweir 		// autofilters work weirdly with openoffice, unnamed is the default
4207cdf0e10cSrcweir 		// named range which is used to create an autofilter, but
4208cdf0e10cSrcweir 		// its also possible that another name could be used
4209cdf0e10cSrcweir 		//     this also causes problems when an autofilter is created on
4210cdf0e10cSrcweir 		//     another sheet
4211cdf0e10cSrcweir 		// ( but.. you can use any named range )
4212cdf0e10cSrcweir 		dbAddress = xDBRange->getDataArea();
4213cdf0e10cSrcweir 		if ( dbAddress.Sheet == nSheet )
4214cdf0e10cSrcweir 		{
4215cdf0e10cSrcweir 			sal_Bool bHasAuto = sal_False;
4216cdf0e10cSrcweir 			uno::Reference< beans::XPropertySet > xProps( xDBRange, uno::UNO_QUERY_THROW );
4217cdf0e10cSrcweir 			xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("AutoFilter") ) ) >>= bHasAuto;
4218cdf0e10cSrcweir 			if ( bHasAuto )
4219cdf0e10cSrcweir 			{
4220cdf0e10cSrcweir 				sName = xNamed->getName();
4221cdf0e10cSrcweir 				xDataBaseRange=xDBRange;
4222cdf0e10cSrcweir 				break;
4223cdf0e10cSrcweir 			}
4224cdf0e10cSrcweir 		}
4225cdf0e10cSrcweir 	}
4226cdf0e10cSrcweir 	return xDataBaseRange;
4227cdf0e10cSrcweir }
4228cdf0e10cSrcweir 
4229cdf0e10cSrcweir // Helper functions for AutoFilter
lcl_GetDBData_Impl(ScDocShell * pDocShell,sal_Int16 nSheet)4230cdf0e10cSrcweir ScDBData* lcl_GetDBData_Impl( ScDocShell* pDocShell, sal_Int16 nSheet )
4231cdf0e10cSrcweir {
4232cdf0e10cSrcweir 	rtl::OUString sName;
4233cdf0e10cSrcweir 	lcl_GetAutoFiltRange( pDocShell, nSheet, sName );
4234cdf0e10cSrcweir 	OSL_TRACE("lcl_GetDBData_Impl got autofilter range %s for sheet %d",
4235cdf0e10cSrcweir 		rtl::OUStringToOString( sName, RTL_TEXTENCODING_UTF8 ).getStr() , nSheet );
4236cdf0e10cSrcweir 	ScDBData* pRet = NULL;
4237cdf0e10cSrcweir 	if (pDocShell)
4238cdf0e10cSrcweir 	{
4239cdf0e10cSrcweir 		ScDBCollection* pNames = pDocShell->GetDocument()->GetDBCollection();
4240cdf0e10cSrcweir 		if (pNames)
4241cdf0e10cSrcweir 		{
4242cdf0e10cSrcweir 			sal_uInt16 nPos = 0;
4243cdf0e10cSrcweir 			if (pNames->SearchName( sName , nPos ))
4244cdf0e10cSrcweir 				pRet = (*pNames)[nPos];
4245cdf0e10cSrcweir 		}
4246cdf0e10cSrcweir 	}
4247cdf0e10cSrcweir 	return pRet;
4248cdf0e10cSrcweir }
4249cdf0e10cSrcweir 
lcl_SelectAll(ScDocShell * pDocShell,ScQueryParam & aParam)4250cdf0e10cSrcweir void lcl_SelectAll( ScDocShell* pDocShell, ScQueryParam& aParam )
4251cdf0e10cSrcweir {
4252cdf0e10cSrcweir 	if ( pDocShell )
4253cdf0e10cSrcweir 	{
4254cdf0e10cSrcweir 		ScViewData* pViewData = pDocShell->GetViewData();
4255cdf0e10cSrcweir 		if ( pViewData )
4256cdf0e10cSrcweir 		{
4257cdf0e10cSrcweir 			OSL_TRACE("Pushing out SelectAll query");
4258cdf0e10cSrcweir 			pViewData->GetView()->Query( aParam, NULL, sal_True );
4259cdf0e10cSrcweir 		}
4260cdf0e10cSrcweir 	}
4261cdf0e10cSrcweir }
4262cdf0e10cSrcweir 
lcl_GetQueryParam(ScDocShell * pDocShell,sal_Int16 nSheet)4263cdf0e10cSrcweir ScQueryParam lcl_GetQueryParam( ScDocShell* pDocShell, sal_Int16 nSheet )
4264cdf0e10cSrcweir {
4265cdf0e10cSrcweir 	ScDBData* pDBData = lcl_GetDBData_Impl( pDocShell, nSheet );
4266cdf0e10cSrcweir 	ScQueryParam aParam;
4267cdf0e10cSrcweir 	if (pDBData)
4268cdf0e10cSrcweir 	{
4269cdf0e10cSrcweir 		pDBData->GetQueryParam( aParam );
4270cdf0e10cSrcweir 	}
4271cdf0e10cSrcweir 	return aParam;
4272cdf0e10cSrcweir }
4273cdf0e10cSrcweir 
lcl_SetAllQueryForField(ScQueryParam & aParam,SCCOLROW nField)4274cdf0e10cSrcweir void lcl_SetAllQueryForField( ScQueryParam& aParam, SCCOLROW nField )
4275cdf0e10cSrcweir {
4276cdf0e10cSrcweir 	bool bFound = false;
4277cdf0e10cSrcweir 	SCSIZE i = 0;
4278cdf0e10cSrcweir 	for (; i<MAXQUERY && !bFound; i++)
4279cdf0e10cSrcweir 	{
4280cdf0e10cSrcweir 		ScQueryEntry& rEntry = aParam.GetEntry(i);
4281cdf0e10cSrcweir 		if ( rEntry.nField == nField)
4282cdf0e10cSrcweir 		{
4283cdf0e10cSrcweir 			OSL_TRACE("found at pos %d", i );
4284cdf0e10cSrcweir 			bFound = true;
4285cdf0e10cSrcweir 		}
4286cdf0e10cSrcweir 	}
4287cdf0e10cSrcweir 	if ( bFound )
4288cdf0e10cSrcweir 	{
4289cdf0e10cSrcweir 		OSL_TRACE("field %d to delete at pos %d", nField, ( i - 1 ) );
4290cdf0e10cSrcweir 		aParam.DeleteQuery(--i);
4291cdf0e10cSrcweir 	}
4292cdf0e10cSrcweir }
4293cdf0e10cSrcweir 
4294cdf0e10cSrcweir 
lcl_SetAllQueryForField(ScDocShell * pDocShell,SCCOLROW nField,sal_Int16 nSheet)4295cdf0e10cSrcweir void lcl_SetAllQueryForField( ScDocShell* pDocShell, SCCOLROW nField, sal_Int16 nSheet )
4296cdf0e10cSrcweir {
4297cdf0e10cSrcweir 	ScQueryParam aParam = lcl_GetQueryParam( pDocShell, nSheet );
4298cdf0e10cSrcweir 	lcl_SetAllQueryForField( aParam, nField );
4299cdf0e10cSrcweir 	lcl_SelectAll( pDocShell, aParam );
4300cdf0e10cSrcweir }
4301cdf0e10cSrcweir 
4302cdf0e10cSrcweir // Modifies sCriteria, and nOp depending on the value of sCriteria
lcl_setTableFieldsFromCriteria(rtl::OUString & sCriteria1,uno::Reference<beans::XPropertySet> & xDescProps,sheet::TableFilterField2 & rFilterField)4303cdf0e10cSrcweir void lcl_setTableFieldsFromCriteria( rtl::OUString& sCriteria1, uno::Reference< beans::XPropertySet >& xDescProps, sheet::TableFilterField2& rFilterField )
4304cdf0e10cSrcweir {
4305cdf0e10cSrcweir 	// #TODO make this more efficient and cycle through
4306cdf0e10cSrcweir 	// sCriteria1 character by character to pick up <,<>,=, * etc.
4307cdf0e10cSrcweir 	// right now I am more concerned with just getting it to work right
4308cdf0e10cSrcweir 
4309cdf0e10cSrcweir 	sCriteria1 = sCriteria1.trim();
4310cdf0e10cSrcweir 	// table of translation of criteria text to FilterOperators
4311cdf0e10cSrcweir 	// <>searchtext - NOT_EQUAL
4312cdf0e10cSrcweir 	//  =searchtext - EQUAL
4313cdf0e10cSrcweir 	//  *searchtext - startwith
4314cdf0e10cSrcweir 	//  <>*searchtext - doesn't startwith
4315cdf0e10cSrcweir 	//  *searchtext* - contains
4316cdf0e10cSrcweir 	//  <>*searchtext* - doesn't contain
4317cdf0e10cSrcweir 	// [>|>=|<=|...]searchtext for GREATER_value, GREATER_EQUAL_value etc.
4318cdf0e10cSrcweir 	sal_Int32 nPos = 0;
4319cdf0e10cSrcweir 	bool bIsNumeric = false;
4320cdf0e10cSrcweir 	if ( ( nPos = sCriteria1.indexOf( EQUALS ) ) == 0 )
4321cdf0e10cSrcweir 	{
4322cdf0e10cSrcweir 		if ( sCriteria1.getLength() == EQUALS.getLength() )
4323cdf0e10cSrcweir             rFilterField.Operator = sheet::FilterOperator2::EMPTY;
4324cdf0e10cSrcweir 		else
4325cdf0e10cSrcweir 		{
4326cdf0e10cSrcweir             rFilterField.Operator = sheet::FilterOperator2::EQUAL;
4327cdf0e10cSrcweir 			sCriteria1 = sCriteria1.copy( EQUALS.getLength() );
4328cdf0e10cSrcweir 			sCriteria1 = VBAToRegexp( sCriteria1 );
4329cdf0e10cSrcweir 			// UseRegularExpressions
4330cdf0e10cSrcweir 			if ( xDescProps.is() )
4331cdf0e10cSrcweir 				xDescProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseRegularExpressions" ) ), uno::Any( sal_True ) );
4332cdf0e10cSrcweir 		}
4333cdf0e10cSrcweir 
4334cdf0e10cSrcweir 	}
4335cdf0e10cSrcweir 	else if ( ( nPos = sCriteria1.indexOf( NOTEQUALS ) ) == 0 )
4336cdf0e10cSrcweir 	{
4337cdf0e10cSrcweir 		if ( sCriteria1.getLength() == NOTEQUALS.getLength() )
4338cdf0e10cSrcweir             rFilterField.Operator = sheet::FilterOperator2::NOT_EMPTY;
4339cdf0e10cSrcweir 		else
4340cdf0e10cSrcweir 		{
4341cdf0e10cSrcweir             rFilterField.Operator = sheet::FilterOperator2::NOT_EQUAL;
4342cdf0e10cSrcweir 			sCriteria1 = sCriteria1.copy( NOTEQUALS.getLength() );
4343cdf0e10cSrcweir 			sCriteria1 = VBAToRegexp( sCriteria1 );
4344cdf0e10cSrcweir 			// UseRegularExpressions
4345cdf0e10cSrcweir 			if ( xDescProps.is() )
4346cdf0e10cSrcweir 				xDescProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseRegularExpressions" ) ), uno::Any( sal_True ) );
4347cdf0e10cSrcweir 		}
4348cdf0e10cSrcweir 	}
4349cdf0e10cSrcweir 	else if ( ( nPos = sCriteria1.indexOf( GREATERTHAN ) ) == 0 )
4350cdf0e10cSrcweir 	{
4351cdf0e10cSrcweir 		bIsNumeric = true;
4352cdf0e10cSrcweir 		if ( ( nPos = sCriteria1.indexOf( GREATERTHANEQUALS ) ) == 0 )
4353cdf0e10cSrcweir 		{
4354cdf0e10cSrcweir 			sCriteria1 = sCriteria1.copy( GREATERTHANEQUALS.getLength() );
4355cdf0e10cSrcweir             rFilterField.Operator = sheet::FilterOperator2::GREATER_EQUAL;
4356cdf0e10cSrcweir 		}
4357cdf0e10cSrcweir 		else
4358cdf0e10cSrcweir 		{
4359cdf0e10cSrcweir 			sCriteria1 = sCriteria1.copy( GREATERTHAN.getLength() );
4360cdf0e10cSrcweir             rFilterField.Operator = sheet::FilterOperator2::GREATER;
4361cdf0e10cSrcweir 		}
4362cdf0e10cSrcweir 
4363cdf0e10cSrcweir 	}
4364cdf0e10cSrcweir 	else if ( ( nPos = sCriteria1.indexOf( LESSTHAN ) ) == 0 )
4365cdf0e10cSrcweir 	{
4366cdf0e10cSrcweir 		bIsNumeric = true;
4367cdf0e10cSrcweir 		if ( ( nPos = sCriteria1.indexOf( LESSTHANEQUALS ) ) == 0 )
4368cdf0e10cSrcweir 		{
4369cdf0e10cSrcweir 			sCriteria1 = sCriteria1.copy( LESSTHANEQUALS.getLength() );
4370cdf0e10cSrcweir             rFilterField.Operator = sheet::FilterOperator2::LESS_EQUAL;
4371cdf0e10cSrcweir 		}
4372cdf0e10cSrcweir 		else
4373cdf0e10cSrcweir 		{
4374cdf0e10cSrcweir 			sCriteria1 = sCriteria1.copy( LESSTHAN.getLength() );
4375cdf0e10cSrcweir             rFilterField.Operator = sheet::FilterOperator2::LESS;
4376cdf0e10cSrcweir 		}
4377cdf0e10cSrcweir 
4378cdf0e10cSrcweir 	}
4379cdf0e10cSrcweir 	else
4380cdf0e10cSrcweir         rFilterField.Operator = sheet::FilterOperator2::EQUAL;
4381cdf0e10cSrcweir 
4382cdf0e10cSrcweir 	if ( bIsNumeric )
4383cdf0e10cSrcweir 	{
4384cdf0e10cSrcweir 		rFilterField.IsNumeric= sal_True;
4385cdf0e10cSrcweir 		rFilterField.NumericValue = sCriteria1.toDouble();
4386cdf0e10cSrcweir 	}
4387cdf0e10cSrcweir 	rFilterField.StringValue = sCriteria1;
4388cdf0e10cSrcweir }
4389cdf0e10cSrcweir 
4390cdf0e10cSrcweir void SAL_CALL
AutoFilter(const uno::Any & Field,const uno::Any & Criteria1,const uno::Any & Operator,const uno::Any & Criteria2,const uno::Any & VisibleDropDown)4391cdf0e10cSrcweir ScVbaRange::AutoFilter( const uno::Any& Field, const uno::Any& Criteria1, const uno::Any& Operator, const uno::Any& Criteria2, const uno::Any& VisibleDropDown ) throw (uno::RuntimeException)
4392cdf0e10cSrcweir {
4393cdf0e10cSrcweir 	// Is there an existing autofilter
4394cdf0e10cSrcweir 	RangeHelper thisRange( mxRange );
4395cdf0e10cSrcweir 	table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
4396cdf0e10cSrcweir 	sal_Int16 nSheet = thisAddress.Sheet;
4397cdf0e10cSrcweir 	ScDocShell* pShell = getScDocShell();
4398cdf0e10cSrcweir 	sal_Bool bHasAuto = sal_False;
4399cdf0e10cSrcweir 	rtl::OUString sAutofiltRangeName;
4400cdf0e10cSrcweir 	uno::Reference< sheet::XDatabaseRange > xDataBaseRange = lcl_GetAutoFiltRange( pShell, nSheet, sAutofiltRangeName );
4401cdf0e10cSrcweir 	if ( xDataBaseRange.is() )
4402cdf0e10cSrcweir 		bHasAuto = true;
4403cdf0e10cSrcweir 
4404cdf0e10cSrcweir 	uno::Reference< table::XCellRange > xFilterRange;
4405cdf0e10cSrcweir 	if ( !bHasAuto )
4406cdf0e10cSrcweir 	{
4407cdf0e10cSrcweir 		if (  m_Areas->getCount() > 1 )
4408cdf0e10cSrcweir 			throw uno::RuntimeException( STR_ERRORMESSAGE_APPLIESTOSINGLERANGEONLY, uno::Reference< uno::XInterface >() );
4409cdf0e10cSrcweir 
4410cdf0e10cSrcweir 		table::CellRangeAddress autoFiltAddress;
4411cdf0e10cSrcweir 		//CurrentRegion()
4412cdf0e10cSrcweir 		if ( isSingleCellRange() )
4413cdf0e10cSrcweir 		{
4414cdf0e10cSrcweir 			uno::Reference< excel::XRange > xCurrent( CurrentRegion() );
4415cdf0e10cSrcweir 			if ( xCurrent.is() )
4416cdf0e10cSrcweir 			{
4417cdf0e10cSrcweir 				ScVbaRange* pRange = getImplementation( xCurrent );
4418cdf0e10cSrcweir 				if ( pRange->isSingleCellRange() )
4419cdf0e10cSrcweir 					throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Can't create AutoFilter") ), uno::Reference< uno::XInterface >() );
4420cdf0e10cSrcweir 				if ( pRange )
4421cdf0e10cSrcweir 				{
4422cdf0e10cSrcweir 					RangeHelper currentRegion( pRange->mxRange );
4423cdf0e10cSrcweir 					autoFiltAddress = currentRegion.getCellRangeAddressable()->getRangeAddress();
4424cdf0e10cSrcweir 				}
4425cdf0e10cSrcweir 			}
4426cdf0e10cSrcweir 		}
4427cdf0e10cSrcweir 		else // multi-cell range
4428cdf0e10cSrcweir 		{
4429cdf0e10cSrcweir 			RangeHelper multiCellRange( mxRange );
4430cdf0e10cSrcweir 			autoFiltAddress = multiCellRange.getCellRangeAddressable()->getRangeAddress();
4431cdf0e10cSrcweir             // #163530# Filter box shows only entry of first row
4432cdf0e10cSrcweir             ScDocument* pDocument = ( pShell ? pShell->GetDocument() : NULL );
4433cdf0e10cSrcweir             if ( pDocument )
4434cdf0e10cSrcweir             {
4435cdf0e10cSrcweir                 SCCOL nStartCol = autoFiltAddress.StartColumn;
4436cdf0e10cSrcweir                 SCROW nStartRow = autoFiltAddress.StartRow;
4437cdf0e10cSrcweir                 SCCOL nEndCol = autoFiltAddress.EndColumn;
4438cdf0e10cSrcweir                 SCROW nEndRow = autoFiltAddress.EndRow;
4439cdf0e10cSrcweir                 pDocument->GetDataArea( autoFiltAddress.Sheet, nStartCol, nStartRow, nEndCol, nEndRow, sal_True, true );
4440cdf0e10cSrcweir                 autoFiltAddress.StartColumn = nStartCol;
4441cdf0e10cSrcweir                 autoFiltAddress.StartRow = nStartRow;
4442cdf0e10cSrcweir                 autoFiltAddress.EndColumn = nEndCol;
4443cdf0e10cSrcweir                 autoFiltAddress.EndRow = nEndRow;
4444cdf0e10cSrcweir             }
4445cdf0e10cSrcweir 		}
4446cdf0e10cSrcweir 
4447cdf0e10cSrcweir 		uno::Reference< sheet::XDatabaseRanges > xDBRanges = lcl_GetDataBaseRanges( pShell );
4448cdf0e10cSrcweir 		if ( xDBRanges.is() )
4449cdf0e10cSrcweir 		{
4450cdf0e10cSrcweir 			rtl::OUString sGenName( RTL_CONSTASCII_USTRINGPARAM("VBA_Autofilter_") );
4451cdf0e10cSrcweir 			sGenName += rtl::OUString::valueOf( static_cast< sal_Int32 >( nSheet ) );
4452cdf0e10cSrcweir 			OSL_TRACE("Going to add new autofilter range.. name %s",
4453cdf0e10cSrcweir 				rtl::OUStringToOString( sGenName, RTL_TEXTENCODING_UTF8 ).getStr() , nSheet );
4454cdf0e10cSrcweir 			if ( !xDBRanges->hasByName( sGenName ) )
4455cdf0e10cSrcweir 				xDBRanges->addNewByName(  sGenName, autoFiltAddress );
4456cdf0e10cSrcweir 			xDataBaseRange.set( xDBRanges->getByName(  sGenName ), uno::UNO_QUERY_THROW );
4457cdf0e10cSrcweir 		}
4458cdf0e10cSrcweir 		if ( !xDataBaseRange.is() )
4459cdf0e10cSrcweir 			throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Failed to find the autofilter placeholder range" ) ), uno::Reference< uno::XInterface >() );
4460cdf0e10cSrcweir 
4461cdf0e10cSrcweir 		uno::Reference< beans::XPropertySet > xDBRangeProps( xDataBaseRange, uno::UNO_QUERY_THROW );
4462cdf0e10cSrcweir 		// set autofilt
4463cdf0e10cSrcweir 		xDBRangeProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("AutoFilter") ), uno::Any(sal_True) );
4464cdf0e10cSrcweir 		// set header (autofilter always need column headers)
4465cdf0e10cSrcweir 		uno::Reference< beans::XPropertySet > xFiltProps( xDataBaseRange->getFilterDescriptor(), uno::UNO_QUERY_THROW );
4466cdf0e10cSrcweir 		xFiltProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ContainsHeader") ), uno::Any( sal_True ) );
4467cdf0e10cSrcweir 	}
4468cdf0e10cSrcweir 
4469cdf0e10cSrcweir 
4470cdf0e10cSrcweir 	sal_Int32 nField = 0; // *IS* 1 based
4471cdf0e10cSrcweir 	rtl::OUString sCriteria1;
4472cdf0e10cSrcweir 	sal_Int32 nOperator = excel::XlAutoFilterOperator::xlAnd;
4473cdf0e10cSrcweir 
4474cdf0e10cSrcweir 	sal_Bool bVisible = sal_True;
4475cdf0e10cSrcweir 	bool  bChangeDropDown = false;
4476cdf0e10cSrcweir 	VisibleDropDown >>= bVisible;
4477cdf0e10cSrcweir 
4478cdf0e10cSrcweir 	if ( bVisible == bHasAuto ) // dropdown is displayed/notdisplayed as
4479cdf0e10cSrcweir 								// required
4480cdf0e10cSrcweir 		bVisible = sal_False;
4481cdf0e10cSrcweir 	else
4482cdf0e10cSrcweir 		bChangeDropDown = true;
4483cdf0e10cSrcweir 	sheet::FilterConnection nConn = sheet::FilterConnection_AND;
4484cdf0e10cSrcweir 	double nCriteria1 = 0;
4485cdf0e10cSrcweir 
4486cdf0e10cSrcweir 	bool bHasCritValue = Criteria1.hasValue();
4487cdf0e10cSrcweir 	bool bCritHasNumericValue = sal_False; // not sure if a numeric criteria is possible
4488cdf0e10cSrcweir 	if ( bHasCritValue )
4489cdf0e10cSrcweir 		bCritHasNumericValue = ( Criteria1 >>= nCriteria1 );
4490cdf0e10cSrcweir 
4491cdf0e10cSrcweir 	if (  !Field.hasValue() && ( Criteria1.hasValue() || Operator.hasValue() || Criteria2.hasValue() ) )
4492cdf0e10cSrcweir 		throw uno::RuntimeException();
4493cdf0e10cSrcweir 	// Use the normal uno api, sometimes e.g. when you want to use ALL as the filter
4494cdf0e10cSrcweir 	// we can't use refresh as the uno interface doesn't have a concept of ALL
4495cdf0e10cSrcweir 	// in this case we just call the core calc functionality -
4496cdf0e10cSrcweir 	bool bAll = false;
4497cdf0e10cSrcweir 	if ( ( Field >>= nField )  )
4498cdf0e10cSrcweir 	{
4499cdf0e10cSrcweir         uno::Reference< sheet::XSheetFilterDescriptor2 > xDesc(
4500cdf0e10cSrcweir                 xDataBaseRange->getFilterDescriptor(), uno::UNO_QUERY );
4501cdf0e10cSrcweir         if ( xDesc.is() )
4502cdf0e10cSrcweir         {
4503cdf0e10cSrcweir             uno::Sequence< sheet::TableFilterField2 > sTabFilts;
4504cdf0e10cSrcweir             uno::Reference< beans::XPropertySet > xDescProps( xDesc, uno::UNO_QUERY_THROW );
4505cdf0e10cSrcweir 		if ( Criteria1.hasValue() )
4506cdf0e10cSrcweir 		{
4507cdf0e10cSrcweir 			sTabFilts.realloc( 1 );
4508cdf0e10cSrcweir             sTabFilts[0].Operator = sheet::FilterOperator2::EQUAL;// sensible default
4509cdf0e10cSrcweir 			if ( !bCritHasNumericValue )
4510cdf0e10cSrcweir 			{
4511cdf0e10cSrcweir 				Criteria1 >>= sCriteria1;
4512cdf0e10cSrcweir 				sTabFilts[0].IsNumeric = bCritHasNumericValue;
4513cdf0e10cSrcweir 				if ( bHasCritValue && sCriteria1.getLength() )
4514cdf0e10cSrcweir 					lcl_setTableFieldsFromCriteria( sCriteria1, xDescProps, sTabFilts[0]  );
4515cdf0e10cSrcweir 				else
4516cdf0e10cSrcweir 					bAll = true;
4517cdf0e10cSrcweir 			}
4518cdf0e10cSrcweir 			else // numeric
4519cdf0e10cSrcweir 			{
4520cdf0e10cSrcweir 				sTabFilts[0].IsNumeric = sal_True;
4521cdf0e10cSrcweir 				sTabFilts[0].NumericValue = nCriteria1;
4522cdf0e10cSrcweir 			}
4523cdf0e10cSrcweir 		}
4524cdf0e10cSrcweir 		else // no value specified
4525cdf0e10cSrcweir 			bAll = true;
4526cdf0e10cSrcweir 		// not sure what the relationship between Criteria1 and Operator is,
4527cdf0e10cSrcweir 		// e.g. can you have a Operator without a Criteria ? in openoffice it
4528cdf0e10cSrcweir 		if ( Operator.hasValue()  && ( Operator >>= nOperator ) )
4529cdf0e10cSrcweir 		{
4530cdf0e10cSrcweir 			// if its a bottom/top Ten(Percent/Value) and there
4531cdf0e10cSrcweir 			// is no value specified for critera1 set it to 10
4532cdf0e10cSrcweir 			if ( !bCritHasNumericValue && !sCriteria1.getLength() && ( nOperator != excel::XlAutoFilterOperator::xlOr ) && ( nOperator != excel::XlAutoFilterOperator::xlAnd ) )
4533cdf0e10cSrcweir 			{
4534cdf0e10cSrcweir 				sTabFilts[0].IsNumeric = sal_True;
4535cdf0e10cSrcweir 				sTabFilts[0].NumericValue = 10;
4536cdf0e10cSrcweir 				bAll = false;
4537cdf0e10cSrcweir 			}
4538cdf0e10cSrcweir 			switch ( nOperator )
4539cdf0e10cSrcweir 			{
4540cdf0e10cSrcweir 				case excel::XlAutoFilterOperator::xlBottom10Items:
4541cdf0e10cSrcweir                     sTabFilts[0].Operator = sheet::FilterOperator2::BOTTOM_VALUES;
4542cdf0e10cSrcweir 					break;
4543cdf0e10cSrcweir 				case excel::XlAutoFilterOperator::xlBottom10Percent:
4544cdf0e10cSrcweir                     sTabFilts[0].Operator = sheet::FilterOperator2::BOTTOM_PERCENT;
4545cdf0e10cSrcweir 					break;
4546cdf0e10cSrcweir 				case excel::XlAutoFilterOperator::xlTop10Items:
4547cdf0e10cSrcweir                     sTabFilts[0].Operator = sheet::FilterOperator2::TOP_VALUES;
4548cdf0e10cSrcweir 					break;
4549cdf0e10cSrcweir 				case excel::XlAutoFilterOperator::xlTop10Percent:
4550cdf0e10cSrcweir                     sTabFilts[0].Operator = sheet::FilterOperator2::TOP_PERCENT;
4551cdf0e10cSrcweir 					break;
4552cdf0e10cSrcweir 				case excel::XlAutoFilterOperator::xlOr:
4553cdf0e10cSrcweir 					nConn = sheet::FilterConnection_OR;
4554cdf0e10cSrcweir 					break;
4555cdf0e10cSrcweir 				case excel::XlAutoFilterOperator::xlAnd:
4556cdf0e10cSrcweir 					nConn = sheet::FilterConnection_AND;
4557cdf0e10cSrcweir 					break;
4558cdf0e10cSrcweir 				default:
4559cdf0e10cSrcweir 					throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("UnknownOption") ), uno::Reference< uno::XInterface >() );
4560cdf0e10cSrcweir 
4561cdf0e10cSrcweir 			}
4562cdf0e10cSrcweir 
4563cdf0e10cSrcweir 		}
4564cdf0e10cSrcweir 		if ( !bAll )
4565cdf0e10cSrcweir 		{
4566cdf0e10cSrcweir 			sTabFilts[0].Connection = sheet::FilterConnection_AND;
4567cdf0e10cSrcweir 			sTabFilts[0].Field = (nField - 1);
4568cdf0e10cSrcweir 
4569cdf0e10cSrcweir 			rtl::OUString sCriteria2;
4570cdf0e10cSrcweir 			if ( Criteria2.hasValue() ) // there is a Criteria2
4571cdf0e10cSrcweir 			{
4572cdf0e10cSrcweir 				sTabFilts.realloc(2);
4573cdf0e10cSrcweir 				sTabFilts[1].Field = sTabFilts[0].Field;
4574cdf0e10cSrcweir 				sTabFilts[1].Connection = nConn;
4575cdf0e10cSrcweir 
4576cdf0e10cSrcweir 				if ( Criteria2 >>= sCriteria2 )
4577cdf0e10cSrcweir 				{
4578cdf0e10cSrcweir 					if ( sCriteria2.getLength() > 0 )
4579cdf0e10cSrcweir 					{
4580cdf0e10cSrcweir 						uno::Reference< beans::XPropertySet > xProps;
4581cdf0e10cSrcweir 						lcl_setTableFieldsFromCriteria( sCriteria2, xProps,  sTabFilts[1] );
4582cdf0e10cSrcweir 						sTabFilts[1].IsNumeric = sal_False;
4583cdf0e10cSrcweir 					}
4584cdf0e10cSrcweir 				}
4585cdf0e10cSrcweir 				else // numeric
4586cdf0e10cSrcweir 				{
4587cdf0e10cSrcweir 					Criteria2 >>= sTabFilts[1].NumericValue;
4588cdf0e10cSrcweir 					sTabFilts[1].IsNumeric = sal_True;
4589cdf0e10cSrcweir                     sTabFilts[1].Operator = sheet::FilterOperator2::EQUAL;
4590cdf0e10cSrcweir 				}
4591cdf0e10cSrcweir 			}
4592cdf0e10cSrcweir 		}
4593cdf0e10cSrcweir 
4594cdf0e10cSrcweir         xDesc->setFilterFields2( sTabFilts );
4595cdf0e10cSrcweir 		if ( !bAll )
4596cdf0e10cSrcweir 		{
4597cdf0e10cSrcweir 			xDataBaseRange->refresh();
4598cdf0e10cSrcweir 		}
4599cdf0e10cSrcweir 		else
4600cdf0e10cSrcweir 			// was 0 based now seems to be 1
4601cdf0e10cSrcweir 			lcl_SetAllQueryForField( pShell, nField, nSheet );
4602cdf0e10cSrcweir         }
4603cdf0e10cSrcweir 	}
4604cdf0e10cSrcweir 	else
4605cdf0e10cSrcweir 	{
4606cdf0e10cSrcweir 		// this is just to toggle autofilter on and off ( not to be confused with
4607cdf0e10cSrcweir 		// a VisibleDropDown option combined with a field, in that case just the
4608cdf0e10cSrcweir 		// button should be disabled ) - currently we don't support that
4609cdf0e10cSrcweir 		bChangeDropDown = true;
4610cdf0e10cSrcweir 		uno::Reference< beans::XPropertySet > xDBRangeProps( xDataBaseRange, uno::UNO_QUERY_THROW );
4611cdf0e10cSrcweir 		if ( bHasAuto )
4612cdf0e10cSrcweir 		{
4613cdf0e10cSrcweir 			// find the any field with the query and select all
4614cdf0e10cSrcweir 			ScQueryParam aParam = lcl_GetQueryParam( pShell, nSheet );
4615cdf0e10cSrcweir 			SCSIZE i = 0;
4616cdf0e10cSrcweir 			for (; i<MAXQUERY; i++)
4617cdf0e10cSrcweir 			{
4618cdf0e10cSrcweir 				ScQueryEntry& rEntry = aParam.GetEntry(i);
4619cdf0e10cSrcweir 				if ( rEntry.bDoQuery )
4620cdf0e10cSrcweir 					lcl_SetAllQueryForField( pShell, rEntry.nField, nSheet );
4621cdf0e10cSrcweir 			}
4622cdf0e10cSrcweir 			// remove exising filters
4623cdf0e10cSrcweir             uno::Reference< sheet::XSheetFilterDescriptor2 > xSheetFilterDescriptor(
4624cdf0e10cSrcweir                     xDataBaseRange->getFilterDescriptor(), uno::UNO_QUERY );
4625cdf0e10cSrcweir             if( xSheetFilterDescriptor.is() )
4626cdf0e10cSrcweir 			    xSheetFilterDescriptor->setFilterFields2( uno::Sequence< sheet::TableFilterField2 >() );
4627cdf0e10cSrcweir 		}
4628cdf0e10cSrcweir 		xDBRangeProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("AutoFilter") ), uno::Any(!bHasAuto) );
4629cdf0e10cSrcweir 
4630cdf0e10cSrcweir 	}
4631cdf0e10cSrcweir }
4632cdf0e10cSrcweir 
4633cdf0e10cSrcweir void SAL_CALL
Insert(const uno::Any & Shift,const uno::Any &)4634cdf0e10cSrcweir ScVbaRange::Insert( const uno::Any& Shift, const uno::Any& /* CopyOrigin */ ) throw (uno::RuntimeException)
4635cdf0e10cSrcweir {
4636cdf0e10cSrcweir 	// It appears ( from the web ) that the undocumented CopyOrigin
4637cdf0e10cSrcweir 	// param should contain member of enum XlInsertFormatOrigin
4638cdf0e10cSrcweir 	// which can have values xlFormatFromLeftOrAbove or xlFormatFromRightOrBelow
4639cdf0e10cSrcweir 	// #TODO investigate resultant behaviour using these constants
4640cdf0e10cSrcweir 	// currently just processing Shift
4641cdf0e10cSrcweir 
4642cdf0e10cSrcweir 	sheet::CellInsertMode mode = sheet::CellInsertMode_NONE;
4643cdf0e10cSrcweir 	if ( Shift.hasValue() )
4644cdf0e10cSrcweir 	{
4645cdf0e10cSrcweir 		sal_Int32 nShift = 0;
4646cdf0e10cSrcweir 		Shift >>= nShift;
4647cdf0e10cSrcweir 		switch ( nShift )
4648cdf0e10cSrcweir 		{
4649cdf0e10cSrcweir 			case excel::XlInsertShiftDirection::xlShiftToRight:
4650cdf0e10cSrcweir 				mode = sheet::CellInsertMode_RIGHT;
4651cdf0e10cSrcweir 				break;
4652cdf0e10cSrcweir 			case excel::XlInsertShiftDirection::xlShiftDown:
4653cdf0e10cSrcweir 				mode = sheet::CellInsertMode_DOWN;
4654cdf0e10cSrcweir 				break;
4655cdf0e10cSrcweir 			default:
4656cdf0e10cSrcweir 				throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ("Illegal paramater ") ), uno::Reference< uno::XInterface >() );
4657cdf0e10cSrcweir 		}
4658cdf0e10cSrcweir 	}
4659cdf0e10cSrcweir 	else
4660cdf0e10cSrcweir 	{
4661cdf0e10cSrcweir 		if ( getRow() >=  getColumn() )
4662cdf0e10cSrcweir 			mode = sheet::CellInsertMode_DOWN;
4663cdf0e10cSrcweir 		else
4664cdf0e10cSrcweir 			mode = sheet::CellInsertMode_RIGHT;
4665cdf0e10cSrcweir 	}
4666cdf0e10cSrcweir 	RangeHelper thisRange( mxRange );
4667cdf0e10cSrcweir 	table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
4668cdf0e10cSrcweir 	uno::Reference< sheet::XCellRangeMovement > xCellRangeMove( thisRange.getSpreadSheet(), uno::UNO_QUERY_THROW );
4669cdf0e10cSrcweir 	xCellRangeMove->insertCells( thisAddress, mode );
4670cdf0e10cSrcweir 
4671cdf0e10cSrcweir     // Paste from clipboard only if the clipboard content was copied via VBA, and not already pasted via VBA again.
4672cdf0e10cSrcweir     // "Insert" behavior should not depend on random clipboard content previously copied by the user.
4673cdf0e10cSrcweir     ScTransferObj* pClipObj = ScTransferObj::GetOwnClipboard( NULL );
4674cdf0e10cSrcweir     if ( pClipObj && pClipObj->GetUseInApi() )
4675cdf0e10cSrcweir 	{
4676cdf0e10cSrcweir 		// After the insert ( this range ) actually has moved
4677cdf0e10cSrcweir 		ScRange aRange( static_cast< SCCOL >( thisAddress.StartColumn ), static_cast< SCROW >( thisAddress.StartRow ), static_cast< SCTAB >( thisAddress.Sheet ), static_cast< SCCOL >( thisAddress.EndColumn ), static_cast< SCROW >( thisAddress.EndRow ), static_cast< SCTAB >( thisAddress.Sheet ) );
4678cdf0e10cSrcweir 	 	uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( getDocShellFromRange( mxRange ) , aRange ) );
4679cdf0e10cSrcweir 		uno::Reference< excel::XRange > xVbaRange( new ScVbaRange( mxParent, mxContext, xRange, mbIsRows, mbIsColumns ) );
4680cdf0e10cSrcweir 		xVbaRange->PasteSpecial( uno::Any(), uno::Any(), uno::Any(), uno::Any() );
4681cdf0e10cSrcweir 	}
4682cdf0e10cSrcweir }
4683cdf0e10cSrcweir 
4684cdf0e10cSrcweir void SAL_CALL
Autofit()4685cdf0e10cSrcweir ScVbaRange::Autofit() throw (uno::RuntimeException)
4686cdf0e10cSrcweir {
4687cdf0e10cSrcweir 	sal_Int32 nLen = m_Areas->getCount();
4688cdf0e10cSrcweir 	if ( nLen > 1 )
4689cdf0e10cSrcweir 	{
4690cdf0e10cSrcweir 		for ( sal_Int32 index = 1; index != nLen; ++index )
4691cdf0e10cSrcweir 		{
4692cdf0e10cSrcweir 			uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny( sal_Int32(index) ), uno::Any() ), uno::UNO_QUERY_THROW );
4693cdf0e10cSrcweir 			xRange->Autofit();
4694cdf0e10cSrcweir 		}
4695cdf0e10cSrcweir 		return;
4696cdf0e10cSrcweir 	}
4697cdf0e10cSrcweir 		// if the range is a not a row or column range autofit will
4698cdf0e10cSrcweir 		// throw an error
4699cdf0e10cSrcweir 
4700cdf0e10cSrcweir 		if ( !( mbIsColumns || mbIsRows ) )
4701cdf0e10cSrcweir 			DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
4702cdf0e10cSrcweir         ScDocShell* pDocShell = getDocShellFromRange( mxRange );
4703cdf0e10cSrcweir         if ( pDocShell )
4704cdf0e10cSrcweir         {
4705cdf0e10cSrcweir 			RangeHelper thisRange( mxRange );
4706cdf0e10cSrcweir 			table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
4707cdf0e10cSrcweir 
4708cdf0e10cSrcweir 			ScDocFunc aFunc(*pDocShell);
4709cdf0e10cSrcweir 			SCCOLROW nColArr[2];
4710cdf0e10cSrcweir 			nColArr[0] = thisAddress.StartColumn;
4711cdf0e10cSrcweir 			nColArr[1] = thisAddress.EndColumn;
4712cdf0e10cSrcweir 			sal_Bool bDirection = sal_True;
4713cdf0e10cSrcweir 			if ( mbIsRows )
4714cdf0e10cSrcweir 			{
4715cdf0e10cSrcweir 				bDirection = sal_False;
4716cdf0e10cSrcweir 				nColArr[0] = thisAddress.StartRow;
4717cdf0e10cSrcweir 				nColArr[1] = thisAddress.EndRow;
4718cdf0e10cSrcweir 			}
4719cdf0e10cSrcweir 			aFunc.SetWidthOrHeight( bDirection, 1, nColArr, thisAddress.Sheet, SC_SIZE_OPTIMAL,
4720cdf0e10cSrcweir 		                                                                        0, sal_True, sal_True );
4721cdf0e10cSrcweir 
4722cdf0e10cSrcweir 	}
4723cdf0e10cSrcweir }
4724cdf0e10cSrcweir 
4725cdf0e10cSrcweir /***************************************************************************************
4726cdf0e10cSrcweir  * interface for text:
4727cdf0e10cSrcweir  * com.sun.star.text.XText, com.sun.star.table.XCell, com.sun.star.container.XEnumerationAccess
4728cdf0e10cSrcweir  * com.sun.star.text.XTextRange,
4729cdf0e10cSrcweir  * the main problem is to recognize the numeric and date, which assosiate with DecimalSeparator, ThousandsSeparator,
4730cdf0e10cSrcweir  * TrailingMinusNumbers and FieldInfo.
4731cdf0e10cSrcweir ***************************************************************************************/
4732cdf0e10cSrcweir void SAL_CALL
TextToColumns(const css::uno::Any & Destination,const css::uno::Any & DataType,const css::uno::Any & TextQualifier,const css::uno::Any & ConsecutinveDelimiter,const css::uno::Any & Tab,const css::uno::Any & Semicolon,const css::uno::Any & Comma,const css::uno::Any & Space,const css::uno::Any & Other,const css::uno::Any & OtherChar,const css::uno::Any &,const css::uno::Any & DecimalSeparator,const css::uno::Any & ThousandsSeparator,const css::uno::Any &)4733cdf0e10cSrcweir ScVbaRange::TextToColumns( const css::uno::Any& Destination, const css::uno::Any& DataType, const css::uno::Any& TextQualifier,
4734cdf0e10cSrcweir         const css::uno::Any& ConsecutinveDelimiter, const css::uno::Any& Tab, const css::uno::Any& Semicolon, const css::uno::Any& Comma,
4735cdf0e10cSrcweir         const css::uno::Any& Space, const css::uno::Any& Other, const css::uno::Any& OtherChar, const css::uno::Any& /*FieldInfo*/,
4736cdf0e10cSrcweir         const css::uno::Any& DecimalSeparator, const css::uno::Any& ThousandsSeparator, const css::uno::Any& /*TrailingMinusNumbers*/  ) throw (css::uno::RuntimeException)
4737cdf0e10cSrcweir {
4738cdf0e10cSrcweir     uno::Reference< excel::XRange > xRange;
4739cdf0e10cSrcweir     if( Destination.hasValue() )
4740cdf0e10cSrcweir     {
4741cdf0e10cSrcweir         if( !( Destination >>= xRange ) )
4742cdf0e10cSrcweir             throw uno::RuntimeException( rtl::OUString::createFromAscii( "Destination parameter should be a range" ),
4743cdf0e10cSrcweir                     uno::Reference< uno::XInterface >() );
4744cdf0e10cSrcweir         OSL_TRACE("set range\n");
4745cdf0e10cSrcweir     }
4746cdf0e10cSrcweir     else
4747cdf0e10cSrcweir     {
4748cdf0e10cSrcweir         //set as current
4749cdf0e10cSrcweir         xRange = this;
4750cdf0e10cSrcweir         OSL_TRACE("set range as himself\n");
4751cdf0e10cSrcweir     }
4752cdf0e10cSrcweir 
4753cdf0e10cSrcweir    sal_Int16 xlTextParsingType = excel::XlTextParsingType::xlDelimited;
4754cdf0e10cSrcweir     if ( DataType.hasValue() )
4755cdf0e10cSrcweir     {
4756cdf0e10cSrcweir         if( !( DataType >>= xlTextParsingType ) )
4757cdf0e10cSrcweir             throw uno::RuntimeException( rtl::OUString::createFromAscii( "DataType parameter should be a short" ),
4758cdf0e10cSrcweir                     uno::Reference< uno::XInterface >() );
4759cdf0e10cSrcweir         OSL_TRACE("set Datatype\n" );
4760cdf0e10cSrcweir     }
4761cdf0e10cSrcweir     sal_Bool bDilimited = ( xlTextParsingType == excel::XlTextParsingType::xlDelimited );
4762cdf0e10cSrcweir 
4763cdf0e10cSrcweir     sal_Int16 xlTextQualifier = excel::XlTextQualifier::xlTextQualifierDoubleQuote;
4764cdf0e10cSrcweir     if( TextQualifier.hasValue() )
4765cdf0e10cSrcweir     {
4766cdf0e10cSrcweir         if( !( TextQualifier >>= xlTextQualifier ))
4767cdf0e10cSrcweir              throw uno::RuntimeException( rtl::OUString::createFromAscii( "TextQualifier parameter should be a short" ),
4768cdf0e10cSrcweir                     uno::Reference< uno::XInterface >() );
4769cdf0e10cSrcweir         OSL_TRACE("set TextQualifier\n");
4770cdf0e10cSrcweir     }
4771cdf0e10cSrcweir 
4772cdf0e10cSrcweir     sal_Bool bConsecutinveDelimiter = sal_False;
4773cdf0e10cSrcweir     if( ConsecutinveDelimiter.hasValue() )
4774cdf0e10cSrcweir     {
4775cdf0e10cSrcweir         if( !( ConsecutinveDelimiter >>= bConsecutinveDelimiter ) )
4776cdf0e10cSrcweir             throw uno::RuntimeException( rtl::OUString::createFromAscii( "ConsecutinveDelimiter parameter should be a boolean" ),
4777cdf0e10cSrcweir                     uno::Reference< uno::XInterface >() );
4778cdf0e10cSrcweir         OSL_TRACE("set ConsecutinveDelimiter\n");
4779cdf0e10cSrcweir     }
4780cdf0e10cSrcweir 
4781cdf0e10cSrcweir     sal_Bool bTab = sal_False;
4782cdf0e10cSrcweir     if( Tab.hasValue() && bDilimited )
4783cdf0e10cSrcweir     {
4784cdf0e10cSrcweir         if( !( Tab >>= bTab ) )
4785cdf0e10cSrcweir             throw uno::RuntimeException( rtl::OUString::createFromAscii( "Tab parameter should be a boolean" ),
4786cdf0e10cSrcweir                     uno::Reference< uno::XInterface >() );
4787cdf0e10cSrcweir         OSL_TRACE("set Tab\n");
4788cdf0e10cSrcweir     }
4789cdf0e10cSrcweir 
4790cdf0e10cSrcweir     sal_Bool bSemicolon = sal_False;
4791cdf0e10cSrcweir     if( Semicolon.hasValue() && bDilimited )
4792cdf0e10cSrcweir     {
4793cdf0e10cSrcweir         if( !( Semicolon >>= bSemicolon ) )
4794cdf0e10cSrcweir             throw uno::RuntimeException( rtl::OUString::createFromAscii( "Semicolon parameter should be a boolean" ),
4795cdf0e10cSrcweir                     uno::Reference< uno::XInterface >() );
4796cdf0e10cSrcweir         OSL_TRACE("set Semicolon\n");
4797cdf0e10cSrcweir     }
4798cdf0e10cSrcweir     sal_Bool bComma = sal_False;
4799cdf0e10cSrcweir     if( Comma.hasValue() && bDilimited )
4800cdf0e10cSrcweir     {
4801cdf0e10cSrcweir         if( !( Comma >>= bComma ) )
4802cdf0e10cSrcweir             throw uno::RuntimeException( rtl::OUString::createFromAscii( "Comma parameter should be a boolean" ),
4803cdf0e10cSrcweir                     uno::Reference< uno::XInterface >() );
4804cdf0e10cSrcweir         OSL_TRACE("set Comma\n");
4805cdf0e10cSrcweir     }
4806cdf0e10cSrcweir     sal_Bool bSpace = sal_False;
4807cdf0e10cSrcweir     if( Space.hasValue() && bDilimited )
4808cdf0e10cSrcweir     {
4809cdf0e10cSrcweir         if( !( Space >>= bSpace ) )
4810cdf0e10cSrcweir             throw uno::RuntimeException( rtl::OUString::createFromAscii( "Space parameter should be a boolean" ),
4811cdf0e10cSrcweir                     uno::Reference< uno::XInterface >() );
4812cdf0e10cSrcweir         OSL_TRACE("set Space\n");
4813cdf0e10cSrcweir     }
4814cdf0e10cSrcweir     sal_Bool bOther = sal_False;
4815cdf0e10cSrcweir     rtl::OUString sOtherChar;
4816cdf0e10cSrcweir     if( Other.hasValue() && bDilimited )
4817cdf0e10cSrcweir     {
4818cdf0e10cSrcweir         if( Other >>= bOther )
4819cdf0e10cSrcweir         {
4820cdf0e10cSrcweir             if( OtherChar.hasValue() )
4821cdf0e10cSrcweir                 if( !( OtherChar >>= sOtherChar ) )
4822cdf0e10cSrcweir                     throw uno::RuntimeException( rtl::OUString::createFromAscii( "OtherChar parameter should be a String" ),
4823cdf0e10cSrcweir                         uno::Reference< uno::XInterface >() );
4824cdf0e10cSrcweir         OSL_TRACE("set OtherChar\n" );
4825cdf0e10cSrcweir         }
4826cdf0e10cSrcweir      else if( bOther )
4827cdf0e10cSrcweir             throw uno::RuntimeException( rtl::OUString::createFromAscii( "Other parameter should be a True" ),
4828cdf0e10cSrcweir                     uno::Reference< uno::XInterface >() );
4829cdf0e10cSrcweir     }
4830cdf0e10cSrcweir  //TODO* FieldInfo   Optional Variant. An array containing parse information for the individual columns of data. The interpretation depends on the value of DataType. When the data is delimited, this argument is an array of two-element arrays, with each two-element array specifying the conversion options for a particular column. The first element is the column number (1-based), and the second element is one of the xlColumnDataType  constants specifying how the column is parsed.
4831cdf0e10cSrcweir 
4832cdf0e10cSrcweir     rtl::OUString sDecimalSeparator;
4833cdf0e10cSrcweir     if( DecimalSeparator.hasValue() )
4834cdf0e10cSrcweir     {
4835cdf0e10cSrcweir         if( !( DecimalSeparator >>= sDecimalSeparator ) )
4836cdf0e10cSrcweir             throw uno::RuntimeException( rtl::OUString::createFromAscii( "DecimalSeparator parameter should be a String" ),
4837cdf0e10cSrcweir                 uno::Reference< uno::XInterface >() );
4838cdf0e10cSrcweir         OSL_TRACE("set DecimalSeparator\n" );
4839cdf0e10cSrcweir     }
4840cdf0e10cSrcweir     rtl::OUString sThousandsSeparator;
4841cdf0e10cSrcweir     if( ThousandsSeparator.hasValue() )
4842cdf0e10cSrcweir     {
4843cdf0e10cSrcweir         if( !( ThousandsSeparator >>= sThousandsSeparator ) )
4844cdf0e10cSrcweir             throw uno::RuntimeException( rtl::OUString::createFromAscii( "ThousandsSeparator parameter should be a String" ),
4845cdf0e10cSrcweir                 uno::Reference< uno::XInterface >() );
4846cdf0e10cSrcweir         OSL_TRACE("set ThousandsSpeparator\n" );
4847cdf0e10cSrcweir     }
4848cdf0e10cSrcweir  //TODO* TrailingMinusNumbers  Optional Variant. Numbers that begin with a minus character.
4849cdf0e10cSrcweir }
4850cdf0e10cSrcweir 
4851cdf0e10cSrcweir uno::Any SAL_CALL
Hyperlinks(const uno::Any & aIndex)4852cdf0e10cSrcweir ScVbaRange::Hyperlinks( const uno::Any& aIndex ) throw (uno::RuntimeException)
4853cdf0e10cSrcweir {
4854cdf0e10cSrcweir     /*  The range object always returns a new Hyperlinks object containing a
4855cdf0e10cSrcweir         fixed list of existing hyperlinks in the range.
4856cdf0e10cSrcweir         See vbahyperlinks.hxx for more details. */
4857cdf0e10cSrcweir 
4858cdf0e10cSrcweir     // get the global hyperlink object of the sheet (sheet should always be the parent of a Range object)
4859cdf0e10cSrcweir     uno::Reference< excel::XWorksheet > xWorksheet( getParent(), uno::UNO_QUERY_THROW );
4860cdf0e10cSrcweir     uno::Reference< excel::XHyperlinks > xSheetHlinks( xWorksheet->Hyperlinks( uno::Any() ), uno::UNO_QUERY_THROW );
4861cdf0e10cSrcweir     ScVbaHyperlinksRef xScSheetHlinks( dynamic_cast< ScVbaHyperlinks* >( xSheetHlinks.get() ) );
4862cdf0e10cSrcweir     if( !xScSheetHlinks.is() )
4863cdf0e10cSrcweir         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Cannot obtain hyperlinks implementation object" ) ), uno::Reference< uno::XInterface >() );
4864cdf0e10cSrcweir 
4865cdf0e10cSrcweir     // create a new local hyperlinks object based on the sheet hyperlinks
4866cdf0e10cSrcweir     ScVbaHyperlinksRef xHlinks( new ScVbaHyperlinks( getParent(), mxContext, xScSheetHlinks, getScRangeList() ) );
4867cdf0e10cSrcweir     if( aIndex.hasValue() )
4868cdf0e10cSrcweir         return xHlinks->Item( aIndex, uno::Any() );
4869cdf0e10cSrcweir     return uno::Any( uno::Reference< excel::XHyperlinks >( xHlinks.get() ) );
4870cdf0e10cSrcweir }
4871cdf0e10cSrcweir 
4872cdf0e10cSrcweir css::uno::Reference< excel::XValidation > SAL_CALL
getValidation()4873cdf0e10cSrcweir ScVbaRange::getValidation() throw (css::uno::RuntimeException)
4874cdf0e10cSrcweir {
4875cdf0e10cSrcweir 	if ( !m_xValidation.is() )
4876cdf0e10cSrcweir 		m_xValidation = new ScVbaValidation( this, mxContext, mxRange );
4877cdf0e10cSrcweir 	return m_xValidation;
4878cdf0e10cSrcweir }
4879cdf0e10cSrcweir 
4880cdf0e10cSrcweir namespace {
4881cdf0e10cSrcweir 
lclGetPrefixChar(const uno::Reference<table::XCell> & rxCell)4882cdf0e10cSrcweir sal_Unicode lclGetPrefixChar( const uno::Reference< table::XCell >& rxCell ) throw (uno::RuntimeException)
4883cdf0e10cSrcweir {
4884cdf0e10cSrcweir     /*  TODO/FIXME: We need an apostroph-prefix property at the cell to
4885cdf0e10cSrcweir         implement this correctly. For now, return an apostroph for every text
4886cdf0e10cSrcweir         cell.
4887cdf0e10cSrcweir 
4888cdf0e10cSrcweir         TODO/FIXME: When Application.TransitionNavigKeys is supported and true,
4889cdf0e10cSrcweir         this function needs to inspect the cell formatting and return different
4890cdf0e10cSrcweir         prefixes according to the horizontal cell alignment.
4891cdf0e10cSrcweir      */
4892cdf0e10cSrcweir     return (rxCell->getType() == table::CellContentType_TEXT) ? '\'' : 0;
4893cdf0e10cSrcweir }
4894cdf0e10cSrcweir 
lclGetPrefixChar(const uno::Reference<table::XCellRange> & rxRange)4895cdf0e10cSrcweir sal_Unicode lclGetPrefixChar( const uno::Reference< table::XCellRange >& rxRange ) throw (uno::RuntimeException)
4896cdf0e10cSrcweir {
4897cdf0e10cSrcweir     /*  This implementation is able to handle different prefixes (needed if
4898cdf0e10cSrcweir         Application.TransitionNavigKeys is true). The function lclGetPrefixChar
4899cdf0e10cSrcweir         for single cells called from here may return any prefix. If that
4900cdf0e10cSrcweir         function returns an empty prefix (NUL character) or different non-empty
4901cdf0e10cSrcweir         prefixes for two cells, this function returns 0.
4902cdf0e10cSrcweir      */
4903cdf0e10cSrcweir     sal_Unicode cCurrPrefix = 0;
4904cdf0e10cSrcweir     table::CellRangeAddress aRangeAddr = lclGetRangeAddress( rxRange );
4905cdf0e10cSrcweir     sal_Int32 nEndCol = aRangeAddr.EndColumn - aRangeAddr.StartColumn;
4906cdf0e10cSrcweir     sal_Int32 nEndRow = aRangeAddr.EndRow - aRangeAddr.StartRow;
4907cdf0e10cSrcweir     for( sal_Int32 nRow = 0; nRow <= nEndRow; ++nRow )
4908cdf0e10cSrcweir     {
4909cdf0e10cSrcweir         for( sal_Int32 nCol = 0; nCol <= nEndCol; ++nCol )
4910cdf0e10cSrcweir         {
4911cdf0e10cSrcweir             uno::Reference< table::XCell > xCell( rxRange->getCellByPosition( nCol, nRow ), uno::UNO_SET_THROW );
4912cdf0e10cSrcweir             sal_Unicode cNewPrefix = lclGetPrefixChar( xCell );
4913cdf0e10cSrcweir             if( (cNewPrefix == 0) || ((cCurrPrefix != 0) && (cNewPrefix != cCurrPrefix)) )
4914cdf0e10cSrcweir                 return 0;
4915cdf0e10cSrcweir             cCurrPrefix = cNewPrefix;
4916cdf0e10cSrcweir         }
4917cdf0e10cSrcweir     }
4918cdf0e10cSrcweir     // all cells contain the same prefix - return it
4919cdf0e10cSrcweir     return cCurrPrefix;
4920cdf0e10cSrcweir }
4921cdf0e10cSrcweir 
lclGetPrefixChar(const uno::Reference<sheet::XSheetCellRangeContainer> & rxRanges)4922cdf0e10cSrcweir sal_Unicode lclGetPrefixChar( const uno::Reference< sheet::XSheetCellRangeContainer >& rxRanges ) throw (uno::RuntimeException)
4923cdf0e10cSrcweir {
4924cdf0e10cSrcweir     sal_Unicode cCurrPrefix = 0;
4925cdf0e10cSrcweir     uno::Reference< container::XEnumerationAccess > xRangesEA( rxRanges, uno::UNO_QUERY_THROW );
4926cdf0e10cSrcweir     uno::Reference< container::XEnumeration > xRangesEnum( xRangesEA->createEnumeration(), uno::UNO_SET_THROW );
4927cdf0e10cSrcweir     while( xRangesEnum->hasMoreElements() )
4928cdf0e10cSrcweir     {
4929cdf0e10cSrcweir         uno::Reference< table::XCellRange > xRange( xRangesEnum->nextElement(), uno::UNO_QUERY_THROW );
4930cdf0e10cSrcweir         sal_Unicode cNewPrefix = lclGetPrefixChar( xRange );
4931cdf0e10cSrcweir         if( (cNewPrefix == 0) || ((cCurrPrefix != 0) && (cNewPrefix != cCurrPrefix)) )
4932cdf0e10cSrcweir             return 0;
4933cdf0e10cSrcweir         cCurrPrefix = cNewPrefix;
4934cdf0e10cSrcweir     }
4935cdf0e10cSrcweir     // all ranges contain the same prefix - return it
4936cdf0e10cSrcweir     return cCurrPrefix;
4937cdf0e10cSrcweir }
4938cdf0e10cSrcweir 
lclGetPrefixVariant(sal_Unicode cPrefixChar)4939cdf0e10cSrcweir inline uno::Any lclGetPrefixVariant( sal_Unicode cPrefixChar )
4940cdf0e10cSrcweir {
4941cdf0e10cSrcweir     return uno::Any( (cPrefixChar == 0) ? ::rtl::OUString() : ::rtl::OUString( cPrefixChar ) );
4942cdf0e10cSrcweir }
4943cdf0e10cSrcweir 
4944cdf0e10cSrcweir } // namespace
4945cdf0e10cSrcweir 
getPrefixCharacter()4946cdf0e10cSrcweir uno::Any SAL_CALL ScVbaRange::getPrefixCharacter() throw (uno::RuntimeException)
4947cdf0e10cSrcweir {
4948cdf0e10cSrcweir     /*  (1) If Application.TransitionNavigKeys is false, this function returns
4949cdf0e10cSrcweir         an apostroph character if the text cell begins with an apostroph
4950cdf0e10cSrcweir         character (formula return values are not taken into account); otherwise
4951cdf0e10cSrcweir         an empty string.
4952cdf0e10cSrcweir 
4953cdf0e10cSrcweir         (2) If Application.TransitionNavigKeys is true, this function returns
4954cdf0e10cSrcweir         an apostroph character, if the cell is left-aligned; a double-quote
4955cdf0e10cSrcweir         character, if the cell is right-aligned; a circumflex character, if the
4956cdf0e10cSrcweir         cell is centered; a backslash character, if the cell is set to filled;
4957cdf0e10cSrcweir         or an empty string, if nothing of the above.
4958cdf0e10cSrcweir 
4959cdf0e10cSrcweir         If a range or a list of ranges contains texts with leading apostroph
4960cdf0e10cSrcweir         character as well as other cells, this function returns an empty
4961cdf0e10cSrcweir         string.
4962cdf0e10cSrcweir      */
4963cdf0e10cSrcweir 
4964cdf0e10cSrcweir     if( mxRange.is() )
4965cdf0e10cSrcweir         return lclGetPrefixVariant( lclGetPrefixChar( mxRange ) );
4966cdf0e10cSrcweir     if( mxRanges.is() )
4967cdf0e10cSrcweir         return lclGetPrefixVariant( lclGetPrefixChar( mxRanges ) );
4968cdf0e10cSrcweir 	throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected empty Range object" ) ), uno::Reference< uno::XInterface >() );
4969cdf0e10cSrcweir }
4970cdf0e10cSrcweir 
getShowDetail()4971cdf0e10cSrcweir uno::Any ScVbaRange::getShowDetail() throw ( css::uno::RuntimeException)
4972cdf0e10cSrcweir {
4973cdf0e10cSrcweir 	// #FIXME, If the specified range is in a PivotTable report
4974cdf0e10cSrcweir 
4975cdf0e10cSrcweir 	// In MSO VBA, the specified range must be a single summary column or row in an outline. otherwise throw exception
4976cdf0e10cSrcweir 	if( m_Areas->getCount() > 1 )
4977cdf0e10cSrcweir 		throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Can not get Range.ShowDetail attribute ")), uno::Reference< uno::XInterface >() );
4978cdf0e10cSrcweir 
4979cdf0e10cSrcweir 	sal_Bool bShowDetail = sal_False;
4980cdf0e10cSrcweir 
4981cdf0e10cSrcweir 	RangeHelper helper( mxRange );
4982cdf0e10cSrcweir 	uno::Reference< sheet::XSheetCellCursor > xSheetCellCursor = helper.getSheetCellCursor();
4983cdf0e10cSrcweir 	xSheetCellCursor->collapseToCurrentRegion();
4984cdf0e10cSrcweir 	uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable(xSheetCellCursor, uno::UNO_QUERY_THROW);
4985cdf0e10cSrcweir 	table::CellRangeAddress aOutlineAddress = xCellRangeAddressable->getRangeAddress();
4986cdf0e10cSrcweir 
4987cdf0e10cSrcweir 	// check if the specified range is a single summary column or row.
4988cdf0e10cSrcweir 	table::CellRangeAddress thisAddress = helper.getCellRangeAddressable()->getRangeAddress();
4989cdf0e10cSrcweir 	if( (thisAddress.StartRow == thisAddress.EndRow &&  thisAddress.EndRow == aOutlineAddress.EndRow ) ||
4990cdf0e10cSrcweir 		(thisAddress.StartColumn == thisAddress.EndColumn && thisAddress.EndColumn == aOutlineAddress.EndColumn ))
4991cdf0e10cSrcweir 	{
4992cdf0e10cSrcweir 		sal_Bool bColumn =thisAddress.StartRow == thisAddress.EndRow ? sal_False:sal_True;
4993cdf0e10cSrcweir 		ScDocument* pDoc = getDocumentFromRange( mxRange );
4994cdf0e10cSrcweir 		ScOutlineTable* pOutlineTable = pDoc->GetOutlineTable(static_cast<SCTAB>(thisAddress.Sheet), sal_True);
4995cdf0e10cSrcweir 		const ScOutlineArray* pOutlineArray =  bColumn ? pOutlineTable->GetColArray(): pOutlineTable->GetRowArray();
4996cdf0e10cSrcweir 		if( pOutlineArray )
4997cdf0e10cSrcweir 		{
4998cdf0e10cSrcweir 			SCCOLROW nPos = bColumn ? (SCCOLROW)(thisAddress.EndColumn-1):(SCCOLROW)(thisAddress.EndRow-1);
4999cdf0e10cSrcweir 			ScOutlineEntry* pEntry = pOutlineArray->GetEntryByPos( 0, nPos );
5000cdf0e10cSrcweir 			if( pEntry )
5001cdf0e10cSrcweir 			{
5002cdf0e10cSrcweir 				bShowDetail = !pEntry->IsHidden();
5003cdf0e10cSrcweir 				return uno::makeAny( bShowDetail );
5004cdf0e10cSrcweir 			}
5005cdf0e10cSrcweir 		}
5006cdf0e10cSrcweir 	}
5007cdf0e10cSrcweir 	else
5008cdf0e10cSrcweir 	{
5009cdf0e10cSrcweir 		throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Can not set Range.ShowDetail attribute ")), uno::Reference< uno::XInterface >() );
5010cdf0e10cSrcweir 	}
5011cdf0e10cSrcweir     return aNULL();
5012cdf0e10cSrcweir }
5013cdf0e10cSrcweir 
setShowDetail(const uno::Any & aShowDetail)5014cdf0e10cSrcweir void ScVbaRange::setShowDetail(const uno::Any& aShowDetail) throw ( css::uno::RuntimeException)
5015cdf0e10cSrcweir {
5016cdf0e10cSrcweir 	// #FIXME, If the specified range is in a PivotTable report
5017cdf0e10cSrcweir 
5018cdf0e10cSrcweir 	// In MSO VBA, the specified range must be a single summary column or row in an outline. otherwise throw exception
5019cdf0e10cSrcweir 	if( m_Areas->getCount() > 1 )
5020cdf0e10cSrcweir 		throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Can not set Range.ShowDetail attribute ")), uno::Reference< uno::XInterface >() );
5021cdf0e10cSrcweir 
5022cdf0e10cSrcweir 	bool bShowDetail = extractBoolFromAny( aShowDetail );
5023cdf0e10cSrcweir 
5024cdf0e10cSrcweir 	RangeHelper helper( mxRange );
5025cdf0e10cSrcweir 	uno::Reference< sheet::XSheetCellCursor > xSheetCellCursor = helper.getSheetCellCursor();
5026cdf0e10cSrcweir 	xSheetCellCursor->collapseToCurrentRegion();
5027cdf0e10cSrcweir 	uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable(xSheetCellCursor, uno::UNO_QUERY_THROW);
5028cdf0e10cSrcweir 	table::CellRangeAddress aOutlineAddress = xCellRangeAddressable->getRangeAddress();
5029cdf0e10cSrcweir 
5030cdf0e10cSrcweir 	// check if the specified range is a single summary column or row.
5031cdf0e10cSrcweir 	table::CellRangeAddress thisAddress = helper.getCellRangeAddressable()->getRangeAddress();
5032cdf0e10cSrcweir 	if( (thisAddress.StartRow == thisAddress.EndRow &&  thisAddress.EndRow == aOutlineAddress.EndRow ) ||
5033cdf0e10cSrcweir 		(thisAddress.StartColumn == thisAddress.EndColumn && thisAddress.EndColumn == aOutlineAddress.EndColumn ))
5034cdf0e10cSrcweir 	{
5035cdf0e10cSrcweir 		// #FIXME, seems there is a different behavior between MSO and OOo.
5036cdf0e10cSrcweir 		//	In OOo, the showDetail will show all the level entrys, while only show the first level entry in MSO
5037cdf0e10cSrcweir 		uno::Reference< sheet::XSheetOutline > xSheetOutline( helper.getSpreadSheet(), uno::UNO_QUERY_THROW );
5038cdf0e10cSrcweir 		if( bShowDetail )
5039cdf0e10cSrcweir 			xSheetOutline->showDetail( aOutlineAddress );
5040cdf0e10cSrcweir 		else
5041cdf0e10cSrcweir 			xSheetOutline->hideDetail( aOutlineAddress );
5042cdf0e10cSrcweir 	}
5043cdf0e10cSrcweir 	else
5044cdf0e10cSrcweir 	{
5045cdf0e10cSrcweir 		throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Can not set Range.ShowDetail attribute ")), uno::Reference< uno::XInterface >() );
5046cdf0e10cSrcweir 	}
5047cdf0e10cSrcweir }
5048cdf0e10cSrcweir 
5049cdf0e10cSrcweir uno::Reference< excel::XRange > SAL_CALL
MergeArea()5050cdf0e10cSrcweir ScVbaRange::MergeArea() throw (script::BasicErrorException, uno::RuntimeException)
5051cdf0e10cSrcweir {
5052cdf0e10cSrcweir     uno::Reference< sheet::XSheetCellRange > xMergeShellCellRange(mxRange->getCellRangeByPosition(0,0,0,0), uno::UNO_QUERY_THROW);
5053cdf0e10cSrcweir     uno::Reference< sheet::XSheetCellCursor > xMergeSheetCursor(xMergeShellCellRange->getSpreadsheet()->createCursorByRange( xMergeShellCellRange ), uno::UNO_QUERY_THROW);
5054cdf0e10cSrcweir     if( xMergeSheetCursor.is() )
5055cdf0e10cSrcweir     {
5056cdf0e10cSrcweir         xMergeSheetCursor->collapseToMergedArea();
5057cdf0e10cSrcweir         uno::Reference<sheet::XCellRangeAddressable> xMergeCellAddress(xMergeSheetCursor, uno::UNO_QUERY_THROW);
5058cdf0e10cSrcweir         if( xMergeCellAddress.is() )
5059cdf0e10cSrcweir         {
5060cdf0e10cSrcweir             table::CellRangeAddress aCellAddress = xMergeCellAddress->getRangeAddress();
5061cdf0e10cSrcweir             if( aCellAddress.StartColumn ==0 && aCellAddress.EndColumn==0 &&
5062cdf0e10cSrcweir                 aCellAddress.StartRow==0 && aCellAddress.EndRow==0)
5063cdf0e10cSrcweir             {
5064cdf0e10cSrcweir                 return new ScVbaRange( mxParent,mxContext,mxRange );
5065cdf0e10cSrcweir             }
5066cdf0e10cSrcweir             else
5067cdf0e10cSrcweir             {
5068cdf0e10cSrcweir                 ScRange refRange( static_cast< SCCOL >( aCellAddress.StartColumn ), static_cast< SCROW >( aCellAddress.StartRow ), static_cast< SCTAB >( aCellAddress.Sheet ),
5069cdf0e10cSrcweir                                   static_cast< SCCOL >( aCellAddress.EndColumn ), static_cast< SCROW >( aCellAddress.EndRow ), static_cast< SCTAB >( aCellAddress.Sheet ) );
5070cdf0e10cSrcweir                 uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( getScDocShell() , refRange ) );
5071cdf0e10cSrcweir                 return new ScVbaRange( mxParent, mxContext,xRange );
5072cdf0e10cSrcweir             }
5073cdf0e10cSrcweir         }
5074cdf0e10cSrcweir     }
5075cdf0e10cSrcweir     return new ScVbaRange( mxParent, mxContext, mxRange );
5076cdf0e10cSrcweir }
5077cdf0e10cSrcweir 
5078cdf0e10cSrcweir void SAL_CALL
PrintOut(const uno::Any & From,const uno::Any & To,const uno::Any & Copies,const uno::Any & Preview,const uno::Any & ActivePrinter,const uno::Any & PrintToFile,const uno::Any & Collate,const uno::Any & PrToFileName)5079cdf0e10cSrcweir ScVbaRange::PrintOut( const uno::Any& From, const uno::Any& To, const uno::Any& Copies, const uno::Any& Preview, const uno::Any& ActivePrinter, const uno::Any& PrintToFile, const uno::Any& Collate, const uno::Any& PrToFileName ) throw (uno::RuntimeException)
5080cdf0e10cSrcweir {
5081cdf0e10cSrcweir 	ScDocShell* pShell = NULL;
5082cdf0e10cSrcweir 
5083cdf0e10cSrcweir 	sal_Int32 nItems = m_Areas->getCount();
5084cdf0e10cSrcweir 	uno::Sequence< 	table::CellRangeAddress > printAreas( nItems );
5085cdf0e10cSrcweir 	uno::Reference< sheet::XPrintAreas > xPrintAreas;
5086cdf0e10cSrcweir 	for ( sal_Int32 index=1; index <= nItems; ++index )
5087cdf0e10cSrcweir 	{
5088cdf0e10cSrcweir 		uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW );
5089cdf0e10cSrcweir 
5090cdf0e10cSrcweir 		RangeHelper thisRange( xRange->getCellRange() );
5091cdf0e10cSrcweir 		table::CellRangeAddress rangeAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
5092cdf0e10cSrcweir 		if ( index == 1 )
5093cdf0e10cSrcweir 		{
5094cdf0e10cSrcweir 			ScVbaRange* pRange = getImplementation( xRange );
5095cdf0e10cSrcweir 			// initialise the doc shell and the printareas
5096cdf0e10cSrcweir 			pShell = getDocShellFromRange( pRange->mxRange );
5097cdf0e10cSrcweir 			xPrintAreas.set( thisRange.getSpreadSheet(), uno::UNO_QUERY_THROW );
5098cdf0e10cSrcweir 		}
5099cdf0e10cSrcweir 		printAreas[ index - 1 ] = rangeAddress;
5100cdf0e10cSrcweir 	}
5101cdf0e10cSrcweir 	if ( pShell )
5102cdf0e10cSrcweir 	{
5103cdf0e10cSrcweir 		if ( xPrintAreas.is() )
5104cdf0e10cSrcweir 		{
5105cdf0e10cSrcweir 			xPrintAreas->setPrintAreas( printAreas );
5106cdf0e10cSrcweir 			uno::Reference< frame::XModel > xModel = pShell->GetModel();
5107cdf0e10cSrcweir 			PrintOutHelper( excel::getBestViewShell( xModel ), From, To, Copies, Preview, ActivePrinter, PrintToFile, Collate, PrToFileName, sal_True );
5108cdf0e10cSrcweir 		}
5109cdf0e10cSrcweir 	}
5110cdf0e10cSrcweir }
5111cdf0e10cSrcweir 
5112cdf0e10cSrcweir void SAL_CALL
AutoFill(const uno::Reference<excel::XRange> & Destination,const uno::Any & Type)5113cdf0e10cSrcweir ScVbaRange::AutoFill(  const uno::Reference< excel::XRange >& Destination, const uno::Any& Type ) throw (uno::RuntimeException)
5114cdf0e10cSrcweir {
5115cdf0e10cSrcweir 	uno::Reference< excel::XRange > xDest( Destination, uno::UNO_QUERY_THROW );
5116cdf0e10cSrcweir 	ScVbaRange* pRange = getImplementation( xDest );
5117cdf0e10cSrcweir 	RangeHelper destRangeHelper( pRange->mxRange );
5118cdf0e10cSrcweir 	table::CellRangeAddress destAddress = destRangeHelper.getCellRangeAddressable()->getRangeAddress();
5119cdf0e10cSrcweir 
5120cdf0e10cSrcweir 	RangeHelper thisRange( mxRange );
5121cdf0e10cSrcweir 	table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
5122cdf0e10cSrcweir 	ScRange sourceRange;
5123cdf0e10cSrcweir 	ScRange destRange;
5124cdf0e10cSrcweir 
5125cdf0e10cSrcweir 	ScUnoConversion::FillScRange( destRange, destAddress );
5126cdf0e10cSrcweir 	ScUnoConversion::FillScRange( sourceRange, thisAddress );
5127cdf0e10cSrcweir 
5128cdf0e10cSrcweir 
5129cdf0e10cSrcweir 	// source is valid
5130cdf0e10cSrcweir //	if (  !sourceRange.In( destRange ) )
5131cdf0e10cSrcweir //		throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "source not in destination" ) ), uno::Reference< uno::XInterface >() );
5132cdf0e10cSrcweir 
5133cdf0e10cSrcweir 	FillDir eDir = FILL_TO_BOTTOM;
5134cdf0e10cSrcweir 	double fStep = 1.0;
5135cdf0e10cSrcweir 
5136cdf0e10cSrcweir 	ScRange aRange( destRange );
5137cdf0e10cSrcweir 	ScRange aSourceRange( destRange );
5138cdf0e10cSrcweir 
5139cdf0e10cSrcweir 	// default to include the number of Rows in the source range;
5140cdf0e10cSrcweir 	SCCOLROW nSourceCount = ( sourceRange.aEnd.Row() - sourceRange.aStart.Row() ) + 1;
5141cdf0e10cSrcweir 	SCCOLROW nCount = 0;
5142cdf0e10cSrcweir 
5143cdf0e10cSrcweir 	if ( sourceRange != destRange )
5144cdf0e10cSrcweir 	{
5145cdf0e10cSrcweir 		// Find direction of fill, vertical or horizontal
5146cdf0e10cSrcweir 		if ( sourceRange.aStart == destRange.aStart )
5147cdf0e10cSrcweir 		{
5148cdf0e10cSrcweir 			if ( sourceRange.aEnd.Row() == destRange.aEnd.Row() )
5149cdf0e10cSrcweir 			{
5150cdf0e10cSrcweir 				nSourceCount = ( sourceRange.aEnd.Col() - sourceRange.aStart.Col() + 1 );
5151cdf0e10cSrcweir 				aSourceRange.aEnd.SetCol( static_cast<SCCOL>( aSourceRange.aStart.Col() + nSourceCount - 1 ) );
5152cdf0e10cSrcweir 				eDir = FILL_TO_RIGHT;
5153cdf0e10cSrcweir 				nCount = aRange.aEnd.Col() - aSourceRange.aEnd.Col();
5154cdf0e10cSrcweir 			}
5155cdf0e10cSrcweir 			else if ( sourceRange.aEnd.Col() == destRange.aEnd.Col() )
5156cdf0e10cSrcweir 			{
5157cdf0e10cSrcweir 				aSourceRange.aEnd.SetRow( static_cast<SCROW>( aSourceRange.aStart.Row() + nSourceCount ) - 1 );
5158cdf0e10cSrcweir 				nCount = aRange.aEnd.Row() - aSourceRange.aEnd.Row();
5159cdf0e10cSrcweir 				eDir = FILL_TO_BOTTOM;
5160cdf0e10cSrcweir 			}
5161cdf0e10cSrcweir 		}
5162cdf0e10cSrcweir 
5163cdf0e10cSrcweir 		else if ( aSourceRange.aEnd == destRange.aEnd )
5164cdf0e10cSrcweir 		{
5165cdf0e10cSrcweir 			if ( sourceRange.aStart.Col() == destRange.aStart.Col() )
5166cdf0e10cSrcweir 			{
5167cdf0e10cSrcweir 				aSourceRange.aStart.SetRow( static_cast<SCROW>( aSourceRange.aEnd.Row() - nSourceCount + 1 ) );
5168cdf0e10cSrcweir 				nCount = aSourceRange.aStart.Row() - aRange.aStart.Row();
5169cdf0e10cSrcweir 				eDir = FILL_TO_TOP;
5170cdf0e10cSrcweir 				fStep = -fStep;
5171cdf0e10cSrcweir 			}
5172cdf0e10cSrcweir 			else if ( sourceRange.aStart.Row() == destRange.aStart.Row() )
5173cdf0e10cSrcweir 			{
5174cdf0e10cSrcweir 				nSourceCount = ( sourceRange.aEnd.Col() - sourceRange.aStart.Col() ) + 1;
5175cdf0e10cSrcweir 				aSourceRange.aStart.SetCol( static_cast<SCCOL>( aSourceRange.aEnd.Col() - nSourceCount + 1 ) );
5176cdf0e10cSrcweir 				nCount = aSourceRange.aStart.Col() - aRange.aStart.Col();
5177cdf0e10cSrcweir 				eDir = FILL_TO_LEFT;
5178cdf0e10cSrcweir 				fStep = -fStep;
5179cdf0e10cSrcweir 			}
5180cdf0e10cSrcweir 		}
5181cdf0e10cSrcweir 	}
5182cdf0e10cSrcweir 	ScDocShell* pDocSh= getDocShellFromRange( mxRange );
5183cdf0e10cSrcweir 
5184cdf0e10cSrcweir 	FillCmd eCmd = FILL_AUTO;
5185cdf0e10cSrcweir 	FillDateCmd eDateCmd = FILL_DAY;
5186cdf0e10cSrcweir 
5187cdf0e10cSrcweir #ifdef VBA_OOBUILD_HACK
5188cdf0e10cSrcweir 	double fEndValue =  MAXDOUBLE;
5189cdf0e10cSrcweir #endif
5190cdf0e10cSrcweir 
5191cdf0e10cSrcweir 	if ( Type.hasValue() )
5192cdf0e10cSrcweir 	{
5193cdf0e10cSrcweir 		sal_Int16 nFillType = excel::XlAutoFillType::xlFillDefault;
5194cdf0e10cSrcweir 		Type >>= nFillType;
5195cdf0e10cSrcweir 		switch ( nFillType )
5196cdf0e10cSrcweir 		{
5197cdf0e10cSrcweir 			case excel::XlAutoFillType::xlFillCopy:
5198cdf0e10cSrcweir 				eCmd = 	FILL_SIMPLE;
5199cdf0e10cSrcweir 				fStep = 0.0;
5200cdf0e10cSrcweir 				break;
5201cdf0e10cSrcweir 			case excel::XlAutoFillType::xlFillDays:
5202cdf0e10cSrcweir 				eCmd = FILL_DATE;
5203cdf0e10cSrcweir 				break;
5204cdf0e10cSrcweir 			case excel::XlAutoFillType::xlFillMonths:
5205cdf0e10cSrcweir 				eCmd = FILL_DATE;
5206cdf0e10cSrcweir 				eDateCmd = FILL_MONTH;
5207cdf0e10cSrcweir 				break;
5208cdf0e10cSrcweir 			case excel::XlAutoFillType::xlFillWeekdays:
5209cdf0e10cSrcweir 				eCmd = FILL_DATE;
5210cdf0e10cSrcweir 				eDateCmd = FILL_WEEKDAY;
5211cdf0e10cSrcweir 				break;
5212cdf0e10cSrcweir 			case excel::XlAutoFillType::xlFillYears:
5213cdf0e10cSrcweir 				eCmd = FILL_DATE;
5214cdf0e10cSrcweir 				eDateCmd = FILL_YEAR;
5215cdf0e10cSrcweir 				break;
5216cdf0e10cSrcweir 			case excel::XlAutoFillType::xlGrowthTrend:
5217cdf0e10cSrcweir 				eCmd = FILL_GROWTH;
5218cdf0e10cSrcweir 				break;
5219cdf0e10cSrcweir 			case excel::XlAutoFillType::xlFillFormats:
5220cdf0e10cSrcweir 				throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "xlFillFormat not supported for AutoFill" ) ), uno::Reference< uno::XInterface >() );
5221cdf0e10cSrcweir 			case excel::XlAutoFillType::xlFillValues:
5222cdf0e10cSrcweir 			case excel::XlAutoFillType::xlFillSeries:
5223cdf0e10cSrcweir 			case excel::XlAutoFillType::xlLinearTrend:
5224cdf0e10cSrcweir 				eCmd = FILL_LINEAR;
5225cdf0e10cSrcweir 				break;
5226cdf0e10cSrcweir 			case excel::XlAutoFillType::xlFillDefault:
5227cdf0e10cSrcweir 			default:
5228cdf0e10cSrcweir 				eCmd = 	FILL_AUTO;
5229cdf0e10cSrcweir 				break;
5230cdf0e10cSrcweir 		}
5231cdf0e10cSrcweir 	}
5232cdf0e10cSrcweir 	ScDocFunc aFunc(*pDocSh);
5233cdf0e10cSrcweir #ifdef VBA_OOBUILD_HACK
5234cdf0e10cSrcweir 	aFunc.FillAuto( aSourceRange, NULL, eDir, eCmd, eDateCmd, nCount, fStep, fEndValue, sal_True, sal_True );
5235cdf0e10cSrcweir #endif
5236cdf0e10cSrcweir }
5237cdf0e10cSrcweir sal_Bool SAL_CALL
GoalSeek(const uno::Any & Goal,const uno::Reference<excel::XRange> & ChangingCell)5238cdf0e10cSrcweir ScVbaRange::GoalSeek( const uno::Any& Goal, const uno::Reference< excel::XRange >& ChangingCell ) throw (uno::RuntimeException)
5239cdf0e10cSrcweir {
5240cdf0e10cSrcweir 	ScDocShell* pDocShell = getScDocShell();
5241cdf0e10cSrcweir 	sal_Bool bRes = sal_True;
5242cdf0e10cSrcweir 	ScVbaRange* pRange = static_cast< ScVbaRange* >( ChangingCell.get() );
5243cdf0e10cSrcweir 	if ( pDocShell && pRange )
5244cdf0e10cSrcweir 	{
5245cdf0e10cSrcweir 		uno::Reference< sheet::XGoalSeek > xGoalSeek(  pDocShell->GetModel(), uno::UNO_QUERY_THROW );
5246cdf0e10cSrcweir 		RangeHelper thisRange( mxRange );
5247cdf0e10cSrcweir 		table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
5248cdf0e10cSrcweir 		RangeHelper changingCellRange( pRange->mxRange );
5249cdf0e10cSrcweir 		table::CellRangeAddress changingCellAddr = changingCellRange.getCellRangeAddressable()->getRangeAddress();
5250cdf0e10cSrcweir 		rtl::OUString sGoal = getAnyAsString( Goal );
5251cdf0e10cSrcweir 		table::CellAddress thisCell( thisAddress.Sheet, thisAddress.StartColumn, thisAddress.StartRow );
5252cdf0e10cSrcweir 		table::CellAddress changingCell( changingCellAddr.Sheet, changingCellAddr.StartColumn, changingCellAddr.StartRow );
5253cdf0e10cSrcweir 		sheet::GoalResult res = xGoalSeek->seekGoal( thisCell, changingCell, sGoal );
5254cdf0e10cSrcweir 		ChangingCell->setValue( uno::makeAny( res.Result ) );
5255cdf0e10cSrcweir 
5256cdf0e10cSrcweir 		// openoffice behaves differently, result is 0 if the divergence is too great
5257cdf0e10cSrcweir                 // but... if it detects 0 is the value it requires then it will use that
5258cdf0e10cSrcweir 		// e.g. divergence & result both = 0.0 does NOT mean there is an error
5259cdf0e10cSrcweir 		if ( ( res.Divergence != 0.0 ) && ( res.Result == 0.0 ) )
5260cdf0e10cSrcweir 			bRes = sal_False;
5261cdf0e10cSrcweir 	}
5262cdf0e10cSrcweir 	else
5263cdf0e10cSrcweir 		bRes = sal_False;
5264cdf0e10cSrcweir 	return bRes;
5265cdf0e10cSrcweir }
5266cdf0e10cSrcweir 
5267cdf0e10cSrcweir void
Calculate()5268cdf0e10cSrcweir ScVbaRange::Calculate(  ) throw (script::BasicErrorException, uno::RuntimeException)
5269cdf0e10cSrcweir {
5270cdf0e10cSrcweir 	getWorksheet()->Calculate();
5271cdf0e10cSrcweir }
5272cdf0e10cSrcweir 
5273cdf0e10cSrcweir uno::Reference< excel::XRange > SAL_CALL
Item(const uno::Any & row,const uno::Any & column)5274cdf0e10cSrcweir ScVbaRange::Item( const uno::Any& row, const uno::Any& column ) throw (script::BasicErrorException, uno::RuntimeException)
5275cdf0e10cSrcweir {
5276cdf0e10cSrcweir 	if ( mbIsRows || mbIsColumns )
5277cdf0e10cSrcweir 	{
5278cdf0e10cSrcweir 		if ( column.hasValue() )
5279cdf0e10cSrcweir 			DebugHelper::exception(SbERR_BAD_PARAMETER, rtl::OUString() );
5280cdf0e10cSrcweir 		uno::Reference< excel::XRange > xRange;
5281cdf0e10cSrcweir 		if ( mbIsColumns )
5282cdf0e10cSrcweir 			xRange = Columns( row );
5283cdf0e10cSrcweir 		else
5284cdf0e10cSrcweir 			xRange = Rows( row );
5285cdf0e10cSrcweir 		return xRange;
5286cdf0e10cSrcweir 	}
5287cdf0e10cSrcweir 	return Cells( row, column );
5288cdf0e10cSrcweir }
5289cdf0e10cSrcweir 
5290cdf0e10cSrcweir void
AutoOutline()5291cdf0e10cSrcweir ScVbaRange::AutoOutline(  ) throw (script::BasicErrorException, uno::RuntimeException)
5292cdf0e10cSrcweir {
5293cdf0e10cSrcweir 	// #TODO #FIXME needs to check for summary row/col ( whatever they are )
5294cdf0e10cSrcweir 	// not valid for multi Area Addresses
5295cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
5296cdf0e10cSrcweir 		DebugHelper::exception(SbERR_METHOD_FAILED, STR_ERRORMESSAGE_APPLIESTOSINGLERANGEONLY);
5297cdf0e10cSrcweir 	// So needs to either span an entire Row or a just be a single cell
5298cdf0e10cSrcweir 	// ( that contains a summary RowColumn )
5299cdf0e10cSrcweir 	// also the Single cell cause doesn't seem to be handled specially in
5300cdf0e10cSrcweir 	// this code ( ported from the helperapi RangeImpl.java,
5301cdf0e10cSrcweir 	// RangeRowsImpl.java, RangesImpl.java, RangeSingleCellImpl.java
5302cdf0e10cSrcweir 	RangeHelper thisRange( mxRange );
5303cdf0e10cSrcweir 	table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
5304cdf0e10cSrcweir 
5305cdf0e10cSrcweir 	if ( isSingleCellRange() || mbIsRows )
5306cdf0e10cSrcweir 	{
5307cdf0e10cSrcweir 		uno::Reference< sheet::XSheetOutline > xSheetOutline( thisRange.getSpreadSheet(), uno::UNO_QUERY_THROW );
5308cdf0e10cSrcweir        		 xSheetOutline->autoOutline( thisAddress );
5309cdf0e10cSrcweir 	}
5310cdf0e10cSrcweir 	else
5311cdf0e10cSrcweir 		DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
5312cdf0e10cSrcweir }
5313cdf0e10cSrcweir 
5314cdf0e10cSrcweir void SAL_CALL
ClearOutline()5315cdf0e10cSrcweir ScVbaRange:: ClearOutline(  ) throw (script::BasicErrorException, uno::RuntimeException)
5316cdf0e10cSrcweir {
5317cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
5318cdf0e10cSrcweir 	{
5319cdf0e10cSrcweir 		sal_Int32 nItems = m_Areas->getCount();
5320cdf0e10cSrcweir 		for ( sal_Int32 index=1; index <= nItems; ++index )
5321cdf0e10cSrcweir 		{
5322cdf0e10cSrcweir 			uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW );
5323cdf0e10cSrcweir 			xRange->ClearOutline();
5324cdf0e10cSrcweir 		}
5325cdf0e10cSrcweir 		return;
5326cdf0e10cSrcweir 	}
5327cdf0e10cSrcweir 	RangeHelper thisRange( mxRange );
5328cdf0e10cSrcweir 	table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
5329cdf0e10cSrcweir 	uno::Reference< sheet::XSheetOutline > xSheetOutline( thisRange.getSpreadSheet(), uno::UNO_QUERY_THROW );
5330cdf0e10cSrcweir         xSheetOutline->clearOutline();
5331cdf0e10cSrcweir }
5332cdf0e10cSrcweir 
5333cdf0e10cSrcweir void
groupUnGroup(bool bUnGroup)5334cdf0e10cSrcweir ScVbaRange::groupUnGroup( bool bUnGroup ) throw ( script::BasicErrorException, uno::RuntimeException )
5335cdf0e10cSrcweir {
5336cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
5337cdf0e10cSrcweir 		 DebugHelper::exception(SbERR_METHOD_FAILED, STR_ERRORMESSAGE_APPLIESTOSINGLERANGEONLY);
5338cdf0e10cSrcweir 	table::TableOrientation nOrient = table::TableOrientation_ROWS;
5339cdf0e10cSrcweir 	if ( mbIsColumns )
5340cdf0e10cSrcweir 		nOrient = table::TableOrientation_COLUMNS;
5341cdf0e10cSrcweir 	RangeHelper thisRange( mxRange );
5342cdf0e10cSrcweir 	table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
5343cdf0e10cSrcweir 	uno::Reference< sheet::XSheetOutline > xSheetOutline( thisRange.getSpreadSheet(), uno::UNO_QUERY_THROW );
5344cdf0e10cSrcweir 	if ( bUnGroup )
5345cdf0e10cSrcweir 	        xSheetOutline->ungroup( thisAddress, nOrient );
5346cdf0e10cSrcweir 	else
5347cdf0e10cSrcweir 	        xSheetOutline->group( thisAddress, nOrient );
5348cdf0e10cSrcweir }
5349cdf0e10cSrcweir 
5350cdf0e10cSrcweir void SAL_CALL
Group()5351cdf0e10cSrcweir ScVbaRange::Group(  ) throw (script::BasicErrorException, uno::RuntimeException)
5352cdf0e10cSrcweir {
5353cdf0e10cSrcweir 	groupUnGroup();
5354cdf0e10cSrcweir }
5355cdf0e10cSrcweir void SAL_CALL
Ungroup()5356cdf0e10cSrcweir ScVbaRange::Ungroup(  ) throw (script::BasicErrorException, uno::RuntimeException)
5357cdf0e10cSrcweir {
5358cdf0e10cSrcweir 	groupUnGroup(true);
5359cdf0e10cSrcweir }
5360cdf0e10cSrcweir 
lcl_mergeCellsOfRange(const uno::Reference<table::XCellRange> & xCellRange,sal_Bool _bMerge=sal_True)5361cdf0e10cSrcweir void lcl_mergeCellsOfRange( const uno::Reference< table::XCellRange >& xCellRange, sal_Bool _bMerge = sal_True ) throw ( uno::RuntimeException )
5362cdf0e10cSrcweir {
5363cdf0e10cSrcweir         uno::Reference< util::XMergeable > xMergeable( xCellRange, uno::UNO_QUERY_THROW );
5364cdf0e10cSrcweir         xMergeable->merge(_bMerge);
5365cdf0e10cSrcweir }
5366cdf0e10cSrcweir void SAL_CALL
Merge(const uno::Any & Across)5367cdf0e10cSrcweir ScVbaRange::Merge( const uno::Any& Across ) throw (script::BasicErrorException, uno::RuntimeException)
5368cdf0e10cSrcweir {
5369cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
5370cdf0e10cSrcweir 	{
5371cdf0e10cSrcweir 		sal_Int32 nItems = m_Areas->getCount();
5372cdf0e10cSrcweir 		for ( sal_Int32 index=1; index <= nItems; ++index )
5373cdf0e10cSrcweir 		{
5374cdf0e10cSrcweir 			uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW );
5375cdf0e10cSrcweir 			xRange->Merge(Across);
5376cdf0e10cSrcweir 		}
5377cdf0e10cSrcweir 		return;
5378cdf0e10cSrcweir 	}
5379cdf0e10cSrcweir 	uno::Reference< table::XCellRange > oCellRange;
5380cdf0e10cSrcweir 	sal_Bool bAcross = sal_False;
5381cdf0e10cSrcweir 	Across >>= bAcross;
5382cdf0e10cSrcweir 	if ( !bAcross )
5383cdf0e10cSrcweir 		lcl_mergeCellsOfRange( mxRange );
5384cdf0e10cSrcweir 	else
5385cdf0e10cSrcweir 	{
5386cdf0e10cSrcweir 		uno::Reference< excel::XRange > oRangeRowsImpl = Rows( uno::Any() );
5387cdf0e10cSrcweir 		// #TODO #FIXME this seems incredibly lame, this can't be right
5388cdf0e10cSrcweir 		for (sal_Int32 i=1; i <= oRangeRowsImpl->getCount();i++)
5389cdf0e10cSrcweir 		{
5390cdf0e10cSrcweir                		oRangeRowsImpl->Cells( uno::makeAny( i ), uno::Any() )->Merge( uno::makeAny( sal_False ) );
5391cdf0e10cSrcweir            	}
5392cdf0e10cSrcweir 	}
5393cdf0e10cSrcweir }
5394cdf0e10cSrcweir 
5395cdf0e10cSrcweir void SAL_CALL
UnMerge()5396cdf0e10cSrcweir ScVbaRange::UnMerge(  ) throw (script::BasicErrorException, uno::RuntimeException)
5397cdf0e10cSrcweir {
5398cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
5399cdf0e10cSrcweir 	{
5400cdf0e10cSrcweir 		sal_Int32 nItems = m_Areas->getCount();
5401cdf0e10cSrcweir 		for ( sal_Int32 index=1; index <= nItems; ++index )
5402cdf0e10cSrcweir 		{
5403cdf0e10cSrcweir 			uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW );
5404cdf0e10cSrcweir 			xRange->UnMerge();
5405cdf0e10cSrcweir 		}
5406cdf0e10cSrcweir 		return;
5407cdf0e10cSrcweir 	}
5408cdf0e10cSrcweir 	lcl_mergeCellsOfRange( mxRange, sal_False);
5409cdf0e10cSrcweir }
5410cdf0e10cSrcweir 
5411cdf0e10cSrcweir uno::Any SAL_CALL
getStyle()5412cdf0e10cSrcweir ScVbaRange::getStyle() throw (uno::RuntimeException)
5413cdf0e10cSrcweir {
5414cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
5415cdf0e10cSrcweir 	{
5416cdf0e10cSrcweir 		uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny( sal_Int32( 1 ) ), uno::Any() ), uno::UNO_QUERY_THROW  );
5417cdf0e10cSrcweir 		return xRange->getStyle();
5418cdf0e10cSrcweir 	}
5419cdf0e10cSrcweir 	uno::Reference< beans::XPropertySet > xProps( mxRange, uno::UNO_QUERY_THROW );
5420cdf0e10cSrcweir 	rtl::OUString sStyleName;
5421cdf0e10cSrcweir     xProps->getPropertyValue(CELLSTYLE) >>= sStyleName;
5422cdf0e10cSrcweir 	ScDocShell* pShell = getScDocShell();
5423cdf0e10cSrcweir 	uno::Reference< frame::XModel > xModel( pShell->GetModel() );
5424cdf0e10cSrcweir 	uno::Reference< excel::XStyle > xStyle = new ScVbaStyle( this, mxContext,  sStyleName, xModel );
5425cdf0e10cSrcweir 	return uno::makeAny( xStyle );
5426cdf0e10cSrcweir }
5427cdf0e10cSrcweir void SAL_CALL
setStyle(const uno::Any & _style)5428cdf0e10cSrcweir ScVbaRange::setStyle( const uno::Any& _style ) throw (uno::RuntimeException)
5429cdf0e10cSrcweir {
5430cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
5431cdf0e10cSrcweir 	{
5432cdf0e10cSrcweir 		uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny( sal_Int32( 1 ) ), uno::Any() ), uno::UNO_QUERY_THROW );
5433cdf0e10cSrcweir 		xRange->setStyle( _style );
5434cdf0e10cSrcweir 		return;
5435cdf0e10cSrcweir 	}
5436cdf0e10cSrcweir 	uno::Reference< beans::XPropertySet > xProps( mxRange, uno::UNO_QUERY_THROW );
5437cdf0e10cSrcweir 	uno::Reference< excel::XStyle > xStyle;
5438cdf0e10cSrcweir 	_style >>= xStyle;
5439cdf0e10cSrcweir 	xProps->setPropertyValue(CELLSTYLE, uno::makeAny(xStyle->getName()));
5440cdf0e10cSrcweir }
5441cdf0e10cSrcweir 
5442cdf0e10cSrcweir uno::Reference< excel::XRange >
PreviousNext(bool bIsPrevious)5443cdf0e10cSrcweir ScVbaRange::PreviousNext( bool bIsPrevious )
5444cdf0e10cSrcweir {
5445cdf0e10cSrcweir 	ScMarkData markedRange;
5446cdf0e10cSrcweir 	ScRange refRange;
5447cdf0e10cSrcweir 	RangeHelper thisRange( mxRange );
5448cdf0e10cSrcweir 
5449cdf0e10cSrcweir 	ScUnoConversion::FillScRange( refRange, thisRange.getCellRangeAddressable()->getRangeAddress());
5450cdf0e10cSrcweir 	markedRange. SetMarkArea( refRange );
5451cdf0e10cSrcweir 	short nMove = bIsPrevious ? -1 : 1;
5452cdf0e10cSrcweir 
5453cdf0e10cSrcweir 	SCCOL nNewX = refRange.aStart.Col();
5454cdf0e10cSrcweir 	SCROW nNewY = refRange.aStart.Row();
5455cdf0e10cSrcweir 	SCTAB nTab = refRange.aStart.Tab();
5456cdf0e10cSrcweir 
5457cdf0e10cSrcweir 	ScDocument* pDoc = getScDocument();
5458cdf0e10cSrcweir 	pDoc->GetNextPos( nNewX,nNewY, nTab, nMove,0, sal_True,sal_True, markedRange );
5459cdf0e10cSrcweir 	refRange.aStart.SetCol( nNewX );
5460cdf0e10cSrcweir 	refRange.aStart.SetRow( nNewY );
5461cdf0e10cSrcweir 	refRange.aStart.SetTab( nTab );
5462cdf0e10cSrcweir 	refRange.aEnd.SetCol( nNewX );
5463cdf0e10cSrcweir 	refRange.aEnd.SetRow( nNewY );
5464cdf0e10cSrcweir 	refRange.aEnd.SetTab( nTab );
5465cdf0e10cSrcweir 
5466cdf0e10cSrcweir 	uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( getScDocShell() , refRange ) );
5467cdf0e10cSrcweir 
5468cdf0e10cSrcweir 	return new ScVbaRange( mxParent, mxContext, xRange );
5469cdf0e10cSrcweir }
5470cdf0e10cSrcweir 
5471cdf0e10cSrcweir uno::Reference< excel::XRange > SAL_CALL
Next()5472cdf0e10cSrcweir ScVbaRange::Next() throw (script::BasicErrorException, uno::RuntimeException)
5473cdf0e10cSrcweir {
5474cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
5475cdf0e10cSrcweir 	{
5476cdf0e10cSrcweir 		uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny( sal_Int32( 1 ) ), uno::Any() ) , uno::UNO_QUERY_THROW  );
5477cdf0e10cSrcweir 		return xRange->Next();
5478cdf0e10cSrcweir 	}
5479cdf0e10cSrcweir 	return PreviousNext( false );
5480cdf0e10cSrcweir }
5481cdf0e10cSrcweir 
5482cdf0e10cSrcweir uno::Reference< excel::XRange > SAL_CALL
Previous()5483cdf0e10cSrcweir ScVbaRange::Previous() throw (script::BasicErrorException, uno::RuntimeException)
5484cdf0e10cSrcweir {
5485cdf0e10cSrcweir 	if ( m_Areas->getCount() > 1 )
5486cdf0e10cSrcweir 	{
5487cdf0e10cSrcweir 		uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny( sal_Int32( 1 ) ), uno::Any() ), uno::UNO_QUERY_THROW  );
5488cdf0e10cSrcweir 		return xRange->Previous();
5489cdf0e10cSrcweir 	}
5490cdf0e10cSrcweir 	return PreviousNext( true );
5491cdf0e10cSrcweir }
5492cdf0e10cSrcweir 
5493cdf0e10cSrcweir uno::Reference< excel::XRange > SAL_CALL
SpecialCells(const uno::Any & _oType,const uno::Any & _oValue)5494cdf0e10cSrcweir ScVbaRange::SpecialCells( const uno::Any& _oType, const uno::Any& _oValue) throw ( script::BasicErrorException )
5495cdf0e10cSrcweir {
5496cdf0e10cSrcweir 	bool bIsSingleCell = isSingleCellRange();
5497cdf0e10cSrcweir 	bool bIsMultiArea = ( m_Areas->getCount() > 1 );
5498cdf0e10cSrcweir 	ScVbaRange* pRangeToUse = this;
5499cdf0e10cSrcweir 	sal_Int32 nType = 0;
5500cdf0e10cSrcweir 	if ( !( _oType >>= nType ) )
5501cdf0e10cSrcweir 		DebugHelper::exception(SbERR_BAD_PARAMETER, rtl::OUString() );
5502cdf0e10cSrcweir 	switch(nType)
5503cdf0e10cSrcweir 	{
5504cdf0e10cSrcweir 		case excel::XlCellType::xlCellTypeSameFormatConditions:
5505cdf0e10cSrcweir 		case excel::XlCellType::xlCellTypeAllValidation:
5506cdf0e10cSrcweir 		case excel::XlCellType::xlCellTypeSameValidation:
5507cdf0e10cSrcweir 			DebugHelper::exception(SbERR_NOT_IMPLEMENTED, rtl::OUString());
5508cdf0e10cSrcweir 			break;
5509cdf0e10cSrcweir 		case excel::XlCellType::xlCellTypeBlanks:
5510cdf0e10cSrcweir 		case excel::XlCellType::xlCellTypeComments:
5511cdf0e10cSrcweir 		case excel::XlCellType::xlCellTypeConstants:
5512cdf0e10cSrcweir 		case excel::XlCellType::xlCellTypeFormulas:
5513cdf0e10cSrcweir 		case excel::XlCellType::xlCellTypeVisible:
5514cdf0e10cSrcweir 		case excel::XlCellType::xlCellTypeLastCell:
5515cdf0e10cSrcweir 		{
5516cdf0e10cSrcweir 			if ( bIsMultiArea )
5517cdf0e10cSrcweir 			{
5518cdf0e10cSrcweir 				// need to process each area, gather the results and
5519cdf0e10cSrcweir 				// create a new range from those
5520cdf0e10cSrcweir 				std::vector< table::CellRangeAddress > rangeResults;
5521cdf0e10cSrcweir 				sal_Int32 nItems = ( m_Areas->getCount() + 1 );
5522cdf0e10cSrcweir 				for ( sal_Int32 index=1; index <= nItems; ++index )
5523cdf0e10cSrcweir 				{
5524cdf0e10cSrcweir 					uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW );
5525cdf0e10cSrcweir 					xRange = xRange->SpecialCells( _oType,  _oValue);
5526cdf0e10cSrcweir 					ScVbaRange* pRange = getImplementation( xRange );
5527cdf0e10cSrcweir 					if ( xRange.is() && pRange )
5528cdf0e10cSrcweir 					{
5529cdf0e10cSrcweir 						sal_Int32 nElems = ( pRange->m_Areas->getCount() + 1 );
5530cdf0e10cSrcweir 						for ( sal_Int32 nArea = 1; nArea < nElems; ++nArea )
5531cdf0e10cSrcweir 						{
5532cdf0e10cSrcweir 							uno::Reference< excel::XRange > xTmpRange( m_Areas->Item( uno::makeAny( nArea ), uno::Any() ), uno::UNO_QUERY_THROW );
5533cdf0e10cSrcweir 							RangeHelper rHelper( xTmpRange->getCellRange() );
5534cdf0e10cSrcweir 							rangeResults.push_back( rHelper.getCellRangeAddressable()->getRangeAddress() );
5535cdf0e10cSrcweir 						}
5536cdf0e10cSrcweir 					}
5537cdf0e10cSrcweir 				}
5538cdf0e10cSrcweir 				ScRangeList aCellRanges;
5539cdf0e10cSrcweir 				std::vector< table::CellRangeAddress >::iterator it = rangeResults.begin();
5540cdf0e10cSrcweir 				std::vector< table::CellRangeAddress >::iterator it_end = rangeResults.end();
5541cdf0e10cSrcweir 				for ( ; it != it_end; ++ it )
5542cdf0e10cSrcweir 				{
5543cdf0e10cSrcweir 					ScRange refRange;
5544cdf0e10cSrcweir 					ScUnoConversion::FillScRange( refRange, *it );
5545cdf0e10cSrcweir 					aCellRanges.Append( refRange );
5546cdf0e10cSrcweir 				}
5547cdf0e10cSrcweir 				// Single range
5548cdf0e10cSrcweir 				if ( aCellRanges.First() == aCellRanges.Last() )
5549cdf0e10cSrcweir 				{
5550cdf0e10cSrcweir 					uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( getScDocShell(), *aCellRanges.First() ) );
5551cdf0e10cSrcweir 					return new ScVbaRange( mxParent, mxContext, xRange );
5552cdf0e10cSrcweir 				}
5553cdf0e10cSrcweir 				uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( getScDocShell(), aCellRanges ) );
5554cdf0e10cSrcweir 
5555cdf0e10cSrcweir 				return new ScVbaRange( mxParent, mxContext, xRanges );
5556cdf0e10cSrcweir 			}
5557cdf0e10cSrcweir 			else if ( bIsSingleCell )
5558cdf0e10cSrcweir 			{
5559cdf0e10cSrcweir 				uno::Reference< excel::XRange > xUsedRange = getWorksheet()->getUsedRange();
5560cdf0e10cSrcweir 				pRangeToUse = static_cast< ScVbaRange* >( xUsedRange.get() );
5561cdf0e10cSrcweir 			}
5562cdf0e10cSrcweir 
5563cdf0e10cSrcweir 			break;
5564cdf0e10cSrcweir 		}
5565cdf0e10cSrcweir 		default:
5566cdf0e10cSrcweir 		DebugHelper::exception(SbERR_BAD_PARAMETER, rtl::OUString() );
5567cdf0e10cSrcweir 			break;
5568cdf0e10cSrcweir 	}
5569cdf0e10cSrcweir 	if ( !pRangeToUse )
5570cdf0e10cSrcweir 		DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() );
5571cdf0e10cSrcweir 	return pRangeToUse->SpecialCellsImpl( nType, _oValue );
5572cdf0e10cSrcweir }
5573cdf0e10cSrcweir 
lcl_getFormulaResultFlags(const uno::Any & aType)5574cdf0e10cSrcweir sal_Int32 lcl_getFormulaResultFlags(const uno::Any& aType) throw ( script::BasicErrorException )
5575cdf0e10cSrcweir {
5576cdf0e10cSrcweir 	sal_Int32 nType = excel::XlSpecialCellsValue::xlNumbers;
5577cdf0e10cSrcweir 	aType >>= nType;
5578cdf0e10cSrcweir 	sal_Int32 nRes = sheet::FormulaResult::VALUE;
5579cdf0e10cSrcweir 
5580cdf0e10cSrcweir 	switch(nType)
5581cdf0e10cSrcweir 	{
5582cdf0e10cSrcweir 		case excel::XlSpecialCellsValue::xlErrors:
5583cdf0e10cSrcweir 			nRes= sheet::FormulaResult::ERROR;
5584cdf0e10cSrcweir 			break;
5585cdf0e10cSrcweir 		case excel::XlSpecialCellsValue::xlLogical:
5586cdf0e10cSrcweir 			//TODO bc93774: ask NN if this is really an appropriate substitute
5587cdf0e10cSrcweir 			nRes = sheet::FormulaResult::VALUE;
5588cdf0e10cSrcweir 			break;
5589cdf0e10cSrcweir 		case excel::XlSpecialCellsValue::xlNumbers:
5590cdf0e10cSrcweir 			nRes = sheet::FormulaResult::VALUE;
5591cdf0e10cSrcweir 			break;
5592cdf0e10cSrcweir 		case excel::XlSpecialCellsValue::xlTextValues:
5593cdf0e10cSrcweir 			nRes = sheet::FormulaResult::STRING;
5594cdf0e10cSrcweir 			break;
5595cdf0e10cSrcweir 		default:
5596cdf0e10cSrcweir 			DebugHelper::exception(SbERR_BAD_PARAMETER, rtl::OUString() );
5597cdf0e10cSrcweir 	}
5598cdf0e10cSrcweir 	return nRes;
5599cdf0e10cSrcweir }
5600cdf0e10cSrcweir 
5601cdf0e10cSrcweir uno::Reference< excel::XRange >
SpecialCellsImpl(sal_Int32 nType,const uno::Any & _oValue)5602cdf0e10cSrcweir ScVbaRange::SpecialCellsImpl( sal_Int32 nType, const uno::Any& _oValue) throw ( script::BasicErrorException )
5603cdf0e10cSrcweir {
5604cdf0e10cSrcweir 	uno::Reference< excel::XRange > xRange;
5605cdf0e10cSrcweir 	try
5606cdf0e10cSrcweir 	{
5607cdf0e10cSrcweir 		uno::Reference< sheet::XCellRangesQuery > xQuery( mxRange, uno::UNO_QUERY_THROW );
5608cdf0e10cSrcweir 		uno::Reference< excel::XRange > oLocRangeImpl;
5609cdf0e10cSrcweir 		uno::Reference< sheet::XSheetCellRanges > xLocSheetCellRanges;
5610cdf0e10cSrcweir 		switch(nType)
5611cdf0e10cSrcweir 		{
5612cdf0e10cSrcweir 			case excel::XlCellType::xlCellTypeAllFormatConditions:
5613cdf0e10cSrcweir 			case excel::XlCellType::xlCellTypeSameFormatConditions:
5614cdf0e10cSrcweir 			case excel::XlCellType::xlCellTypeAllValidation:
5615cdf0e10cSrcweir 			case excel::XlCellType::xlCellTypeSameValidation:
5616cdf0e10cSrcweir 				// Shouldn't get here ( should be filtered out by
5617cdf0e10cSrcweir 				// ScVbaRange::SpecialCells()
5618cdf0e10cSrcweir 				DebugHelper::exception(SbERR_NOT_IMPLEMENTED, rtl::OUString());
5619cdf0e10cSrcweir 				break;
5620cdf0e10cSrcweir 			case excel::XlCellType::xlCellTypeBlanks:
5621cdf0e10cSrcweir 				xLocSheetCellRanges = xQuery->queryEmptyCells();
5622cdf0e10cSrcweir 				break;
5623cdf0e10cSrcweir 			case excel::XlCellType::xlCellTypeComments:
5624cdf0e10cSrcweir 				xLocSheetCellRanges = xQuery->queryContentCells(sheet::CellFlags::ANNOTATION);
5625cdf0e10cSrcweir 				break;
5626cdf0e10cSrcweir 			case excel::XlCellType::xlCellTypeConstants:
5627cdf0e10cSrcweir 				xLocSheetCellRanges = xQuery->queryContentCells(23);
5628cdf0e10cSrcweir 				break;
5629cdf0e10cSrcweir 			case excel::XlCellType::xlCellTypeFormulas:
5630cdf0e10cSrcweir 			{
5631cdf0e10cSrcweir 				sal_Int32 nFormulaResult = lcl_getFormulaResultFlags(_oValue);
5632cdf0e10cSrcweir 				xLocSheetCellRanges = xQuery->queryFormulaCells(nFormulaResult);
5633cdf0e10cSrcweir 				break;
5634cdf0e10cSrcweir 			}
5635cdf0e10cSrcweir 			case excel::XlCellType::xlCellTypeLastCell:
5636cdf0e10cSrcweir 				xRange = Cells( uno::makeAny( getCount() ), uno::Any() );
5637cdf0e10cSrcweir 			case excel::XlCellType::xlCellTypeVisible:
5638cdf0e10cSrcweir 				xLocSheetCellRanges = xQuery->queryVisibleCells();
5639cdf0e10cSrcweir 				break;
5640cdf0e10cSrcweir 			default:
5641cdf0e10cSrcweir 				DebugHelper::exception(SbERR_BAD_PARAMETER, rtl::OUString() );
5642cdf0e10cSrcweir 				break;
5643cdf0e10cSrcweir 		}
5644cdf0e10cSrcweir 		if (xLocSheetCellRanges.is())
5645cdf0e10cSrcweir 		{
5646cdf0e10cSrcweir 			xRange = lcl_makeXRangeFromSheetCellRanges( getParent(), mxContext, xLocSheetCellRanges, getScDocShell() );
5647cdf0e10cSrcweir 		}
5648cdf0e10cSrcweir 	}
5649cdf0e10cSrcweir 	catch (uno::Exception& )
5650cdf0e10cSrcweir 	{
5651cdf0e10cSrcweir 		DebugHelper::exception(SbERR_METHOD_FAILED, STR_ERRORMESSAGE_NOCELLSWEREFOUND);
5652cdf0e10cSrcweir 	}
5653cdf0e10cSrcweir 	return xRange;
5654cdf0e10cSrcweir }
5655cdf0e10cSrcweir 
5656cdf0e10cSrcweir void SAL_CALL
RemoveSubtotal()5657cdf0e10cSrcweir ScVbaRange::RemoveSubtotal(  ) throw (script::BasicErrorException, uno::RuntimeException)
5658cdf0e10cSrcweir {
5659cdf0e10cSrcweir 	uno::Reference< sheet::XSubTotalCalculatable > xSub( mxRange, uno::UNO_QUERY_THROW );
5660cdf0e10cSrcweir 	xSub->removeSubTotals();
5661cdf0e10cSrcweir }
5662cdf0e10cSrcweir 
5663cdf0e10cSrcweir void SAL_CALL
Subtotal(::sal_Int32 _nGroupBy,::sal_Int32 _nFunction,const uno::Sequence<::sal_Int32> & _nTotalList,const uno::Any & aReplace,const uno::Any & PageBreaks,const uno::Any &)5664cdf0e10cSrcweir ScVbaRange::Subtotal( ::sal_Int32 _nGroupBy, ::sal_Int32 _nFunction, const uno::Sequence< ::sal_Int32 >& _nTotalList, const uno::Any& aReplace, const uno::Any& PageBreaks, const uno::Any& /*SummaryBelowData*/ ) throw (script::BasicErrorException, uno::RuntimeException)
5665cdf0e10cSrcweir {
5666cdf0e10cSrcweir 	try
5667cdf0e10cSrcweir 	{
5668cdf0e10cSrcweir 		sal_Bool bDoReplace = sal_False;
5669cdf0e10cSrcweir 		aReplace >>= bDoReplace;
5670cdf0e10cSrcweir 		sal_Bool bAddPageBreaks = sal_False;
5671cdf0e10cSrcweir 		PageBreaks >>= bAddPageBreaks;
5672cdf0e10cSrcweir 
5673cdf0e10cSrcweir 		uno::Reference< sheet::XSubTotalCalculatable> xSub(mxRange, uno::UNO_QUERY_THROW );
5674cdf0e10cSrcweir 		uno::Reference< sheet::XSubTotalDescriptor > xSubDesc = xSub->createSubTotalDescriptor(sal_True);
5675cdf0e10cSrcweir 		uno::Reference< beans::XPropertySet > xSubDescPropertySet( xSubDesc, uno::UNO_QUERY_THROW );
5676cdf0e10cSrcweir 		xSubDescPropertySet->setPropertyValue(INSERTPAGEBREAKS, uno::makeAny( bAddPageBreaks));
5677cdf0e10cSrcweir 		sal_Int32 nLen = _nTotalList.getLength();
5678cdf0e10cSrcweir 		uno::Sequence< sheet::SubTotalColumn > aColumns( nLen );
5679cdf0e10cSrcweir 		for (int i = 0; i < nLen; i++)
5680cdf0e10cSrcweir 		{
5681cdf0e10cSrcweir 			aColumns[i].Column = _nTotalList[i] - 1;
5682cdf0e10cSrcweir 			switch (_nFunction)
5683cdf0e10cSrcweir 			{
5684cdf0e10cSrcweir 				case excel::XlConsolidationFunction::xlAverage:
5685cdf0e10cSrcweir 					aColumns[i].Function = sheet::GeneralFunction_AVERAGE;
5686cdf0e10cSrcweir 					break;
5687cdf0e10cSrcweir 				case excel::XlConsolidationFunction::xlCount:
5688cdf0e10cSrcweir 					aColumns[i].Function = sheet::GeneralFunction_COUNT;
5689cdf0e10cSrcweir 					break;
5690cdf0e10cSrcweir 				case excel::XlConsolidationFunction::xlCountNums:
5691cdf0e10cSrcweir 					aColumns[i].Function = sheet::GeneralFunction_COUNTNUMS;
5692cdf0e10cSrcweir 					break;
5693cdf0e10cSrcweir 				case excel::XlConsolidationFunction::xlMax:
5694cdf0e10cSrcweir 					aColumns[i].Function = sheet::GeneralFunction_MAX;
5695cdf0e10cSrcweir 					break;
5696cdf0e10cSrcweir 				case excel::XlConsolidationFunction::xlMin:
5697cdf0e10cSrcweir 					aColumns[i].Function = sheet::GeneralFunction_MIN;
5698cdf0e10cSrcweir 					break;
5699cdf0e10cSrcweir 				case excel::XlConsolidationFunction::xlProduct:
5700cdf0e10cSrcweir 					aColumns[i].Function = sheet::GeneralFunction_PRODUCT;
5701cdf0e10cSrcweir 					break;
5702cdf0e10cSrcweir 				case excel::XlConsolidationFunction::xlStDev:
5703cdf0e10cSrcweir 					aColumns[i].Function = sheet::GeneralFunction_STDEV;
5704cdf0e10cSrcweir 					break;
5705cdf0e10cSrcweir 				case excel::XlConsolidationFunction::xlStDevP:
5706cdf0e10cSrcweir 					aColumns[i].Function = sheet::GeneralFunction_STDEVP;
5707cdf0e10cSrcweir 					break;
5708cdf0e10cSrcweir 				case excel::XlConsolidationFunction::xlSum:
5709cdf0e10cSrcweir 					aColumns[i].Function = sheet::GeneralFunction_SUM;
5710cdf0e10cSrcweir 					break;
5711cdf0e10cSrcweir 				case excel::XlConsolidationFunction::xlUnknown:
5712cdf0e10cSrcweir 					aColumns[i].Function = sheet::GeneralFunction_NONE;
5713cdf0e10cSrcweir 					break;
5714cdf0e10cSrcweir 				case excel::XlConsolidationFunction::xlVar:
5715cdf0e10cSrcweir 					aColumns[i].Function = sheet::GeneralFunction_VAR;
5716cdf0e10cSrcweir 					break;
5717cdf0e10cSrcweir 				case excel::XlConsolidationFunction::xlVarP:
5718cdf0e10cSrcweir 					aColumns[i].Function = sheet::GeneralFunction_VARP;
5719cdf0e10cSrcweir 					break;
5720cdf0e10cSrcweir 				default:
5721cdf0e10cSrcweir 					DebugHelper::exception(SbERR_BAD_PARAMETER, rtl::OUString()) ;
5722cdf0e10cSrcweir 					return;
5723cdf0e10cSrcweir 			}
5724cdf0e10cSrcweir 		}
5725cdf0e10cSrcweir 		xSubDesc->addNew(aColumns, _nGroupBy - 1);
5726cdf0e10cSrcweir 		xSub->applySubTotals(xSubDesc, bDoReplace);
5727cdf0e10cSrcweir 	}
5728cdf0e10cSrcweir 	catch (uno::Exception& )
5729cdf0e10cSrcweir 	{
5730cdf0e10cSrcweir 		DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString());
5731cdf0e10cSrcweir 	}
5732cdf0e10cSrcweir }
5733cdf0e10cSrcweir 
5734cdf0e10cSrcweir rtl::OUString&
getServiceImplName()5735cdf0e10cSrcweir ScVbaRange::getServiceImplName()
5736cdf0e10cSrcweir {
5737cdf0e10cSrcweir 	static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaRange") );
5738cdf0e10cSrcweir 	return sImplName;
5739cdf0e10cSrcweir }
5740cdf0e10cSrcweir 
5741cdf0e10cSrcweir uno::Sequence< rtl::OUString >
getServiceNames()5742cdf0e10cSrcweir ScVbaRange::getServiceNames()
5743cdf0e10cSrcweir {
5744cdf0e10cSrcweir 	static uno::Sequence< rtl::OUString > aServiceNames;
5745cdf0e10cSrcweir 	if ( aServiceNames.getLength() == 0 )
5746cdf0e10cSrcweir 	{
5747cdf0e10cSrcweir 		aServiceNames.realloc( 1 );
5748cdf0e10cSrcweir 		aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Range" ) );
5749cdf0e10cSrcweir 	}
5750cdf0e10cSrcweir 	return aServiceNames;
5751cdf0e10cSrcweir }
5752cdf0e10cSrcweir 
5753cdf0e10cSrcweir namespace range
5754cdf0e10cSrcweir {
5755cdf0e10cSrcweir namespace sdecl = comphelper::service_decl;
5756cdf0e10cSrcweir sdecl::vba_service_class_<ScVbaRange, sdecl::with_args<true> > serviceImpl;
5757cdf0e10cSrcweir extern sdecl::ServiceDecl const serviceDecl(
5758cdf0e10cSrcweir     serviceImpl,
5759cdf0e10cSrcweir     "SvVbaRange",
5760cdf0e10cSrcweir     "ooo.vba.excel.Range" );
5761cdf0e10cSrcweir }
5762