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