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