| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| #include "excelvbahelper.hxx" |
| |
| #include <comphelper/processfactory.hxx> |
| #include <com/sun/star/sheet/XSheetCellRange.hpp> |
| #include "docuno.hxx" |
| #include "tabvwsh.hxx" |
| #include "transobj.hxx" |
| #include "scmod.hxx" |
| #include "cellsuno.hxx" |
| |
| namespace ooo { |
| namespace vba { |
| namespace excel { |
| |
| using namespace ::com::sun::star; |
| using namespace ::ooo::vba; |
| |
| // ============================================================================ |
| |
| ScDocShell* GetDocShellFromRange( const uno::Reference< uno::XInterface >& xRange ) throw ( uno::RuntimeException ) |
| { |
| ScCellRangesBase* pScCellRangesBase = ScCellRangesBase::getImplementation( xRange ); |
| if ( !pScCellRangesBase ) |
| { |
| throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to access underlying doc shell uno range object" ) ), uno::Reference< uno::XInterface >() ); |
| } |
| return pScCellRangesBase->GetDocShell(); |
| } |
| |
| ScDocument* GetDocumentFromRange( const uno::Reference< uno::XInterface >& xRange ) throw ( uno::RuntimeException ) |
| { |
| ScDocShell* pDocShell = GetDocShellFromRange( xRange ); |
| if ( !pDocShell ) |
| { |
| throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to access underlying document from uno range object" ) ), uno::Reference< uno::XInterface >() ); |
| } |
| return pDocShell->GetDocument(); |
| } |
| |
| void implSetZoom( const uno::Reference< frame::XModel >& xModel, sal_Int16 nZoom, std::vector< SCTAB >& nTabs ) |
| { |
| ScTabViewShell* pViewSh = excel::getBestViewShell( xModel ); |
| Fraction aFract( nZoom, 100 ); |
| pViewSh->GetViewData()->SetZoom( aFract, aFract, nTabs ); |
| pViewSh->RefreshZoom(); |
| } |
| bool isInPrintPreview( SfxViewFrame* pView ) |
| { |
| sal_uInt16 nViewNo = SID_VIEWSHELL1 - SID_VIEWSHELL0; |
| if ( pView->GetObjectShell()->GetFactory().GetViewFactoryCount() > |
| nViewNo && !pView->GetObjectShell()->IsInPlaceActive() ) |
| { |
| SfxViewFactory &rViewFactory = |
| pView->GetObjectShell()->GetFactory().GetViewFactory(nViewNo); |
| if ( pView->GetCurViewId() == rViewFactory.GetOrdinal() ) |
| return true; |
| } |
| return false; |
| } |
| |
| const ::rtl::OUString REPLACE_CELLS_WARNING( RTL_CONSTASCII_USTRINGPARAM( "ReplaceCellsWarning")); |
| |
| class PasteCellsWarningReseter |
| { |
| private: |
| bool bInitialWarningState; |
| static uno::Reference< beans::XPropertySet > getGlobalSheetSettings() throw ( uno::RuntimeException ) |
| { |
| static uno::Reference< beans::XPropertySet > xTmpProps( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW ); |
| static uno::Reference<uno::XComponentContext > xContext( xTmpProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))), uno::UNO_QUERY_THROW ); |
| static uno::Reference<lang::XMultiComponentFactory > xServiceManager( |
| xContext->getServiceManager(), uno::UNO_QUERY_THROW ); |
| static uno::Reference< beans::XPropertySet > xProps( xServiceManager->createInstanceWithContext( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.GlobalSheetSettings" ) ) ,xContext ), uno::UNO_QUERY_THROW ); |
| return xProps; |
| } |
| |
| bool getReplaceCellsWarning() throw ( uno::RuntimeException ) |
| { |
| sal_Bool res = sal_False; |
| getGlobalSheetSettings()->getPropertyValue( REPLACE_CELLS_WARNING ) >>= res; |
| return ( res == sal_True ); |
| } |
| |
| void setReplaceCellsWarning( bool bState ) throw ( uno::RuntimeException ) |
| { |
| getGlobalSheetSettings()->setPropertyValue( REPLACE_CELLS_WARNING, uno::makeAny( bState ) ); |
| } |
| public: |
| PasteCellsWarningReseter() throw ( uno::RuntimeException ) |
| { |
| bInitialWarningState = getReplaceCellsWarning(); |
| if ( bInitialWarningState ) |
| setReplaceCellsWarning( false ); |
| } |
| ~PasteCellsWarningReseter() |
| { |
| if ( bInitialWarningState ) |
| { |
| // don't allow dtor to throw |
| try |
| { |
| setReplaceCellsWarning( true ); |
| } |
| catch ( uno::Exception& /*e*/ ){} |
| } |
| } |
| }; |
| |
| void |
| implnPaste( const uno::Reference< frame::XModel>& xModel ) |
| { |
| PasteCellsWarningReseter resetWarningBox; |
| ScTabViewShell* pViewShell = getBestViewShell( xModel ); |
| if ( pViewShell ) |
| { |
| pViewShell->PasteFromSystem(); |
| pViewShell->CellContentChanged(); |
| } |
| } |
| |
| |
| void |
| implnCopy( const uno::Reference< frame::XModel>& xModel ) |
| { |
| ScTabViewShell* pViewShell = getBestViewShell( xModel ); |
| if ( pViewShell ) |
| { |
| pViewShell->CopyToClip(NULL,false,false,true); |
| |
| // mark the copied transfer object so it is used in ScVbaRange::Insert |
| ScTransferObj* pClipObj = ScTransferObj::GetOwnClipboard( NULL ); |
| if (pClipObj) |
| pClipObj->SetUseInApi( true ); |
| } |
| } |
| |
| void |
| implnCut( const uno::Reference< frame::XModel>& xModel ) |
| { |
| ScTabViewShell* pViewShell = getBestViewShell( xModel ); |
| if ( pViewShell ) |
| { |
| pViewShell->CutToClip( NULL, sal_True ); |
| |
| // mark the copied transfer object so it is used in ScVbaRange::Insert |
| ScTransferObj* pClipObj = ScTransferObj::GetOwnClipboard( NULL ); |
| if (pClipObj) |
| pClipObj->SetUseInApi( true ); |
| } |
| } |
| |
| void implnPasteSpecial( const uno::Reference< frame::XModel>& xModel, sal_uInt16 nFlags,sal_uInt16 nFunction,sal_Bool bSkipEmpty, sal_Bool bTranspose) |
| { |
| PasteCellsWarningReseter resetWarningBox; |
| sal_Bool bAsLink(sal_False), bOtherDoc(sal_False); |
| InsCellCmd eMoveMode = INS_NONE; |
| |
| ScTabViewShell* pTabViewShell = getBestViewShell( xModel ); |
| if ( pTabViewShell ) |
| { |
| ScViewData* pView = pTabViewShell->GetViewData(); |
| Window* pWin = ( pView != NULL ) ? pView->GetActiveWin() : NULL; |
| if ( pView && pWin ) |
| { |
| if ( bAsLink && bOtherDoc ) |
| pTabViewShell->PasteFromSystem(0);//SOT_FORMATSTR_ID_LINK |
| else |
| { |
| ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pWin ); |
| ScDocument* pDoc = NULL; |
| if ( pOwnClip ) |
| { |
| pDoc = pOwnClip->GetDocument(); |
| pOwnClip->SetUseInApi( false ); // don't use in Insert after it was pasted once |
| } |
| pTabViewShell->PasteFromClip( nFlags, pDoc, |
| nFunction, bSkipEmpty, bTranspose, bAsLink, |
| eMoveMode, IDF_NONE, sal_True ); |
| pTabViewShell->CellContentChanged(); |
| } |
| } |
| } |
| |
| } |
| |
| ScDocShell* |
| getDocShell( const css::uno::Reference< css::frame::XModel>& xModel ) |
| { |
| uno::Reference< uno::XInterface > xIf( xModel, uno::UNO_QUERY_THROW ); |
| ScModelObj* pModel = dynamic_cast< ScModelObj* >( xIf.get() ); |
| ScDocShell* pDocShell = NULL; |
| if ( pModel ) |
| pDocShell = (ScDocShell*)pModel->GetEmbeddedObject(); |
| return pDocShell; |
| |
| } |
| |
| ScTabViewShell* |
| getBestViewShell( const css::uno::Reference< css::frame::XModel>& xModel ) |
| { |
| ScDocShell* pDocShell = getDocShell( xModel ); |
| if ( pDocShell ) |
| return pDocShell->GetBestViewShell(); |
| return NULL; |
| } |
| |
| ScTabViewShell* |
| getCurrentBestViewShell( const uno::Reference< uno::XComponentContext >& xContext ) |
| { |
| uno::Reference< frame::XModel > xModel = getCurrentExcelDoc( xContext ); |
| return getBestViewShell( xModel ); |
| } |
| |
| SfxViewFrame* |
| getViewFrame( const uno::Reference< frame::XModel >& xModel ) |
| { |
| ScTabViewShell* pViewShell = getBestViewShell( xModel ); |
| if ( pViewShell ) |
| return pViewShell->GetViewFrame(); |
| return NULL; |
| } |
| |
| uno::Reference< XHelperInterface > |
| getUnoSheetModuleObj( const uno::Reference< sheet::XSpreadsheet >& xSheet ) throw ( uno::RuntimeException ) |
| { |
| uno::Reference< beans::XPropertySet > xProps( xSheet, uno::UNO_QUERY_THROW ); |
| rtl::OUString sCodeName; |
| xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("CodeName") ) ) >>= sCodeName; |
| // #TODO #FIXME ideally we should 'throw' here if we don't get a valid parent, but... it is possible |
| // to create a module ( and use 'Option VBASupport 1' ) for a calc document, in this scenario there |
| // are *NO* special document module objects ( of course being able to switch between vba/non vba mode at |
| // the document in the future could fix this, especially IF the switching of the vba mode takes care to |
| // create the special document module objects if they don't exist. |
| return getUnoDocModule( sCodeName, GetDocShellFromRange( xSheet ) ); |
| } |
| |
| uno::Reference< XHelperInterface > |
| getUnoSheetModuleObj( const uno::Reference< table::XCellRange >& xRange ) throw ( uno::RuntimeException ) |
| { |
| uno::Reference< sheet::XSheetCellRange > xSheetRange( xRange, uno::UNO_QUERY_THROW ); |
| uno::Reference< sheet::XSpreadsheet > xSheet( xSheetRange->getSpreadsheet(), uno::UNO_SET_THROW ); |
| return getUnoSheetModuleObj( xSheet ); |
| } |
| |
| uno::Reference< XHelperInterface > |
| getUnoSheetModuleObj( const uno::Reference< sheet::XSheetCellRangeContainer >& xRanges ) throw ( uno::RuntimeException ) |
| { |
| uno::Reference< container::XEnumerationAccess > xEnumAccess( xRanges, uno::UNO_QUERY_THROW ); |
| uno::Reference< container::XEnumeration > xEnum = xEnumAccess->createEnumeration(); |
| uno::Reference< table::XCellRange > xRange( xEnum->nextElement(), uno::UNO_QUERY_THROW ); |
| return getUnoSheetModuleObj( xRange ); |
| } |
| |
| uno::Reference< XHelperInterface > |
| getUnoSheetModuleObj( const uno::Reference< table::XCell >& xCell ) throw ( uno::RuntimeException ) |
| { |
| uno::Reference< sheet::XSheetCellRange > xSheetRange( xCell, uno::UNO_QUERY_THROW ); |
| uno::Reference< sheet::XSpreadsheet > xSheet( xSheetRange->getSpreadsheet(), uno::UNO_SET_THROW ); |
| return getUnoSheetModuleObj( xSheet ); |
| } |
| |
| uno::Reference< XHelperInterface > |
| getUnoSheetModuleObj( const uno::Reference< frame::XModel >& xModel, SCTAB nTab ) throw ( uno::RuntimeException ) |
| { |
| uno::Reference< sheet::XSpreadsheetDocument > xDoc( xModel, uno::UNO_QUERY_THROW ); |
| uno::Reference< container::XIndexAccess > xSheets( xDoc->getSheets(), uno::UNO_QUERY_THROW ); |
| uno::Reference< sheet::XSpreadsheet > xSheet( xSheets->getByIndex( nTab ), uno::UNO_QUERY_THROW ); |
| return getUnoSheetModuleObj( xSheet ); |
| } |
| |
| SfxItemSet* |
| ScVbaCellRangeAccess::GetDataSet( ScCellRangesBase* pRangeObj ) |
| { |
| return pRangeObj ? pRangeObj->GetCurrentDataSet( true ) : 0; |
| } |
| |
| // ============================================================================ |
| |
| } // namespace excel |
| } // namespace vba |
| } // namespace ooo |