tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / vba / vbaworksheet.cxx
blob26835553af2d2289a493719b31797448e230db23
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 .
20 #include <sal/config.h>
22 #include <string_view>
24 #include "vbaworksheet.hxx"
25 #include "vbanames.hxx"
27 #include <com/sun/star/beans/XPropertySet.hpp>
28 #include <com/sun/star/beans/XIntrospectionAccess.hpp>
29 #include <com/sun/star/container/XNamed.hpp>
30 #include <com/sun/star/util/XProtectable.hpp>
31 #include <com/sun/star/table/XCellRange.hpp>
32 #include <com/sun/star/sheet/XSpreadsheetView.hpp>
33 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
34 #include <com/sun/star/sheet/XCalculatable.hpp>
35 #include <com/sun/star/sheet/XCellRangeAddressable.hpp>
36 #include <com/sun/star/sheet/XSheetCellRange.hpp>
37 #include <com/sun/star/sheet/XSheetCellCursor.hpp>
38 #include <com/sun/star/sheet/XSheetAnnotationsSupplier.hpp>
39 #include <com/sun/star/sheet/XUsedAreaCursor.hpp>
40 #include <com/sun/star/sheet/XSpreadsheets.hpp>
41 #include <com/sun/star/sheet/XSheetOutline.hpp>
42 #include <com/sun/star/sheet/XSheetPageBreak.hpp>
43 #include <com/sun/star/sheet/XDataPilotTablesSupplier.hpp>
44 #include <com/sun/star/sheet/XNamedRanges.hpp>
45 #include <com/sun/star/frame/Desktop.hpp>
46 #include <com/sun/star/table/XTableChartsSupplier.hpp>
47 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
48 #include <com/sun/star/drawing/XControlShape.hpp>
49 #include <com/sun/star/form/XFormsSupplier.hpp>
50 #include <ooo/vba/excel/XApplication.hpp>
51 #include <ooo/vba/excel/XlEnableSelection.hpp>
52 #include <ooo/vba/excel/XlSheetVisibility.hpp>
53 #include <ooo/vba/XControlProvider.hpp>
55 #include <basic/sberrors.hxx>
56 #include <comphelper/processfactory.hxx>
57 #include <comphelper/servicehelper.hxx>
58 #include <utility>
59 #include <vbahelper/vbashapes.hxx>
61 //zhangyun showdataform
62 #include <scabstdlg.hxx>
63 #include <tabvwsh.hxx>
65 #include <tabprotection.hxx>
66 #include "excelvbahelper.hxx"
67 #include "vbaoutline.hxx"
68 #include "vbarange.hxx"
69 #include "vbacomments.hxx"
70 #include "vbachartobjects.hxx"
71 #include "vbapivottables.hxx"
72 #include "vbaoleobjects.hxx"
73 #include "vbapagesetup.hxx"
74 #include "vbapagebreaks.hxx"
75 #include "vbaworksheets.hxx"
76 #include "vbahyperlinks.hxx"
77 #include "vbasheetobjects.hxx"
78 #include <dbdata.hxx>
80 #include <attrib.hxx>
82 #define STANDARDWIDTH 2267
83 #define STANDARDHEIGHT 427
85 using namespace com::sun::star;
86 using namespace ooo::vba;
88 static void getNewSpreadsheetName (OUString &aNewName, std::u16string_view aOldName, const uno::Reference <sheet::XSpreadsheetDocument>& xSpreadDoc )
90 if (!xSpreadDoc.is())
91 throw lang::IllegalArgumentException( u"getNewSpreadsheetName() xSpreadDoc is null"_ustr, uno::Reference< uno::XInterface >(), 1 );
92 static const char aUnderScore[] = "_";
93 int currentNum =2;
94 aNewName = OUString::Concat(aOldName) + aUnderScore + OUString::number(currentNum) ;
95 SCTAB nTab = 0;
96 while ( ScVbaWorksheets::nameExists(xSpreadDoc,aNewName, nTab ) )
98 aNewName = OUString::Concat(aOldName) + aUnderScore + OUString::number(++currentNum);
102 static void removeAllSheets( const uno::Reference <sheet::XSpreadsheetDocument>& xSpreadDoc, const OUString& aSheetName)
104 if (!xSpreadDoc.is())
105 throw lang::IllegalArgumentException( u"removeAllSheets() xSpreadDoc is null"_ustr, uno::Reference< uno::XInterface >(), 1 );
106 uno::Reference<sheet::XSpreadsheets> xSheets = xSpreadDoc->getSheets();
107 uno::Reference <container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY );
109 if ( !xIndex.is() )
110 return;
112 uno::Reference<container::XNameContainer> xNameContainer(xSheets,uno::UNO_QUERY_THROW);
113 for (sal_Int32 i = xIndex->getCount() -1; i>= 1; i--)
115 uno::Reference< sheet::XSpreadsheet > xSheet(xIndex->getByIndex(i), uno::UNO_QUERY);
116 uno::Reference< container::XNamed > xNamed( xSheet, uno::UNO_QUERY_THROW );
117 xNameContainer->removeByName(xNamed->getName());
120 uno::Reference< sheet::XSpreadsheet > xSheet(xIndex->getByIndex(0), uno::UNO_QUERY);
121 uno::Reference< container::XNamed > xNamed( xSheet, uno::UNO_QUERY_THROW );
122 xNamed->setName(aSheetName);
125 static uno::Reference<frame::XModel>
126 openNewDoc(const OUString& aSheetName )
128 uno::Reference<frame::XModel> xModel;
131 const uno::Reference< uno::XComponentContext >& xContext(
132 comphelper::getProcessComponentContext() );
134 uno::Reference <frame::XDesktop2 > xComponentLoader = frame::Desktop::create(xContext);
136 uno::Reference<lang::XComponent > xComponent( xComponentLoader->loadComponentFromURL(
137 u"private:factory/scalc"_ustr,
138 u"_blank"_ustr, 0,
139 uno::Sequence < css::beans::PropertyValue >() ) );
140 uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( xComponent, uno::UNO_QUERY_THROW );
141 removeAllSheets(xSpreadDoc,aSheetName);
142 xModel.set(xSpreadDoc,uno::UNO_QUERY_THROW);
144 catch ( uno::Exception & /*e*/ )
147 return xModel;
150 ScVbaWorksheet::ScVbaWorksheet(const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext,
151 uno::Reference< sheet::XSpreadsheet > xSheet,
152 uno::Reference< frame::XModel > xModel ) : WorksheetImpl_BASE( xParent, xContext ), mxSheet(std::move( xSheet )), mxModel(std::move(xModel)), mbVeryHidden( false )
156 ScVbaWorksheet::ScVbaWorksheet( uno::Sequence< uno::Any> const & args,
157 uno::Reference< uno::XComponentContext> const & xContext ) : WorksheetImpl_BASE( getXSomethingFromArgs< XHelperInterface >( args, 0 ), xContext ), mxModel( getXSomethingFromArgs< frame::XModel >( args, 1 ) ), mbVeryHidden( false )
159 if ( args.getLength() < 3 )
160 throw lang::IllegalArgumentException();
162 OUString sSheetName;
163 args[2] >>= sSheetName;
165 uno::Reference< sheet::XSpreadsheetDocument > xSpreadDoc( mxModel, uno::UNO_QUERY_THROW );
166 uno::Reference< container::XNameAccess > xNameAccess( xSpreadDoc->getSheets(), uno::UNO_QUERY_THROW );
167 mxSheet.set( xNameAccess->getByName( sSheetName ), uno::UNO_QUERY_THROW );
170 ScVbaWorksheet::~ScVbaWorksheet()
174 const uno::Sequence<sal_Int8>& ScVbaWorksheet::getUnoTunnelId()
176 static const comphelper::UnoIdInit theScVbaWorksheetUnoTunnelId;
177 return theScVbaWorksheetUnoTunnelId.getSeq();
180 uno::Reference< ov::excel::XWorksheet >
181 ScVbaWorksheet::createSheetCopyInNewDoc(const OUString& aCurrSheetName)
183 uno::Reference< sheet::XSheetCellCursor > xSheetCellCursor = getSheet()->createCursor( );
184 uno::Reference<sheet::XUsedAreaCursor> xUsedCursor(xSheetCellCursor,uno::UNO_QUERY_THROW);
185 uno::Reference<excel::XRange> xRange = new ScVbaRange( this, mxContext, xSheetCellCursor);
186 if (xRange.is())
187 xRange->Select();
188 excel::implnCopy(mxModel);
189 uno::Reference<frame::XModel> xModel = openNewDoc(aCurrSheetName);
190 if (xModel.is())
192 excel::implnPaste(xModel);
194 uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( xModel, uno::UNO_QUERY_THROW );
195 excel::setUpDocumentModules(xSpreadDoc);
196 uno::Reference <sheet::XSpreadsheets> xSheets( xSpreadDoc->getSheets(), uno::UNO_SET_THROW );
197 uno::Reference <container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY_THROW );
198 uno::Reference< sheet::XSpreadsheet > xSheet(xIndex->getByIndex(0), uno::UNO_QUERY_THROW);
200 ScDocShell* pShell = excel::getDocShell( xModel );
201 OUString aCodeName;
202 if (pShell)
203 pShell->GetDocument().GetCodeName( 0, aCodeName );
204 return uno::Reference< excel::XWorksheet >( getUnoDocModule( aCodeName, pShell ), uno::UNO_QUERY_THROW );
207 css::uno::Reference< ov::excel::XWorksheet >
208 ScVbaWorksheet::createSheetCopy(uno::Reference<excel::XWorksheet> const & xSheet, bool bAfter)
210 OUString aCurrSheetName = getName();
211 ScVbaWorksheet* pDestSheet = excel::getImplFromDocModuleWrapper<ScVbaWorksheet>( xSheet );
213 uno::Reference <sheet::XSpreadsheetDocument> xDestDoc( pDestSheet->getModel(), uno::UNO_QUERY );
214 uno::Reference <sheet::XSpreadsheetDocument> xSrcDoc( getModel(), uno::UNO_QUERY );
216 SCTAB nDest = 0;
217 SCTAB nSrc = 0;
218 OUString aSheetName = xSheet->getName();
219 bool bSameDoc = ( pDestSheet->getModel() == getModel() );
220 bool bDestSheetExists = ScVbaWorksheets::nameExists (xDestDoc, aSheetName, nDest );
221 bool bSheetExists = ScVbaWorksheets::nameExists (xSrcDoc, aCurrSheetName, nSrc );
223 // set sheet name to be newSheet name
224 aSheetName = aCurrSheetName;
225 if ( bSheetExists && bDestSheetExists )
227 SCTAB nDummy=0;
228 if(bAfter)
229 nDest++;
230 uno::Reference<sheet::XSpreadsheets> xSheets = xDestDoc->getSheets();
231 if ( bSameDoc || ScVbaWorksheets::nameExists( xDestDoc, aCurrSheetName, nDummy ) )
232 getNewSpreadsheetName(aSheetName,aCurrSheetName,xDestDoc);
233 if ( bSameDoc )
234 xSheets->copyByName(aCurrSheetName,aSheetName,nDest);
235 else
237 ScDocShell* pDestDocShell = excel::getDocShell( pDestSheet->getModel() );
238 ScDocShell* pSrcDocShell = excel::getDocShell( getModel() );
239 if ( pDestDocShell && pSrcDocShell )
240 pDestDocShell->TransferTab( *pSrcDocShell, nSrc, nDest, true, true );
243 // return new sheet
244 uno::Reference< excel::XApplication > xApplication( Application(), uno::UNO_QUERY_THROW );
245 uno::Reference< excel::XWorksheet > xNewSheet( xApplication->Worksheets( uno::Any( aSheetName ) ), uno::UNO_QUERY_THROW );
246 return xNewSheet;
249 OUString
250 ScVbaWorksheet::getName()
252 uno::Reference< container::XNamed > xNamed( getSheet(), uno::UNO_QUERY_THROW );
253 return xNamed->getName();
256 void
257 ScVbaWorksheet::setName(const OUString &rName )
259 uno::Reference< container::XNamed > xNamed( getSheet(), uno::UNO_QUERY_THROW );
260 xNamed->setName( rName );
263 sal_Int32
264 ScVbaWorksheet::getVisible()
266 uno::Reference< beans::XPropertySet > xProps( getSheet(), uno::UNO_QUERY_THROW );
267 bool bVisible = false;
268 xProps->getPropertyValue( u"IsVisible"_ustr ) >>= bVisible;
269 using namespace ::ooo::vba::excel::XlSheetVisibility;
270 return bVisible ? xlSheetVisible : (mbVeryHidden ? xlSheetVeryHidden : xlSheetHidden);
273 void
274 ScVbaWorksheet::setVisible( sal_Int32 nVisible )
276 using namespace ::ooo::vba::excel::XlSheetVisibility;
277 bool bVisible = true;
278 switch( nVisible )
280 case xlSheetVisible: case 1: // Excel accepts -1 and 1 for visible sheets
281 bVisible = true;
282 mbVeryHidden = false;
283 break;
284 case xlSheetHidden:
285 bVisible = false;
286 mbVeryHidden = false;
287 break;
288 case xlSheetVeryHidden:
289 bVisible = false;
290 mbVeryHidden = true;
291 break;
292 default:
293 throw uno::RuntimeException();
295 uno::Reference< beans::XPropertySet > xProps( getSheet(), uno::UNO_QUERY_THROW );
296 xProps->setPropertyValue( u"IsVisible"_ustr, uno::Any( bVisible ) );
299 sal_Int16
300 ScVbaWorksheet::getIndex()
302 return getSheetID() + 1;
305 sal_Int32
306 ScVbaWorksheet::getEnableSelection()
308 uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW );
309 SCTAB nTab = 0;
310 if ( !ScVbaWorksheets::nameExists(xSpreadDoc, getName(), nTab) )
311 throw uno::RuntimeException(u"Sheet Name does not exist."_ustr );
313 if ( ScDocShell* pShell = excel::getDocShell( getModel() ))
315 ScDocument& rDoc = pShell->GetDocument();
316 const ScTableProtection* pProtect = rDoc.GetTabProtection(nTab);
317 bool bLockedCells = false;
318 bool bUnlockedCells = false;
319 if( pProtect )
321 bLockedCells = pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
322 bUnlockedCells = pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
324 if( bLockedCells )
325 return excel::XlEnableSelection::xlNoRestrictions;
326 if( bUnlockedCells )
327 return excel::XlEnableSelection::xlUnlockedCells;
329 return excel::XlEnableSelection::xlNoSelection;
333 void
334 ScVbaWorksheet::setEnableSelection( sal_Int32 nSelection )
336 if( (nSelection != excel::XlEnableSelection::xlNoRestrictions) &&
337 (nSelection != excel::XlEnableSelection::xlUnlockedCells) &&
338 (nSelection != excel::XlEnableSelection::xlNoSelection) )
340 DebugHelper::runtimeexception(ERRCODE_BASIC_BAD_PARAMETER);
343 uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW );
344 SCTAB nTab = 0;
345 if ( !ScVbaWorksheets::nameExists(xSpreadDoc, getName(), nTab) )
346 throw uno::RuntimeException(u"Sheet Name does not exist."_ustr );
348 if ( ScDocShell* pShell = excel::getDocShell( getModel() ))
350 ScDocument& rDoc = pShell->GetDocument();
351 const ScTableProtection* pProtect = rDoc.GetTabProtection(nTab);
352 // default is xlNoSelection
353 bool bLockedCells = false;
354 bool bUnlockedCells = false;
355 if( nSelection == excel::XlEnableSelection::xlNoRestrictions )
357 bLockedCells = true;
358 bUnlockedCells = true;
360 else if( nSelection == excel::XlEnableSelection::xlUnlockedCells )
362 bUnlockedCells = true;
364 if( pProtect )
366 ScTableProtection aNewProtect(*pProtect);
367 aNewProtect.setOption(ScTableProtection::SELECT_LOCKED_CELLS, bLockedCells);
368 aNewProtect.setOption(ScTableProtection::SELECT_UNLOCKED_CELLS, bUnlockedCells);
369 rDoc.SetTabProtection(nTab, &aNewProtect);
374 sal_Bool SAL_CALL ScVbaWorksheet::getAutoFilterMode()
376 if ( ScDocShell* pShell = excel::getDocShell( getModel() ))
378 ScDocument& rDoc = pShell->GetDocument();
379 ScDBData* pDBData = rDoc.GetAnonymousDBData(getSheetID());
380 if (pDBData)
381 return pDBData->HasAutoFilter();
383 return false;
386 void SAL_CALL ScVbaWorksheet::setAutoFilterMode( sal_Bool bAutoFilterMode )
388 ScDocShell* pDocShell = excel::getDocShell( getModel() );
389 if (!pDocShell)
390 return;
391 ScDocument& rDoc = pDocShell->GetDocument();
392 ScDBData* pDBData = rDoc.GetAnonymousDBData(getSheetID());
393 if (!pDBData)
394 return;
396 pDBData->SetAutoFilter(bAutoFilterMode);
397 ScRange aRange;
398 pDBData->GetArea(aRange);
399 if (bAutoFilterMode)
400 rDoc.ApplyFlagsTab( aRange.aStart.Col(), aRange.aStart.Row(),
401 aRange.aEnd.Col(), aRange.aStart.Row(),
402 aRange.aStart.Tab(), ScMF::Auto );
403 else if (!bAutoFilterMode)
404 rDoc.RemoveFlagsTab(aRange.aStart.Col(), aRange.aStart.Row(),
405 aRange.aEnd.Col(), aRange.aStart.Row(),
406 aRange.aStart.Tab(), ScMF::Auto );
407 ScRange aPaintRange(aRange.aStart, aRange.aEnd);
408 aPaintRange.aEnd.SetRow(aPaintRange.aStart.Row());
409 pDocShell->PostPaint(aPaintRange, PaintPartFlags::Grid);
412 uno::Reference< excel::XRange >
413 ScVbaWorksheet::getUsedRange()
415 uno::Reference< sheet::XSheetCellRange > xSheetCellRange(getSheet(), uno::UNO_QUERY_THROW );
416 uno::Reference< sheet::XSheetCellCursor > xSheetCellCursor( getSheet()->createCursorByRange( xSheetCellRange ), uno::UNO_SET_THROW );
417 uno::Reference<sheet::XUsedAreaCursor> xUsedCursor(xSheetCellCursor,uno::UNO_QUERY_THROW);
418 xUsedCursor->gotoStartOfUsedArea( false );
419 xUsedCursor->gotoEndOfUsedArea( true );
420 return new ScVbaRange(this, mxContext, xSheetCellCursor);
423 uno::Reference< excel::XOutline >
424 ScVbaWorksheet::Outline( )
426 uno::Reference<sheet::XSheetOutline> xOutline(getSheet(),uno::UNO_QUERY_THROW);
427 return new ScVbaOutline( this, mxContext, xOutline);
430 uno::Reference< excel::XPageSetup >
431 ScVbaWorksheet::PageSetup( )
433 return new ScVbaPageSetup( this, mxContext, getSheet(), getModel() );
436 uno::Any
437 ScVbaWorksheet::HPageBreaks( const uno::Any& aIndex )
439 uno::Reference< sheet::XSheetPageBreak > xSheetPageBreak(getSheet(),uno::UNO_QUERY_THROW);
440 uno::Reference< excel::XHPageBreaks > xHPageBreaks( new ScVbaHPageBreaks( this, mxContext, xSheetPageBreak));
441 if ( aIndex.hasValue() )
442 return xHPageBreaks->Item( aIndex, uno::Any());
443 return uno::Any( xHPageBreaks );
446 uno::Any
447 ScVbaWorksheet::VPageBreaks( const uno::Any& aIndex )
449 uno::Reference< sheet::XSheetPageBreak > xSheetPageBreak( getSheet(), uno::UNO_QUERY_THROW );
450 uno::Reference< excel::XVPageBreaks > xVPageBreaks( new ScVbaVPageBreaks( this, mxContext, xSheetPageBreak ) );
451 if( aIndex.hasValue() )
452 return xVPageBreaks->Item( aIndex, uno::Any());
453 return uno::Any( xVPageBreaks );
456 sal_Int32
457 ScVbaWorksheet::getStandardWidth()
459 return STANDARDWIDTH ;
462 sal_Int32
463 ScVbaWorksheet::getStandardHeight()
465 return STANDARDHEIGHT;
468 sal_Bool
469 ScVbaWorksheet::getProtectionMode()
471 return false;
474 sal_Bool
475 ScVbaWorksheet::getProtectContents()
477 uno::Reference<util::XProtectable > xProtectable(getSheet(), uno::UNO_QUERY_THROW);
478 return xProtectable->isProtected();
481 sal_Bool
482 ScVbaWorksheet::getProtectDrawingObjects()
484 SCTAB nTab = 0;
485 OUString aSheetName = getName();
486 uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW );
487 bool bSheetExists = ScVbaWorksheets::nameExists (xSpreadDoc, aSheetName, nTab);
488 if ( bSheetExists )
490 if ( ScDocShell* pShell = excel::getDocShell( getModel() ))
492 ScDocument& rDoc = pShell->GetDocument();
493 const ScTableProtection* pProtect = rDoc.GetTabProtection(nTab);
494 if ( pProtect )
495 return pProtect->isOptionEnabled( ScTableProtection::OBJECTS );
498 return false;
501 sal_Bool
502 ScVbaWorksheet::getProtectScenarios()
504 return false;
507 void
508 ScVbaWorksheet::Activate()
510 uno::Reference< sheet::XSpreadsheetView > xSpreadsheet(
511 getModel()->getCurrentController(), uno::UNO_QUERY_THROW );
512 xSpreadsheet->setActiveSheet(getSheet());
515 void
516 ScVbaWorksheet::Select()
518 Activate();
521 void
522 ScVbaWorksheet::Move( const uno::Any& Before, const uno::Any& After )
524 uno::Reference<excel::XWorksheet> xSheet;
525 OUString aCurrSheetName = getName();
527 if (!(Before >>= xSheet) && !(After >>=xSheet)&& !(Before.hasValue()) && !(After.hasValue()))
529 uno::Reference< sheet::XSheetCellCursor > xSheetCellCursor = getSheet()->createCursor( );
530 uno::Reference<sheet::XUsedAreaCursor> xUsedCursor(xSheetCellCursor,uno::UNO_QUERY_THROW);
531 // #FIXME needs worksheet as parent
532 uno::Reference<excel::XRange> xRange = new ScVbaRange( this, mxContext, xSheetCellCursor);
533 if (xRange.is())
534 xRange->Select();
535 excel::implnCopy(mxModel);
536 uno::Reference<frame::XModel> xModel = openNewDoc(aCurrSheetName);
537 if (xModel.is())
539 excel::implnPaste(xModel);
540 Delete();
542 return ;
545 uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW );
546 SCTAB nDest = 0;
547 if ( ScVbaWorksheets::nameExists (xSpreadDoc, xSheet->getName(), nDest) )
549 bool bAfter = After.hasValue();
550 if (bAfter)
551 nDest++;
552 uno::Reference<sheet::XSpreadsheets> xSheets = xSpreadDoc->getSheets();
553 xSheets->moveByName(aCurrSheetName,nDest);
557 void
558 ScVbaWorksheet::Copy( const uno::Any& Before, const uno::Any& After )
560 uno::Reference<excel::XWorksheet> xSheet;
561 if (!(Before >>= xSheet) && !(After >>=xSheet)&& !(Before.hasValue()) && !(After.hasValue()))
563 createSheetCopyInNewDoc(getName());
564 return;
567 uno::Reference<excel::XWorksheet> xNewSheet = createSheetCopy(xSheet, After.hasValue());
568 xNewSheet->Activate();
571 void
572 ScVbaWorksheet::Paste( const uno::Any& Destination, const uno::Any& /*Link*/ )
574 // #TODO# #FIXME# Link is not used
575 uno::Reference<excel::XRange> xRange( Destination, uno::UNO_QUERY );
576 if ( xRange.is() )
577 xRange->Select();
578 excel::implnPaste( mxModel );
581 void
582 ScVbaWorksheet::Delete()
584 uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW );
585 OUString aSheetName = getName();
586 SCTAB nTab = 0;
587 if (!ScVbaWorksheets::nameExists(xSpreadDoc, aSheetName, nTab ))
589 return;
591 uno::Reference<sheet::XSpreadsheets> xSheets = xSpreadDoc->getSheets();
592 uno::Reference<container::XNameContainer> xNameContainer(xSheets,uno::UNO_QUERY_THROW);
593 xNameContainer->removeByName(aSheetName);
594 mxSheet.clear();
597 uno::Reference< excel::XWorksheet >
598 ScVbaWorksheet::getSheetAtOffset(SCTAB offset)
600 uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW );
601 uno::Reference <sheet::XSpreadsheets> xSheets( xSpreadDoc->getSheets(), uno::UNO_SET_THROW );
602 uno::Reference <container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY_THROW );
604 SCTAB nIdx = 0;
605 if ( !ScVbaWorksheets::nameExists (xSpreadDoc, getName(), nIdx ) )
606 return uno::Reference< excel::XWorksheet >();
607 nIdx = nIdx + offset;
608 uno::Reference< sheet::XSpreadsheet > xSheet(xIndex->getByIndex(nIdx), uno::UNO_QUERY_THROW);
609 // parent will be the parent of 'this' worksheet
610 return new ScVbaWorksheet (getParent(), mxContext, xSheet, getModel());
613 uno::Reference< excel::XWorksheet >
614 ScVbaWorksheet::getNext()
616 return getSheetAtOffset(static_cast<SCTAB>(1));
619 uno::Reference< excel::XWorksheet >
620 ScVbaWorksheet::getPrevious()
622 return getSheetAtOffset(-1);
625 void
626 ScVbaWorksheet::Protect( const uno::Any& Password, const uno::Any& /*DrawingObjects*/, const uno::Any& /*Contents*/, const uno::Any& /*Scenarios*/, const uno::Any& /*UserInterfaceOnly*/ )
628 // #TODO# #FIXME# is there anything we can do with the unused param
629 // can the implementation use anything else here
630 uno::Reference<util::XProtectable > xProtectable(getSheet(), uno::UNO_QUERY_THROW);
631 OUString aPasswd;
632 Password >>= aPasswd;
633 xProtectable->protect( aPasswd );
636 void
637 ScVbaWorksheet::Unprotect( const uno::Any& Password )
639 uno::Reference<util::XProtectable > xProtectable(getSheet(), uno::UNO_QUERY_THROW);
640 OUString aPasswd;
641 Password >>= aPasswd;
642 xProtectable->unprotect( aPasswd );
645 void
646 ScVbaWorksheet::Calculate()
648 uno::Reference <sheet::XCalculatable> xReCalculate(getModel(), uno::UNO_QUERY_THROW);
649 xReCalculate->calculate();
652 uno::Reference< excel::XRange >
653 ScVbaWorksheet::Range( const ::uno::Any& Cell1, const ::uno::Any& Cell2 )
655 uno::Reference< excel::XRange > xSheetRange( new ScVbaRange( this, mxContext
656 , uno::Reference< table::XCellRange >( getSheet(), uno::UNO_QUERY_THROW ) ) );
657 return xSheetRange->Range( Cell1, Cell2 );
660 void
661 ScVbaWorksheet::CheckSpelling( const uno::Any& /*CustomDictionary*/,const uno::Any& /*IgnoreUppercase*/,const uno::Any& /*AlwaysSuggest*/, const uno::Any& /*SpellingLang*/ )
663 // #TODO# #FIXME# unused params above, can we do anything with those
664 uno::Reference< frame::XModel > xModel( getModel() );
665 dispatchRequests(xModel,u".uno:SpellDialog"_ustr);
668 uno::Reference< excel::XRange >
669 ScVbaWorksheet::getSheetRange()
671 uno::Reference< table::XCellRange > xRange( getSheet(),uno::UNO_QUERY_THROW );
672 return uno::Reference< excel::XRange >( new ScVbaRange( this, mxContext, xRange ) );
675 // These are hacks - we prolly (somehow) need to inherit
676 // the vbarange functionality here ...
677 uno::Reference< excel::XRange >
678 ScVbaWorksheet::Cells( const ::uno::Any &nRow, const ::uno::Any &nCol )
680 // Performance optimization for often-called Cells method:
681 // Use a common helper method instead of creating a new ScVbaRange object
682 uno::Reference< table::XCellRange > xRange( getSheet(), uno::UNO_QUERY_THROW );
683 uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_SET_THROW );
684 if(ScDocShell* pShell = excel::getDocShell( xModel ))
685 return ScVbaRange::CellsHelper(pShell->GetDocument(), this, mxContext, xRange, nRow, nCol );
686 throw uno::RuntimeException();
689 uno::Reference< excel::XRange >
690 ScVbaWorksheet::Rows(const uno::Any& aIndex )
692 return getSheetRange()->Rows( aIndex );
695 uno::Reference< excel::XRange >
696 ScVbaWorksheet::Columns( const uno::Any& aIndex )
698 return getSheetRange()->Columns( aIndex );
701 uno::Any SAL_CALL
702 ScVbaWorksheet::ChartObjects( const uno::Any& Index )
704 if ( !mxCharts.is() )
706 uno::Reference< table::XTableChartsSupplier > xChartSupplier( getSheet(), uno::UNO_QUERY_THROW );
707 uno::Reference< table::XTableCharts > xTableCharts = xChartSupplier->getCharts();
709 uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( mxSheet, uno::UNO_QUERY_THROW );
710 mxCharts = new ScVbaChartObjects( this, mxContext, xTableCharts, xDrawPageSupplier );
712 if ( Index.hasValue() )
714 return mxCharts->Item( Index, uno::Any() );
716 else
717 return uno::Any( uno::Reference<ov::excel::XChartObjects>(mxCharts) );
721 uno::Any SAL_CALL
722 ScVbaWorksheet::PivotTables( const uno::Any& Index )
724 uno::Reference< css::sheet::XSpreadsheet > xSheet = getSheet();
725 uno::Reference< sheet::XDataPilotTablesSupplier > xTables(xSheet, uno::UNO_QUERY_THROW ) ;
726 uno::Reference< container::XIndexAccess > xIndexAccess( xTables->getDataPilotTables(), uno::UNO_QUERY_THROW );
728 uno::Reference< XCollection > xColl( new ScVbaPivotTables( this, mxContext, xIndexAccess ) );
729 if ( Index.hasValue() )
730 return xColl->Item( Index, uno::Any() );
731 return uno::Any( xColl );
734 uno::Any SAL_CALL
735 ScVbaWorksheet::Comments( const uno::Any& Index )
737 uno::Reference< css::sheet::XSpreadsheet > xSheet = getSheet();
738 uno::Reference< sheet::XSheetAnnotationsSupplier > xAnnosSupp( xSheet, uno::UNO_QUERY_THROW );
739 uno::Reference< sheet::XSheetAnnotations > xAnnos( xAnnosSupp->getAnnotations(), uno::UNO_SET_THROW );
740 uno::Reference< container::XIndexAccess > xIndexAccess( xAnnos, uno::UNO_QUERY_THROW );
741 uno::Reference< XCollection > xColl( new ScVbaComments( this, mxContext, mxModel, xIndexAccess ) );
742 if ( Index.hasValue() )
743 return xColl->Item( Index, uno::Any() );
744 return uno::Any( xColl );
747 uno::Any SAL_CALL
748 ScVbaWorksheet::Hyperlinks( const uno::Any& aIndex )
750 /* The worksheet always returns the same Hyperlinks object.
751 See vbahyperlinks.hxx for more details. */
752 if( !mxHlinks.is() )
753 mxHlinks.set( new ScVbaHyperlinks( this, mxContext ) );
754 if( aIndex.hasValue() )
755 return uno::Reference< XCollection >( mxHlinks, uno::UNO_QUERY_THROW )->Item( aIndex, uno::Any() );
756 return uno::Any( mxHlinks );
759 uno::Any SAL_CALL
760 ScVbaWorksheet::Names( const css::uno::Any& aIndex )
762 css::uno::Reference<css::beans::XPropertySet> xProps(getSheet(), css::uno::UNO_QUERY_THROW);
763 uno::Reference< sheet::XNamedRanges > xNamedRanges( xProps->getPropertyValue(u"NamedRanges"_ustr), uno::UNO_QUERY_THROW );
764 uno::Reference< XCollection > xNames( new ScVbaNames( this, mxContext, xNamedRanges, mxModel ) );
765 if ( aIndex.hasValue() )
766 return xNames->Item( aIndex, uno::Any() );
767 return uno::Any( xNames );
770 uno::Any SAL_CALL
771 ScVbaWorksheet::OLEObjects( const uno::Any& Index )
773 uno::Reference< sheet::XSpreadsheet > xSpreadsheet( getSheet(), uno::UNO_SET_THROW );
774 uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( xSpreadsheet, uno::UNO_QUERY_THROW );
775 uno::Reference< drawing::XDrawPage > xDrawPage( xDrawPageSupplier->getDrawPage(), uno::UNO_SET_THROW );
776 uno::Reference< container::XIndexAccess > xIndexAccess( xDrawPage, uno::UNO_QUERY_THROW );
778 uno::Reference< excel::XOLEObjects >xOleObjects( new ScVbaOLEObjects( this, mxContext, xIndexAccess ) );
779 if( Index.hasValue() )
780 return xOleObjects->Item( Index, uno::Any() );
781 return uno::Any( xOleObjects );
784 uno::Any SAL_CALL
785 ScVbaWorksheet::Shapes( const uno::Any& aIndex )
787 uno::Reference< sheet::XSpreadsheet > xSpreadsheet( getSheet(), uno::UNO_SET_THROW );
788 uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( xSpreadsheet, uno::UNO_QUERY_THROW );
789 uno::Reference< drawing::XShapes > xShapes( xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY_THROW );
790 uno::Reference< container::XIndexAccess > xIndexAccess( xShapes, uno::UNO_QUERY_THROW );
792 uno::Reference< msforms::XShapes> xVbaShapes( new ScVbaShapes( this, mxContext, xIndexAccess, getModel() ) );
793 if ( aIndex.hasValue() )
794 return xVbaShapes->Item( aIndex, uno::Any() );
795 return uno::Any( xVbaShapes );
798 uno::Any
799 ScVbaWorksheet::getButtons( const uno::Any &rIndex, bool bOptionButtons )
801 ::rtl::Reference< ScVbaSheetObjectsBase > &rxButtons = bOptionButtons ? mxButtons[0] : mxButtons[1];
803 if( !rxButtons.is() )
804 rxButtons.set( new ScVbaButtons( this, mxContext, mxModel, mxSheet, bOptionButtons ) );
805 else
806 rxButtons->collectShapes();
807 if( rIndex.hasValue() )
808 return rxButtons->Item( rIndex, uno::Any() );
809 return uno::Any( uno::Reference< XCollection >( rxButtons ) );
812 uno::Any SAL_CALL
813 ScVbaWorksheet::Buttons( const uno::Any& rIndex )
815 return getButtons( rIndex, false );
818 uno::Any SAL_CALL
819 ScVbaWorksheet::CheckBoxes( const uno::Any& /*rIndex*/ )
821 throw uno::RuntimeException();
824 uno::Any SAL_CALL
825 ScVbaWorksheet::DropDowns( const uno::Any& /*rIndex*/ )
827 throw uno::RuntimeException();
830 uno::Any SAL_CALL
831 ScVbaWorksheet::GroupBoxes( const uno::Any& /*rIndex*/ )
833 throw uno::RuntimeException();
836 uno::Any SAL_CALL
837 ScVbaWorksheet::Labels( const uno::Any& /*rIndex*/ )
839 throw uno::RuntimeException();
842 uno::Any SAL_CALL
843 ScVbaWorksheet::ListBoxes( const uno::Any& /*rIndex*/ )
845 throw uno::RuntimeException();
848 uno::Any SAL_CALL
849 ScVbaWorksheet::OptionButtons( const uno::Any& rIndex )
851 return getButtons( rIndex, true );
854 uno::Any SAL_CALL
855 ScVbaWorksheet::ScrollBars( const uno::Any& /*rIndex*/ )
857 throw uno::RuntimeException();
860 uno::Any SAL_CALL
861 ScVbaWorksheet::Spinners( const uno::Any& /*rIndex*/ )
863 throw uno::RuntimeException();
866 void SAL_CALL
867 ScVbaWorksheet::ShowDataForm( )
869 uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_SET_THROW );
870 if (ScTabViewShell* pTabViewShell = excel::getBestViewShell( xModel ))
872 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
873 ScopedVclPtr<AbstractScDataFormDlg> pDlg(pFact->CreateScDataFormDlg(pTabViewShell->GetFrameWeld(),
874 pTabViewShell));
875 pDlg->Execute();
879 uno::Any SAL_CALL
880 ScVbaWorksheet::Evaluate( const OUString& Name )
882 // #TODO Evaluate allows other things to be evaluated, e.g. functions
883 // I think ( like SIN(3) etc. ) need to investigate that
884 // named Ranges also? e.g. [MyRange] if so need a list of named ranges
885 uno::Any aVoid;
886 return uno::Any( Range( uno::Any( Name ), aVoid ) );
889 uno::Reference< beans::XIntrospectionAccess > SAL_CALL
890 ScVbaWorksheet::getIntrospection( )
892 return uno::Reference< beans::XIntrospectionAccess >();
895 uno::Any SAL_CALL
896 ScVbaWorksheet::invoke( const OUString& /*aFunctionName*/, const uno::Sequence< uno::Any >& /*aParams*/, uno::Sequence< ::sal_Int16 >& /*aOutParamIndex*/, uno::Sequence< uno::Any >& /*aOutParam*/ )
898 throw uno::RuntimeException(u"Unsupported"_ustr); // unsupported operation
901 void SAL_CALL
902 ScVbaWorksheet::setValue( const OUString& aPropertyName, const uno::Any& aValue )
904 setDefaultPropByIntrospection( getValue( aPropertyName ), aValue );
906 uno::Any SAL_CALL
907 ScVbaWorksheet::getValue( const OUString& aPropertyName )
909 uno::Reference< drawing::XControlShape > xControlShape( getControlShape( aPropertyName ), uno::UNO_QUERY_THROW );
911 uno::Reference<lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_SET_THROW );
912 uno::Reference< XControlProvider > xControlProvider( xServiceManager->createInstanceWithContext(u"ooo.vba.ControlProvider"_ustr, mxContext ), uno::UNO_QUERY_THROW );
913 uno::Reference< msforms::XControl > xControl( xControlProvider->createControl( xControlShape, getModel() ) );
914 return uno::Any( xControl );
917 sal_Bool SAL_CALL
918 ScVbaWorksheet::hasMethod( const OUString& /*aName*/ )
920 return false;
923 uno::Reference< container::XNameAccess >
924 ScVbaWorksheet::getFormControls() const
926 uno::Reference< container::XNameAccess > xFormControls;
929 uno::Reference< sheet::XSpreadsheet > xSpreadsheet( getSheet(), uno::UNO_SET_THROW );
930 uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( xSpreadsheet, uno::UNO_QUERY_THROW );
931 uno::Reference< form::XFormsSupplier > xFormSupplier( xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY_THROW );
932 uno::Reference< container::XIndexAccess > xIndexAccess( xFormSupplier->getForms(), uno::UNO_QUERY_THROW );
933 // get the www-standard container ( maybe we should access the
934 // 'www-standard' by name rather than index, this seems an
935 // implementation detail
936 if( xIndexAccess->hasElements() )
937 xFormControls.set( xIndexAccess->getByIndex(0), uno::UNO_QUERY );
940 catch( uno::Exception& )
943 return xFormControls;
946 sal_Bool SAL_CALL
947 ScVbaWorksheet::hasProperty( const OUString& aName )
949 uno::Reference< container::XNameAccess > xFormControls( getFormControls() );
950 if ( xFormControls.is() )
951 return xFormControls->hasByName( aName );
952 return false;
955 uno::Any
956 ScVbaWorksheet::getControlShape( std::u16string_view sName )
958 // ideally we would get an XControl object but it appears an XControl
959 // implementation only exists for a Control implementation obtained from the
960 // view ( e.g. in basic you would get this from
961 // thiscomponent.currentcontroller.getControl( controlModel ) )
962 // and the thing to realise is that it is only possible to get an XControl
963 // for a currently displayed control :-( often we would want to modify
964 // a control not on the active sheet. But... you can always access the
965 // XControlShape from the DrawPage whether that is the active drawpage or not
967 uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( getSheet(), uno::UNO_QUERY_THROW );
968 uno::Reference< container::XIndexAccess > xIndexAccess( xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY_THROW );
970 sal_Int32 nCount = xIndexAccess->getCount();
971 for( int index = 0; index < nCount; index++ )
973 uno::Any aUnoObj = xIndexAccess->getByIndex( index );
974 // It seems there are some drawing objects that can not query into Control shapes?
975 uno::Reference< drawing::XControlShape > xControlShape( aUnoObj, uno::UNO_QUERY );
976 if( xControlShape.is() )
978 uno::Reference< container::XNamed > xNamed( xControlShape->getControl(), uno::UNO_QUERY_THROW );
979 if( sName == xNamed->getName() )
981 return aUnoObj;
985 return uno::Any();
988 OUString
989 ScVbaWorksheet::getServiceImplName()
991 return u"ScVbaWorksheet"_ustr;
994 void SAL_CALL
995 ScVbaWorksheet::setEnableCalculation( sal_Bool bEnableCalculation )
997 uno::Reference <sheet::XCalculatable> xCalculatable(getModel(), uno::UNO_QUERY_THROW);
998 xCalculatable->enableAutomaticCalculation( bEnableCalculation);
1000 sal_Bool SAL_CALL
1001 ScVbaWorksheet::getEnableCalculation( )
1003 uno::Reference <sheet::XCalculatable> xCalculatable(getModel(), uno::UNO_QUERY_THROW);
1004 return xCalculatable->isAutomaticCalculationEnabled();
1007 uno::Sequence< OUString >
1008 ScVbaWorksheet::getServiceNames()
1010 static uno::Sequence< OUString > const aServiceNames
1012 u"ooo.vba.excel.Worksheet"_ustr
1014 return aServiceNames;
1017 OUString SAL_CALL
1018 ScVbaWorksheet::getCodeName()
1020 uno::Reference< beans::XPropertySet > xSheetProp( mxSheet, uno::UNO_QUERY_THROW );
1021 return xSheetProp->getPropertyValue(u"CodeName"_ustr).get< OUString >();
1024 sal_Int16
1025 ScVbaWorksheet::getSheetID() const
1027 uno::Reference< sheet::XCellRangeAddressable > xAddressable( mxSheet, uno::UNO_QUERY_THROW ); // if ActiveSheet, mxSheet is null.
1028 return xAddressable->getRangeAddress().Sheet;
1031 void SAL_CALL
1032 ScVbaWorksheet::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, const uno::Any& )
1034 sal_Int32 nTo = 0;
1035 sal_Int32 nFrom = 0;
1036 bool bSelection = false;
1037 From >>= nFrom;
1038 To >>= nTo;
1040 if ( !( nFrom || nTo ) )
1041 bSelection = true;
1043 uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_SET_THROW );
1044 PrintOutHelper( excel::getBestViewShell( xModel ), From, To, Copies, Preview, ActivePrinter, PrintToFile, Collate, PrToFileName, bSelection );
1047 void SAL_CALL
1048 ScVbaWorksheet::ExportAsFixedFormat(const css::uno::Any& Type, const css::uno::Any& FileName, const css::uno::Any& Quality,
1049 const css::uno::Any& IncludeDocProperties, const css::uno::Any& /*IgnorePrintAreas*/, const css::uno::Any& From,
1050 const css::uno::Any& To, const css::uno::Any& OpenAfterPublish, const css::uno::Any& /*FixedFormatExtClassPtr*/)
1052 uno::Reference< frame::XModel > xModel(getModel(), uno::UNO_SET_THROW);
1053 uno::Reference< excel::XApplication > xApplication(Application(), uno::UNO_QUERY_THROW);
1055 excel::ExportAsFixedFormatHelper(xModel, xApplication, Type, FileName, Quality,
1056 IncludeDocProperties, From, To, OpenAfterPublish);
1059 sal_Int64 SAL_CALL
1060 ScVbaWorksheet::getSomething(const uno::Sequence<sal_Int8 > & rId)
1062 return comphelper::getSomethingImpl(rId, this);
1065 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
1066 Calc_ScVbaWorksheet_get_implementation(
1067 css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& args)
1069 return cppu::acquire(new ScVbaWorksheet(args, context));
1072 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */