GPU-Calc: remove Alloc_Host_Ptr for clmem of NAN vector
[LibreOffice.git] / sc / source / ui / vba / vbaworksheets.cxx
blobb8332af98a44d9187e9c7b79877015f3faa3626d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #include "vbaworksheets.hxx"
21 #include <sfx2/dispatch.hxx>
22 #include <sfx2/app.hxx>
23 #include <sfx2/bindings.hxx>
24 #include <sfx2/request.hxx>
25 #include <sfx2/viewfrm.hxx>
26 #include <sfx2/itemwrapper.hxx>
27 #include <svl/itemset.hxx>
28 #include <svl/eitem.hxx>
30 #include <comphelper/processfactory.hxx>
31 #include <cppuhelper/implbase3.hxx>
33 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
34 #include <com/sun/star/container/XEnumerationAccess.hpp>
35 #include <com/sun/star/sheet/XSpreadsheetView.hpp>
36 #include <com/sun/star/container/XNamed.hpp>
37 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
38 #include <com/sun/star/beans/XPropertySet.hpp>
40 #include <ooo/vba/excel/XApplication.hpp>
41 #include "tabvwsh.hxx"
43 #include "vbaglobals.hxx"
44 #include "vbaworksheet.hxx"
45 #include "vbaworkbook.hxx"
46 #include "unonames.hxx"
47 #include "markdata.hxx"
49 #include <vector>
50 #include "prevwsh.hxx"
51 #include "preview.hxx"
52 using namespace ::ooo::vba;
53 using namespace ::com::sun::star;
56 typedef ::cppu::WeakImplHelper1< container::XEnumeration > SheetEnumeration_BASE;
57 typedef ::cppu::WeakImplHelper3< container::XNameAccess, container::XIndexAccess, container::XEnumerationAccess > SheetCollectionHelper_BASE;
58 // a map ( or hashmap ) wont do as we need also to preserve the order
59 // (as added ) of the items
60 typedef std::vector< uno::Reference< sheet::XSpreadsheet > > SheetMap;
63 // #FIXME #TODO the implementation of the Sheets collections sucks,
64 // e.g. there is no support for tracking sheets added/removed from the collection
66 class WorkSheetsEnumeration : public SheetEnumeration_BASE
68 SheetMap mSheetMap;
69 SheetMap::iterator mIt;
70 public:
71 WorkSheetsEnumeration( const SheetMap& sMap ) : mSheetMap( sMap ), mIt( mSheetMap.begin() ) {}
72 virtual ::sal_Bool SAL_CALL hasMoreElements( ) throw (uno::RuntimeException)
74 return ( mIt != mSheetMap.end() );
76 virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
78 if ( !hasMoreElements() )
79 throw container::NoSuchElementException();
80 uno::Reference< sheet::XSpreadsheet > xSheet( *mIt++ );
81 return uno::makeAny( xSheet ) ;
85 class SheetCollectionHelper : public SheetCollectionHelper_BASE
87 SheetMap mSheetMap;
88 SheetMap::iterator cachePos;
89 public:
90 SheetCollectionHelper( const SheetMap& sMap ) : mSheetMap( sMap ), cachePos(mSheetMap.begin()) {}
91 // XElementAccess
92 virtual uno::Type SAL_CALL getElementType( ) throw (uno::RuntimeException) { return sheet::XSpreadsheet::static_type(0); }
93 virtual ::sal_Bool SAL_CALL hasElements( ) throw (uno::RuntimeException) { return ( !mSheetMap.empty() ); }
94 // XNameAcess
95 virtual uno::Any SAL_CALL getByName( const OUString& aName ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
97 if ( !hasByName(aName) )
98 throw container::NoSuchElementException();
99 return uno::makeAny( *cachePos );
101 virtual uno::Sequence< OUString > SAL_CALL getElementNames( ) throw (uno::RuntimeException)
103 uno::Sequence< OUString > sNames( mSheetMap.size() );
104 OUString* pString = sNames.getArray();
105 SheetMap::iterator it = mSheetMap.begin();
106 SheetMap::iterator it_end = mSheetMap.end();
108 for ( ; it != it_end; ++it, ++pString )
110 uno::Reference< container::XNamed > xName( *it, uno::UNO_QUERY_THROW );
111 *pString = xName->getName();
113 return sNames;
115 virtual ::sal_Bool SAL_CALL hasByName( const OUString& aName ) throw (uno::RuntimeException)
117 cachePos = mSheetMap.begin();
118 SheetMap::iterator it_end = mSheetMap.end();
119 for ( ; cachePos != it_end; ++cachePos )
121 uno::Reference< container::XNamed > xName( *cachePos, uno::UNO_QUERY_THROW );
122 if ( aName.equals( xName->getName() ) )
123 break;
125 return ( cachePos != it_end );
128 // XElementAccess
129 virtual ::sal_Int32 SAL_CALL getCount( ) throw (uno::RuntimeException) { return mSheetMap.size(); }
130 virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException )
132 if ( Index < 0 || Index >= getCount() )
133 throw lang::IndexOutOfBoundsException();
135 return uno::makeAny( mSheetMap[ Index ] );
138 // XEnumerationAccess
139 virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) throw (uno::RuntimeException)
141 return new WorkSheetsEnumeration( mSheetMap );
145 class SheetsEnumeration : public EnumerationHelperImpl
147 uno::Reference< frame::XModel > m_xModel;
148 public:
149 SheetsEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Reference< frame::XModel >& xModel ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), m_xModel( xModel ) {}
151 virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
153 uno::Reference< sheet::XSpreadsheet > xSheet( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW );
154 uno::Reference< XHelperInterface > xIf = excel::getUnoSheetModuleObj( xSheet );
155 uno::Any aRet;
156 if ( !xIf.is() )
158 // if the Sheet is in a document created by the api unfortunately ( at the
159 // moment, it actually wont have the special Document modules
160 uno::Reference< excel::XWorksheet > xNewSheet( new ScVbaWorksheet( m_xParent, m_xContext, xSheet, m_xModel ) );
161 aRet <<= xNewSheet;
163 else
164 aRet <<= xIf;
165 return aRet;
170 ScVbaWorksheets::ScVbaWorksheets( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< ::com::sun::star::uno::XComponentContext > & xContext, const uno::Reference< container::XIndexAccess >& xSheets, const uno::Reference< frame::XModel >& xModel ): ScVbaWorksheets_BASE( xParent, xContext, xSheets ), mxModel( xModel ), m_xSheets( uno::Reference< sheet::XSpreadsheets >( xSheets, uno::UNO_QUERY ) )
174 ScVbaWorksheets::ScVbaWorksheets( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< ::com::sun::star::uno::XComponentContext > & xContext, const uno::Reference< container::XEnumerationAccess >& xEnumAccess, const uno::Reference< frame::XModel >& xModel ): ScVbaWorksheets_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( xEnumAccess, uno::UNO_QUERY ) ), mxModel(xModel)
178 // XEnumerationAccess
179 uno::Type
180 ScVbaWorksheets::getElementType() throw (uno::RuntimeException)
182 return excel::XWorksheet::static_type(0);
185 uno::Reference< container::XEnumeration >
186 ScVbaWorksheets::createEnumeration() throw (uno::RuntimeException)
188 if ( !m_xSheets.is() )
190 uno::Reference< container::XEnumerationAccess > xAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
191 return xAccess->createEnumeration();
193 uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xSheets, uno::UNO_QUERY_THROW );
194 return new SheetsEnumeration( this, mxContext, xEnumAccess->createEnumeration(), mxModel );
197 uno::Any
198 ScVbaWorksheets::createCollectionObject( const uno::Any& aSource )
200 uno::Reference< sheet::XSpreadsheet > xSheet( aSource, uno::UNO_QUERY );
201 uno::Reference< XHelperInterface > xIf = excel::getUnoSheetModuleObj( xSheet );
202 uno::Any aRet;
203 if ( !xIf.is() )
205 // if the Sheet is in a document created by the api unfortunately ( at the
206 // moment, it actually wont have the special Document modules
207 uno::Reference< excel::XWorksheet > xNewSheet( new ScVbaWorksheet( getParent(), mxContext, xSheet, mxModel ) );
208 aRet <<= xNewSheet;
210 else
211 aRet <<= xIf;
212 return aRet;
215 // XWorksheets
216 uno::Any
217 ScVbaWorksheets::Add( const uno::Any& Before, const uno::Any& After,
218 const uno::Any& Count, const uno::Any& Type ) throw (uno::RuntimeException)
220 if ( isSelectedSheets() )
221 return uno::Any(); // or should we throw?
223 OUString aStringSheet;
224 sal_Bool bBefore(sal_True);
225 SCTAB nSheetIndex = 0;
226 SCTAB nNewSheets = 1, nType = 0;
227 Count >>= nNewSheets;
228 Type >>= nType;
229 SCTAB nCount = 0;
231 uno::Reference< excel::XWorksheet > xBeforeAfterSheet;
233 if ( Before.hasValue() )
235 if ( Before >>= xBeforeAfterSheet )
236 aStringSheet = xBeforeAfterSheet->getName();
237 else
238 Before >>= aStringSheet;
241 if (aStringSheet.isEmpty() && After.hasValue() )
243 if ( After >>= xBeforeAfterSheet )
244 aStringSheet = xBeforeAfterSheet->getName();
245 else
246 After >>= aStringSheet;
247 bBefore = false;
249 if (aStringSheet.isEmpty())
251 uno::Reference< excel::XApplication > xApplication( Application(), uno::UNO_QUERY_THROW );
252 aStringSheet = xApplication->getActiveWorkbook()->getActiveSheet()->getName();
253 bBefore = sal_True;
255 nCount = static_cast< SCTAB >( m_xIndexAccess->getCount() );
256 for (SCTAB i=0; i < nCount; i++)
258 uno::Reference< sheet::XSpreadsheet > xSheet(m_xIndexAccess->getByIndex(i), uno::UNO_QUERY);
259 uno::Reference< container::XNamed > xNamed( xSheet, uno::UNO_QUERY_THROW );
260 if (xNamed->getName() == aStringSheet)
262 nSheetIndex = i;
263 break;
267 if(!bBefore)
268 nSheetIndex++;
270 SCTAB nSheetName = nCount + 1L;
271 OUString aStringBase( "Sheet" );
272 uno::Any result;
273 for (SCTAB i=0; i < nNewSheets; i++, nSheetName++)
275 OUString aStringName = aStringBase + OUString::number(nSheetName);
276 while (m_xNameAccess->hasByName(aStringName))
278 nSheetName++;
279 aStringName = aStringBase + OUString::number(nSheetName);
281 m_xSheets->insertNewByName(aStringName, nSheetIndex + i);
282 result = getItemByStringIndex( aStringName );
284 uno::Reference< excel::XWorksheet > xNewSheet( result, uno::UNO_QUERY );
285 if ( xNewSheet.is() )
286 xNewSheet->Activate();
287 return result;
290 void
291 ScVbaWorksheets::Delete() throw (uno::RuntimeException)
293 // #TODO #INVESTIGATE
294 // mmm this method could be trouble if the underlying
295 // uno objects ( the m_xIndexAccess etc ) aren't aware of the
296 // contents that are deleted
297 sal_Int32 nElems = getCount();
298 for ( sal_Int32 nItem = 1; nItem <= nElems; ++nItem )
300 uno::Reference< excel::XWorksheet > xSheet( Item( uno::makeAny( nItem ), uno::Any() ), uno::UNO_QUERY_THROW );
301 xSheet->Delete();
305 bool
306 ScVbaWorksheets::isSelectedSheets()
308 return !m_xSheets.is();
311 void SAL_CALL
312 ScVbaWorksheets::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)
314 sal_Int32 nTo = 0;
315 sal_Int32 nFrom = 0;
316 sal_Int16 nCopies = 1;
317 sal_Bool bCollate = false;
318 sal_Bool bSelection = false;
319 From >>= nFrom;
320 To >>= nTo;
321 Copies >>= nCopies;
322 if ( nCopies > 1 ) // Collate only useful when more that 1 copy
323 Collate >>= bCollate;
325 if ( !( nFrom || nTo ) )
326 if ( isSelectedSheets() )
327 bSelection = sal_True;
329 PrintOutHelper( excel::getBestViewShell( mxModel ), From, To, Copies, Preview, ActivePrinter, PrintToFile, Collate, PrToFileName, bSelection );
332 uno::Any SAL_CALL
333 ScVbaWorksheets::getVisible() throw (uno::RuntimeException)
335 sal_Bool bVisible = sal_True;
336 uno::Reference< container::XEnumeration > xEnum( createEnumeration(), uno::UNO_QUERY_THROW );
337 while ( xEnum->hasMoreElements() )
339 uno::Reference< excel::XWorksheet > xSheet( xEnum->nextElement(), uno::UNO_QUERY_THROW );
340 if ( xSheet->getVisible() == false )
342 bVisible = false;
343 break;
346 return uno::makeAny( bVisible );
349 void SAL_CALL
350 ScVbaWorksheets::setVisible( const uno::Any& _visible ) throw (uno::RuntimeException)
352 sal_Bool bState = false;
353 if ( _visible >>= bState )
355 uno::Reference< container::XEnumeration > xEnum( createEnumeration(), uno::UNO_QUERY_THROW );
356 while ( xEnum->hasMoreElements() )
358 uno::Reference< excel::XWorksheet > xSheet( xEnum->nextElement(), uno::UNO_QUERY_THROW );
359 xSheet->setVisible( bState );
362 else
363 throw uno::RuntimeException("Visible property doesn't support non boolean #FIXME", uno::Reference< uno::XInterface >() );
366 void SAL_CALL
367 ScVbaWorksheets::Select( const uno::Any& Replace ) throw (uno::RuntimeException)
369 ScTabViewShell* pViewShell = excel::getBestViewShell( mxModel );
370 if ( !pViewShell )
371 throw uno::RuntimeException("Cannot obtain view shell", uno::Reference< uno::XInterface >() );
373 ScMarkData& rMarkData = pViewShell->GetViewData()->GetMarkData();
374 sal_Bool bReplace = sal_True;
375 Replace >>= bReplace;
376 // Replace is defaulted to True, meanining this current collection
377 // becomes the Selection, if it were false then the current selection would
378 // be extended
379 bool bSelectSingle = bReplace;
380 sal_Int32 nElems = getCount();
381 for ( sal_Int32 nItem = 1; nItem <= nElems; ++nItem )
383 uno::Reference< excel::XWorksheet > xSheet( Item( uno::makeAny( nItem ), uno::Any() ), uno::UNO_QUERY_THROW );
384 ScVbaWorksheet* pSheet = excel::getImplFromDocModuleWrapper<ScVbaWorksheet>( xSheet );
385 if ( bSelectSingle )
387 rMarkData.SelectOneTable( static_cast< SCTAB >( pSheet->getSheetID() ) );
388 bSelectSingle = false;
390 else
391 rMarkData.SelectTable( static_cast< SCTAB >( pSheet->getSheetID() ), sal_True );
397 void SAL_CALL
398 ScVbaWorksheets::Copy ( const uno::Any& Before, const uno::Any& After) throw (css::uno::RuntimeException)
400 uno::Reference<excel::XWorksheet> xSheet;
401 sal_Int32 nElems = getCount();
402 bool bAfter = After.hasValue();
403 std::vector< uno::Reference< excel::XWorksheet > > Sheets;
404 sal_Int32 nItem = 0;
406 for ( nItem = 1; nItem <= nElems; ++nItem)
408 uno::Reference<excel::XWorksheet> xWorksheet(Item( uno::makeAny( nItem ), uno::Any() ), uno::UNO_QUERY_THROW );
409 Sheets.push_back(xWorksheet);
411 bool bNewDoc = (!(Before >>= xSheet) && !(After >>=xSheet)&& !(Before.hasValue()) && !(After.hasValue()));
413 uno::Reference< excel::XWorksheet > xSrcSheet;
414 if ( bNewDoc )
416 bAfter = true;
417 xSrcSheet = Sheets.at(0);
418 ScVbaWorksheet* pSrcSheet = excel::getImplFromDocModuleWrapper<ScVbaWorksheet>( xSrcSheet );
419 xSheet = pSrcSheet->createSheetCopyInNewDoc(xSrcSheet->getName());
420 nItem = 1;
422 else
424 nItem=0;
427 for (; nItem < nElems; ++nItem )
429 xSrcSheet = Sheets[nItem];
430 ScVbaWorksheet* pSrcSheet = excel::getImplFromDocModuleWrapper<ScVbaWorksheet>( xSrcSheet );
431 if ( bAfter )
432 xSheet = pSrcSheet->createSheetCopy(xSheet, bAfter);
433 else
434 pSrcSheet->createSheetCopy(xSheet, bAfter);
438 //ScVbaCollectionBaseImpl
439 uno::Any SAL_CALL
440 ScVbaWorksheets::Item( const uno::Any& Index, const uno::Any& Index2 ) throw (uno::RuntimeException)
442 if ( Index.getValueTypeClass() == uno::TypeClass_SEQUENCE )
444 uno::Reference< script::XTypeConverter > xConverter = getTypeConverter(mxContext);
445 uno::Any aConverted;
446 aConverted = xConverter->convertTo( Index, getCppuType((uno::Sequence< uno::Any >*)0) );
447 SheetMap mSheets;
448 uno::Sequence< uno::Any > sIndices;
449 aConverted >>= sIndices;
450 sal_Int32 nElems = sIndices.getLength();
451 for( sal_Int32 index = 0; index < nElems; ++index )
453 uno::Reference< excel::XWorksheet > xWorkSheet( ScVbaWorksheets_BASE::Item( sIndices[ index ], Index2 ), uno::UNO_QUERY_THROW );
454 ScVbaWorksheet* pWorkSheet = excel::getImplFromDocModuleWrapper<ScVbaWorksheet>( xWorkSheet );
455 uno::Reference< sheet::XSpreadsheet > xSheet( pWorkSheet->getSheet() , uno::UNO_QUERY_THROW );
456 uno::Reference< container::XNamed > xName( xSheet, uno::UNO_QUERY_THROW );
457 mSheets.push_back( xSheet );
459 uno::Reference< container::XIndexAccess > xIndexAccess = new SheetCollectionHelper( mSheets );
460 uno::Reference< XCollection > xSelectedSheets( new ScVbaWorksheets( this->getParent(), mxContext, xIndexAccess, mxModel ) );
461 return uno::makeAny( xSelectedSheets );
463 return ScVbaWorksheets_BASE::Item( Index, Index2 );
466 uno::Any
467 ScVbaWorksheets::getItemByStringIndex( const OUString& sIndex ) throw (uno::RuntimeException)
469 return ScVbaWorksheets_BASE::getItemByStringIndex( sIndex );
472 OUString
473 ScVbaWorksheets::getServiceImplName()
475 return OUString("ScVbaWorksheets");
478 css::uno::Sequence<OUString>
479 ScVbaWorksheets::getServiceNames()
481 static uno::Sequence< OUString > sNames;
482 if ( sNames.getLength() == 0 )
484 sNames.realloc( 1 );
485 sNames[0] = "ooo.vba.excel.Worksheets";
487 return sNames;
490 bool ScVbaWorksheets::nameExists( uno::Reference <sheet::XSpreadsheetDocument>& xSpreadDoc, const OUString & name, SCTAB& nTab ) throw ( lang::IllegalArgumentException )
492 if (!xSpreadDoc.is())
493 throw lang::IllegalArgumentException( OUString( "nameExists() xSpreadDoc is null" ), uno::Reference< uno::XInterface >(), 1 );
494 uno::Reference <container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY );
495 if ( xIndex.is() )
497 SCTAB nCount = static_cast< SCTAB >( xIndex->getCount() );
498 for (SCTAB i=0; i < nCount; i++)
500 uno::Reference< container::XNamed > xNamed( xIndex->getByIndex(i), uno::UNO_QUERY_THROW );
501 if (xNamed->getName() == name)
503 nTab = i;
504 return true;
508 return false;
511 void ScVbaWorksheets::PrintPreview( const css::uno::Any& /*EnableChanges*/ ) throw (css::uno::RuntimeException)
513 // need test, print preview current active sheet
514 // !! TODO !! get view shell from controller
515 ScTabViewShell* pViewShell = excel::getBestViewShell( mxModel );
516 SfxViewFrame* pViewFrame = NULL;
517 if ( pViewShell )
518 pViewFrame = pViewShell->GetViewFrame();
519 if ( pViewFrame )
521 if ( !pViewFrame->GetFrame().IsInPlace() )
523 dispatchExecute( pViewShell, SID_VIEWSHELL1 );
524 SfxViewShell* pShell = SfxViewShell::Get( pViewFrame->GetFrame().GetFrameInterface()->getController() );
526 if ( pShell->ISA( ScPreviewShell ) )
528 ScPreviewShell* pPrvShell = static_cast< ScPreviewShell* >( pShell );
529 ScPreview* pPrvView = pPrvShell->GetPreview();
530 ScMarkData aMarkData;
531 sal_Int32 nElems = getCount();
532 for ( sal_Int32 nItem = 1; nItem <= nElems; ++nItem )
534 uno::Reference< excel::XWorksheet > xSheet( Item( uno::makeAny( nItem ), uno::Any() ), uno::UNO_QUERY_THROW );
535 ScVbaWorksheet* pSheet = excel::getImplFromDocModuleWrapper<ScVbaWorksheet>( xSheet );
536 if ( pSheet )
537 aMarkData.SelectTable(static_cast< SCTAB >( pSheet->getSheetID() ), true );
539 // save old selection, setting the selectedtabs in the preview
540 // can affect the current selection when preview has been
541 // closed
542 ScMarkData::MarkedTabsType aOldTabs = pPrvView->GetSelectedTabs();
543 pPrvView->SetSelectedTabs( aMarkData );
544 // force update
545 pPrvView->DataChanged();
546 // set sensible first page
547 long nPage = pPrvView->GetFirstPage( 1 );
548 pPrvView->SetPageNo( nPage );
549 WaitUntilPreviewIsClosed( pViewFrame );
550 // restore old tab selection
551 pViewShell = excel::getBestViewShell( mxModel );
552 pViewShell->GetViewData()->GetMarkData().SetSelectedTabs(aOldTabs);
559 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */