xref: /aoo41x/main/sc/source/ui/vba/excelvbahelper.cxx (revision b3f79822)
1*b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*b3f79822SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*b3f79822SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*b3f79822SAndrew Rist  * distributed with this work for additional information
6*b3f79822SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*b3f79822SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*b3f79822SAndrew Rist  * "License"); you may not use this file except in compliance
9*b3f79822SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*b3f79822SAndrew Rist  *
11*b3f79822SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*b3f79822SAndrew Rist  *
13*b3f79822SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*b3f79822SAndrew Rist  * software distributed under the License is distributed on an
15*b3f79822SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b3f79822SAndrew Rist  * KIND, either express or implied.  See the License for the
17*b3f79822SAndrew Rist  * specific language governing permissions and limitations
18*b3f79822SAndrew Rist  * under the License.
19*b3f79822SAndrew Rist  *
20*b3f79822SAndrew Rist  *************************************************************/
21*b3f79822SAndrew Rist 
22*b3f79822SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include "excelvbahelper.hxx"
25cdf0e10cSrcweir 
26cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
27cdf0e10cSrcweir #include <com/sun/star/sheet/XSheetCellRange.hpp>
28cdf0e10cSrcweir #include "docuno.hxx"
29cdf0e10cSrcweir #include "tabvwsh.hxx"
30cdf0e10cSrcweir #include "transobj.hxx"
31cdf0e10cSrcweir #include "scmod.hxx"
32cdf0e10cSrcweir #include "cellsuno.hxx"
33cdf0e10cSrcweir 
34cdf0e10cSrcweir namespace ooo {
35cdf0e10cSrcweir namespace vba {
36cdf0e10cSrcweir namespace excel {
37cdf0e10cSrcweir 
38cdf0e10cSrcweir using namespace ::com::sun::star;
39cdf0e10cSrcweir using namespace ::ooo::vba;
40cdf0e10cSrcweir 
41cdf0e10cSrcweir // ============================================================================
42cdf0e10cSrcweir 
GetDocShellFromRange(const uno::Reference<uno::XInterface> & xRange)43cdf0e10cSrcweir ScDocShell* GetDocShellFromRange( const uno::Reference< uno::XInterface >& xRange ) throw ( uno::RuntimeException )
44cdf0e10cSrcweir {
45cdf0e10cSrcweir     ScCellRangesBase* pScCellRangesBase = ScCellRangesBase::getImplementation( xRange );
46cdf0e10cSrcweir     if ( !pScCellRangesBase )
47cdf0e10cSrcweir     {
48cdf0e10cSrcweir         throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to access underlying doc shell uno range object" ) ), uno::Reference< uno::XInterface >() );
49cdf0e10cSrcweir     }
50cdf0e10cSrcweir     return pScCellRangesBase->GetDocShell();
51cdf0e10cSrcweir }
52cdf0e10cSrcweir 
GetDocumentFromRange(const uno::Reference<uno::XInterface> & xRange)53cdf0e10cSrcweir ScDocument* GetDocumentFromRange( const uno::Reference< uno::XInterface >& xRange ) throw ( uno::RuntimeException )
54cdf0e10cSrcweir {
55cdf0e10cSrcweir         ScDocShell* pDocShell = GetDocShellFromRange( xRange );
56cdf0e10cSrcweir         if ( !pDocShell )
57cdf0e10cSrcweir         {
58cdf0e10cSrcweir                 throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to access underlying document from uno range object" ) ), uno::Reference< uno::XInterface >() );
59cdf0e10cSrcweir         }
60cdf0e10cSrcweir         return pDocShell->GetDocument();
61cdf0e10cSrcweir }
62cdf0e10cSrcweir 
implSetZoom(const uno::Reference<frame::XModel> & xModel,sal_Int16 nZoom,std::vector<SCTAB> & nTabs)63cdf0e10cSrcweir void implSetZoom( const uno::Reference< frame::XModel >& xModel, sal_Int16 nZoom, std::vector< SCTAB >& nTabs )
64cdf0e10cSrcweir {
65cdf0e10cSrcweir     ScTabViewShell* pViewSh = excel::getBestViewShell( xModel );
66cdf0e10cSrcweir     Fraction aFract( nZoom, 100 );
67cdf0e10cSrcweir     pViewSh->GetViewData()->SetZoom( aFract, aFract, nTabs );
68cdf0e10cSrcweir     pViewSh->RefreshZoom();
69cdf0e10cSrcweir }
isInPrintPreview(SfxViewFrame * pView)70cdf0e10cSrcweir bool isInPrintPreview( SfxViewFrame* pView )
71cdf0e10cSrcweir {
72cdf0e10cSrcweir 	sal_uInt16 nViewNo = SID_VIEWSHELL1 - SID_VIEWSHELL0;
73cdf0e10cSrcweir 	if ( pView->GetObjectShell()->GetFactory().GetViewFactoryCount() >
74cdf0e10cSrcweir nViewNo && !pView->GetObjectShell()->IsInPlaceActive() )
75cdf0e10cSrcweir 	{
76cdf0e10cSrcweir 		SfxViewFactory &rViewFactory =
77cdf0e10cSrcweir 			pView->GetObjectShell()->GetFactory().GetViewFactory(nViewNo);
78cdf0e10cSrcweir 		if (  pView->GetCurViewId() == rViewFactory.GetOrdinal() )
79cdf0e10cSrcweir 			return true;
80cdf0e10cSrcweir 	}
81cdf0e10cSrcweir 	return false;
82cdf0e10cSrcweir }
83cdf0e10cSrcweir 
84cdf0e10cSrcweir const ::rtl::OUString REPLACE_CELLS_WARNING(  RTL_CONSTASCII_USTRINGPARAM( "ReplaceCellsWarning"));
85cdf0e10cSrcweir 
86cdf0e10cSrcweir class PasteCellsWarningReseter
87cdf0e10cSrcweir {
88cdf0e10cSrcweir private:
89cdf0e10cSrcweir 	bool bInitialWarningState;
getGlobalSheetSettings()90cdf0e10cSrcweir 	static uno::Reference< beans::XPropertySet > getGlobalSheetSettings() throw ( uno::RuntimeException )
91cdf0e10cSrcweir 	{
92cdf0e10cSrcweir 		static uno::Reference< beans::XPropertySet > xTmpProps( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW );
93cdf0e10cSrcweir 		static uno::Reference<uno::XComponentContext > xContext( xTmpProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))), uno::UNO_QUERY_THROW );
94cdf0e10cSrcweir 		static uno::Reference<lang::XMultiComponentFactory > xServiceManager(
95cdf0e10cSrcweir 				xContext->getServiceManager(), uno::UNO_QUERY_THROW );
96cdf0e10cSrcweir 		static uno::Reference< beans::XPropertySet > xProps( xServiceManager->createInstanceWithContext( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.GlobalSheetSettings" ) ) ,xContext ), uno::UNO_QUERY_THROW );
97cdf0e10cSrcweir 		return xProps;
98cdf0e10cSrcweir 	}
99cdf0e10cSrcweir 
getReplaceCellsWarning()100cdf0e10cSrcweir 	bool getReplaceCellsWarning() throw ( uno::RuntimeException )
101cdf0e10cSrcweir 	{
102cdf0e10cSrcweir 		sal_Bool res = sal_False;
103cdf0e10cSrcweir 		getGlobalSheetSettings()->getPropertyValue( REPLACE_CELLS_WARNING ) >>= res;
104cdf0e10cSrcweir 		return ( res == sal_True );
105cdf0e10cSrcweir 	}
106cdf0e10cSrcweir 
setReplaceCellsWarning(bool bState)107cdf0e10cSrcweir 	void setReplaceCellsWarning( bool bState ) throw ( uno::RuntimeException )
108cdf0e10cSrcweir 	{
109cdf0e10cSrcweir 		getGlobalSheetSettings()->setPropertyValue( REPLACE_CELLS_WARNING, uno::makeAny( bState ) );
110cdf0e10cSrcweir 	}
111cdf0e10cSrcweir public:
PasteCellsWarningReseter()112cdf0e10cSrcweir 	PasteCellsWarningReseter() throw ( uno::RuntimeException )
113cdf0e10cSrcweir 	{
114cdf0e10cSrcweir 		bInitialWarningState = getReplaceCellsWarning();
115cdf0e10cSrcweir 		if ( bInitialWarningState )
116cdf0e10cSrcweir 			setReplaceCellsWarning( false );
117cdf0e10cSrcweir 	}
~PasteCellsWarningReseter()118cdf0e10cSrcweir 	~PasteCellsWarningReseter()
119cdf0e10cSrcweir 	{
120cdf0e10cSrcweir 		if ( bInitialWarningState )
121cdf0e10cSrcweir 		{
122cdf0e10cSrcweir 			// don't allow dtor to throw
123cdf0e10cSrcweir 			try
124cdf0e10cSrcweir 			{
125cdf0e10cSrcweir 				setReplaceCellsWarning( true );
126cdf0e10cSrcweir 			}
127cdf0e10cSrcweir 			catch ( uno::Exception& /*e*/ ){}
128cdf0e10cSrcweir 		}
129cdf0e10cSrcweir 	}
130cdf0e10cSrcweir };
131cdf0e10cSrcweir 
132cdf0e10cSrcweir void
implnPaste(const uno::Reference<frame::XModel> & xModel)133cdf0e10cSrcweir implnPaste( const uno::Reference< frame::XModel>& xModel )
134cdf0e10cSrcweir {
135cdf0e10cSrcweir 	PasteCellsWarningReseter resetWarningBox;
136cdf0e10cSrcweir 	ScTabViewShell* pViewShell = getBestViewShell( xModel );
137cdf0e10cSrcweir 	if ( pViewShell )
138cdf0e10cSrcweir 	{
139cdf0e10cSrcweir 		pViewShell->PasteFromSystem();
140cdf0e10cSrcweir 		pViewShell->CellContentChanged();
141cdf0e10cSrcweir 	}
142cdf0e10cSrcweir }
143cdf0e10cSrcweir 
144cdf0e10cSrcweir 
145cdf0e10cSrcweir void
implnCopy(const uno::Reference<frame::XModel> & xModel)146cdf0e10cSrcweir implnCopy( const uno::Reference< frame::XModel>& xModel )
147cdf0e10cSrcweir {
148cdf0e10cSrcweir 	ScTabViewShell* pViewShell = getBestViewShell( xModel );
149cdf0e10cSrcweir 	if ( pViewShell )
150cdf0e10cSrcweir     {
151cdf0e10cSrcweir 		pViewShell->CopyToClip(NULL,false,false,true);
152cdf0e10cSrcweir 
153cdf0e10cSrcweir         // mark the copied transfer object so it is used in ScVbaRange::Insert
154cdf0e10cSrcweir         ScTransferObj* pClipObj = ScTransferObj::GetOwnClipboard( NULL );
155cdf0e10cSrcweir         if (pClipObj)
156cdf0e10cSrcweir             pClipObj->SetUseInApi( true );
157cdf0e10cSrcweir     }
158cdf0e10cSrcweir }
159cdf0e10cSrcweir 
160cdf0e10cSrcweir void
implnCut(const uno::Reference<frame::XModel> & xModel)161cdf0e10cSrcweir implnCut( const uno::Reference< frame::XModel>& xModel )
162cdf0e10cSrcweir {
163cdf0e10cSrcweir 	ScTabViewShell* pViewShell =  getBestViewShell( xModel );
164cdf0e10cSrcweir 	if ( pViewShell )
165cdf0e10cSrcweir     {
166cdf0e10cSrcweir 		pViewShell->CutToClip( NULL, sal_True );
167cdf0e10cSrcweir 
168cdf0e10cSrcweir         // mark the copied transfer object so it is used in ScVbaRange::Insert
169cdf0e10cSrcweir         ScTransferObj* pClipObj = ScTransferObj::GetOwnClipboard( NULL );
170cdf0e10cSrcweir         if (pClipObj)
171cdf0e10cSrcweir             pClipObj->SetUseInApi( true );
172cdf0e10cSrcweir     }
173cdf0e10cSrcweir }
174cdf0e10cSrcweir 
implnPasteSpecial(const uno::Reference<frame::XModel> & xModel,sal_uInt16 nFlags,sal_uInt16 nFunction,sal_Bool bSkipEmpty,sal_Bool bTranspose)175cdf0e10cSrcweir void implnPasteSpecial( const uno::Reference< frame::XModel>& xModel, sal_uInt16 nFlags,sal_uInt16 nFunction,sal_Bool bSkipEmpty, sal_Bool bTranspose)
176cdf0e10cSrcweir {
177cdf0e10cSrcweir 	PasteCellsWarningReseter resetWarningBox;
178cdf0e10cSrcweir 	sal_Bool bAsLink(sal_False), bOtherDoc(sal_False);
179cdf0e10cSrcweir 	InsCellCmd eMoveMode = INS_NONE;
180cdf0e10cSrcweir 
181cdf0e10cSrcweir 	ScTabViewShell* pTabViewShell = getBestViewShell( xModel );
182cdf0e10cSrcweir 	if ( pTabViewShell )
183cdf0e10cSrcweir 	{
184cdf0e10cSrcweir 		ScViewData* pView = pTabViewShell->GetViewData();
185cdf0e10cSrcweir 		Window* pWin = ( pView != NULL ) ? pView->GetActiveWin() : NULL;
186cdf0e10cSrcweir 		if ( pView && pWin )
187cdf0e10cSrcweir 		{
188cdf0e10cSrcweir 			if ( bAsLink && bOtherDoc )
189cdf0e10cSrcweir 				pTabViewShell->PasteFromSystem(0);//SOT_FORMATSTR_ID_LINK
190cdf0e10cSrcweir 			else
191cdf0e10cSrcweir 			{
192cdf0e10cSrcweir 				ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pWin );
193cdf0e10cSrcweir 				ScDocument* pDoc = NULL;
194cdf0e10cSrcweir 				if ( pOwnClip )
195cdf0e10cSrcweir                 {
196cdf0e10cSrcweir 					pDoc = pOwnClip->GetDocument();
197cdf0e10cSrcweir                     pOwnClip->SetUseInApi( false );     // don't use in Insert after it was pasted once
198cdf0e10cSrcweir                 }
199cdf0e10cSrcweir 				pTabViewShell->PasteFromClip( nFlags, pDoc,
200cdf0e10cSrcweir 					nFunction, bSkipEmpty, bTranspose, bAsLink,
201cdf0e10cSrcweir 					eMoveMode, IDF_NONE, sal_True );
202cdf0e10cSrcweir 				pTabViewShell->CellContentChanged();
203cdf0e10cSrcweir 			}
204cdf0e10cSrcweir 		}
205cdf0e10cSrcweir 	}
206cdf0e10cSrcweir 
207cdf0e10cSrcweir }
208cdf0e10cSrcweir 
209cdf0e10cSrcweir ScDocShell*
getDocShell(const css::uno::Reference<css::frame::XModel> & xModel)210cdf0e10cSrcweir getDocShell( const css::uno::Reference< css::frame::XModel>& xModel )
211cdf0e10cSrcweir {
212cdf0e10cSrcweir 	uno::Reference< uno::XInterface > xIf( xModel, uno::UNO_QUERY_THROW );
213cdf0e10cSrcweir 	ScModelObj* pModel = dynamic_cast< ScModelObj* >( xIf.get() );
214cdf0e10cSrcweir 	ScDocShell* pDocShell = NULL;
215cdf0e10cSrcweir 	if ( pModel )
216cdf0e10cSrcweir 		pDocShell = (ScDocShell*)pModel->GetEmbeddedObject();
217cdf0e10cSrcweir 	return pDocShell;
218cdf0e10cSrcweir 
219cdf0e10cSrcweir }
220cdf0e10cSrcweir 
221cdf0e10cSrcweir ScTabViewShell*
getBestViewShell(const css::uno::Reference<css::frame::XModel> & xModel)222cdf0e10cSrcweir getBestViewShell( const css::uno::Reference< css::frame::XModel>& xModel )
223cdf0e10cSrcweir {
224cdf0e10cSrcweir 	ScDocShell* pDocShell = getDocShell( xModel );
225cdf0e10cSrcweir 	if ( pDocShell )
226cdf0e10cSrcweir 		return pDocShell->GetBestViewShell();
227cdf0e10cSrcweir 	return NULL;
228cdf0e10cSrcweir }
229cdf0e10cSrcweir 
230cdf0e10cSrcweir ScTabViewShell*
getCurrentBestViewShell(const uno::Reference<uno::XComponentContext> & xContext)231cdf0e10cSrcweir getCurrentBestViewShell(  const uno::Reference< uno::XComponentContext >& xContext )
232cdf0e10cSrcweir {
233cdf0e10cSrcweir 	uno::Reference< frame::XModel > xModel = getCurrentExcelDoc( xContext );
234cdf0e10cSrcweir 	return getBestViewShell( xModel );
235cdf0e10cSrcweir }
236cdf0e10cSrcweir 
237cdf0e10cSrcweir SfxViewFrame*
getViewFrame(const uno::Reference<frame::XModel> & xModel)238cdf0e10cSrcweir getViewFrame( const uno::Reference< frame::XModel >& xModel )
239cdf0e10cSrcweir {
240cdf0e10cSrcweir 	ScTabViewShell* pViewShell = getBestViewShell( xModel );
241cdf0e10cSrcweir 	if ( pViewShell )
242cdf0e10cSrcweir 		return pViewShell->GetViewFrame();
243cdf0e10cSrcweir 	return NULL;
244cdf0e10cSrcweir }
245cdf0e10cSrcweir 
246cdf0e10cSrcweir uno::Reference< XHelperInterface >
getUnoSheetModuleObj(const uno::Reference<sheet::XSpreadsheet> & xSheet)247cdf0e10cSrcweir getUnoSheetModuleObj( const uno::Reference< sheet::XSpreadsheet >& xSheet ) throw ( uno::RuntimeException )
248cdf0e10cSrcweir {
249cdf0e10cSrcweir     uno::Reference< beans::XPropertySet > xProps( xSheet, uno::UNO_QUERY_THROW );
250cdf0e10cSrcweir     rtl::OUString sCodeName;
251cdf0e10cSrcweir     xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("CodeName") ) ) >>= sCodeName;
252cdf0e10cSrcweir     // #TODO #FIXME ideally we should 'throw' here if we don't get a valid parent, but... it is possible
253cdf0e10cSrcweir     // to create a module ( and use 'Option VBASupport 1' ) for a calc document, in this scenario there
254cdf0e10cSrcweir     // are *NO* special document module objects ( of course being able to switch between vba/non vba mode at
255cdf0e10cSrcweir     // the document in the future could fix this, especially IF the switching of the vba mode takes care to
256cdf0e10cSrcweir     // create the special document module objects if they don't exist.
257cdf0e10cSrcweir     return getUnoDocModule( sCodeName, GetDocShellFromRange( xSheet ) );
258cdf0e10cSrcweir }
259cdf0e10cSrcweir 
260cdf0e10cSrcweir uno::Reference< XHelperInterface >
getUnoSheetModuleObj(const uno::Reference<table::XCellRange> & xRange)261cdf0e10cSrcweir getUnoSheetModuleObj( const uno::Reference< table::XCellRange >& xRange ) throw ( uno::RuntimeException )
262cdf0e10cSrcweir {
263cdf0e10cSrcweir     uno::Reference< sheet::XSheetCellRange > xSheetRange( xRange, uno::UNO_QUERY_THROW );
264cdf0e10cSrcweir     uno::Reference< sheet::XSpreadsheet > xSheet( xSheetRange->getSpreadsheet(), uno::UNO_SET_THROW );
265cdf0e10cSrcweir     return getUnoSheetModuleObj( xSheet );
266cdf0e10cSrcweir }
267cdf0e10cSrcweir 
268cdf0e10cSrcweir uno::Reference< XHelperInterface >
getUnoSheetModuleObj(const uno::Reference<sheet::XSheetCellRangeContainer> & xRanges)269cdf0e10cSrcweir getUnoSheetModuleObj( const uno::Reference< sheet::XSheetCellRangeContainer >& xRanges ) throw ( uno::RuntimeException )
270cdf0e10cSrcweir {
271cdf0e10cSrcweir     uno::Reference< container::XEnumerationAccess > xEnumAccess( xRanges, uno::UNO_QUERY_THROW );
272cdf0e10cSrcweir     uno::Reference< container::XEnumeration > xEnum = xEnumAccess->createEnumeration();
273cdf0e10cSrcweir     uno::Reference< table::XCellRange > xRange( xEnum->nextElement(), uno::UNO_QUERY_THROW );
274cdf0e10cSrcweir     return getUnoSheetModuleObj( xRange );
275cdf0e10cSrcweir }
276cdf0e10cSrcweir 
277cdf0e10cSrcweir uno::Reference< XHelperInterface >
getUnoSheetModuleObj(const uno::Reference<table::XCell> & xCell)278cdf0e10cSrcweir getUnoSheetModuleObj( const uno::Reference< table::XCell >& xCell ) throw ( uno::RuntimeException )
279cdf0e10cSrcweir {
280cdf0e10cSrcweir     uno::Reference< sheet::XSheetCellRange > xSheetRange( xCell, uno::UNO_QUERY_THROW );
281cdf0e10cSrcweir     uno::Reference< sheet::XSpreadsheet > xSheet( xSheetRange->getSpreadsheet(), uno::UNO_SET_THROW );
282cdf0e10cSrcweir     return getUnoSheetModuleObj( xSheet );
283cdf0e10cSrcweir }
284cdf0e10cSrcweir 
285cdf0e10cSrcweir uno::Reference< XHelperInterface >
getUnoSheetModuleObj(const uno::Reference<frame::XModel> & xModel,SCTAB nTab)286cdf0e10cSrcweir getUnoSheetModuleObj( const uno::Reference< frame::XModel >& xModel, SCTAB nTab ) throw ( uno::RuntimeException )
287cdf0e10cSrcweir {
288cdf0e10cSrcweir     uno::Reference< sheet::XSpreadsheetDocument > xDoc( xModel, uno::UNO_QUERY_THROW );
289cdf0e10cSrcweir     uno::Reference< container::XIndexAccess > xSheets( xDoc->getSheets(), uno::UNO_QUERY_THROW );
290cdf0e10cSrcweir     uno::Reference< sheet::XSpreadsheet > xSheet( xSheets->getByIndex( nTab ), uno::UNO_QUERY_THROW );
291cdf0e10cSrcweir     return getUnoSheetModuleObj( xSheet );
292cdf0e10cSrcweir }
293cdf0e10cSrcweir 
294cdf0e10cSrcweir SfxItemSet*
GetDataSet(ScCellRangesBase * pRangeObj)295cdf0e10cSrcweir ScVbaCellRangeAccess::GetDataSet( ScCellRangesBase* pRangeObj )
296cdf0e10cSrcweir {
297cdf0e10cSrcweir 	return pRangeObj ? pRangeObj->GetCurrentDataSet( true ) : 0;
298cdf0e10cSrcweir }
299cdf0e10cSrcweir 
300cdf0e10cSrcweir // ============================================================================
301cdf0e10cSrcweir 
302cdf0e10cSrcweir } // namespace excel
303cdf0e10cSrcweir } // namespace vba
304cdf0e10cSrcweir } // namespace ooo
305