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