diff options
author | Daniel Rentz <dr@openoffice.org> | 2010-06-15 20:02:53 +0200 |
---|---|---|
committer | Daniel Rentz <dr@openoffice.org> | 2010-06-15 20:02:53 +0200 |
commit | 5624330c20ccbbcbbbc90631130e7d2f7a06d0bd (patch) | |
tree | 27308cb5a7f8c3eca0655d99c1fd654d8580de7a /sc | |
parent | fc1ac6254cde85bedfff1f8f78d678d4e10cc3dd (diff) |
mib16: contributed bugfixes and various new symbols in VBA compatibility implementation
Diffstat (limited to 'sc')
79 files changed, 2039 insertions, 711 deletions
diff --git a/sc/inc/cellsuno.hxx b/sc/inc/cellsuno.hxx index 13469b110455..a53f167b164a 100644 --- a/sc/inc/cellsuno.hxx +++ b/sc/inc/cellsuno.hxx @@ -90,6 +90,7 @@ #include <com/sun/star/document/XActionLockable.hpp> #include <com/sun/star/beans/XTolerantMultiPropertySet.hpp> #include <com/sun/star/sheet/XExternalSheetName.hpp> +#include <com/sun/star/document/XEventsSupplier.hpp> #include <cppuhelper/implbase2.hxx> #include <cppuhelper/implbase3.hxx> @@ -1002,7 +1003,8 @@ class ScTableSheetObj : public ScCellRangeObj, public com::sun::star::util::XProtectable, public com::sun::star::sheet::XScenario, public com::sun::star::sheet::XScenarioEnhanced, - public com::sun::star::sheet::XExternalSheetName + public com::sun::star::sheet::XExternalSheetName, + public com::sun::star::document::XEventsSupplier { friend class ScTableSheetsObj; // fuer insertByName() @@ -1207,6 +1209,10 @@ public: throw (::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException); + // XEventsSupplier + virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameReplace > SAL_CALL getEvents() + throw (::com::sun::star::uno::RuntimeException); + // XPropertySet ueberladen wegen Sheet-Properties virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() diff --git a/sc/inc/convuno.hxx b/sc/inc/convuno.hxx index 135ac055b2fe..0f93d6d6de0d 100644 --- a/sc/inc/convuno.hxx +++ b/sc/inc/convuno.hxx @@ -28,6 +28,7 @@ #ifndef SC_CONVUNO_HXX #define SC_CONVUNO_HXX +#include <algorithm> #include <i18npool/lang.h> #include <com/sun/star/table/CellAddress.hpp> #include <com/sun/star/table/CellRangeAddress.hpp> @@ -70,6 +71,19 @@ public: static inline void FillApiEndAddress( ::com::sun::star::table::CellAddress& rApiAddress, const ::com::sun::star::table::CellRangeAddress& rApiRange ); + + /** Returns true, if the passed ranges have at least one common cell. */ + static inline bool Intersects( + const ::com::sun::star::table::CellRangeAddress& rApiARange1, + const ::com::sun::star::table::CellRangeAddress& rApiARange2 ); + /** Returns true, if the passed address rApiInner is inside the passed range rApiOuter. */ + static inline bool Contains( + const ::com::sun::star::table::CellRangeAddress& rApiOuter, + const ::com::sun::star::table::CellAddress& rApiInner ); + /** Returns true, if the passed range rApiInner is completely inside the passed range rApiOuter. */ + static inline bool Contains( + const ::com::sun::star::table::CellRangeAddress& rApiOuter, + const ::com::sun::star::table::CellRangeAddress& rApiInner ); }; @@ -135,6 +149,33 @@ inline void ScUnoConversion::FillApiEndAddress( rApiAddress.Sheet = rApiRange.Sheet; } +inline bool ScUnoConversion::Intersects( + const ::com::sun::star::table::CellRangeAddress& rApiRange1, + const ::com::sun::star::table::CellRangeAddress& rApiRange2 ) +{ + return (rApiRange1.Sheet == rApiRange2.Sheet) && + (::std::max( rApiRange1.StartColumn, rApiRange2.StartColumn ) <= ::std::min( rApiRange1.EndColumn, rApiRange2.EndColumn )) && + (::std::max( rApiRange1.StartRow, rApiRange2.StartRow ) <= ::std::min( rApiRange1.EndRow, rApiRange2.EndRow )); +} + +inline bool ScUnoConversion::Contains( + const ::com::sun::star::table::CellRangeAddress& rApiOuter, + const ::com::sun::star::table::CellAddress& rApiInner ) +{ + return (rApiOuter.Sheet == rApiInner.Sheet) && + (rApiOuter.StartColumn <= rApiInner.Column) && (rApiInner.Column <= rApiOuter.EndColumn) && + (rApiOuter.StartRow <= rApiInner.Row) && (rApiInner.Row <= rApiOuter.EndRow); +} + +inline bool ScUnoConversion::Contains( + const ::com::sun::star::table::CellRangeAddress& rApiOuter, + const ::com::sun::star::table::CellRangeAddress& rApiInner ) +{ + return (rApiOuter.Sheet == rApiInner.Sheet) && + (rApiOuter.StartColumn <= rApiInner.StartColumn) && (rApiInner.EndColumn <= rApiOuter.EndColumn) && + (rApiOuter.StartRow <= rApiInner.StartRow) && (rApiInner.EndRow <= rApiOuter.EndRow); +} + //___________________________________________________________________ inline sal_Bool operator==( diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index ad8f56600531..e59b7fda095a 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -731,6 +731,14 @@ public: BOOL HasBackgroundDraw( SCTAB nTab, const Rectangle& rMMRect ); BOOL HasAnyDraw( SCTAB nTab, const Rectangle& rMMRect ); + const ScSheetEvents* GetSheetEvents( SCTAB nTab ) const; + void SetSheetEvents( SCTAB nTab, const ScSheetEvents* pNew ); + bool HasSheetEventScript( sal_Int32 nEvent ) const; // on any sheet + + BOOL HasCalcNotification( SCTAB nTab ) const; + void SetCalcNotification( SCTAB nTab ); + void ResetCalcNotifications(); + SC_DLLPUBLIC ScOutlineTable* GetOutlineTable( SCTAB nTab, BOOL bCreate = FALSE ); BOOL SetOutlineTable( SCTAB nTab, const ScOutlineTable* pNewOutline ); diff --git a/sc/inc/docuno.hxx b/sc/inc/docuno.hxx index 15a0c5e72359..2c3ecee39e32 100644 --- a/sc/inc/docuno.hxx +++ b/sc/inc/docuno.hxx @@ -112,6 +112,7 @@ private: const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& rOptions, ScMarkData& rMark, ScPrintSelectionStatus& rStatus, String& rPagesStr ) const; com::sun::star::uno::Reference<com::sun::star::uno::XAggregation> GetFormatter(); + void HandleCalculateEvents(); rtl::OUString maBuildId; sal_Int32 mnXlsWriteProtPass; diff --git a/sc/inc/funcuno.hxx b/sc/inc/funcuno.hxx index 3eef9082e26d..4413782a0e2f 100644 --- a/sc/inc/funcuno.hxx +++ b/sc/inc/funcuno.hxx @@ -72,7 +72,8 @@ private: ScTempDocCache aDocCache; ScDocOptions* pOptions; SfxItemPropertyMap aPropertyMap; - BOOL bInvalid; + bool mbArray; + bool mbValid; public: ScFunctionAccess(); diff --git a/sc/inc/sc.hrc b/sc/inc/sc.hrc index a7d05925957a..9a2401f21ce5 100644 --- a/sc/inc/sc.hrc +++ b/sc/inc/sc.hrc @@ -833,6 +833,7 @@ #define FID_TAB_INDEX (TAB_POPUP_START+6) #define FID_TAB_RTL (TAB_POPUP_START+7) #define FID_TAB_DESELECTALL (TAB_POPUP_START+8) +#define FID_TAB_EVENTS (TAB_POPUP_START+9) #define TAB_POPUP_END (DATA_MENU_END + 20) diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index 42fcbb063930..2d68d35545ea 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -63,6 +63,7 @@ class ScPrintSaverTab; class ScProgress; class ScProgress; class ScRangeList; +class ScSheetEvents; class ScSortInfoArray; class ScStyleSheet; class ScTableLink; @@ -118,6 +119,8 @@ private: ScOutlineTable* pOutlineTable; + ScSheetEvents* pSheetEvents; + SCCOL nTableAreaX; SCROW nTableAreaY; BOOL bTableAreaValid; @@ -126,6 +129,7 @@ private: BOOL bVisible; BOOL bStreamValid; BOOL bPendingRowHeights; + BOOL bCalcNotification; SCTAB nTab; USHORT nRecalcLvl; // Rekursionslevel Size-Recalc @@ -189,6 +193,9 @@ public: void RemoveSubTotals( ScSubTotalParam& rParam ); BOOL DoSubTotals( ScSubTotalParam& rParam ); + const ScSheetEvents* GetSheetEvents() const { return pSheetEvents; } + void SetSheetEvents( const ScSheetEvents* pNew ); + BOOL IsVisible() const { return bVisible; } void SetVisible( BOOL bVis ); @@ -198,6 +205,9 @@ public: BOOL IsPendingRowHeights() const { return bPendingRowHeights; } void SetPendingRowHeights( BOOL bSet ); + BOOL GetCalcNotification() const { return bCalcNotification; } + void SetCalcNotification( BOOL bSet ); + BOOL IsLayoutRTL() const { return bLayoutRTL; } BOOL IsLoadingRTL() const { return bLoadingRTL; } void SetLayoutRTL( BOOL bSet ); diff --git a/sc/inc/unonames.hxx b/sc/inc/unonames.hxx index 5bcc22ae72d3..83065891c6f0 100644 --- a/sc/inc/unonames.hxx +++ b/sc/inc/unonames.hxx @@ -631,5 +631,10 @@ #define SC_UNO_SHAREDOC "IsDocumentShared" +// EventDescriptor + +#define SC_UNO_EVENTTYPE "EventType" +#define SC_UNO_SCRIPT "Script" + #endif diff --git a/sc/inc/viewuno.hxx b/sc/inc/viewuno.hxx index 988602b2056f..19b5c60fd070 100644 --- a/sc/inc/viewuno.hxx +++ b/sc/inc/viewuno.hxx @@ -48,6 +48,8 @@ #include <com/sun/star/lang/XUnoTunnel.hpp> #include <com/sun/star/datatransfer/XTransferableSupplier.hpp> +#include "address.hxx" + class ScTabViewShell; #define SC_VIEWPANE_ACTIVE 0xFFFF @@ -195,6 +197,7 @@ private: XViewPropertyChangeListenerArr_Impl aPropertyChgListeners; XMouseClickHandlerArr_Impl aMouseClickHandlers; XActivationEventListenerArr_Impl aActivationListeners; + SCTAB nPreviousTab; sal_Bool bDrawSelModeSet; ScViewPaneObj* GetObjectByIndex_Impl(USHORT nIndex) const; @@ -223,7 +226,7 @@ public: void SelectionChanged(); void VisAreaChanged(); void SheetChanged(); - sal_Bool IsMouseListening() { return aMouseClickHandlers.Count() > 0; } + bool IsMouseListening() const; sal_Bool MousePressed( const ::com::sun::star::awt::MouseEvent& e ) throw (::com::sun::star::uno::RuntimeException); sal_Bool MouseReleased( const ::com::sun::star::awt::MouseEvent& e ) throw (::com::sun::star::uno::RuntimeException); diff --git a/sc/sdi/scalc.sdi b/sc/sdi/scalc.sdi index 904ee22d3d8c..c1866d022439 100644 --- a/sc/sdi/scalc.sdi +++ b/sc/sdi/scalc.sdi @@ -6819,6 +6819,31 @@ SfxVoidItem TableDeselectAll FID_TAB_DESELECTALL ] //-------------------------------------------------------------------------- +SfxVoidItem TableEvents FID_TAB_EVENTS +() +[ + /* flags: */ + AutoUpdate = FALSE, + Cachable = Cachable, + FastCall = FALSE, + HasCoreId = FALSE, + HasDialog = TRUE, + ReadOnlyDoc = TRUE, + Toggle = FALSE, + Container = FALSE, + RecordAbsolute = FALSE, + RecordPerSet; + Synchron; + + /* config: */ + AccelConfig = TRUE, + MenuConfig = TRUE, + StatusBarConfig = FALSE, + ToolBoxConfig = FALSE, + GroupId = GID_EDIT; +] + +//-------------------------------------------------------------------------- SfxVoidItem TextAttributes SID_DRAWTEXT_ATTR_DLG () [ diff --git a/sc/sdi/tabvwsh.sdi b/sc/sdi/tabvwsh.sdi index 4129aaef7d85..578687886287 100644 --- a/sc/sdi/tabvwsh.sdi +++ b/sc/sdi/tabvwsh.sdi @@ -58,6 +58,7 @@ interface Tables FID_TABLE_HIDE [ ExecMethod = ExecuteTable; StateMethod = GetStateTable; ] FID_TABLE_SHOW [ ExecMethod = ExecuteTable; StateMethod = GetStateTable; ] SID_SELECT_TABLES [ ExecMethod = Execute; StateMethod = GetState; ] + FID_TAB_EVENTS [ ExecMethod = ExecuteTable; StateMethod = GetStateTable; ] } // =========================================================================== diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx index 557f181c9d8f..3e4a66f3cbd4 100644 --- a/sc/source/core/data/documen3.cxx +++ b/sc/source/core/data/documen3.cxx @@ -83,6 +83,7 @@ #include "tabprotection.hxx" #include "formulaparserpool.hxx" #include "clipparam.hxx" +#include "sheetevents.hxx" #include <memory> @@ -481,6 +482,52 @@ ScFormulaParserPool& ScDocument::GetFormulaParserPool() const return *mxFormulaParserPool; } +const ScSheetEvents* ScDocument::GetSheetEvents( SCTAB nTab ) const +{ + if (VALIDTAB(nTab) && pTab[nTab]) + return pTab[nTab]->GetSheetEvents(); + return NULL; +} + +void ScDocument::SetSheetEvents( SCTAB nTab, const ScSheetEvents* pNew ) +{ + if (VALIDTAB(nTab) && pTab[nTab]) + pTab[nTab]->SetSheetEvents( pNew ); +} + +bool ScDocument::HasSheetEventScript( sal_Int32 nEvent ) const +{ + for (SCTAB nTab = 0; nTab <= MAXTAB; nTab++) + if (pTab[nTab]) + { + const ScSheetEvents* pEvents = pTab[nTab]->GetSheetEvents(); + if ( pEvents && pEvents->GetScript( nEvent ) ) + return true; + } + return false; +} + +BOOL ScDocument::HasCalcNotification( SCTAB nTab ) const +{ + if (VALIDTAB(nTab) && pTab[nTab]) + return pTab[nTab]->GetCalcNotification(); + return FALSE; +} + +void ScDocument::SetCalcNotification( SCTAB nTab ) +{ + // set only if not set before + if (VALIDTAB(nTab) && pTab[nTab] && !pTab[nTab]->GetCalcNotification()) + pTab[nTab]->SetCalcNotification(TRUE); +} + +void ScDocument::ResetCalcNotifications() +{ + for (SCTAB nTab = 0; nTab <= MAXTAB; nTab++) + if (pTab[nTab] && pTab[nTab]->GetCalcNotification()) + pTab[nTab]->SetCalcNotification(FALSE); +} + ScOutlineTable* ScDocument::GetOutlineTable( SCTAB nTab, BOOL bCreate ) { ScOutlineTable* pVal = NULL; diff --git a/sc/source/core/data/documen7.cxx b/sc/source/core/data/documen7.cxx index ad2ec90379df..97aae44f1a7b 100644 --- a/sc/source/core/data/documen7.cxx +++ b/sc/source/core/data/documen7.cxx @@ -52,6 +52,7 @@ #include "scmod.hxx" // SC_MOD #include "inputopt.hxx" // GetExpandRefs #include "conditio.hxx" +#include "sheetevents.hxx" #include <tools/shl.hxx> @@ -452,6 +453,8 @@ void ScDocument::TrackFormulas( ULONG nHintId ) if ( pFormulaTrack ) { erBEEPER(); + // outside the loop, check if any sheet has a "calculate" event script + bool bCalcEvent = HasSheetEventScript( SC_SHEETEVENT_CALCULATE ); SvtBroadcaster* pBC; ScFormulaCell* pTrack; ScFormulaCell* pNext; @@ -465,6 +468,9 @@ void ScDocument::TrackFormulas( ULONG nHintId ) // Repaint fuer bedingte Formate mit relativen Referenzen: if ( pCondFormList ) pCondFormList->SourceChanged( pTrack->aPos ); + // for "calculate" event, keep track of which sheets are affected by tracked formulas + if ( bCalcEvent ) + SetCalcNotification( pTrack->aPos.Tab() ); pTrack = pTrack->GetNextTrack(); } while ( pTrack ); pTrack = pFormulaTrack; diff --git a/sc/source/core/data/makefile.mk b/sc/source/core/data/makefile.mk index cf51e1e543a4..f299c09ea622 100755 --- a/sc/source/core/data/makefile.mk +++ b/sc/source/core/data/makefile.mk @@ -98,6 +98,7 @@ SLOFILES = \ $(SLO)$/patattr.obj \ $(SLO)$/pivot2.obj \ $(SLO)$/poolhelp.obj \ + $(SLO)$/sheetevents.obj \ $(SLO)$/sortparam.obj \ $(SLO)$/stlpool.obj \ $(SLO)$/stlsheet.obj \ diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx index f8cf1489f3aa..b5db5294edc3 100644 --- a/sc/source/core/data/table1.cxx +++ b/sc/source/core/data/table1.cxx @@ -112,6 +112,7 @@ #include "hints.hxx" // fuer Paint-Broadcast #include "prnsave.hxx" #include "tabprotection.hxx" +#include "sheetevents.hxx" // STATIC DATA ----------------------------------------------------------- @@ -137,10 +138,12 @@ ScTable::ScTable( ScDocument* pDoc, SCTAB nNewTab, const String& rNewName, pColFlags( NULL ), pRowFlags( NULL ), pOutlineTable( NULL ), + pSheetEvents( NULL ), bTableAreaValid( FALSE ), bVisible( TRUE ), bStreamValid( FALSE ), bPendingRowHeights( FALSE ), + bCalcNotification( FALSE ), nTab( nNewTab ), nRecalcLvl( 0 ), pDocument( pDoc ), @@ -215,6 +218,7 @@ ScTable::~ScTable() delete[] pColFlags; delete pRowHeight; delete pRowFlags; + delete pSheetEvents; delete pOutlineTable; delete pSearchParam; delete pSearchText; diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index 4dc7dddcaba1..d82f5d1789cb 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -56,6 +56,7 @@ #include "fillinfo.hxx" #include "bcaslot.hxx" #include "postit.hxx" +#include "sheetevents.hxx" #include "globstr.hrc" #include <math.h> @@ -97,6 +98,27 @@ void ScTable::StartOutlineTable() } +void ScTable::SetSheetEvents( const ScSheetEvents* pNew ) +{ + delete pSheetEvents; + if (pNew) + pSheetEvents = new ScSheetEvents(*pNew); + else + pSheetEvents = NULL; + + SetCalcNotification( FALSE ); // discard notifications before the events were set + + if (IsStreamValid()) + SetStreamValid(FALSE); +} + + +void ScTable::SetCalcNotification( BOOL bSet ) +{ + bCalcNotification = bSet; +} + + BOOL ScTable::TestInsertRow( SCCOL nStartCol, SCCOL nEndCol, SCSIZE nSize ) { BOOL bTest = TRUE; diff --git a/sc/source/filter/excel/excimp8.cxx b/sc/source/filter/excel/excimp8.cxx index a3ea403bf4c3..9608804da9f9 100644 --- a/sc/source/filter/excel/excimp8.cxx +++ b/sc/source/filter/excel/excimp8.cxx @@ -30,6 +30,7 @@ #include "excimp8.hxx" +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> #include <scitems.hxx> #include <comphelper/processfactory.hxx> @@ -54,6 +55,8 @@ #include <editeng/flditem.hxx> #include <svx/xflclit.hxx> #include <filter/msfilter/svxmsbas.hxx> +#include <basic/basmgr.hxx> +#include <oox/xls/excelvbaproject.hxx> #include <vcl/graph.hxx> #include <vcl/bmpacc.hxx> @@ -64,6 +67,7 @@ #include <tools/string.hxx> #include <tools/urlobj.hxx> #include <rtl/math.hxx> +#include <rtl/ustrbuf.hxx> #include <unotools/localedatawrapper.hxx> #include <unotools/charclass.hxx> #include <drwlayer.hxx> @@ -99,27 +103,19 @@ #include <com/sun/star/document/XDocumentProperties.hpp> #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> -#include <basic/basmgr.hxx> #include <cppuhelper/component_context.hxx> -#include <com/sun/star/container/XNameContainer.hpp> #include <sfx2/app.hxx> using namespace com::sun::star; - - -#define INVALID_POS 0xFFFFFFFF - - +using ::rtl::OUString; ImportExcel8::ImportExcel8( XclImpRootData& rImpData, SvStream& rStrm ) : - ImportExcel( rImpData, rStrm ), mnTab(0) + ImportExcel( rImpData, rStrm ) { + // replace BIFF2-BIFF5 formula importer with BIFF8 formula importer delete pFormConv; - pFormConv = pExcRoot->pFmlaConverter = new ExcelToSc8( GetRoot() ); - - bHasBasic = FALSE; } @@ -228,27 +224,6 @@ void ImportExcel8::Labelsst( void ) } -void ImportExcel8::Codename( BOOL bWorkbookGlobals ) -{ - if( bHasBasic ) - { - String aName( aIn.ReadUniString() ); - if( aName.Len() ) - { - if( bWorkbookGlobals ) - { - GetExtDocOptions().GetDocSettings().maGlobCodeName = aName; - GetDoc().SetCodeName( aName ); - } - else - { - GetExtDocOptions().AppendCodeName( aName ); - GetDoc().SetCodeName( mnTab++, aName ); - } - } - } -} - void ImportExcel8::SheetProtection( void ) { GetSheetProtectBuffer().ReadOptions( aIn, GetCurrScTab() ); @@ -294,9 +269,8 @@ void ImportExcel8::EndSheet( void ) void ImportExcel8::PostDocLoad( void ) { - // delay reading basic until sheet object ( codenames etc. ) are read - - if ( bHasBasic ) + // reading basic has been delayed until sheet objects (codenames etc.) are read + if( HasBasic() ) ReadBasic(); // #i11776# filtered ranges before outlines and hidden rows if( pExcRoot->pAutoFilterBuffer ) @@ -317,24 +291,47 @@ void ImportExcel8::PostDocLoad( void ) } // read doc info (no docshell while pasting from clipboard) + LoadDocumentProperties(); + // attach document events to VBA macros + AttachDocumentEvents(); + + // #i45843# Pivot tables are now handled outside of PostDocLoad, so they are available + // when formula cells are calculated, for the GETPIVOTDATA function. +} + +void ImportExcel8::LoadDocumentProperties() +{ + // no docshell while pasting from clipboard if( SfxObjectShell* pShell = GetDocShell() ) { // BIFF5+ without storage is possible SotStorageRef xRootStrg = GetRootStorage(); - if( xRootStrg.Is() ) + if( xRootStrg.Is() ) try + { + uno::Reference< document::XDocumentPropertiesSupplier > xDPS( pShell->GetModel(), uno::UNO_QUERY_THROW ); + uno::Reference< document::XDocumentProperties > xDocProps( xDPS->getDocumentProperties(), uno::UNO_SET_THROW ); + sfx2::LoadOlePropertySet( xDocProps, xRootStrg ); + } + catch( uno::Exception& ) { - uno::Reference<document::XDocumentPropertiesSupplier> xDPS( - pShell->GetModel(), uno::UNO_QUERY_THROW); - uno::Reference<document::XDocumentProperties> xDocProps - = xDPS->getDocumentProperties(); - sfx2::LoadOlePropertySet(xDocProps, GetRootStorage()); } } - - // #i45843# Pivot tables are now handled outside of PostDocLoad, so they are available - // when formula cells are calculated, for the GETPIVOTDATA function. } +void ImportExcel8::AttachDocumentEvents() +{ + SfxObjectShell* pShell = GetDocShell(); + if( HasBasic() && pShell ) + { + uno::Reference< lang::XMultiServiceFactory > xGlobalFactory = ::comphelper::getProcessServiceFactory(); + uno::Reference< sheet::XSpreadsheetDocument > xDocument( pShell->GetModel(), uno::UNO_QUERY ); + if( xGlobalFactory.is() && xDocument.is() ) + { + ::oox::xls::VbaProject aVbaProject( xGlobalFactory, xDocument ); + aVbaProject.attachToEvents(); + } + } +} //___________________________________________________________________ // autofilter diff --git a/sc/source/filter/excel/read.cxx b/sc/source/filter/excel/read.cxx index 5b9cc3180699..9b06d8713857 100644 --- a/sc/source/filter/excel/read.cxx +++ b/sc/source/filter/excel/read.cxx @@ -986,10 +986,10 @@ FltError ImportExcel8::Read( void ) case 0x22: Rec1904(); break; // 1904 [ 2345 ] case 0x56: Builtinfmtcnt(); break; // BUILTINFMTCNT[ 34 ] case 0x8D: Hideobj(); break; // HIDEOBJ [ 345 ] - case 0xD3: bHasBasic = true; break; + case 0xD3: SetHasBasic(); break; case 0xDE: Olesize(); break; - case 0x01BA: Codename( TRUE ); break; + case EXC_ID_CODENAME: ReadCodeName( aIn, true ); break; case EXC_ID_USESELFS: ReadUsesElfs(); break; case EXC_ID2_FONT: rFontBfr.ReadFont( maStrm ); break; @@ -1082,6 +1082,8 @@ FltError ImportExcel8::Read( void ) case EXC_ID2_DIMENSIONS: case EXC_ID3_DIMENSIONS: ReadDimensions(); break; + case EXC_ID_CODENAME: ReadCodeName( aIn, false ); break; + case 0x0A: // EOF [ 2345 ] eAkt = EXC_STATE_SHEET; aIn.SeekGlobalPosition(); // und zurueck an alte Position @@ -1097,7 +1099,6 @@ FltError ImportExcel8::Read( void ) case 0x9B: FilterMode(); break; // FILTERMODE case 0x9D: AutoFilterInfo(); break;// AUTOFILTERINFO case 0x9E: AutoFilter(); break; // AUTOFILTER - case 0x01BA: Codename( FALSE ); break; case 0x0208: Row34(); break; // ROW [ 34 ] case 0x0021: case 0x0221: Array34(); break; // ARRAY [ 34 ] diff --git a/sc/source/filter/excel/xichart.cxx b/sc/source/filter/excel/xichart.cxx index 6734f90948e4..e7669abce05d 100644 --- a/sc/source/filter/excel/xichart.cxx +++ b/sc/source/filter/excel/xichart.cxx @@ -3831,6 +3831,8 @@ void XclImpChart::ReadChartSubStream( XclImpStream& rStrm ) case EXC_ID_WINDOW2: rTabViewSett.ReadWindow2( rStrm, true );break; case EXC_ID_SCL: rTabViewSett.ReadScl( rStrm ); break; + + case EXC_ID_CODENAME: ReadCodeName( rStrm, false ); break; } // common records diff --git a/sc/source/filter/excel/xiescher.cxx b/sc/source/filter/excel/xiescher.cxx index 3d055d94a498..02c5203d356a 100644 --- a/sc/source/filter/excel/xiescher.cxx +++ b/sc/source/filter/excel/xiescher.cxx @@ -62,10 +62,6 @@ #include <basegfx/point/b2dpoint.hxx> #include <basegfx/polygon/b2dpolygon.hxx> -#include <basic/sbstar.hxx> -#include <basic/sbmod.hxx> -#include <basic/sbmeth.hxx> - #include <svx/svdopath.hxx> #include <svx/svdocirc.hxx> #include <svx/svdoedge.hxx> @@ -478,14 +474,14 @@ void XclImpDrawObjBase::PreProcessSdrObject( XclImpDffConverter& rDffConv, SdrOb { if( ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( &rSdrObj, TRUE ) ) { - pInfo->SetMacro( XclControlHelper::GetScMacroName( maMacroName, GetDocShell() ) ); + pInfo->SetMacro( XclTools::GetSbMacroUrl( maMacroName, GetDocShell() ) ); pInfo->SetHlink( maHyperlink ); } } #else if( mbSimpleMacro && (maMacroName.Len() > 0) ) if( ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( &rSdrObj, TRUE ) ) - pInfo->SetMacro( XclControlHelper::GetScMacroName( maMacroName, GetDocShell() ) ); + pInfo->SetMacro( XclTools::GetSbMacroUrl( maMacroName, GetDocShell() ) ); #endif // call virtual function for object type specific processing @@ -550,16 +546,7 @@ void XclImpDrawObjBase::ReadMacro8( XclImpStream& rStrm ) DBG_ASSERT( nTokenId == XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX, EXC_TOKCLASS_REF ), "XclImpDrawObjBase::ReadMacro - tNameXR token expected" ); if( nTokenId == XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX, EXC_TOKCLASS_REF ) ) - { maMacroName = GetLinkManager().GetMacroName( nExtSheet, nExtName ); - // #i38718# missing module name - try to find the macro in the imported modules - if( maMacroName.Len() && (maMacroName.Search( '.' ) == STRING_NOTFOUND) ) - if( SfxObjectShell* pDocShell = GetDocShell() ) - if( StarBASIC* pBasic = pDocShell->GetBasic() ) - if( SbMethod* pMethod = dynamic_cast< SbMethod* >( pBasic->Find( maMacroName, SbxCLASS_METHOD ) ) ) - if( SbModule* pModule = pMethod->GetModule() ) - maMacroName.Insert( '.', 0 ).Insert( pModule->GetName(), 0 ); - } } } } diff --git a/sc/source/filter/excel/xiroot.cxx b/sc/source/filter/excel/xiroot.cxx index 3384cf248c87..3fd2650cf2ff 100644 --- a/sc/source/filter/excel/xiroot.cxx +++ b/sc/source/filter/excel/xiroot.cxx @@ -29,6 +29,8 @@ #include "precompiled_sc.hxx" #include "xiroot.hxx" #include "addincol.hxx" +#include "document.hxx" +#include "scextopt.hxx" #include "xltracer.hxx" #include "xihelper.hxx" #include "xiformula.hxx" @@ -49,7 +51,8 @@ XclImpRootData::XclImpRootData( XclBiff eBiff, SfxMedium& rMedium, SotStorageRef xRootStrg, ScDocument& rDoc, rtl_TextEncoding eTextEnc ) : XclRootData( eBiff, rMedium, xRootStrg, rDoc, eTextEnc, false ), - mbHasCodePage( false ) + mbHasCodePage( false ), + mbHasBasic( false ) { } @@ -272,5 +275,25 @@ String XclImpRoot::GetScAddInName( const String& rXclName ) const return rXclName; } -// ============================================================================ +void XclImpRoot::ReadCodeName( XclImpStream& rStrm, bool bGlobals ) +{ + if( mrImpData.mbHasBasic && (GetBiff() == EXC_BIFF8) ) + { + String aName = rStrm.ReadUniString(); + if( aName.Len() > 0 ) + { + if( bGlobals ) + { + GetExtDocOptions().GetDocSettings().maGlobCodeName = aName; + GetDoc().SetCodeName( aName ); + } + else + { + GetExtDocOptions().AppendCodeName( aName ); + GetDoc().SetCodeName( GetCurrScTab(), aName ); + } + } + } +} +// ============================================================================ diff --git a/sc/source/filter/excel/xlescher.cxx b/sc/source/filter/excel/xlescher.cxx index e1132c1b5606..3b4b8e29ac0b 100644 --- a/sc/source/filter/excel/xlescher.cxx +++ b/sc/source/filter/excel/xlescher.cxx @@ -28,14 +28,15 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" +#include "xlescher.hxx" + #include <com/sun/star/drawing/XControlShape.hpp> #include <com/sun/star/script/ScriptEventDescriptor.hpp> #include <svx/unoapi.hxx> -#include "xestream.hxx" #include "document.hxx" +#include "xestream.hxx" #include "xistream.hxx" -#include "xlescher.hxx" -#include <filter/msfilter/msvbahelper.hxx> +#include "xltools.hxx" using ::rtl::OUString; using ::com::sun::star::uno::Reference; @@ -326,33 +327,7 @@ Reference< XControlModel > XclControlHelper::GetControlModel( Reference< XShape return xCtrlModel; } -#define EXC_MACRONAME_PRE "vnd.sun.star.script:Standard." -#define EXC_MACRONAME_SUF "?language=Basic&location=document" - -OUString XclControlHelper::GetScMacroName( const String& rXclMacroName, SfxObjectShell* pDocShell ) -{ - String sTmp( rXclMacroName ); - if( rXclMacroName.Len() > 0 ) - { - ooo::vba::VBAMacroResolvedInfo aMacro = ooo::vba::resolveVBAMacro( pDocShell, rXclMacroName, false ); - if ( aMacro.IsResolved() ) - return ooo::vba::makeMacroURL( aMacro.ResolvedMacro() ); - - } - return OUString(); -} - -String XclControlHelper::GetXclMacroName( const OUString& rScMacroName ) -{ - const OUString saMacroNamePre = CREATE_OUSTRING( EXC_MACRONAME_PRE ); - const OUString saMacroNameSuf = CREATE_OUSTRING( EXC_MACRONAME_SUF ); - sal_Int32 snScMacroNameLen = rScMacroName.getLength(); - sal_Int32 snXclMacroNameLen = snScMacroNameLen - saMacroNamePre.getLength() - saMacroNameSuf.getLength(); - if( (snXclMacroNameLen > 0) && rScMacroName.matchIgnoreAsciiCase( saMacroNamePre, 0 ) && - rScMacroName.matchIgnoreAsciiCase( saMacroNameSuf, snScMacroNameLen - saMacroNameSuf.getLength() ) ) - return rScMacroName.copy( saMacroNamePre.getLength(), snXclMacroNameLen ); - return String::EmptyString(); -} +namespace { static const struct { @@ -369,17 +344,17 @@ spTbxListenerData[] = /*EXC_TBX_EVENT_CHANGE*/ { "XChangeListener", "changed" } }; -#define EXC_MACROSCRIPT "Script" +} // namespace bool XclControlHelper::FillMacroDescriptor( ScriptEventDescriptor& rDescriptor, - XclTbxEventType eEventType, const String& rXclMacroName, SfxObjectShell* pShell ) + XclTbxEventType eEventType, const String& rXclMacroName, SfxObjectShell* pDocShell ) { if( rXclMacroName.Len() > 0 ) { rDescriptor.ListenerType = OUString::createFromAscii( spTbxListenerData[ eEventType ].mpcListenerType ); rDescriptor.EventMethod = OUString::createFromAscii( spTbxListenerData[ eEventType ].mpcEventMethod ); - rDescriptor.ScriptType = CREATE_OUSTRING( EXC_MACROSCRIPT ); - rDescriptor.ScriptCode = GetScMacroName( rXclMacroName, pShell ); + rDescriptor.ScriptType = CREATE_OUSTRING( "Script" ); + rDescriptor.ScriptCode = XclTools::GetSbMacroUrl( rXclMacroName, pDocShell ); return true; } return false; @@ -389,12 +364,11 @@ String XclControlHelper::ExtractFromMacroDescriptor( const ScriptEventDescriptor& rDescriptor, XclTbxEventType eEventType ) { if( (rDescriptor.ScriptCode.getLength() > 0) && - rDescriptor.ScriptType.equalsIgnoreAsciiCaseAscii( EXC_MACROSCRIPT ) && + rDescriptor.ScriptType.equalsIgnoreAsciiCaseAscii( "Script" ) && rDescriptor.ListenerType.equalsAscii( spTbxListenerData[ eEventType ].mpcListenerType ) && rDescriptor.EventMethod.equalsAscii( spTbxListenerData[ eEventType ].mpcEventMethod ) ) - return GetXclMacroName( rDescriptor.ScriptCode ); + return XclTools::GetXclMacroName( rDescriptor.ScriptCode ); return String::EmptyString(); } // ============================================================================ - diff --git a/sc/source/filter/excel/xltools.cxx b/sc/source/filter/excel/xltools.cxx index 90393ae6a787..0dd988d67586 100644 --- a/sc/source/filter/excel/xltools.cxx +++ b/sc/source/filter/excel/xltools.cxx @@ -34,6 +34,7 @@ #include <unotools/fontcvt.hxx> #include <sfx2/objsh.hxx> #include <editeng/editstat.hxx> +#include <filter/msfilter/msvbahelper.hxx> #include "xestream.hxx" #include "document.hxx" #include "docuno.hxx" @@ -46,6 +47,8 @@ #include "xiroot.hxx" #include "xltools.hxx" +using ::rtl::OUString; + // GUID import/export ========================================================= XclGuid::XclGuid() @@ -684,6 +687,37 @@ void XclTools::SkipSubStream( XclImpStream& rStrm ) } } +// Basic macro names ---------------------------------------------------------- + +const OUString XclTools::maSbMacroPrefix( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.script:Standard." ) ); +const OUString XclTools::maSbMacroSuffix( RTL_CONSTASCII_USTRINGPARAM( "?language=Basic&location=document" ) ); + +OUString XclTools::GetSbMacroUrl( const String& rMacroName, SfxObjectShell* pDocShell ) +{ + OSL_ENSURE( rMacroName.Len() > 0, "XclTools::GetSbMacroUrl - macro name is empty" ); + ::ooo::vba::VBAMacroResolvedInfo aMacroInfo = ::ooo::vba::resolveVBAMacro( pDocShell, rMacroName, false ); + if( aMacroInfo.IsResolved() ) + return ::ooo::vba::makeMacroURL( aMacroInfo.ResolvedMacro() ); + return OUString(); +} + +OUString XclTools::GetSbMacroUrl( const String& rModuleName, const String& rMacroName, SfxObjectShell* pDocShell ) +{ + OSL_ENSURE( rModuleName.Len() > 0, "XclTools::GetSbMacroUrl - module name is empty" ); + OSL_ENSURE( rMacroName.Len() > 0, "XclTools::GetSbMacroUrl - macro name is empty" ); + return GetSbMacroUrl( rModuleName + OUString( sal_Unicode( '.' ) ) + rMacroName, pDocShell ); +} + +String XclTools::GetXclMacroName( const OUString& rSbMacroUrl ) +{ + sal_Int32 nSbMacroUrlLen = rSbMacroUrl.getLength(); + sal_Int32 nMacroNameLen = nSbMacroUrlLen - maSbMacroPrefix.getLength() - maSbMacroSuffix.getLength(); + if( (nMacroNameLen > 0) && rSbMacroUrl.matchIgnoreAsciiCase( maSbMacroPrefix, 0 ) && + rSbMacroUrl.matchIgnoreAsciiCase( maSbMacroSuffix, nSbMacroUrlLen - maSbMacroSuffix.getLength() ) ) + return rSbMacroUrl.copy( maSbMacroPrefix.getLength(), nMacroNameLen ); + return String::EmptyString(); +} + // read/write colors ---------------------------------------------------------- XclImpStream& operator>>( XclImpStream& rStrm, Color& rColor ) @@ -700,4 +734,3 @@ XclExpStream& operator<<( XclExpStream& rStrm, const Color& rColor ) } // ============================================================================ - diff --git a/sc/source/filter/inc/excimp8.hxx b/sc/source/filter/inc/excimp8.hxx index 1340f7c6f8be..5b2bbe2e7b5d 100644 --- a/sc/source/filter/inc/excimp8.hxx +++ b/sc/source/filter/inc/excimp8.hxx @@ -50,37 +50,38 @@ class XclImpStream; class ImportExcel8 : public ImportExcel { - SCTAB mnTab; - protected: - ExcScenarioList aScenList; - - BOOL bHasBasic; - - void Calccount( void ); // 0x0C - void Precision( void ); // 0x0E - void Delta( void ); // 0x10 - void Iteration( void ); // 0x11 - void Boundsheet( void ); // 0x85 - void FilterMode( void ); // 0x9B - void AutoFilterInfo( void ); // 0x9D - void AutoFilter( void ); // 0x9E - void Scenman( void ); // 0xAE - void Scenario( void ); // 0xAF - void ReadBasic( void ); // 0xD3 - void Labelsst( void ); // 0xFD - - void Hlink( void ); // 0x01B8 - void Codename( BOOL bWBGlobals ); // 0x01BA - void SheetProtection( void ); // 0x0867 - - virtual void EndSheet( void ); - virtual void PostDocLoad( void ); - - public: - ImportExcel8( XclImpRootData& rImpData, SvStream& rStrm ); - virtual ~ImportExcel8( void ); - - virtual FltError Read( void ); +public: + ImportExcel8( XclImpRootData& rImpData, SvStream& rStrm ); + virtual ~ImportExcel8( void ); + + virtual FltError Read( void ); + +protected: + ExcScenarioList aScenList; + + void Calccount( void ); // 0x0C + void Precision( void ); // 0x0E + void Delta( void ); // 0x10 + void Iteration( void ); // 0x11 + void Boundsheet( void ); // 0x85 + void FilterMode( void ); // 0x9B + void AutoFilterInfo( void ); // 0x9D + void AutoFilter( void ); // 0x9E + void Scenman( void ); // 0xAE + void Scenario( void ); // 0xAF + void ReadBasic( void ); // 0xD3 + void Labelsst( void ); // 0xFD + + void Hlink( void ); // 0x01B8 + void Codename( BOOL bWBGlobals ); // 0x01BA + void SheetProtection( void ); // 0x0867 + + virtual void EndSheet( void ); + virtual void PostDocLoad( void ); + +private: + void LoadDocumentProperties(); + void AttachDocumentEvents(); }; diff --git a/sc/source/filter/inc/xiroot.hxx b/sc/source/filter/inc/xiroot.hxx index 0e06b31b650d..c5cf284d2d2e 100644 --- a/sc/source/filter/inc/xiroot.hxx +++ b/sc/source/filter/inc/xiroot.hxx @@ -116,6 +116,7 @@ struct XclImpRootData : public XclRootData XclImpDocProtectRef mxDocProtect; /// Document protection options. bool mbHasCodePage; /// true = CODEPAGE record exists. + bool mbHasBasic; /// true = document contains VB project. explicit XclImpRootData( XclBiff eBiff, SfxMedium& rMedium, SotStorageRef xRootStrg, ScDocument& rDoc, rtl_TextEncoding eTextEnc ); @@ -202,6 +203,13 @@ public: /** Returns the Calc add-in function name for an Excel function name. */ String GetScAddInName( const String& rXclName ) const; + /** Returns true, if the document contains a VB project. */ + inline bool HasBasic() const { return mrImpData.mbHasBasic; } + /** Called to indicate that the document contains a VB project. */ + inline void SetHasBasic() { mrImpData.mbHasBasic = true; } + /** Reads the CODENAME record and inserts the codename into the document. */ + void ReadCodeName( XclImpStream& rStrm, bool bGlobals ); + private: mutable XclImpRootData& mrImpData; /// Reference to the global import data struct. }; @@ -209,4 +217,3 @@ private: // ============================================================================ #endif - diff --git a/sc/source/filter/inc/xlconst.hxx b/sc/source/filter/inc/xlconst.hxx index 0ffdcc3f1a6d..42160aae7529 100644 --- a/sc/source/filter/inc/xlconst.hxx +++ b/sc/source/filter/inc/xlconst.hxx @@ -250,7 +250,11 @@ const sal_uInt16 EXC_ID_DSF = 0x0161; const sal_uInt16 EXC_ID_USERSVIEWBEGIN = 0x01AA; const sal_uInt16 EXC_ID_USERSVIEWEND = 0x01AB; -// (0x01C0) XL9FILE -------------------------------------------------------- +// (0x01BA) CODENAME ---------------------------------------------------------- + +const sal_uInt16 EXC_ID_CODENAME = 0x01BA; + +// (0x01C0) XL9FILE ----------------------------------------------------------- const sal_uInt16 EXC_ID_XL9FILE = 0x01C0; diff --git a/sc/source/filter/inc/xlescher.hxx b/sc/source/filter/inc/xlescher.hxx index 95a87b51de12..10194ab41bc0 100644 --- a/sc/source/filter/inc/xlescher.hxx +++ b/sc/source/filter/inc/xlescher.hxx @@ -28,6 +28,7 @@ #ifndef SC_XLESCHER_HXX #define SC_XLESCHER_HXX +#include <tools/gen.hxx> #include <vcl/mapunit.hxx> #include "fapihelper.hxx" #include "xladdress.hxx" @@ -431,16 +432,12 @@ public: static ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > GetControlModel( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape ); - /** Returns the Calc macro name from an Excel macro name. */ - static ::rtl::OUString GetScMacroName( const String& rXclMacroName, SfxObjectShell* pShell = NULL ); - /** Returns the Excel macro name from a Calc macro name. */ - static String GetXclMacroName( const ::rtl::OUString& rScMacroName ); - /** Fills the macro descriptor according to the passed macro name. */ static bool FillMacroDescriptor( ::com::sun::star::script::ScriptEventDescriptor& rDescriptor, XclTbxEventType eEventType, - const String& rXclMacroName, SfxObjectShell* pShell = NULL ); + const String& rXclMacroName, + SfxObjectShell* pDocShell = 0 ); /** Tries to extract an Excel macro name from the passed macro descriptor. */ static String ExtractFromMacroDescriptor( const ::com::sun::star::script::ScriptEventDescriptor& rDescriptor, diff --git a/sc/source/filter/inc/xltools.hxx b/sc/source/filter/inc/xltools.hxx index e8ceed8248d6..efe20a583104 100644 --- a/sc/source/filter/inc/xltools.hxx +++ b/sc/source/filter/inc/xltools.hxx @@ -31,6 +31,8 @@ #include "address.hxx" #include "ftools.hxx" +class SfxObjectShell; + // BIFF versions ============================================================== #define DBG_ERROR_BIFF() DBG_ERRORFILE( "Unknown BIFF type!" ) @@ -229,13 +231,24 @@ public: /** Skips a substream (BOF/EOF record block). Includes all embedded substreams. */ static void SkipSubStream( XclImpStream& rStrm ); - // ------------------------------------------------------------------------ + // Basic macro names ------------------------------------------------------ + + /** Returns the full StarBasic macro URL from an Excel macro name. */ + static ::rtl::OUString GetSbMacroUrl( const String& rMacroName, SfxObjectShell* pDocShell = 0 ); + /** Returns the full StarBasic macro URL from an Excel module and macro name. */ + static ::rtl::OUString GetSbMacroUrl( const String& rModuleName, const String& rMacroName, SfxObjectShell* pDocShell = 0 ); + /** Returns the Excel macro name from a full StarBasic macro URL. */ + static String GetXclMacroName( const ::rtl::OUString& rSbMacroUrl ); + +// ------------------------------------------------------------------------ private: - static const String maDefNamePrefix; /// Prefix for built-in defined names. - static const String maStyleNamePrefix1; /// Prefix for built-in cell style names. - static const String maStyleNamePrefix2; /// Prefix for built-in cell style names from OOX filter. - static const String maCFStyleNamePrefix1; /// Prefix for cond. formatting style names. - static const String maCFStyleNamePrefix2; /// Prefix for cond. formatting style names from OOX filter. + static const String maDefNamePrefix; /// Prefix for built-in defined names. + static const String maStyleNamePrefix1; /// Prefix for built-in cell style names. + static const String maStyleNamePrefix2; /// Prefix for built-in cell style names from OOX filter. + static const String maCFStyleNamePrefix1; /// Prefix for cond. formatting style names. + static const String maCFStyleNamePrefix2; /// Prefix for cond. formatting style names from OOX filter. + static const ::rtl::OUString maSbMacroPrefix; /// Prefix for StarBasic macros. + static const ::rtl::OUString maSbMacroSuffix; /// Suffix for StarBasic macros. }; // read/write colors ---------------------------------------------------------- diff --git a/sc/source/filter/xml/makefile.mk b/sc/source/filter/xml/makefile.mk index 360148d38244..7f9f2d529a90 100644 --- a/sc/source/filter/xml/makefile.mk +++ b/sc/source/filter/xml/makefile.mk @@ -96,7 +96,8 @@ SLOFILES = \ $(SLO)$/XMLChangeTrackingImportHelper.obj \ $(SLO)$/XMLTrackedChangesContext.obj \ $(SLO)$/XMLExportSharedData.obj \ - $(SLO)$/XMLEmptyContext.obj + $(SLO)$/XMLEmptyContext.obj \ + $(SLO)$/XMLCodeNameProvider.obj NOOPTFILES= \ diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx index d53f26a5e887..52c22c3feb15 100644 --- a/sc/source/filter/xml/xmlexprt.cxx +++ b/sc/source/filter/xml/xmlexprt.cxx @@ -80,6 +80,7 @@ #include <xmloff/txtparae.hxx> #include <xmloff/xmlcnitm.hxx> #include <xmloff/xmlerror.hxx> +#include <xmloff/XMLEventExport.hxx> #include <rtl/ustring.hxx> @@ -132,6 +133,8 @@ #include <com/sun/star/document/XDocumentProperties.hpp> #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> +#include "XMLCodeNameProvider.hxx" + #include <sfx2/objsh.hxx> #include <vector> @@ -1743,6 +1746,16 @@ void ScXMLExport::_ExportContent() AddAttribute( XML_NAMESPACE_TABLE, XML_PRINT, XML_FALSE); SvXMLElementExport aElemT(*this, sElemTab, sal_True, sal_True); CheckAttrList(); + + if ( pDoc && pDoc->GetSheetEvents( static_cast<SCTAB>(nTable) ) && + getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST ) + { + // store sheet events + uno::Reference<document::XEventsSupplier> xSupplier(xTable, uno::UNO_QUERY); + uno::Reference<container::XNameAccess> xEvents(xSupplier->getEvents(), uno::UNO_QUERY); + GetEventExport().ExportExt( xEvents ); + } + WriteTableSource(); WriteScenario(); uno::Reference<drawing::XDrawPage> xDrawPage; @@ -4245,6 +4258,9 @@ void ScXMLExport::GetViewSettings(uno::Sequence<beans::PropertyValue>& rProps) GetChangeTrackViewSettings(rProps); } + + + void ScXMLExport::GetConfigurationSettings(uno::Sequence<beans::PropertyValue>& rProps) { if (GetModel().is()) @@ -4255,16 +4271,41 @@ void ScXMLExport::GetConfigurationSettings(uno::Sequence<beans::PropertyValue>& uno::Reference <beans::XPropertySet> xProperties(xMultiServiceFactory->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.SpreadsheetSettings"))), uno::UNO_QUERY); if (xProperties.is()) SvXMLUnitConverter::convertPropertySet(rProps, xProperties); + + sal_Int32 nPropsToAdd = 0; + rtl::OUStringBuffer aTrackedChangesKey; if (GetDocument() && GetDocument()->GetChangeTrack() && GetDocument()->GetChangeTrack()->IsProtected()) { - rtl::OUStringBuffer aBuffer; - SvXMLUnitConverter::encodeBase64(aBuffer, GetDocument()->GetChangeTrack()->GetProtection()); - if (aBuffer.getLength()) + SvXMLUnitConverter::encodeBase64(aTrackedChangesKey, GetDocument()->GetChangeTrack()->GetProtection()); + if (aTrackedChangesKey.getLength()) + ++nPropsToAdd; + } + + uno::Reference <container::XNameAccess> xCodeNameAccess; + DBG_ASSERT( pDoc, "ScXMLExport::GetConfigurationSettings - no ScDocument!" ); + if( pDoc ) + { + xCodeNameAccess = new XMLCodeNameProvider( pDoc ); + if( xCodeNameAccess.is() && xCodeNameAccess->hasElements() ) + ++nPropsToAdd; + else + xCodeNameAccess = 0; + } + + if( nPropsToAdd > 0 ) + { + sal_Int32 nCount(rProps.getLength()); + rProps.realloc(nCount + nPropsToAdd); + if (aTrackedChangesKey.getLength()) { - sal_Int32 nCount(rProps.getLength()); - rProps.realloc(nCount + 1); rProps[nCount].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TrackedChangesProtectionKey")); - rProps[nCount].Value <<= aBuffer.makeStringAndClear(); + rProps[nCount].Value <<= aTrackedChangesKey.makeStringAndClear(); + ++nCount; + } + if( xCodeNameAccess.is() ) + { + rProps[nCount].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ScriptConfiguration")); + rProps[nCount].Value <<= xCodeNameAccess; } } } @@ -4352,6 +4393,22 @@ sal_uInt32 ScXMLExport::exportDoc( enum XMLTokenEnum eClass ) CollectUserDefinedNamespaces(&pDrawLayer->GetItemPool(), EE_CHAR_XMLATTRIBS); CollectUserDefinedNamespaces(&pDrawLayer->GetItemPool(), SDRATTR_XMLATTRIBUTES); } + + // sheet events use officeooo namespace + if( (getExportFlags() & EXPORT_CONTENT) != 0 && + getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST ) + { + bool bAnySheetEvents = false; + SCTAB nTabCount = pDoc->GetTableCount(); + for (SCTAB nTab=0; nTab<nTabCount; ++nTab) + if (pDoc->GetSheetEvents(nTab)) + bAnySheetEvents = true; + if (bAnySheetEvents) + _GetNamespaceMap().Add( + GetXMLToken( XML_NP_OFFICE_EXT ), + GetXMLToken( XML_N_OFFICE_EXT ), + XML_NAMESPACE_OFFICE_EXT ); + } } } return SvXMLExport::exportDoc( eClass ); diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx index d1ef48bfa9ed..533d9417414f 100644 --- a/sc/source/filter/xml/xmlimprt.cxx +++ b/sc/source/filter/xml/xmlimprt.cxx @@ -645,6 +645,8 @@ const SvXMLTokenMap& ScXMLImport::GetTableElemTokenMap() { XML_NAMESPACE_TABLE, XML_SCENARIO, XML_TOK_TABLE_SCENARIO }, { XML_NAMESPACE_TABLE, XML_SHAPES, XML_TOK_TABLE_SHAPES }, { XML_NAMESPACE_OFFICE, XML_FORMS, XML_TOK_TABLE_FORMS }, + { XML_NAMESPACE_OFFICE, XML_EVENT_LISTENERS, XML_TOK_TABLE_EVENT_LISTENERS }, + { XML_NAMESPACE_OFFICE_EXT, XML_EVENT_LISTENERS, XML_TOK_TABLE_EVENT_LISTENERS_EXT }, XML_TOKEN_MAP_END }; @@ -2216,10 +2218,11 @@ void ScXMLImport::SetConfigurationSettings(const uno::Sequence<beans::PropertyVa if (xMultiServiceFactory.is()) { sal_Int32 nCount(aConfigProps.getLength()); - rtl::OUString sName(RTL_CONSTASCII_USTRINGPARAM("TrackedChangesProtectionKey")); + rtl::OUString sCTName(RTL_CONSTASCII_USTRINGPARAM("TrackedChangesProtectionKey")); + rtl::OUString sSCName(RTL_CONSTASCII_USTRINGPARAM("ScriptConfiguration")); for (sal_Int32 i = nCount - 1; i >= 0; --i) { - if (aConfigProps[i].Name == sName) + if (aConfigProps[i].Name == sCTName) { rtl::OUString sKey; if (aConfigProps[i].Value >>= sKey) @@ -2240,6 +2243,28 @@ void ScXMLImport::SetConfigurationSettings(const uno::Sequence<beans::PropertyVa } } } + else if (aConfigProps[i].Name == sSCName) + { + uno::Type aType = aConfigProps[i].Value.getValueType(); + uno::Reference<beans::XPropertySet> xImportInfo = + getImportInfo(); + + if (xImportInfo.is() && + (aType.equals(getCppuType( + (uno::Reference<container::XNameContainer> *)0 ) ) || + aType.equals(getCppuType( + (uno::Reference<container::XNameAccess> *)0 ) ) ) ) + { + uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = + xImportInfo->getPropertySetInfo(); + if (xPropertySetInfo.is() && + xPropertySetInfo->hasPropertyByName(sSCName) ) + { + xImportInfo->setPropertyValue(sSCName, + aConfigProps[i].Value ); + } + } + } } uno::Reference <uno::XInterface> xInterface = xMultiServiceFactory->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.SpreadsheetSettings"))); uno::Reference <beans::XPropertySet> xProperties(xInterface, uno::UNO_QUERY); diff --git a/sc/source/filter/xml/xmlimprt.hxx b/sc/source/filter/xml/xmlimprt.hxx index e2cea5ae9609..9771655ebd4b 100644 --- a/sc/source/filter/xml/xmlimprt.hxx +++ b/sc/source/filter/xml/xmlimprt.hxx @@ -174,7 +174,9 @@ enum ScXMLTableTokens XML_TOK_TABLE_SOURCE, XML_TOK_TABLE_SCENARIO, XML_TOK_TABLE_SHAPES, - XML_TOK_TABLE_FORMS + XML_TOK_TABLE_FORMS, + XML_TOK_TABLE_EVENT_LISTENERS, + XML_TOK_TABLE_EVENT_LISTENERS_EXT }; enum ScXMLTableRowsTokens diff --git a/sc/source/filter/xml/xmltabi.cxx b/sc/source/filter/xml/xmltabi.cxx index 9afc08308feb..378fbcc6718a 100644 --- a/sc/source/filter/xml/xmltabi.cxx +++ b/sc/source/filter/xml/xmltabi.cxx @@ -53,6 +53,7 @@ #include <xmloff/nmspmap.hxx> #include <xmloff/formsimp.hxx> #include <xmloff/xmltoken.hxx> +#include <xmloff/XMLEventsImportContext.hxx> #include <com/sun/star/sheet/XSpreadsheetDocument.hpp> #include <com/sun/star/sheet/XSpreadsheets.hpp> @@ -316,6 +317,14 @@ SvXMLImportContext *ScXMLTableContext::CreateChildContext( USHORT nPrefix, pContext = GetScImport().GetFormImport()->createOfficeFormsContext( GetScImport(), nPrefix, rLName ); } break; + case XML_TOK_TABLE_EVENT_LISTENERS: + case XML_TOK_TABLE_EVENT_LISTENERS_EXT: + { + // use XEventsSupplier interface of the sheet + uno::Reference<document::XEventsSupplier> xSupplier( GetScImport().GetTables().GetCurrentXSheet(), uno::UNO_QUERY ); + pContext = new XMLEventsImportContext( GetImport(), nPrefix, rLName, xSupplier ); + } + break; default: ; } diff --git a/sc/source/filter/xml/xmlwrap.cxx b/sc/source/filter/xml/xmlwrap.cxx index f21ed7d55ac2..dbe647bc433f 100644 --- a/sc/source/filter/xml/xmlwrap.cxx +++ b/sc/source/filter/xml/xmlwrap.cxx @@ -80,6 +80,7 @@ #include "XMLExportSharedData.hxx" #include "docuno.hxx" #include "sheetdata.hxx" +#include "XMLCodeNameProvider.hxx" #define MAP_LEN(x) x, sizeof(x) - 1 @@ -425,6 +426,7 @@ sal_Bool ScXMLImportWrapper::Import(sal_Bool bStylesOnly, ErrCode& nError) { MAP_LEN( "StreamRelPath" ), 0, &::getCppuType( (rtl::OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, { MAP_LEN( "StreamName" ), 0, &::getCppuType( (rtl::OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, { MAP_LEN( "BuildId" ), 0, &::getCppuType( (OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, + { MAP_LEN( "ScriptConfiguration" ), 0, &::getCppuType((uno::Reference<container::XNameAccess> *)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, { NULL, 0, 0, NULL, 0, 0 } }; @@ -635,6 +637,12 @@ sal_Bool ScXMLImportWrapper::Import(sal_Bool bStylesOnly, ErrCode& nError) xModelSet->setPropertyValue( sBuildPropName, xInfoSet->getPropertyValue(sBuildPropName) ); } } + + // Set Code Names + uno::Any aAny = xInfoSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("ScriptConfiguration") )); + uno::Reference <container::XNameAccess> xCodeNameAccess; + if( aAny >>= xCodeNameAccess ) + XMLCodeNameProvider::set( xCodeNameAccess, &rDoc ); } // Don't test bStylesRetval and bMetaRetval, because it could be an older file which not contain such streams diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx index 01d03d49b50a..662aee58b19b 100644 --- a/sc/source/ui/docshell/docfunc.cxx +++ b/sc/source/ui/docshell/docfunc.cxx @@ -2785,6 +2785,7 @@ BOOL ScDocFunc::DeleteTable( SCTAB nTab, BOOL bRecord, BOOL /* bApi */ ) pUndoDoc->SetActiveScenario( nTab, bActive ); } pUndoDoc->SetVisible( nTab, pDoc->IsVisible( nTab ) ); + pUndoDoc->SetSheetEvents( nTab, pDoc->GetSheetEvents( nTab ) ); // Drawing-Layer muss sein Undo selbst in der Hand behalten !!! pDoc->BeginDrawUndo(); // DeleteTab erzeugt ein SdrUndoDelPage diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx index 157b98497e83..f7bcb3ea9f44 100644 --- a/sc/source/ui/docshell/docsh4.cxx +++ b/sc/source/ui/docshell/docsh4.cxx @@ -120,9 +120,9 @@ using namespace ::com::sun::star; #include "scresid.hxx" //add by CHINA001 #include "scabstdlg.hxx" //CHINA001 #include "externalrefmgr.hxx" - #include "sharedocdlg.hxx" #include "conditio.hxx" +#include "sheetevents.hxx" //------------------------------------------------------------------ @@ -1291,6 +1291,14 @@ void ScDocShell::DoHardRecalc( BOOL /* bApi */ ) if ( pSh ) pSh->UpdateCharts(TRUE); + // set notification flags for "calculate" event (used in SFX_HINT_DATACHANGED broadcast) + // (might check for the presence of any formulas on each sheet) + SCTAB nTabCount = aDocument.GetTableCount(); + SCTAB nTab; + if (aDocument.HasSheetEventScript( SC_SHEETEVENT_CALCULATE )) + for (nTab=0; nTab<nTabCount; nTab++) + aDocument.SetCalcNotification(nTab); + // CalcAll doesn't broadcast value changes, so SC_HINT_CALCALL is broadcasted globally // in addition to SFX_HINT_DATACHANGED. aDocument.BroadcastUno( SfxSimpleHint( SC_HINT_CALCALL ) ); @@ -1298,8 +1306,7 @@ void ScDocShell::DoHardRecalc( BOOL /* bApi */ ) // use hard recalc also to disable stream-copying of all sheets // (somewhat consistent with charts) - SCTAB nTabCount = aDocument.GetTableCount(); - for (SCTAB nTab=0; nTab<nTabCount; nTab++) + for (nTab=0; nTab<nTabCount; nTab++) if (aDocument.IsStreamValid(nTab)) aDocument.SetStreamValid(nTab, FALSE); diff --git a/sc/source/ui/src/popup.src b/sc/source/ui/src/popup.src index abda5c9a0994..e3f721adaa1a 100644 --- a/sc/source/ui/src/popup.src +++ b/sc/source/ui/src/popup.src @@ -190,6 +190,12 @@ Menu RID_POPUP_TAB HelpId = FID_TAB_RTL ; Text [ en-US ] = "S~heet Right-To-Left" ; }; + MenuItem + { + Identifier = FID_TAB_EVENTS ; + HelpId = FID_TAB_EVENTS ; + Text [ en-US ] = "Sheet E~vents..." ; + }; }; }; diff --git a/sc/source/ui/undo/undotab.cxx b/sc/source/ui/undo/undotab.cxx index 17f15af54701..dc299dae8921 100644 --- a/sc/source/ui/undo/undotab.cxx +++ b/sc/source/ui/undo/undotab.cxx @@ -411,6 +411,7 @@ void ScUndoDeleteTab::Undo() pDoc->SetActiveScenario( nTab, bActive ); } pDoc->SetVisible( nTab, pRefUndoDoc->IsVisible( nTab ) ); + pDoc->SetSheetEvents( nTab, pRefUndoDoc->GetSheetEvents( nTab ) ); if ( pRefUndoDoc->IsTabProtected( nTab ) ) pDoc->SetTabProtection(nTab, pRefUndoDoc->GetTabProtection(nTab)); diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx index afe29a8309a7..794b1abd34be 100644 --- a/sc/source/ui/unoobj/cellsuno.cxx +++ b/sc/source/ui/unoobj/cellsuno.cxx @@ -84,6 +84,7 @@ #include "srchuno.hxx" #include "targuno.hxx" #include "tokenuno.hxx" +#include "eventuno.hxx" #include "docsh.hxx" #include "markdata.hxx" #include "patattr.hxx" @@ -6835,6 +6836,7 @@ uno::Any SAL_CALL ScTableSheetObj::queryInterface( const uno::Type& rType ) thro SC_QUERYINTERFACE( sheet::XScenarioEnhanced ) SC_QUERYINTERFACE( sheet::XSheetLinkable ) SC_QUERYINTERFACE( sheet::XExternalSheetName ) + SC_QUERYINTERFACE( document::XEventsSupplier ) return ScCellRangeObj::queryInterface( rType ); } @@ -6858,7 +6860,7 @@ uno::Sequence<uno::Type> SAL_CALL ScTableSheetObj::getTypes() throw(uno::Runtime long nParentLen = aParentTypes.getLength(); const uno::Type* pParentPtr = aParentTypes.getConstArray(); - aTypes.realloc( nParentLen + 17 ); + aTypes.realloc( nParentLen + 18 ); uno::Type* pPtr = aTypes.getArray(); pPtr[nParentLen + 0] = getCppuType((const uno::Reference<sheet::XSpreadsheet>*)0); pPtr[nParentLen + 1] = getCppuType((const uno::Reference<container::XNamed>*)0); @@ -6877,6 +6879,7 @@ uno::Sequence<uno::Type> SAL_CALL ScTableSheetObj::getTypes() throw(uno::Runtime pPtr[nParentLen +14] = getCppuType((const uno::Reference<sheet::XScenarioEnhanced>*)0); pPtr[nParentLen +15] = getCppuType((const uno::Reference<sheet::XSheetLinkable>*)0); pPtr[nParentLen +16] = getCppuType((const uno::Reference<sheet::XExternalSheetName>*)0); + pPtr[nParentLen +17] = getCppuType((const uno::Reference<document::XEventsSupplier>*)0); for (long i=0; i<nParentLen; i++) pPtr[i] = pParentPtr[i]; // parent types first @@ -8158,6 +8161,18 @@ void ScTableSheetObj::setExternalName( const ::rtl::OUString& aUrl, const ::rtl: } } +// XEventsSupplier + +uno::Reference<container::XNameReplace> SAL_CALL ScTableSheetObj::getEvents() throw (uno::RuntimeException) +{ + ScUnoGuard aGuard; + ScDocShell* pDocSh = GetDocShell(); + if ( pDocSh ) + return new ScSheetEventsObj( pDocSh, GetTab_Impl() ); + + return NULL; +} + // XPropertySet erweitert fuer Sheet-Properties uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTableSheetObj::getPropertySetInfo() diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx index e67103cf75e5..41fe13f74f99 100644 --- a/sc/source/ui/unoobj/docuno.cxx +++ b/sc/source/ui/unoobj/docuno.cxx @@ -96,6 +96,7 @@ #include "scmod.hxx" #include "rangeutl.hxx" #include "ViewSettingsSequenceDefines.hxx" +#include "sheetevents.hxx" #include "sc.hrc" #include "scresid.hxx" @@ -591,6 +592,10 @@ void ScModelObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) // (if a broadcast is added to SetDrawModified, is has to be tested here, too) DELETEZ( pPrintFuncCache ); + + // handle "OnCalculate" sheet events + if ( pDocShell && pDocShell->GetDocument()->HasSheetEventScript( SC_SHEETEVENT_CALCULATE ) ) + HandleCalculateEvents(); } } else if ( rHint.ISA( ScPointerChangedHint ) ) @@ -2089,11 +2094,11 @@ sal_Int64 SAL_CALL ScModelObj::getSomething( } if ( rId.getLength() == 16 && - 0 == rtl_compareMemory( SfxObjectShell::getUnoTunnelId().getConstArray(), + 0 == rtl_compareMemory( SfxObjectShell::getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) - { - return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(pDocShell )); - } + { + return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(pDocShell )); + } // aggregated number formats supplier has XUnoTunnel, too // interface from aggregated object must be obtained via queryAggregation @@ -2162,7 +2167,23 @@ void ScModelObj::removeChangesListener( const uno::Reference< util::XChangesList bool ScModelObj::HasChangesListeners() const { - return ( maChangesListeners.getLength() > 0 ); + if ( maChangesListeners.getLength() > 0 ) + return true; + + if ( pDocShell ) + { + // "change" event set in any sheet? + ScDocument* pDoc = pDocShell->GetDocument(); + SCTAB nTabCount = pDoc->GetTableCount(); + for (SCTAB nTab = 0; nTab < nTabCount; nTab++) + { + const ScSheetEvents* pEvents = pDoc->GetSheetEvents(nTab); + if (pEvents && pEvents->GetScript(SC_SHEETEVENT_CHANGE)) + return true; + } + } + + return false; } void ScModelObj::NotifyChanges( const ::rtl::OUString& rOperation, const ScRangeList& rRanges, @@ -2208,6 +2229,91 @@ void ScModelObj::NotifyChanges( const ::rtl::OUString& rOperation, const ScRange } } } + + // handle sheet events + //! separate method with ScMarkData? Then change HasChangesListeners back. + if ( rOperation.compareToAscii("cell-change") == 0 && pDocShell ) + { + ScMarkData aMarkData; + aMarkData.MarkFromRangeList( rRanges, FALSE ); + ScDocument* pDoc = pDocShell->GetDocument(); + SCTAB nTabCount = pDoc->GetTableCount(); + for (SCTAB nTab = 0; nTab < nTabCount; nTab++) + if (aMarkData.GetTableSelect(nTab)) + { + const ScSheetEvents* pEvents = pDoc->GetSheetEvents(nTab); + if (pEvents) + { + const rtl::OUString* pScript = pEvents->GetScript(SC_SHEETEVENT_CHANGE); + if (pScript) + { + ScRangeList aTabRanges; // collect ranges on this sheet + ULONG nRangeCount = rRanges.Count(); + for ( ULONG nIndex = 0; nIndex < nRangeCount; ++nIndex ) + { + ScRange aRange( *rRanges.GetObject( nIndex ) ); + if ( aRange.aStart.Tab() == nTab ) + aTabRanges.Append( aRange ); + } + ULONG nTabRangeCount = aTabRanges.Count(); + if ( nTabRangeCount > 0 ) + { + uno::Reference<uno::XInterface> xTarget; + if ( nTabRangeCount == 1 ) + { + ScRange aRange( *aTabRanges.GetObject( 0 ) ); + if ( aRange.aStart == aRange.aEnd ) + xTarget.set( static_cast<cppu::OWeakObject*>( new ScCellObj( pDocShell, aRange.aStart ) ) ); + else + xTarget.set( static_cast<cppu::OWeakObject*>( new ScCellRangeObj( pDocShell, aRange ) ) ); + } + else + xTarget.set( static_cast<cppu::OWeakObject*>( new ScCellRangesObj( pDocShell, aTabRanges ) ) ); + + uno::Sequence<uno::Any> aParams(1); + aParams[0] <<= xTarget; + + uno::Any aRet; + uno::Sequence<sal_Int16> aOutArgsIndex; + uno::Sequence<uno::Any> aOutArgs; + + /*ErrCode eRet =*/ pDocShell->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs ); + } + } + } + } + } +} + +void ScModelObj::HandleCalculateEvents() +{ + if (pDocShell) + { + ScDocument* pDoc = pDocShell->GetDocument(); + // don't call events before the document is visible + // (might also set a flag on SFX_EVENT_LOADFINISHED and only disable while loading) + if ( pDoc->IsDocVisible() ) + { + SCTAB nTabCount = pDoc->GetTableCount(); + for (SCTAB nTab = 0; nTab < nTabCount; nTab++) + { + const ScSheetEvents* pEvents = pDoc->GetSheetEvents(nTab); + if (pEvents) + { + const rtl::OUString* pScript = pEvents->GetScript(SC_SHEETEVENT_CALCULATE); + if (pScript && pDoc->HasCalcNotification(nTab)) + { + uno::Any aRet; + uno::Sequence<uno::Any> aParams; + uno::Sequence<sal_Int16> aOutArgsIndex; + uno::Sequence<uno::Any> aOutArgs; + pDocShell->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs ); + } + } + } + } + pDoc->ResetCalcNotifications(); + } } //------------------------------------------------------------------------ diff --git a/sc/source/ui/unoobj/funcuno.cxx b/sc/source/ui/unoobj/funcuno.cxx index 0c197a8b738d..d10d5f2f0929 100644 --- a/sc/source/ui/unoobj/funcuno.cxx +++ b/sc/source/ui/unoobj/funcuno.cxx @@ -34,6 +34,7 @@ #include <sfx2/app.hxx> #include <svl/itemprop.hxx> +#include "scitems.hxx" #include "funcuno.hxx" #include "miscuno.hxx" #include "cellsuno.hxx" @@ -55,6 +56,7 @@ #include "docpool.hxx" #include "attrib.hxx" #include "clipparam.hxx" +#include "dociter.hxx" using namespace com::sun::star; @@ -185,6 +187,32 @@ BOOL lcl_CopyData( ScDocument* pSrcDoc, const ScRange& rSrcRange, pClipDoc->ApplyPatternAreaTab( 0,0, MAXCOL,MAXROW, nSrcTab, aPattern ); } + // If the range contains formula cells with default number format, + // apply a number format for the formula result + ScCellIterator aIter( pClipDoc, rSrcRange ); + ScBaseCell* pCell = aIter.GetFirst(); + while (pCell) + { + if (pCell->GetCellType() == CELLTYPE_FORMULA) + { + ScAddress aCellPos = aIter.GetPos(); + sal_uInt32 nFormat = pClipDoc->GetNumberFormat(aCellPos); + if ( (nFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0 ) + { + ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell); + USHORT nErrCode = pFCell->GetErrCode(); + if ( nErrCode == 0 && pFCell->IsValue() ) + { + sal_uInt32 nNewFormat = pFCell->GetStandardFormat( *pClipDoc->GetFormatTable(), nFormat ); + if ( nNewFormat != nFormat ) + pClipDoc->ApplyAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), + SfxUInt32Item( ATTR_VALUE_FORMAT, nNewFormat ) ); + } + } + } + pCell = aIter.GetNext(); + } + ScMarkData aDestMark; aDestMark.SelectOneTable( nDestTab ); aDestMark.SetMarkArea( aNewRange ); @@ -199,7 +227,8 @@ BOOL lcl_CopyData( ScDocument* pSrcDoc, const ScRange& rSrcRange, ScFunctionAccess::ScFunctionAccess() : pOptions( NULL ), aPropertyMap( ScDocOptionsHelper::GetPropertyMap() ), - bInvalid( FALSE ) + mbArray( true ), // default according to behaviour of older Office versions + mbValid( true ) { StartListening( *SFX_APP() ); // for SFX_HINT_DEINITIALIZING } @@ -216,7 +245,7 @@ void ScFunctionAccess::Notify( SfxBroadcaster&, const SfxHint& rHint ) { // document must not be used anymore aDocCache.Clear(); - bInvalid = TRUE; + mbValid = false; } } @@ -288,14 +317,22 @@ void SAL_CALL ScFunctionAccess::setPropertyValue( { ScUnoGuard aGuard; - if ( !pOptions ) - pOptions = new ScDocOptions(); + if( aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsArrayFunction" ) ) ) + { + if( !(aValue >>= mbArray) ) + throw lang::IllegalArgumentException(); + } + else + { + if ( !pOptions ) + pOptions = new ScDocOptions(); - // options aren't initialized from configuration - always get the same default behaviour + // options aren't initialized from configuration - always get the same default behaviour - BOOL bDone = ScDocOptionsHelper::setPropertyValue( *pOptions, aPropertyMap, aPropertyName, aValue ); - if (!bDone) - throw beans::UnknownPropertyException(); + BOOL bDone = ScDocOptionsHelper::setPropertyValue( *pOptions, aPropertyMap, aPropertyName, aValue ); + if (!bDone) + throw beans::UnknownPropertyException(); + } } uno::Any SAL_CALL ScFunctionAccess::getPropertyValue( const rtl::OUString& aPropertyName ) @@ -304,6 +341,9 @@ uno::Any SAL_CALL ScFunctionAccess::getPropertyValue( const rtl::OUString& aProp { ScUnoGuard aGuard; + if( aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsArrayFunction" ) ) ) + return uno::Any( mbArray ); + if ( !pOptions ) pOptions = new ScDocOptions(); @@ -497,7 +537,7 @@ uno::Any SAL_CALL ScFunctionAccess::callFunction( const rtl::OUString& aName, { ScUnoGuard aGuard; - if (bInvalid) + if (!mbValid) throw uno::RuntimeException(); // use cached document if not in use, temporary document otherwise @@ -556,12 +596,13 @@ uno::Any SAL_CALL ScFunctionAccess::callFunction( const rtl::OUString& aName, uno::TypeClass eClass = rArg.getValueTypeClass(); uno::Type aType = rArg.getValueType(); if ( eClass == uno::TypeClass_BYTE || - eClass == uno::TypeClass_SHORT || - eClass == uno::TypeClass_UNSIGNED_SHORT || - eClass == uno::TypeClass_LONG || - eClass == uno::TypeClass_UNSIGNED_LONG || - eClass == uno::TypeClass_FLOAT || - eClass == uno::TypeClass_DOUBLE ) + eClass == uno::TypeClass_BOOLEAN || + eClass == uno::TypeClass_SHORT || + eClass == uno::TypeClass_UNSIGNED_SHORT || + eClass == uno::TypeClass_LONG || + eClass == uno::TypeClass_UNSIGNED_LONG || + eClass == uno::TypeClass_FLOAT || + eClass == uno::TypeClass_DOUBLE ) { // #87871# accept integer types because Basic passes a floating point // variable as byte, short or long if it's an integer number. @@ -650,13 +691,13 @@ uno::Any SAL_CALL ScFunctionAccess::callFunction( const rtl::OUString& aName, // GRAM_PODF_A1 doesn't really matter for the token array but fits with // other API compatibility grammars. ScFormulaCell* pFormula = new ScFormulaCell( pDoc, aFormulaPos, - &aTokenArr,formula::FormulaGrammar::GRAM_PODF_A1, MM_FORMULA ); + &aTokenArr,formula::FormulaGrammar::GRAM_PODF_A1, mbArray ? MM_FORMULA : MM_NONE ); pDoc->PutCell( aFormulaPos, pFormula ); //! necessary? // call GetMatrix before GetErrCode because GetMatrix always recalculates // if there is no matrix result - const ScMatrix* pMat = pFormula->GetMatrix(); + const ScMatrix* pMat = mbArray ? pFormula->GetMatrix() : 0; USHORT nErrCode = pFormula->GetErrCode(); if ( nErrCode == 0 ) { diff --git a/sc/source/ui/unoobj/makefile.mk b/sc/source/ui/unoobj/makefile.mk index 35fdf164bf92..36c3493ceefc 100644 --- a/sc/source/ui/unoobj/makefile.mk +++ b/sc/source/ui/unoobj/makefile.mk @@ -79,6 +79,7 @@ SLO1FILES = \ $(SLO)$/filtuno.obj \ $(SLO)$/unodoc.obj \ $(SLO)$/addruno.obj \ + $(SLO)$/eventuno.obj \ $(SLO)$/listenercalls.obj \ $(SLO)$/cellvaluebinding.obj \ $(SLO)$/celllistsource.obj \ diff --git a/sc/source/ui/unoobj/viewuno.cxx b/sc/source/ui/unoobj/viewuno.cxx index 15fb8183a88f..d10d3ba54f86 100644 --- a/sc/source/ui/unoobj/viewuno.cxx +++ b/sc/source/ui/unoobj/viewuno.cxx @@ -66,7 +66,9 @@ #include "scmod.hxx" #include "appoptio.hxx" #include "gridwin.hxx" +#include "sheetevents.hxx" #include <com/sun/star/view/DocumentZoomType.hpp> +#include <com/sun/star/awt/MouseButton.hpp> #include "AccessibilityHints.hxx" #include <svx/sdrhittesthelper.hxx> @@ -476,9 +478,11 @@ ScTabViewObj::ScTabViewObj( ScTabViewShell* pViewSh ) : aPropSet( lcl_GetViewOptPropertyMap() ), aMouseClickHandlers( 0 ), aActivationListeners( 0 ), + nPreviousTab( 0 ), bDrawSelModeSet(sal_False) { - //! Listening oder so + if (pViewSh) + nPreviousTab = pViewSh->GetViewData()->GetTabNo(); } ScTabViewObj::~ScTabViewObj() @@ -529,15 +533,44 @@ void SAL_CALL ScTabViewObj::release() throw() SfxBaseController::release(); } +void lcl_CallActivate( ScDocShell* pDocSh, SCTAB nTab, sal_Int32 nEvent ) +{ + ScDocument* pDoc = pDocSh->GetDocument(); + // when deleting a sheet, nPreviousTab can be invalid + // (could be handled with reference updates) + if (!pDoc->HasTable(nTab)) + return; + + const ScSheetEvents* pEvents = pDoc->GetSheetEvents(nTab); + if (pEvents) + { + const rtl::OUString* pScript = pEvents->GetScript(nEvent); + if (pScript) + { + uno::Any aRet; + uno::Sequence<uno::Any> aParams; + uno::Sequence<sal_Int16> aOutArgsIndex; + uno::Sequence<uno::Any> aOutArgs; + + /*ErrCode eRet =*/ pDocSh->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs ); + } + } +} + void ScTabViewObj::SheetChanged() { - if (aActivationListeners.Count() > 0 && GetViewShell()) + if ( !GetViewShell() ) + return; + + ScViewData* pViewData = GetViewShell()->GetViewData(); + ScDocShell* pDocSh = pViewData->GetDocShell(); + if (aActivationListeners.Count() > 0) { sheet::ActivationEvent aEvent; uno::Reference< sheet::XSpreadsheetView > xView(this); uno::Reference< uno::XInterface > xSource(xView, uno::UNO_QUERY); aEvent.Source = xSource; - aEvent.ActiveSheet = new ScTableSheetObj(GetViewShell()->GetViewData()->GetDocShell(), GetViewShell()->GetViewData()->GetTabNo()); + aEvent.ActiveSheet = new ScTableSheetObj(pDocSh, pViewData->GetTabNo()); for ( USHORT n=0; n<aActivationListeners.Count(); n++ ) { try @@ -551,6 +584,15 @@ void ScTabViewObj::SheetChanged() } } } + + // handle sheet events + SCTAB nNewTab = pViewData->GetTabNo(); + if ( nNewTab != nPreviousTab ) + { + lcl_CallActivate( pDocSh, nPreviousTab, SC_SHEETEVENT_UNFOCUS ); + lcl_CallActivate( pDocSh, nNewTab, SC_SHEETEVENT_FOCUS ); + } + nPreviousTab = nNewTab; } uno::Sequence<uno::Type> SAL_CALL ScTabViewObj::getTypes() throw(uno::RuntimeException) @@ -1194,6 +1236,22 @@ uno::Reference< uno::XInterface > ScTabViewObj::GetClickedObject(const Point& rP return xTarget; } +bool ScTabViewObj::IsMouseListening() const +{ + if ( aMouseClickHandlers.Count() > 0 ) + return true; + + // also include sheet events, because MousePressed must be called for them + ScTabViewShell* pViewSh = GetViewShell(); + ScViewData* pViewData = pViewSh->GetViewData(); + const ScSheetEvents* pEvents = pViewData->GetDocument()->GetSheetEvents(pViewData->GetTabNo()); + if ( pEvents && ( pEvents->GetScript(SC_SHEETEVENT_RIGHTCLICK) != NULL || + pEvents->GetScript(SC_SHEETEVENT_DOUBLECLICK) != NULL ) ) + return true; + + return false; +} + sal_Bool ScTabViewObj::MousePressed( const awt::MouseEvent& e ) throw (::uno::RuntimeException) { @@ -1229,6 +1287,50 @@ sal_Bool ScTabViewObj::MousePressed( const awt::MouseEvent& e ) } } } + + // handle sheet events + bool bDoubleClick = ( e.Buttons == awt::MouseButton::LEFT && e.ClickCount == 2 ); + bool bRightClick = ( e.Buttons == awt::MouseButton::RIGHT && e.ClickCount == 1 ); + if ( ( bDoubleClick || bRightClick ) && !bReturn ) + { + sal_Int32 nEvent = bDoubleClick ? SC_SHEETEVENT_DOUBLECLICK : SC_SHEETEVENT_RIGHTCLICK; + + ScTabViewShell* pViewSh = GetViewShell(); + ScViewData* pViewData = pViewSh->GetViewData(); + ScDocShell* pDocSh = pViewData->GetDocShell(); + ScDocument* pDoc = pDocSh->GetDocument(); + SCTAB nTab = pViewData->GetTabNo(); + const ScSheetEvents* pEvents = pDoc->GetSheetEvents(nTab); + if (pEvents) + { + const rtl::OUString* pScript = pEvents->GetScript(nEvent); + if (pScript) + { + // the macro parameter is the clicked object, as in the mousePressed call above + uno::Reference< uno::XInterface > xTarget = GetClickedObject(Point(e.X, e.Y)); + if (xTarget.is()) + { + uno::Sequence<uno::Any> aParams(1); + aParams[0] <<= xTarget; + + uno::Any aRet; + uno::Sequence<sal_Int16> aOutArgsIndex; + uno::Sequence<uno::Any> aOutArgs; + + /*ErrCode eRet =*/ pDocSh->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs ); + + // look for a boolean return value of true + sal_Bool bRetValue = sal_False; + if (aRet >>= bRetValue) + { + if (bRetValue) + bReturn = sal_True; + } + } + } + } + } + return bReturn; } @@ -1702,6 +1804,30 @@ void ScTabViewObj::SelectionChanged() aEvent.Source.set(static_cast<cppu::OWeakObject*>(this)); for ( USHORT n=0; n<aSelectionListeners.Count(); n++ ) (*aSelectionListeners[n])->selectionChanged( aEvent ); + + // handle sheet events + ScTabViewShell* pViewSh = GetViewShell(); + ScViewData* pViewData = pViewSh->GetViewData(); + ScDocShell* pDocSh = pViewData->GetDocShell(); + ScDocument* pDoc = pDocSh->GetDocument(); + SCTAB nTab = pViewData->GetTabNo(); + const ScSheetEvents* pEvents = pDoc->GetSheetEvents(nTab); + if (pEvents) + { + const rtl::OUString* pScript = pEvents->GetScript(SC_SHEETEVENT_SELECT); + if (pScript) + { + // the macro parameter is the selection as returned by getSelection + uno::Sequence<uno::Any> aParams(1); + aParams[0] = getSelection(); + + uno::Any aRet; + uno::Sequence<sal_Int16> aOutArgsIndex; + uno::Sequence<uno::Any> aOutArgs; + + /*ErrCode eRet =*/ pDocSh->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs ); + } + } } diff --git a/sc/source/ui/vba/makefile.mk b/sc/source/ui/vba/makefile.mk index 00a26e2f94de..0a84b8dd12a5 100644 --- a/sc/source/ui/vba/makefile.mk +++ b/sc/source/ui/vba/makefile.mk @@ -78,28 +78,31 @@ SLOFILES= \ $(SLO)$/vbaborders.obj \ $(SLO)$/vbacharacters.obj \ $(SLO)$/vbavalidation.obj \ - $(SLO)$/vbaoleobject.obj \ - $(SLO)$/vbaoleobjects.obj \ - $(SLO)$/vbatextboxshape.obj \ - $(SLO)$/vbapane.obj \ - $(SLO)$/vbatextframe.obj \ - $(SLO)$/vbacharttitle.obj \ - $(SLO)$/vbacharts.obj \ - $(SLO)$/vbaaxistitle.obj \ - $(SLO)$/vbaaxes.obj \ - $(SLO)$/vbaaxis.obj \ - $(SLO)$/vbaformat.obj \ - $(SLO)$/vbacondition.obj \ - $(SLO)$/vbaformatcondition.obj \ - $(SLO)$/vbaformatconditions.obj \ - $(SLO)$/vbastyle.obj \ - $(SLO)$/vbastyles.obj \ - $(SLO)$/vbaassistant.obj \ - $(SLO)$/vbahyperlink.obj \ - $(SLO)$/vbapagesetup.obj \ - $(SLO)$/vbapagebreak.obj \ - $(SLO)$/vbapagebreaks.obj \ - $(SLO)$/service.obj + $(SLO)$/vbasheetobject.obj \ + $(SLO)$/vbasheetobjects.obj \ + $(SLO)$/vbaoleobject.obj \ + $(SLO)$/vbaoleobjects.obj \ + $(SLO)$/vbatextboxshape.obj \ + $(SLO)$/vbapane.obj \ + $(SLO)$/vbatextframe.obj \ + $(SLO)$/vbacharttitle.obj \ + $(SLO)$/vbacharts.obj \ + $(SLO)$/vbaaxistitle.obj \ + $(SLO)$/vbaaxes.obj \ + $(SLO)$/vbaaxis.obj \ + $(SLO)$/vbaformat.obj \ + $(SLO)$/vbacondition.obj \ + $(SLO)$/vbaformatcondition.obj \ + $(SLO)$/vbaformatconditions.obj \ + $(SLO)$/vbastyle.obj \ + $(SLO)$/vbastyles.obj \ + $(SLO)$/vbaassistant.obj \ + $(SLO)$/vbahyperlink.obj \ + $(SLO)$/vbahyperlinks.obj \ + $(SLO)$/vbapagesetup.obj \ + $(SLO)$/vbapagebreak.obj \ + $(SLO)$/vbapagebreaks.obj \ + $(SLO)$/service.obj .ENDIF # --- Targets ------------------------------------------------------ diff --git a/sc/source/ui/vba/vbaapplication.cxx b/sc/source/ui/vba/vbaapplication.cxx index 3d5af01acef1..aea8d8bc11d4 100644 --- a/sc/source/ui/vba/vbaapplication.cxx +++ b/sc/source/ui/vba/vbaapplication.cxx @@ -114,7 +114,10 @@ public: ActiveWorkbook( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext) : ScVbaWorkbook( xParent, xContext ){} }; -ScVbaApplication::ScVbaApplication( const uno::Reference<uno::XComponentContext >& xContext ): ScVbaApplication_BASE( xContext ), m_xCalculation( excel::XlCalculation::xlCalculationAutomatic ) +ScVbaApplication::ScVbaApplication( const uno::Reference<uno::XComponentContext >& xContext ) : + ScVbaApplication_BASE( xContext ), + m_xCalculation( excel::XlCalculation::xlCalculationAutomatic ), + m_xDisplayAlerts( sal_True) { } @@ -127,6 +130,66 @@ SfxObjectShell* ScVbaApplication::GetDocShell( const uno::Reference< frame::XMod return static_cast< SfxObjectShell* >( excel::getDocShell( xModel ) ); } +::rtl::OUString SAL_CALL +ScVbaApplication::getExactName( const ::rtl::OUString& aApproximateName ) throw (uno::RuntimeException) +{ + uno::Reference< beans::XExactName > xWSF( new ScVbaWSFunction( this, mxContext ) ); + return xWSF->getExactName( aApproximateName ); +} + +uno::Reference< beans::XIntrospectionAccess > SAL_CALL +ScVbaApplication::getIntrospection() throw(css::uno::RuntimeException) +{ + uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) ); + return xWSF->getIntrospection(); +} + +uno::Any SAL_CALL +ScVbaApplication::invoke( const ::rtl::OUString& FunctionName, const uno::Sequence< uno::Any >& Params, uno::Sequence< sal_Int16 >& OutParamIndex, uno::Sequence< uno::Any >& OutParam) throw(lang::IllegalArgumentException, script::CannotConvertException, reflection::InvocationTargetException, uno::RuntimeException) +{ + /* When calling the functions directly at the Application object, no runtime + errors are thrown, but the error is inserted into the return value. */ + uno::Any aAny; + try + { + uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) ); + aAny = xWSF->invoke( FunctionName, Params, OutParamIndex, OutParam ); + } + catch( uno::Exception& ) + { + aAny <<= script::BasicErrorException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), 1000, ::rtl::OUString() ); + } + return aAny; +} + +void SAL_CALL +ScVbaApplication::setValue( const ::rtl::OUString& PropertyName, const uno::Any& Value ) throw(beans::UnknownPropertyException, script::CannotConvertException, reflection::InvocationTargetException, uno::RuntimeException) +{ + uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) ); + xWSF->setValue( PropertyName, Value ); +} + +uno::Any SAL_CALL +ScVbaApplication::getValue( const ::rtl::OUString& PropertyName ) throw(beans::UnknownPropertyException, uno::RuntimeException) +{ + uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) ); + return xWSF->getValue( PropertyName ); +} + +sal_Bool SAL_CALL +ScVbaApplication::hasMethod( const ::rtl::OUString& Name ) throw(uno::RuntimeException) +{ + uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) ); + return xWSF->hasMethod( Name ); +} + +sal_Bool SAL_CALL +ScVbaApplication::hasProperty( const ::rtl::OUString& Name ) throw(uno::RuntimeException) +{ + uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) ); + return xWSF->hasProperty( Name ); +} + uno::Reference< excel::XWorkbook > ScVbaApplication::getActiveWorkbook() throw (uno::RuntimeException) { @@ -190,7 +253,7 @@ ScVbaApplication::getSelection() throw (uno::RuntimeException) } else { - throw uno::RuntimeException( sImpementaionName + rtl::OUString::createFromAscii(" donot be surpported"), uno::Reference< uno::XInterface >() ); + throw uno::RuntimeException( sImpementaionName + rtl::OUString::createFromAscii(" not suported"), uno::Reference< uno::XInterface >() ); } } @@ -244,7 +307,7 @@ ScVbaApplication::Worksheets( const uno::Any& aIndex ) throw (uno::RuntimeExcept uno::Any SAL_CALL ScVbaApplication::WorksheetFunction( ) throw (::com::sun::star::uno::RuntimeException) { - return uno::makeAny( uno::Reference< script::XInvocation >( new ScVbaWSFunction( this, mxContext) ) ); + return uno::makeAny( uno::Reference< script::XInvocation >( new ScVbaWSFunction( this, mxContext ) ) ); } uno::Any SAL_CALL @@ -270,7 +333,10 @@ uno::Reference< excel::XWindow > SAL_CALL ScVbaApplication::getActiveWindow() throw (uno::RuntimeException) { // #FIXME sofar can't determine Parent - return new ScVbaWindow( uno::Reference< XHelperInterface >(), mxContext, getCurrentDocument() ); + uno::Reference< frame::XModel > xModel = getCurrentDocument(); + ScVbaWindow* pWin = new ScVbaWindow( uno::Reference< XHelperInterface >(), mxContext, xModel ); + uno::Reference< excel::XWindow > xWin( pWin ); + return xWin; } uno::Any SAL_CALL @@ -321,23 +387,6 @@ ScVbaApplication::setStatusBar( const uno::Any& _statusbar ) throw (uno::Runtime uno::Reference< uno::XInterface >() ); } -double SAL_CALL -ScVbaApplication::CountA( const uno::Any& arg1 ) throw (uno::RuntimeException) -{ - double result = 0; - uno::Reference< script::XInvocation > xInvoc( WorksheetFunction(), uno::UNO_QUERY_THROW ); - if ( xInvoc.is() ) - { - static rtl::OUString FunctionName( RTL_CONSTASCII_USTRINGPARAM("CountA" ) ); - uno::Sequence< uno::Any > Params(1); - Params[0] = arg1; - uno::Sequence< sal_Int16 > OutParamIndex; - uno::Sequence< uno::Any > OutParam; - xInvoc->invoke( FunctionName, Params, OutParamIndex, OutParam ) >>= result; - } - return result; -} - ::sal_Int32 SAL_CALL ScVbaApplication::getCalculation() throw (uno::RuntimeException) { @@ -482,8 +531,11 @@ ScVbaApplication::GoTo( const uno::Any& Reference, const uno::Any& Scroll ) thro ScGridWindow* gridWindow = (ScGridWindow*)pShell->GetWindow(); try { - uno::Reference< excel::XRange > xVbaSheetRange = ScVbaRange::getRangeObjectForName( mxContext, sRangeName, excel::getDocShell( xModel ), formula::FormulaGrammar::CONV_XL_R1C1 ); -; + // FIXME: pass proper Worksheet parent + uno::Reference< excel::XRange > xVbaSheetRange = ScVbaRange::getRangeObjectForName( + uno::Reference< XHelperInterface >(), mxContext, sRangeName, + excel::getDocShell( xModel ), formula::FormulaGrammar::CONV_XL_R1C1 ); + if( bScroll ) { xVbaSheetRange->Select(); @@ -621,15 +673,21 @@ ScVbaApplication::getName() throw (uno::RuntimeException) } // #TODO #FIXME get/setDisplayAlerts are just stub impl +// here just the status of the switch is set +// the function that throws an error message needs to +// evaluate this switch in order to know whether it has to disable the +// error message thrown by OpenOffice + void SAL_CALL -ScVbaApplication::setDisplayAlerts(sal_Bool /*displayAlerts*/) throw (uno::RuntimeException) +ScVbaApplication::setDisplayAlerts(sal_Bool displayAlerts) throw (uno::RuntimeException) { + m_xDisplayAlerts = displayAlerts; } sal_Bool SAL_CALL ScVbaApplication::getDisplayAlerts() throw (uno::RuntimeException) { - return sal_True; + return m_xDisplayAlerts; } void SAL_CALL ScVbaApplication::Calculate() throw( script::BasicErrorException , uno::RuntimeException ) @@ -889,7 +947,8 @@ lcl_intersectionImpl( ScRangeList& rl1, ScRangeList& rl2 ) RangesList lcl_intersections( RangesList& vRanges ) { RangesList intersections; - for( RangesList::iterator it = vRanges.begin(); it != vRanges.end(); ++it ) + RangesList::iterator it = vRanges.begin(); + while( it != vRanges.end() ) { Ranges intermediateList; for( RangesList::iterator it_inner = vRanges.begin(); it_inner != vRanges.end(); ++it_inner ) @@ -902,6 +961,7 @@ RangesList lcl_intersections( RangesList& vRanges ) } } it = vRanges.erase( it ); // remove it so we don't include it in the next pass. + // 'it' is removed uncontidionally from vRanges, so the while loop will terminate ScRangeList argIntersect; lcl_strip_containedRanges( intermediateList ); diff --git a/sc/source/ui/vba/vbaapplication.hxx b/sc/source/ui/vba/vbaapplication.hxx index 02822e9f18ad..96638651bcd1 100644 --- a/sc/source/ui/vba/vbaapplication.hxx +++ b/sc/source/ui/vba/vbaapplication.hxx @@ -43,15 +43,29 @@ class ScVbaApplication : public ScVbaApplication_BASE { private: sal_Int32 m_xCalculation; + sal_Bool m_xDisplayAlerts; rtl::OUString getOfficePath( const rtl::OUString& sPath ) throw ( css::uno::RuntimeException ); + protected: - virtual css::uno::Reference< css::frame::XModel > getCurrentDocument() throw (css::uno::RuntimeException); + virtual css::uno::Reference< css::frame::XModel > getCurrentDocument() throw (css::uno::RuntimeException); + public: ScVbaApplication( const css::uno::Reference< css::uno::XComponentContext >& m_xContext ); virtual ~ScVbaApplication(); virtual SfxObjectShell* GetDocShell( const css::uno::Reference< css::frame::XModel >& xModel ) throw (css::uno::RuntimeException); + // XExactName + virtual ::rtl::OUString SAL_CALL getExactName( const ::rtl::OUString& aApproximateName ) throw (css::uno::RuntimeException); + + // XInvocation + virtual css::uno::Reference< css::beans::XIntrospectionAccess > SAL_CALL getIntrospection(void) throw(css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL invoke(const rtl::OUString& FunctionName, const css::uno::Sequence< css::uno::Any >& Params, css::uno::Sequence< sal_Int16 >& OutParamIndex, css::uno::Sequence< css::uno::Any >& OutParam) throw(css::lang::IllegalArgumentException, css::script::CannotConvertException, css::reflection::InvocationTargetException, css::uno::RuntimeException); + virtual void SAL_CALL setValue(const rtl::OUString& PropertyName, const css::uno::Any& Value) throw(css::beans::UnknownPropertyException, css::script::CannotConvertException, css::reflection::InvocationTargetException, css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL getValue(const rtl::OUString& PropertyName) throw(css::beans::UnknownPropertyException, css::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasMethod(const rtl::OUString& Name) throw(css::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasProperty(const rtl::OUString& Name) throw(css::uno::RuntimeException); + // XApplication virtual ::rtl::OUString SAL_CALL PathSeparator( ) throw (css::script::BasicErrorException, css::uno::RuntimeException); virtual void SAL_CALL setDefaultFilePath( const ::rtl::OUString& DefaultFilePath ) throw (css::script::BasicErrorException, css::uno::RuntimeException); @@ -67,8 +81,8 @@ public: virtual css::uno::Any SAL_CALL getSelection() throw (css::uno::RuntimeException); virtual css::uno::Reference< ov::excel::XWorkbook > SAL_CALL getActiveWorkbook() throw (css::uno::RuntimeException); virtual css::uno::Reference< ov::excel::XRange > SAL_CALL getActiveCell() throw ( css::uno::RuntimeException); - virtual css::uno::Reference< ov::excel::XWindow > SAL_CALL getActiveWindow() throw (css::uno::RuntimeException); - virtual css::uno::Reference< ov::excel::XWorksheet > SAL_CALL getActiveSheet() throw (css::uno::RuntimeException); + virtual css::uno::Reference< ov::excel::XWindow > SAL_CALL getActiveWindow() throw (css::uno::RuntimeException); + virtual css::uno::Reference< ov::excel::XWorksheet > SAL_CALL getActiveSheet() throw (css::uno::RuntimeException); virtual ::sal_Bool SAL_CALL getDisplayFormulaBar() throw ( css::uno::RuntimeException ); virtual void SAL_CALL setDisplayFormulaBar( ::sal_Bool _displayformulabar ) throw ( css::uno::RuntimeException ); @@ -86,8 +100,6 @@ public: virtual ::sal_Int32 SAL_CALL getCursor() throw (css::uno::RuntimeException); virtual void SAL_CALL setCursor( ::sal_Int32 _cursor ) throw (css::uno::RuntimeException); - virtual double SAL_CALL CountA( const css::uno::Any& arg1 ) throw (css::uno::RuntimeException) ; - virtual css::uno::Any SAL_CALL Windows( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException); virtual void SAL_CALL wait( double time ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL Range( const css::uno::Any& Cell1, const css::uno::Any& Cell2 ) throw (css::uno::RuntimeException); diff --git a/sc/source/ui/vba/vbacomment.cxx b/sc/source/ui/vba/vbacomment.cxx index a8026f151c79..9c50a25b8b7c 100644 --- a/sc/source/ui/vba/vbacomment.cxx +++ b/sc/source/ui/vba/vbacomment.cxx @@ -27,14 +27,17 @@ #include "vbacomment.hxx" #include <ooo/vba/excel/XlCreator.hpp> +#include <com/sun/star/drawing/XDrawPageSupplier.hpp> #include <com/sun/star/sheet/XSpreadsheet.hpp> #include <com/sun/star/sheet/XSheetAnnotationAnchor.hpp> #include <com/sun/star/sheet/XSheetAnnotationsSupplier.hpp> +#include <com/sun/star/sheet/XSheetAnnotationShapeSupplier.hpp> #include <com/sun/star/sheet/XSheetCellRange.hpp> #include <com/sun/star/table/CellAddress.hpp> #include <com/sun/star/table/XCell.hpp> #include <com/sun/star/text/XText.hpp> +#include <vbahelper/vbashape.hxx> #include "vbaglobals.hxx" #include "vbacomments.hxx" @@ -42,8 +45,14 @@ using namespace ::ooo::vba; using namespace ::com::sun::star; -ScVbaComment::ScVbaComment( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< table::XCellRange >& xRange ) throw( lang::IllegalArgumentException ) -: ScVbaComment_BASE( xParent, xContext ), mxRange( xRange ) +ScVbaComment::ScVbaComment( + const uno::Reference< XHelperInterface >& xParent, + const uno::Reference< uno::XComponentContext >& xContext, + const uno::Reference< frame::XModel >& xModel, + const uno::Reference< table::XCellRange >& xRange ) throw( lang::IllegalArgumentException ) : + ScVbaComment_BASE( xParent, xContext ), + mxModel( xModel, uno::UNO_SET_THROW ), + mxRange( xRange ) { if ( !xRange.is() ) throw lang::IllegalArgumentException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "range is not set " ) ), uno::Reference< uno::XInterface >() , 1 ); @@ -100,7 +109,7 @@ ScVbaComment::getCommentByIndex( sal_Int32 Index ) throw (uno::RuntimeException) { uno::Reference< container::XIndexAccess > xIndexAccess( getAnnotations(), uno::UNO_QUERY_THROW ); // parent is sheet ( parent of the range which is the parent of the comment ) - uno::Reference< XCollection > xColl( new ScVbaComments( getParent()->getParent(), mxContext, xIndexAccess ) ); + uno::Reference< XCollection > xColl( new ScVbaComments( getParent()->getParent(), mxContext, mxModel, xIndexAccess ) ); return uno::Reference< excel::XComment > ( xColl->Item( uno::makeAny( Index ), uno::Any() ), uno::UNO_QUERY_THROW ); } @@ -119,6 +128,17 @@ ScVbaComment::setAuthor( const rtl::OUString& /*_author*/ ) throw (uno::RuntimeE // #TODO #FIXME implementation needed } +uno::Reference< msforms::XShape > SAL_CALL +ScVbaComment::getShape() throw (uno::RuntimeException) +{ + uno::Reference< sheet::XSheetAnnotationShapeSupplier > xAnnoShapeSupp( getAnnotation(), uno::UNO_QUERY_THROW ); + uno::Reference< drawing::XShape > xAnnoShape( xAnnoShapeSupp->getAnnotationShape(), uno::UNO_SET_THROW ); + uno::Reference< sheet::XSheetCellRange > xCellRange( mxRange, uno::UNO_QUERY_THROW ); + uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupp( xCellRange->getSpreadsheet(), uno::UNO_QUERY_THROW ); + uno::Reference< drawing::XShapes > xShapes( xDrawPageSupp->getDrawPage(), uno::UNO_QUERY_THROW ); + return new ScVbaShape( this, mxContext, xAnnoShape, xShapes, mxModel, office::MsoShapeType::msoComment ); +} + sal_Bool SAL_CALL ScVbaComment::getVisible() throw (uno::RuntimeException) { @@ -186,12 +206,15 @@ ScVbaComment::Text( const uno::Any& aText, const uno::Any& aStart, const uno::An uno::Reference< text::XTextRange > xRange( xTextCursor, uno::UNO_QUERY_THROW ); xAnnoText->insertString( xRange, sText, bOverwrite ); + return xAnnoText->getString(); } - else - throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ScVbaComment::Text - bad Start value " ) ), uno::Reference< uno::XInterface >() ); + throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ScVbaComment::Text - bad Start value " ) ), uno::Reference< uno::XInterface >() ); } else if ( aText.hasValue() ) + { xAnnoText->setString( sText ); + return sText; + } return sAnnoText; } diff --git a/sc/source/ui/vba/vbacomment.hxx b/sc/source/ui/vba/vbacomment.hxx index 91d8a8a8e437..4a7d2fab91ef 100644 --- a/sc/source/ui/vba/vbacomment.hxx +++ b/sc/source/ui/vba/vbacomment.hxx @@ -31,6 +31,7 @@ #include <ooo/vba/excel/XComment.hpp> #include <ooo/vba/excel/XApplication.hpp> +#include <ooo/vba/msforms/XShape.hpp> #include <com/sun/star/sheet/XSheetAnnotations.hpp> #include <com/sun/star/sheet/XSheetAnnotation.hpp> #include <com/sun/star/table/XCellRange.hpp> @@ -42,6 +43,7 @@ typedef InheritedHelperInterfaceImpl1< ov::excel::XComment > ScVbaComment_BASE; class ScVbaComment : public ScVbaComment_BASE { + css::uno::Reference< css::frame::XModel > mxModel; css::uno::Reference< css::table::XCellRange > mxRange; private: @@ -50,13 +52,18 @@ private: sal_Int32 SAL_CALL getAnnotationIndex() throw (css::uno::RuntimeException); css::uno::Reference< ov::excel::XComment > SAL_CALL getCommentByIndex( sal_Int32 Index ) throw (css::uno::RuntimeException); public: - ScVbaComment( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::table::XCellRange >& xRange ) throw ( css::lang::IllegalArgumentException ); + ScVbaComment( + const css::uno::Reference< ov::XHelperInterface >& xParent, + const css::uno::Reference< css::uno::XComponentContext >& xContext, + const css::uno::Reference< css::frame::XModel >& xModel, + const css::uno::Reference< css::table::XCellRange >& xRange ) throw ( css::lang::IllegalArgumentException ); virtual ~ScVbaComment() {} // Attributes virtual rtl::OUString SAL_CALL getAuthor() throw (css::uno::RuntimeException); virtual void SAL_CALL setAuthor( const rtl::OUString& _author ) throw (css::uno::RuntimeException); + virtual css::uno::Reference< ov::msforms::XShape > SAL_CALL getShape() throw (css::uno::RuntimeException); virtual sal_Bool SAL_CALL getVisible() throw (css::uno::RuntimeException); virtual void SAL_CALL setVisible( sal_Bool _visible ) throw (css::uno::RuntimeException); diff --git a/sc/source/ui/vba/vbacomments.cxx b/sc/source/ui/vba/vbacomments.cxx index 5090fa6f5ee6..a68dd4245741 100644 --- a/sc/source/ui/vba/vbacomments.cxx +++ b/sc/source/ui/vba/vbacomments.cxx @@ -34,30 +34,43 @@ using namespace ::ooo::vba; using namespace ::com::sun::star; -uno::Any AnnotationToComment( const uno::Any& aSource, uno::Reference< uno::XComponentContext > & xContext ) +uno::Any AnnotationToComment( const uno::Any& aSource, uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< frame::XModel >& xModel ) { uno::Reference< sheet::XSheetAnnotation > xAnno( aSource, uno::UNO_QUERY_THROW ); uno::Reference< container::XChild > xChild( xAnno, uno::UNO_QUERY_THROW ); uno::Reference< table::XCellRange > xCellRange( xChild->getParent(), uno::UNO_QUERY_THROW ); // #FIXME needs to find the correct Parent - return uno::makeAny( uno::Reference< excel::XComment > ( new ScVbaComment( uno::Reference< XHelperInterface >(), xContext, xCellRange ) ) ); + return uno::makeAny( uno::Reference< excel::XComment > ( + new ScVbaComment( uno::Reference< XHelperInterface >(), xContext, xModel, xCellRange ) ) ); } class CommentEnumeration : public EnumerationHelperImpl { + css::uno::Reference< css::frame::XModel > mxModel; public: - CommentEnumeration( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xContext, xEnumeration ) {} + CommentEnumeration( + const uno::Reference< uno::XComponentContext >& xContext, + const uno::Reference< container::XEnumeration >& xEnumeration, + const uno::Reference< frame::XModel >& xModel ) throw ( uno::RuntimeException ) : + EnumerationHelperImpl( xContext, xEnumeration ), + mxModel( xModel, uno::UNO_SET_THROW ) + {} virtual uno::Any SAL_CALL nextElement() throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) { - return AnnotationToComment( m_xEnumeration->nextElement(), m_xContext ); + return AnnotationToComment( m_xEnumeration->nextElement(), m_xContext, mxModel ); } }; -ScVbaComments::ScVbaComments( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< container::XIndexAccess >& xIndexAccess ) -: ScVbaComments_BASE( xParent, xContext, xIndexAccess ) +ScVbaComments::ScVbaComments( + const uno::Reference< XHelperInterface >& xParent, + const uno::Reference< uno::XComponentContext > & xContext, + const uno::Reference< frame::XModel >& xModel, + const uno::Reference< container::XIndexAccess >& xIndexAccess ) : + ScVbaComments_BASE( xParent, xContext, xIndexAccess ), + mxModel( xModel, uno::UNO_SET_THROW ) { } @@ -68,13 +81,13 @@ ScVbaComments::createEnumeration() throw (uno::RuntimeException) { uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW ); - return new CommentEnumeration( mxContext, xEnumAccess->createEnumeration() ); + return new CommentEnumeration( mxContext, xEnumAccess->createEnumeration(), mxModel ); } uno::Any ScVbaComments::createCollectionObject( const css::uno::Any& aSource ) { - return AnnotationToComment( aSource, mxContext ); + return AnnotationToComment( aSource, mxContext, mxModel ); } uno::Type diff --git a/sc/source/ui/vba/vbacomments.hxx b/sc/source/ui/vba/vbacomments.hxx index 0ab11e8d5e97..2f98e5b71897 100644 --- a/sc/source/ui/vba/vbacomments.hxx +++ b/sc/source/ui/vba/vbacomments.hxx @@ -40,7 +40,11 @@ typedef CollTestImplHelper< ov::excel::XComments > ScVbaComments_BASE; class ScVbaComments : public ScVbaComments_BASE { public: - ScVbaComments( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess ); + ScVbaComments( + const css::uno::Reference< ov::XHelperInterface >& xParent, + const css::uno::Reference< css::uno::XComponentContext > & xContext, + const css::uno::Reference< css::frame::XModel >& xModel, + const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess ); virtual ~ScVbaComments() {} @@ -53,6 +57,8 @@ public: virtual rtl::OUString& getServiceImplName(); virtual css::uno::Sequence<rtl::OUString> getServiceNames(); +private: + css::uno::Reference< css::frame::XModel > mxModel; }; #endif /* SC_VBA_COMMENTS_HXX */ diff --git a/sc/source/ui/vba/vbafont.cxx b/sc/source/ui/vba/vbafont.cxx index a8aac44770a9..5894d3ea8c71 100644 --- a/sc/source/ui/vba/vbafont.cxx +++ b/sc/source/ui/vba/vbafont.cxx @@ -36,6 +36,7 @@ #include <ooo/vba/excel/XlColorIndex.hpp> #include <ooo/vba/excel/XlUnderlineStyle.hpp> #include <svl/itemset.hxx> +#include "excelvbahelper.hxx" #include "vbafont.hxx" #include "scitems.hxx" #include "cellsuno.hxx" @@ -43,15 +44,22 @@ using namespace ::ooo::vba; using namespace ::com::sun::star; -ScVbaFont::ScVbaFont( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const ScVbaPalette& dPalette, uno::Reference< beans::XPropertySet > xPropertySet, ScCellRangeObj* pRangeObj ) throw ( uno::RuntimeException ) : ScVbaFont_BASE( xParent, xContext, dPalette.getPalette(), xPropertySet ), mPalette( dPalette ), mpRangeObj( pRangeObj ) +ScVbaFont::ScVbaFont( + const uno::Reference< XHelperInterface >& xParent, + const uno::Reference< uno::XComponentContext >& xContext, + const ScVbaPalette& dPalette, + const uno::Reference< beans::XPropertySet >& xPropertySet, + ScCellRangeObj* pRangeObj, bool bFormControl ) throw ( uno::RuntimeException ) : + ScVbaFont_BASE( xParent, xContext, dPalette.getPalette(), xPropertySet, bFormControl ), + mPalette( dPalette ), + mpRangeObj( pRangeObj ) { } SfxItemSet* ScVbaFont::GetDataSet() { - SfxItemSet* pDataSet = excel::ScVbaCellRangeAccess::GetDataSet( mpRangeObj ); - return pDataSet; + return mpRangeObj ? excel::ScVbaCellRangeAccess::GetDataSet( mpRangeObj ) : 0; } ScVbaFont::~ScVbaFont() diff --git a/sc/source/ui/vba/vbafont.hxx b/sc/source/ui/vba/vbafont.hxx index 4cbcd483b2d8..3ef52c6d240f 100644 --- a/sc/source/ui/vba/vbafont.hxx +++ b/sc/source/ui/vba/vbafont.hxx @@ -46,7 +46,12 @@ class ScVbaFont : public ScVbaFont_BASE ScCellRangeObj* mpRangeObj; SfxItemSet* GetDataSet(); public: - ScVbaFont( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const ScVbaPalette& dPalette, css::uno::Reference< css::beans::XPropertySet > xPropertySet, ScCellRangeObj* pRangeObj = NULL ) throw ( css::uno::RuntimeException ); + ScVbaFont( + const css::uno::Reference< ov::XHelperInterface >& xParent, + const css::uno::Reference< css::uno::XComponentContext >& xContext, + const ScVbaPalette& dPalette, + const css::uno::Reference< css::beans::XPropertySet >& xPropertySet, + ScCellRangeObj* pRangeObj = 0, bool bFormControl = false ) throw ( css::uno::RuntimeException ); virtual ~ScVbaFont();// {} // Attributes diff --git a/sc/source/ui/vba/vbaformat.cxx b/sc/source/ui/vba/vbaformat.cxx index 23c2bf96a810..d08451af63f4 100644 --- a/sc/source/ui/vba/vbaformat.cxx +++ b/sc/source/ui/vba/vbaformat.cxx @@ -40,6 +40,7 @@ #include <rtl/math.hxx> +#include "excelvbahelper.hxx" #include "vbaborders.hxx" #include "vbapalette.hxx" #include "vbafont.hxx" diff --git a/sc/source/ui/vba/vbahelper.cxx b/sc/source/ui/vba/vbahelper.cxx index 4bc57e150c8f..cc76b1e60125 100644 --- a/sc/source/ui/vba/vbahelper.cxx +++ b/sc/source/ui/vba/vbahelper.cxx @@ -160,73 +160,6 @@ public: } }; -void -dispatchRequests (uno::Reference< frame::XModel>& xModel,rtl::OUString & aUrl, uno::Sequence< beans::PropertyValue >& sProps ) -{ - - util::URL url ; - url.Complete = aUrl; - rtl::OUString emptyString = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "" )); - uno::Reference<frame::XController> xController = xModel->getCurrentController(); - uno::Reference<frame::XFrame> xFrame = xController->getFrame(); - uno::Reference<frame::XDispatchProvider> xDispatchProvider (xFrame,uno::UNO_QUERY_THROW); - try - { - uno::Reference< beans::XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW ); - uno::Reference<uno::XComponentContext > xContext( xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))), uno::UNO_QUERY_THROW ); - if ( !xContext.is() ) - { - return ; - } - - uno::Reference<lang::XMultiComponentFactory > xServiceManager( - xContext->getServiceManager() ); - if ( !xServiceManager.is() ) - { - return ; - } - uno::Reference<util::XURLTransformer> xParser( xServiceManager->createInstanceWithContext( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ) ) - ,xContext), uno::UNO_QUERY_THROW ); - if (!xParser.is()) - return; - xParser->parseStrict (url); - } - catch ( uno::Exception & /*e*/ ) - { - return ; - } - - uno::Reference<frame::XDispatch> xDispatcher = xDispatchProvider->queryDispatch(url,emptyString,0); - - uno::Sequence<beans::PropertyValue> dispatchProps(1); - - sal_Int32 nProps = sProps.getLength(); - beans::PropertyValue* pDest = dispatchProps.getArray(); - if ( nProps ) - { - dispatchProps.realloc( nProps + 1 ); - // need to reaccquire pDest after realloc - pDest = dispatchProps.getArray(); - beans::PropertyValue* pSrc = sProps.getArray(); - for ( sal_Int32 index=0; index<nProps; ++index, ++pSrc, ++pDest ) - *pDest = *pSrc; - } - - (*pDest).Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Silent" )); - (*pDest).Value <<= (sal_Bool)sal_True; - - if (xDispatcher.is()) - xDispatcher->dispatch( url, dispatchProps ); -} - -void -dispatchRequests (uno::Reference< frame::XModel>& xModel,rtl::OUString & aUrl) -{ - uno::Sequence<beans::PropertyValue> dispatchProps; - dispatchRequests( xModel, aUrl, dispatchProps ); -} - - void dispatchExecute(css::uno::Reference< css::frame::XModel>& xModel, USHORT nSlot, SfxCallMode nCall) { ScTabViewShell* pViewShell = getBestViewShell( xModel ); @@ -821,7 +754,5 @@ ScVbaCellRangeAccess::GetDataSet( ScCellRangeObj* pRangeObj ) } -} // openoffice -} //org -======= ->>>>>>> other +} // vba +} // ooo diff --git a/sc/source/ui/vba/vbahyperlink.cxx b/sc/source/ui/vba/vbahyperlink.cxx index f3203b130bf2..e37df1e118b4 100644 --- a/sc/source/ui/vba/vbahyperlink.cxx +++ b/sc/source/ui/vba/vbahyperlink.cxx @@ -24,100 +24,213 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ -#include <vbahelper/helperdecl.hxx> + #include "vbahyperlink.hxx" +#include <vbahelper/helperdecl.hxx> #include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/text/XText.hpp> #include <com/sun/star/text/XTextFieldsSupplier.hpp> #include <com/sun/star/container/XEnumerationAccess.hpp> +#include <ooo/vba/office/MsoHyperlinkType.hpp> +#include <ooo/vba/msforms/XShape.hpp> #include "vbarange.hxx" using namespace ::ooo::vba; using namespace ::com::sun::star; +using ::rtl::OUString; +using ::rtl::OUStringBuffer; -ScVbaHyperlink::ScVbaHyperlink( uno::Sequence< uno::Any> const & args, - uno::Reference< uno::XComponentContext> const & xContext ) throw ( lang::IllegalArgumentException ) : HyperlinkImpl_BASE( getXSomethingFromArgs< XHelperInterface >( args, 0 ), xContext ), mxCell( getXSomethingFromArgs< table::XCell >( args, 1, false ) ) +// ============================================================================ + +ScVbaHyperlink::ScVbaHyperlink( const uno::Sequence< uno::Any >& rArgs, + const uno::Reference< uno::XComponentContext >& rxContext ) throw (lang::IllegalArgumentException) : + HyperlinkImpl_BASE( getXSomethingFromArgs< XHelperInterface >( rArgs, 0 ), rxContext ), + mxCell( getXSomethingFromArgs< table::XCell >( rArgs, 1, false ) ), + mnType( office::MsoHyperlinkType::msoHyperlinkRange ) { - mxCell = getXSomethingFromArgs< table::XCell >( args, 1, false ); uno::Reference< text::XTextFieldsSupplier > xTextFields( mxCell, uno::UNO_QUERY_THROW ); uno::Reference< container::XIndexAccess > xIndex( xTextFields->getTextFields(), uno::UNO_QUERY_THROW ); mxTextField.set( xIndex->getByIndex(0), uno::UNO_QUERY_THROW ); } -ScVbaHyperlink::~ScVbaHyperlink() +ScVbaHyperlink::ScVbaHyperlink( const uno::Reference< XHelperInterface >& rxAnchor, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Any& rAddress, const uno::Any& rSubAddress, + const uno::Any& rScreenTip, const uno::Any& rTextToDisplay ) throw (uno::RuntimeException) : + HyperlinkImpl_BASE( rxAnchor, rxContext ) // parent of Hyperlink is the anchor object { -} + // extract parameters, Address must not be empty + UrlComponents aUrlComp; + OUString aTextToDisplay; + if( !(rAddress >>= aUrlComp.first) || (aUrlComp.first.getLength() == 0) ) + throw uno::RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM( "Cannot get address" ) ), uno::Reference< uno::XInterface >() ); + rSubAddress >>= aUrlComp.second; + rScreenTip >>= maScreenTip; + rTextToDisplay >>= aTextToDisplay; -::rtl::OUString -ScVbaHyperlink::getAddress() throw (css::uno::RuntimeException) -{ - rtl::OUString aAddress; - uno::Any aValue = mxTextField->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ) ); - aValue >>= aAddress; - return aAddress; + // get anchor range or anchor shape + uno::Reference< excel::XRange > xAnchorRange( rxAnchor, uno::UNO_QUERY ); + if( xAnchorRange.is() ) + { + mnType = office::MsoHyperlinkType::msoHyperlinkRange; + // only single ranges are allowed + uno::Reference< table::XCellRange > xUnoRange( ScVbaRange::getCellRange( xAnchorRange ), uno::UNO_QUERY_THROW ); + // insert the hyperlink into the top-left cell only + mxCell.set( xUnoRange->getCellByPosition( 0, 0 ), uno::UNO_SET_THROW ); + uno::Reference< text::XText > xText( mxCell, uno::UNO_QUERY_THROW ); + // use cell text or URL if no TextToDisplay has been passed + if( aTextToDisplay.getLength() == 0 ) + { + aTextToDisplay = xText->getString(); + if( aTextToDisplay.getLength() == 0 ) + { + OUStringBuffer aBuffer( aUrlComp.first ); + if( aUrlComp.second.getLength() > 0 ) + aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( " - " ) ).append( aUrlComp.second ); + aTextToDisplay = aBuffer.makeStringAndClear(); + } + } + // create and initialize a new URL text field + uno::Reference< lang::XMultiServiceFactory > xFactory( ScVbaRange::getUnoModel( xAnchorRange ), uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextContent > xUrlField( xFactory->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.TextField.URL" ) ) ), uno::UNO_QUERY_THROW ); + mxTextField.set( xUrlField, uno::UNO_QUERY_THROW ); + setUrlComponents( aUrlComp ); + setTextToDisplay( aTextToDisplay ); + // insert the text field into the document + xText->setString( OUString() ); + uno::Reference< text::XTextRange > xRange( xText->createTextCursor(), uno::UNO_QUERY_THROW ); + xText->insertTextContent( xRange, xUrlField, sal_False ); + } + else + { + uno::Reference< msforms::XShape > xAnchorShape( rxAnchor, uno::UNO_QUERY_THROW ); + mnType = office::MsoHyperlinkType::msoHyperlinkShape; + // FIXME: insert hyperlink into shape + throw uno::RuntimeException(); + } } -void -ScVbaHyperlink::setAddress( const ::rtl::OUString & rAddress ) throw (css::uno::RuntimeException) +ScVbaHyperlink::~ScVbaHyperlink() { - uno::Any aValue; - aValue <<= rAddress; - mxTextField->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ), aValue ); } -::rtl::OUString -ScVbaHyperlink::getName() throw (css::uno::RuntimeException) +OUString ScVbaHyperlink::getName() throw (uno::RuntimeException) { // it seems this attribute is same as TextToDisplay return getTextToDisplay(); } -void -ScVbaHyperlink::setName( const ::rtl::OUString & rName ) throw (css::uno::RuntimeException) +void ScVbaHyperlink::setName( const OUString& rName ) throw (uno::RuntimeException) { setTextToDisplay( rName ); } -::rtl::OUString -ScVbaHyperlink::getTextToDisplay() throw (css::uno::RuntimeException) +OUString ScVbaHyperlink::getAddress() throw (uno::RuntimeException) { - rtl::OUString aTextToDisplay; - uno::Any aValue = mxTextField->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Representation" ) ) ); - aValue >>= aTextToDisplay; - return aTextToDisplay; + return getUrlComponents().first; +} + +void ScVbaHyperlink::setAddress( const OUString& rAddress ) throw (uno::RuntimeException) +{ + UrlComponents aUrlComp = getUrlComponents(); + aUrlComp.first = rAddress; + setUrlComponents( aUrlComp ); +} + +OUString ScVbaHyperlink::getSubAddress() throw (uno::RuntimeException) +{ + return getUrlComponents().second; +} + +void ScVbaHyperlink::setSubAddress( const OUString& rSubAddress ) throw (uno::RuntimeException) +{ + UrlComponents aUrlComp = getUrlComponents(); + aUrlComp.second = rSubAddress; + setUrlComponents( aUrlComp ); } -void -ScVbaHyperlink::setTextToDisplay( const ::rtl::OUString & rTextToDisplay ) throw (css::uno::RuntimeException) +OUString SAL_CALL ScVbaHyperlink::getScreenTip() throw (uno::RuntimeException) { - uno::Any aValue; - aValue <<= rTextToDisplay; - mxTextField->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Representation" ) ), aValue ); + return maScreenTip; } -css::uno::Reference< ov::excel::XRange > SAL_CALL ScVbaHyperlink::Range() throw (css::uno::RuntimeException) +void SAL_CALL ScVbaHyperlink::setScreenTip( const OUString& rScreenTip ) throw (uno::RuntimeException) { - uno::Reference< table::XCellRange > xRange( mxCell,uno::UNO_QUERY_THROW ); - // FIXME: need to pass current worksheet as the parent of XRange. - return uno::Reference< excel::XRange >( new ScVbaRange( uno::Reference< XHelperInterface > (), mxContext, xRange ) ); + maScreenTip = rScreenTip; } -rtl::OUString& -ScVbaHyperlink::getServiceImplName() +OUString ScVbaHyperlink::getTextToDisplay() throw (uno::RuntimeException) { - static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaHyperlink") ); - return sImplName; + ensureTextField(); + OUString aTextToDisplay; + mxTextField->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Representation" ) ) ) >>= aTextToDisplay; + return aTextToDisplay; +} + +void ScVbaHyperlink::setTextToDisplay( const OUString& rTextToDisplay ) throw (uno::RuntimeException) +{ + ensureTextField(); + mxTextField->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Representation" ) ), uno::Any( rTextToDisplay ) ); } -uno::Sequence< rtl::OUString > -ScVbaHyperlink::getServiceNames() +sal_Int32 SAL_CALL ScVbaHyperlink::getType() throw (uno::RuntimeException) { - static uno::Sequence< rtl::OUString > aServiceNames; - if ( aServiceNames.getLength() == 0 ) + return mnType; +} + +uno::Reference< excel::XRange > SAL_CALL ScVbaHyperlink::getRange() throw (uno::RuntimeException) +{ + if( mnType == office::MsoHyperlinkType::msoHyperlinkRange ) { - aServiceNames.realloc( 1 ); - aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Hyperlink" ) ); + // if constructed from Hyperlinks object, range has been passed as parent + uno::Reference< excel::XRange > xAnchorRange( getParent(), uno::UNO_QUERY ); + if( !xAnchorRange.is() ) + { + // if constructed via service c'tor, create new range based on cell + uno::Reference< table::XCellRange > xRange( mxCell, uno::UNO_QUERY_THROW ); + // FIXME: need to pass current worksheet as the parent of XRange. + xAnchorRange.set( new ScVbaRange( uno::Reference< XHelperInterface >(), mxContext, xRange ) ); + } + return xAnchorRange; } - return aServiceNames; + // error if called at a shape Hyperlink object + throw uno::RuntimeException(); +} + +uno::Reference< msforms::XShape > SAL_CALL ScVbaHyperlink::getShape() throw (uno::RuntimeException) +{ + // error if called at a range Hyperlink object + return uno::Reference< msforms::XShape >( getParent(), uno::UNO_QUERY_THROW ); +} + +VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaHyperlink, "ooo.vba.excel.Hyperlink" ) + +// private -------------------------------------------------------------------- + +void ScVbaHyperlink::ensureTextField() throw (uno::RuntimeException) +{ + if( !mxTextField.is() ) + throw uno::RuntimeException(); +} + +ScVbaHyperlink::UrlComponents ScVbaHyperlink::getUrlComponents() throw (uno::RuntimeException) +{ + ensureTextField(); + OUString aUrl; + mxTextField->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ) ) >>= aUrl; + sal_Int32 nHashPos = aUrl.indexOf( '#' ); + if( nHashPos < 0 ) + return UrlComponents( aUrl, OUString() ); + return UrlComponents( aUrl.copy( 0, nHashPos ), aUrl.copy( nHashPos + 1 ) ); +} + +void ScVbaHyperlink::setUrlComponents( const UrlComponents& rUrlComp ) throw (uno::RuntimeException) +{ + ensureTextField(); + OUStringBuffer aUrl( rUrlComp.first ); + if( rUrlComp.second.getLength() > 0 ) + aUrl.append( sal_Unicode( '#' ) ).append( rUrlComp.second ); + mxTextField->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ), uno::Any( aUrl.makeStringAndClear() ) ); } namespace hyperlink @@ -129,3 +242,5 @@ extern sdecl::ServiceDecl const serviceDecl( "ScVbaHyperlink", "ooo.vba.excel.Hyperlink" ); } + +// ============================================================================ diff --git a/sc/source/ui/vba/vbahyperlink.hxx b/sc/source/ui/vba/vbahyperlink.hxx index 570ecdcc2f45..e1520b59c15a 100644 --- a/sc/source/ui/vba/vbahyperlink.hxx +++ b/sc/source/ui/vba/vbahyperlink.hxx @@ -24,6 +24,7 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ + #ifndef SC_VBA_HYPERLINK_HXX #define SC_VBA_HYPERLINK_HXX @@ -38,27 +39,50 @@ typedef InheritedHelperInterfaceImpl1< ov::excel::XHyperlink > HyperlinkImpl_BAS class ScVbaHyperlink : public HyperlinkImpl_BASE { - css::uno::Reference< css::table::XCell > mxCell; - css::uno::Reference< css::beans::XPropertySet > mxTextField; - public: - ScVbaHyperlink( css::uno::Sequence< css::uno::Any > const& aArgs, css::uno::Reference< css::uno::XComponentContext > const& xContext ) throw ( css::lang::IllegalArgumentException ); + ScVbaHyperlink( + const css::uno::Sequence< css::uno::Any >& rArgs, + const css::uno::Reference< css::uno::XComponentContext >& rxContext ) throw (css::lang::IllegalArgumentException); + + ScVbaHyperlink( + const css::uno::Reference< ov::XHelperInterface >& rxAnchor, + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const css::uno::Any& rAddress, const css::uno::Any& rSubAddress, + const css::uno::Any& rScreenTip, const css::uno::Any& rTextToDisplay ) throw (css::uno::RuntimeException); + virtual ~ScVbaHyperlink(); // Attributes - virtual ::rtl::OUString SAL_CALL getAddress() throw (css::uno::RuntimeException); - virtual void SAL_CALL setAddress( const ::rtl::OUString &rAddress ) throw (css::uno::RuntimeException); virtual ::rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException); - virtual void SAL_CALL setName( const ::rtl::OUString &rName ) throw (css::uno::RuntimeException); + virtual void SAL_CALL setName( const ::rtl::OUString& rName ) throw (css::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getAddress() throw (css::uno::RuntimeException); + virtual void SAL_CALL setAddress( const ::rtl::OUString& rAddress ) throw (css::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getSubAddress() throw (css::uno::RuntimeException); + virtual void SAL_CALL setSubAddress( const ::rtl::OUString& rSubAddress ) throw (css::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getScreenTip() throw (css::uno::RuntimeException); + virtual void SAL_CALL setScreenTip( const ::rtl::OUString& rScreenTip ) throw (css::uno::RuntimeException); virtual ::rtl::OUString SAL_CALL getTextToDisplay() throw (css::uno::RuntimeException); - virtual void SAL_CALL setTextToDisplay( const ::rtl::OUString &rTextToDisplay ) throw (css::uno::RuntimeException); - - // Methods - virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Range() throw (css::uno::RuntimeException); + virtual void SAL_CALL setTextToDisplay( const ::rtl::OUString& rTextToDisplay ) throw (css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getType() throw (css::uno::RuntimeException); + virtual css::uno::Reference< ov::excel::XRange > SAL_CALL getRange() throw (css::uno::RuntimeException); + virtual css::uno::Reference< ov::msforms::XShape > SAL_CALL getShape() throw (css::uno::RuntimeException); // XHelperInterface - virtual rtl::OUString& getServiceImplName(); - virtual css::uno::Sequence<rtl::OUString> getServiceNames(); + VBAHELPER_DECL_XHELPERINTERFACE + +private: + typedef ::std::pair< ::rtl::OUString, ::rtl::OUString > UrlComponents; + + void ensureTextField() throw (css::uno::RuntimeException); + UrlComponents getUrlComponents() throw (css::uno::RuntimeException); + void setUrlComponents( const UrlComponents& rUrlComp ) throw (css::uno::RuntimeException); + +private: + css::uno::Reference< css::table::XCell > mxCell; + css::uno::Reference< css::beans::XPropertySet > mxTextField; + ::rtl::OUString maScreenTip; + long mnType; }; + #endif /* SC_VBA_HYPERLINK_HXX */ diff --git a/sc/source/ui/vba/vbainterior.cxx b/sc/source/ui/vba/vbainterior.cxx index 3af6243e0fa7..face47767bdc 100644 --- a/sc/source/ui/vba/vbainterior.cxx +++ b/sc/source/ui/vba/vbainterior.cxx @@ -40,10 +40,13 @@ #include <comphelper/processfactory.hxx> #include <cppuhelper/queryinterface.hxx> +#include <map> + #include <svx/xtable.hxx> #include "vbainterior.hxx" #include "vbapalette.hxx" +#include "document.hxx" #define STATIC_TABLE_SIZE( array ) (sizeof(array)/sizeof(*(array))) #define COLORMAST 0xFFFFFF diff --git a/sc/source/ui/vba/vbainterior.hxx b/sc/source/ui/vba/vbainterior.hxx index f0d4db1334fd..027d06040af9 100644 --- a/sc/source/ui/vba/vbainterior.hxx +++ b/sc/source/ui/vba/vbainterior.hxx @@ -36,6 +36,8 @@ #include <com/sun/star/script/XInvocation.hpp> #include <vbahelper/vbahelperinterface.hxx> +#include <tools/color.hxx> + class ScDocument; typedef InheritedHelperInterfaceImpl1< ov::excel::XInterior > ScVbaInterior_BASE; diff --git a/sc/source/ui/vba/vbaname.cxx b/sc/source/ui/vba/vbaname.cxx index bc0b016177c7..a6e8a402425f 100644 --- a/sc/source/ui/vba/vbaname.cxx +++ b/sc/source/ui/vba/vbaname.cxx @@ -232,7 +232,10 @@ ScVbaName::setRefersToR1C1Local( const ::rtl::OUString & rRefersTo ) throw (css: css::uno::Reference< ov::excel::XRange > ScVbaName::getRefersToRange() throw (css::uno::RuntimeException) { - uno::Reference< ov::excel::XRange > xRange = ScVbaRange::getRangeObjectForName( mxContext, mxNamedRange->getName(), excel::getDocShell( mxModel ), formula::FormulaGrammar::CONV_XL_R1C1 ); + // FIXME: pass proper Worksheet parent + uno::Reference< ov::excel::XRange > xRange = ScVbaRange::getRangeObjectForName( + uno::Reference< XHelperInterface >(), mxContext, + mxNamedRange->getName(), excel::getDocShell( mxModel ), formula::FormulaGrammar::CONV_XL_R1C1 ); return xRange; } diff --git a/sc/source/ui/vba/vbapalette.cxx b/sc/source/ui/vba/vbapalette.cxx index 0ce55547d4a1..c6ae5c488a20 100644 --- a/sc/source/ui/vba/vbapalette.cxx +++ b/sc/source/ui/vba/vbapalette.cxx @@ -24,10 +24,12 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ + #include "vbapalette.hxx" #include <cppuhelper/implbase1.hxx> #include <com/sun/star/beans/XPropertySet.hpp> - +#include <com/sun/star/container/XIndexAccess.hpp> +#include "excelvbahelper.hxx" using namespace ::com::sun::star; using namespace ::ooo::vba; @@ -82,6 +84,11 @@ public: }; +ScVbaPalette::ScVbaPalette( const uno::Reference< frame::XModel >& rxModel ) : + m_pShell( excel::getDocShell( rxModel ) ) +{ +} + uno::Reference< container::XIndexAccess > ScVbaPalette::getDefaultPalette() { diff --git a/sc/source/ui/vba/vbapalette.hxx b/sc/source/ui/vba/vbapalette.hxx index 9c7ea2ebc3f1..b51483772674 100644 --- a/sc/source/ui/vba/vbapalette.hxx +++ b/sc/source/ui/vba/vbapalette.hxx @@ -24,19 +24,26 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ + #ifndef SC_VBAPALETTE_HXX #define SC_VBAPALETTE_HXX -#include "excelvbahelper.hxx" -#include <document.hxx> -#include <com/sun/star/container/XIndexAccess.hpp> +#include <vbahelper/vbahelper.hxx> + +namespace com { namespace sun { namespace star { + namespace container { class XIndexAccess; } + namespace frame { class XModel; } +} } } + +class SfxObjectShell; class ScVbaPalette { private: SfxObjectShell* m_pShell; public: - ScVbaPalette( SfxObjectShell* pShell = NULL ) : m_pShell( pShell ){} + ScVbaPalette( SfxObjectShell* pShell = 0 ) : m_pShell( pShell ) {} + ScVbaPalette( const css::uno::Reference< css::frame::XModel >& rxModel ); // if no palette available e.g. because the document doesn't have a // palette defined then a default palette will be returned. css::uno::Reference< css::container::XIndexAccess > getPalette() const; diff --git a/sc/source/ui/vba/vbapane.cxx b/sc/source/ui/vba/vbapane.cxx index 263529dde145..e1c6cd64dc92 100644 --- a/sc/source/ui/vba/vbapane.cxx +++ b/sc/source/ui/vba/vbapane.cxx @@ -24,18 +24,26 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ -#include<com/sun/star/table/CellRangeAddress.hpp> -#include<vbapane.hxx> + +#include "vbapane.hxx" +#include <com/sun/star/sheet/XSpreadsheet.hpp> +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> +#include <com/sun/star/table/CellRangeAddress.hpp> +#include "vbarange.hxx" using namespace com::sun::star; using namespace ooo::vba; -/* -ScVbaPane::ScVbaPane( uno::Reference< uno::XComponentContext > xContext, uno::Refrence< sheet::XViewPane > xViewPane ) - : m_xContext( xContext ), m_xViewPane( xViewPane ) +ScVbaPane::ScVbaPane( + const css::uno::Reference< ov::XHelperInterface >& xParent, + const uno::Reference< uno::XComponentContext >& xContext, + const uno::Reference< frame::XModel >& xModel, + const uno::Reference< sheet::XViewPane > xViewPane ) : + ScVbaPane_BASE( xParent, xContext ), + m_xModel( xModel, uno::UNO_SET_THROW ), + m_xViewPane( xViewPane, uno::UNO_SET_THROW ) { } -*/ sal_Int32 SAL_CALL ScVbaPane::getScrollColumn() throw (uno::RuntimeException) @@ -71,6 +79,19 @@ ScVbaPane::setScrollRow( sal_Int32 _scrollrow ) throw (uno::RuntimeException) m_xViewPane->setFirstVisibleRow( _scrollrow - 1 ); } +uno::Reference< excel::XRange > SAL_CALL +ScVbaPane::getVisibleRange() throw (uno::RuntimeException) +{ + // TODO: Excel includes partly visible rows/columns, Calc does not + table::CellRangeAddress aRangeAddr = m_xViewPane->getVisibleRange(); + uno::Reference< sheet::XSpreadsheetDocument > xDoc( m_xModel, uno::UNO_QUERY_THROW ); + uno::Reference< container::XIndexAccess > xSheetsIA( xDoc->getSheets(), uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XSpreadsheet > xSheet( xSheetsIA->getByIndex( aRangeAddr.Sheet ), uno::UNO_QUERY_THROW ); + uno::Reference< table::XCellRange > xRange( xSheet->getCellRangeByPosition( aRangeAddr.StartColumn, aRangeAddr.StartRow, aRangeAddr.EndColumn, aRangeAddr.EndRow ), uno::UNO_SET_THROW ); + // TODO: getParent() returns the window, Range needs the worksheet + return new ScVbaRange( getParent(), mxContext, xRange ); +} + //Method void SAL_CALL ScVbaPane::SmallScroll( const uno::Any& Down, const uno::Any& Up, const uno::Any& ToRight, const uno::Any& ToLeft ) throw (uno::RuntimeException) @@ -83,54 +104,34 @@ ScVbaPane::SmallScroll( const uno::Any& Down, const uno::Any& Up, const uno::Any if( Down.hasValue() ) { sal_Int32 down = 0; - try - { - Down >>= down; + if( Down >>= down ) downRows += down; - } - catch ( uno::Exception ) - { + else messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: Down\n" ); - } } if( Up.hasValue() ) { sal_Int32 up = 0; - try - { - Up >>= up; + if( Up >>= up ) downRows -= up; - } - catch ( uno::Exception ) - { + else messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: Up\n" ); - } } if( ToRight.hasValue() ) { sal_Int32 right = 0; - try - { - ToRight >>= right; + if( ToRight >>= right ) rightCols += right; - } - catch ( uno::Exception ) - { + else messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: ToRight\n" ); - } } if( ToLeft.hasValue() ) { sal_Int32 left = 0; - try - { - ToLeft >>= left; + if( ToLeft >>= left ) rightCols -= left; - } - catch ( uno::Exception ) - { + else messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: ToLeft\n" ); - } } if( messageBuffer.getLength() > 0 ) throw(uno::RuntimeException( messageBuffer, uno::Reference< uno::XInterface >() ) ); @@ -158,56 +159,35 @@ ScVbaPane::LargeScroll( const uno::Any& Down, const uno::Any& Up, const uno::Any if( Down.hasValue() ) { sal_Int32 down = 0; - try - { - Down >>= down; + if( Down >>= down ) downPages += down; - } - catch ( uno::Exception ) - { + else messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: Down\n" ); - } } if( Up.hasValue() ) { sal_Int32 up = 0; - try - { - Up >>= up; + if( Up >>= up ) downPages -= up; - } - catch ( uno::Exception ) - { + else messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: Up\n" ); - } } if( ToRight.hasValue() ) { sal_Int32 right = 0; - try - { - ToRight >>= right; + if( ToRight >>= right ) acrossPages += right; - } - catch ( uno::Exception ) - { + else messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: ToRight\n" ); - } } if( ToLeft.hasValue() ) { sal_Int32 left = 0; - try - { - ToLeft >>= left; + if( ToLeft >>= left ) acrossPages -= left; - } - catch ( uno::Exception ) - { + else messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: ToLeft\n" ); - } } - if( messageBuffer.getLength() > 0 ) throw(uno::RuntimeException( messageBuffer, uno::Reference< uno::XInterface >() ) ); @@ -220,3 +200,7 @@ ScVbaPane::LargeScroll( const uno::Any& Down, const uno::Any& Up, const uno::Any m_xViewPane->setFirstVisibleRow( newStartRow ); m_xViewPane->setFirstVisibleColumn( newStartCol ); } + +// XHelperInterface + +VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaPane, "ooo.vba.excel.Pane" ) diff --git a/sc/source/ui/vba/vbapane.hxx b/sc/source/ui/vba/vbapane.hxx index 0fa1d49709de..ff87a9966d80 100644 --- a/sc/source/ui/vba/vbapane.hxx +++ b/sc/source/ui/vba/vbapane.hxx @@ -27,34 +27,41 @@ #ifndef SC_VBA_PANE_HXX #define SC_VBA_PANE_HXX -#include<cppuhelper/implbase1.hxx> -#include<com/sun/star/sheet/XViewPane.hpp> -#include<ooo/vba/excel/XPane.hpp> +#include <com/sun/star/sheet/XViewPane.hpp> +#include <ooo/vba/excel/XPane.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include "excelvbahelper.hxx" -#include"excelvbahelper.hxx" +typedef InheritedHelperInterfaceImpl1< ov::excel::XPane > ScVbaPane_BASE; -typedef cppu::WeakImplHelper1< ov::excel::XPane > PaneImpl_Base; - -class ScVbaPane : public PaneImpl_Base +class ScVbaPane : public ScVbaPane_BASE { -protected: - css::uno::Reference< css::uno::XComponentContext > m_xContext; - css::uno::Reference< css::sheet::XViewPane > m_xViewPane; public: - ScVbaPane( const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::sheet::XViewPane > xViewPane ) : m_xContext( xContext ), m_xViewPane( xViewPane ) {} + ScVbaPane( + const css::uno::Reference< ov::XHelperInterface >& xParent, + const css::uno::Reference< css::uno::XComponentContext >& xContext, + const css::uno::Reference< css::frame::XModel >& xModel, + const css::uno::Reference< css::sheet::XViewPane > xViewPane ) throw (css::uno::RuntimeException); css::uno::Reference< css::sheet::XViewPane > getViewPane() { return m_xViewPane; } - //Attribute + // XPane attributes virtual sal_Int32 SAL_CALL getScrollColumn() throw (css::uno::RuntimeException); virtual void SAL_CALL setScrollColumn( sal_Int32 _scrollcolumn ) throw (css::uno::RuntimeException); virtual sal_Int32 SAL_CALL getScrollRow() throw (css::uno::RuntimeException); virtual void SAL_CALL setScrollRow( sal_Int32 _scrollrow ) throw (css::uno::RuntimeException); + virtual css::uno::Reference< ov::excel::XRange > SAL_CALL getVisibleRange() throw (css::uno::RuntimeException); - //Method + // XPane methods virtual void SAL_CALL SmallScroll( const css::uno::Any& Down, const css::uno::Any& Up, const css::uno::Any& ToRight, const css::uno::Any& ToLeft ) throw (css::uno::RuntimeException); virtual void SAL_CALL LargeScroll( const css::uno::Any& Down, const css::uno::Any& Up, const css::uno::Any& ToRight, const css::uno::Any& ToLeft ) throw (css::uno::RuntimeException); + // XHelperInterface + VBAHELPER_DECL_XHELPERINTERFACE + +protected: + css::uno::Reference< css::frame::XModel > m_xModel; + css::uno::Reference< css::sheet::XViewPane > m_xViewPane; }; -#endif//SC_VBA_PANE_HXX +#endif //SC_VBA_PANE_HXX diff --git a/sc/source/ui/vba/vbarange.cxx b/sc/source/ui/vba/vbarange.cxx index 1a153b440b15..71d29734fc76 100644 --- a/sc/source/ui/vba/vbarange.cxx +++ b/sc/source/ui/vba/vbarange.cxx @@ -81,6 +81,7 @@ #include <com/sun/star/sheet/XSheetFilterable.hpp> #include <com/sun/star/sheet/FilterConnection.hpp> #include <com/sun/star/util/CellProtection.hpp> +#include <com/sun/star/util/TriState.hpp> #include <com/sun/star/style/XStyleFamiliesSupplier.hpp> #include <com/sun/star/awt/XDevice.hpp> @@ -141,6 +142,7 @@ #include "vbaborders.hxx" #include "vbaworksheet.hxx" #include "vbavalidation.hxx" +#include "vbahyperlinks.hxx" #include "tabvwsh.hxx" #include "rangelst.hxx" @@ -367,7 +369,7 @@ ScVbaRangeAreas::createCollectionObject( const uno::Any& aSource ) ScDocShell* getDocShellFromIf( const uno::Reference< uno::XInterface >& xIf ) throw ( uno::RuntimeException ) { - ScCellRangesBase* pUno= dynamic_cast< ScCellRangesBase* >( xIf.get() ); + ScCellRangesBase* pUno = ScCellRangesBase::getImplementation( xIf ); if ( !pUno ) throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to access underlying uno range object" ) ), uno::Reference< uno::XInterface >() ); return pUno->GetDocShell(); @@ -381,6 +383,14 @@ getDocShellFromRange( const uno::Reference< table::XCellRange >& xRange ) throw return getDocShellFromIf(xIf ); } +ScDocShell* +getDocShellFromRanges( const uno::Reference< sheet::XSheetCellRangeContainer >& xRanges ) throw ( uno::RuntimeException ) +{ + // need the ScCellRangesBase to get docshell + uno::Reference< uno::XInterface > xIf( xRanges, uno::UNO_QUERY_THROW ); + return getDocShellFromIf(xIf ); +} + uno::Reference< frame::XModel > getModelFromXIf( const uno::Reference< uno::XInterface >& xIf ) throw ( uno::RuntimeException ) { ScDocShell* pDocShell = getDocShellFromIf(xIf ); @@ -405,7 +415,7 @@ getDocumentFromRange( const uno::Reference< table::XCellRange >& xRange ) ScDocument* -ScVbaRange::getScDocument() +ScVbaRange::getScDocument() throw (uno::RuntimeException) { if ( mxRanges.is() ) { @@ -417,7 +427,7 @@ ScVbaRange::getScDocument() } ScDocShell* -ScVbaRange::getScDocShell() +ScVbaRange::getScDocShell() throw (uno::RuntimeException) { if ( mxRanges.is() ) { @@ -428,6 +438,41 @@ ScVbaRange::getScDocShell() return getDocShellFromRange( mxRange ); } +/*static*/ ScVbaRange* ScVbaRange::getImplementation( const uno::Reference< excel::XRange >& rxRange ) +{ + // FIXME: always save to use dynamic_cast? Or better to (implement and) use XTunnel? + return dynamic_cast< ScVbaRange* >( rxRange.get() ); +} + +uno::Reference< frame::XModel > ScVbaRange::getUnoModel() throw (uno::RuntimeException) +{ + if( ScDocShell* pDocShell = getScDocShell() ) + return pDocShell->GetModel(); + throw uno::RuntimeException(); +} + +/*static*/ uno::Reference< frame::XModel > ScVbaRange::getUnoModel( const uno::Reference< excel::XRange >& rxRange ) throw (uno::RuntimeException) +{ + if( ScVbaRange* pScVbaRange = getImplementation( rxRange ) ) + return pScVbaRange->getUnoModel(); + throw uno::RuntimeException(); +} + +const ScRangeList& ScVbaRange::getScRangeList() throw (uno::RuntimeException) +{ + if( ScCellRangesBase* pScRangesBase = getCellRangesBase() ) + return pScRangesBase->GetRangeList(); + throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Cannot obtain UNO range implementation object" ) ), uno::Reference< uno::XInterface >() ); +} + +/*static*/ const ScRangeList& ScVbaRange::getScRangeList( const uno::Reference< excel::XRange >& rxRange ) throw (uno::RuntimeException) +{ + if( ScVbaRange* pScVbaRange = getImplementation( rxRange ) ) + return pScVbaRange->getScRangeList(); + throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Cannot obtain VBA range implementation object" ) ), uno::Reference< uno::XInterface >() ); +} + + class NumFormatHelper { uno::Reference< util::XNumberFormatsSupplier > mxSupplier; @@ -472,7 +517,7 @@ public: rtl::OUString getNumberFormatString() { uno::Reference< uno::XInterface > xIf( mxRangeProps, uno::UNO_QUERY_THROW ); - ScCellRangeObj* pUnoCellRange = dynamic_cast< ScCellRangeObj* >( xIf.get() ); + ScCellRangesBase* pUnoCellRange = ScCellRangesBase::getImplementation( xIf ); if ( pUnoCellRange ) { @@ -577,20 +622,17 @@ class CellsEnumeration : public CellsEnumeration_BASE uno::Reference< XCollection > m_xAreas; vCellPos m_CellPositions; vCellPos::const_iterator m_it; + uno::Reference< table::XCellRange > getArea( sal_Int32 nVBAIndex ) throw ( uno::RuntimeException ) { if ( nVBAIndex < 1 || nVBAIndex > m_xAreas->getCount() ) throw uno::RuntimeException(); uno::Reference< excel::XRange > xRange( m_xAreas->Item( uno::makeAny(nVBAIndex), uno::Any() ), uno::UNO_QUERY_THROW ); - ScVbaRange* pRange = dynamic_cast< ScVbaRange* >( xRange.get() ); - uno::Reference< table::XCellRange > xCellRange; - if ( !pRange ) - throw uno::RuntimeException(); - xCellRange.set( pRange->getCellRange(), uno::UNO_QUERY_THROW );; + uno::Reference< table::XCellRange > xCellRange( ScVbaRange::getCellRange( xRange ), uno::UNO_QUERY_THROW ); return xCellRange; - } - void populateArea( sal_Int32 nVBAIndex ) + + void populateArea( sal_Int32 nVBAIndex ) { uno::Reference< table::XCellRange > xRange = getArea( nVBAIndex ); uno::Reference< table::XColumnRowRange > xColumnRowRange(xRange, uno::UNO_QUERY_THROW ); @@ -1136,7 +1178,7 @@ bool getScRangeListForAddress( const rtl::OUString& sName, ScDocShell* pDocSh, S ScVbaRange* -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 ) +getRangeForName( const uno::Reference< XHelperInterface >& xParent, 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 ) { ScRangeList aCellRanges; ScRange refRange; @@ -1147,20 +1189,107 @@ getRangeForName( const uno::Reference< uno::XComponentContext >& xContext, const if ( aCellRanges.First() == aCellRanges.Last() ) { uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pDocSh, *aCellRanges.First() ) ); - // #FIXME need proper (WorkSheet) parent - return new ScVbaRange( uno::Reference< XHelperInterface >(), xContext, xRange ); + return new ScVbaRange( xParent, xContext, xRange ); } uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDocSh, aCellRanges ) ); + return new ScVbaRange( xParent, xContext, xRanges ); +} - // #FIXME need proper (WorkSheet) parent - return new ScVbaRange( uno::Reference< XHelperInterface >(), xContext, xRanges ); +// ---------------------------------------------------------------------------- + +namespace { + +template< typename RangeType > +inline table::CellRangeAddress lclGetRangeAddress( const uno::Reference< RangeType >& rxCellRange ) throw (uno::RuntimeException) +{ + return uno::Reference< sheet::XCellRangeAddressable >( rxCellRange, uno::UNO_QUERY_THROW )->getRangeAddress(); +} + +uno::Reference< sheet::XSheetCellRange > lclExpandToMerged( const uno::Reference< table::XCellRange >& rxCellRange, bool bRecursive ) throw (uno::RuntimeException) +{ + uno::Reference< sheet::XSheetCellRange > xNewCellRange( rxCellRange, uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XSpreadsheet > xSheet( xNewCellRange->getSpreadsheet(), uno::UNO_SET_THROW ); + table::CellRangeAddress aNewAddress = lclGetRangeAddress( xNewCellRange ); + table::CellRangeAddress aOldAddress; + // expand as long as there are new merged ranges included + do + { + aOldAddress = aNewAddress; + uno::Reference< sheet::XSheetCellCursor > xCursor( xSheet->createCursorByRange( xNewCellRange ), uno::UNO_SET_THROW ); + xCursor->collapseToMergedArea(); + xNewCellRange.set( xCursor, uno::UNO_QUERY_THROW ); + aNewAddress = lclGetRangeAddress( xNewCellRange ); + } + while( bRecursive && (aOldAddress != aNewAddress) ); + return xNewCellRange; } +uno::Reference< sheet::XSheetCellRangeContainer > lclExpandToMerged( const uno::Reference< sheet::XSheetCellRangeContainer >& rxCellRanges, bool bRecursive ) throw (uno::RuntimeException) +{ + if( !rxCellRanges.is() ) + throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Missing cell ranges object" ) ), uno::Reference< uno::XInterface >() ); + sal_Int32 nCount = rxCellRanges->getCount(); + if( nCount < 1 ) + throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Missing cell ranges object" ) ), uno::Reference< uno::XInterface >() ); + + ScRangeList aScRanges; + for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex ) + { + uno::Reference< table::XCellRange > xRange( rxCellRanges->getByIndex( nIndex ), uno::UNO_QUERY_THROW ); + table::CellRangeAddress aRangeAddr = lclGetRangeAddress( lclExpandToMerged( xRange, bRecursive ) ); + ScRange aScRange; + ScUnoConversion::FillScRange( aScRange, aRangeAddr ); + aScRanges.Append( aScRange ); + } + return new ScCellRangesObj( getDocShellFromRanges( rxCellRanges ), aScRanges ); +} + +void lclExpandAndMerge( const uno::Reference< table::XCellRange >& rxCellRange, bool bMerge ) throw (uno::RuntimeException) +{ + uno::Reference< util::XMergeable > xMerge( lclExpandToMerged( rxCellRange, true ), uno::UNO_QUERY_THROW ); + // Calc cannot merge over merged ranges, always unmerge first + xMerge->merge( sal_False ); + if( bMerge ) + xMerge->merge( sal_True ); + // FIXME need to check whether all the cell contents are retained or lost by popping up a dialog +} + +util::TriState lclGetMergedState( const uno::Reference< table::XCellRange >& rxCellRange ) throw (uno::RuntimeException) +{ + /* 1) Check if range is completely inside one single merged range. To do + this, try to extend from top-left cell only (not from entire range). + This will excude cases where this range consists of several merged + ranges (or parts of them). */ + table::CellRangeAddress aRangeAddr = lclGetRangeAddress( rxCellRange ); + uno::Reference< table::XCellRange > xTopLeft( rxCellRange->getCellRangeByPosition( 0, 0, 0, 0 ), uno::UNO_SET_THROW ); + uno::Reference< sheet::XSheetCellRange > xExpanded( lclExpandToMerged( xTopLeft, false ), uno::UNO_SET_THROW ); + table::CellRangeAddress aExpAddr = lclGetRangeAddress( xExpanded ); + // check that expanded range has more than one cell (really merged) + if( ((aExpAddr.StartColumn < aExpAddr.EndColumn) || (aExpAddr.StartRow < aExpAddr.EndRow)) && ScUnoConversion::Contains( aExpAddr, aRangeAddr ) ) + return util::TriState_YES; + + /* 2) Check if this range contains any merged cells (completely or + partly). This seems to be hardly possible via API, as + XMergeable::getIsMerged() returns only true, if the top-left cell of a + merged range is part of this range, so cases where just the lower part + of a merged range is part of this range are not covered. */ + ScRange aScRange; + ScUnoConversion::FillScRange( aScRange, aRangeAddr ); + bool bHasMerged = getDocumentFromRange( rxCellRange )->HasAttrib( aScRange, HASATTR_MERGED | HASATTR_OVERLAPPED ); + return bHasMerged ? util::TriState_INDETERMINATE : util::TriState_NO; +} + +} // namespace + +// ---------------------------------------------------------------------------- + css::uno::Reference< excel::XRange > -ScVbaRange::getRangeObjectForName( const uno::Reference< uno::XComponentContext >& xContext, const rtl::OUString& sRangeName, ScDocShell* pDocSh, formula::FormulaGrammar::AddressConvention eConv ) throw ( uno::RuntimeException ) +ScVbaRange::getRangeObjectForName( const css::uno::Reference< ov::XHelperInterface >& xParent, + const uno::Reference< uno::XComponentContext >& xContext, const rtl::OUString& sRangeName, + ScDocShell* pDocSh, formula::FormulaGrammar::AddressConvention eConv ) throw ( uno::RuntimeException ) { table::CellRangeAddress refAddr; - return getRangeForName( xContext, sRangeName, pDocSh, refAddr, eConv ); + return getRangeForName( xParent, xContext, sRangeName, pDocSh, refAddr, eConv ); } @@ -1196,9 +1325,7 @@ table::CellRangeAddress getCellRangeAddressForVBARange( const uno::Any& aParam, default: throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Can't extact CellRangeAddress from type" ) ), uno::Reference< uno::XInterface >() ); } - uno::Reference< sheet::XCellRangeAddressable > xAddressable( xRangeParam, uno::UNO_QUERY_THROW ); - return xAddressable->getRangeAddress(); - + return lclGetRangeAddress( xRangeParam ); } uno::Reference< XCollection > @@ -1398,7 +1525,7 @@ ScVbaRange::ClearContents( sal_Int32 nFlags ) throw (uno::RuntimeException) for ( sal_Int32 index=1; index <= nItems; ++index ) { uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW ); - ScVbaRange* pRange = dynamic_cast< ScVbaRange* >( xRange.get() ); + ScVbaRange* pRange = getImplementation( xRange ); if ( pRange ) pRange->ClearContents( nFlags ); } @@ -1595,7 +1722,7 @@ ScVbaRange::fillSeries( sheet::FillDirection nFillDirection, sheet::FillMode nFi for ( sal_Int32 index = 1; index <= xCollection->getCount(); ++index ) { uno::Reference< excel::XRange > xRange( xCollection->Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW ); - ScVbaRange* pThisRange = dynamic_cast< ScVbaRange* >( xRange.get() ); + ScVbaRange* pThisRange = getImplementation( xRange ); pThisRange->fillSeries( nFillDirection, nFillMode, nFillDateMode, fStep, fEndValue ); } @@ -1975,9 +2102,9 @@ ScVbaRange::Select() throw (uno::RuntimeException) uno::Reference< frame::XModel > xModel( pShell->GetModel(), uno::UNO_QUERY_THROW ); uno::Reference< view::XSelectionSupplier > xSelection( xModel->getCurrentController(), uno::UNO_QUERY_THROW ); if ( mxRanges.is() ) - xSelection->select( uno::makeAny( mxRanges ) ); + xSelection->select( uno::Any( lclExpandToMerged( mxRanges, true ) ) ); else - xSelection->select( uno::makeAny( mxRange ) ); + xSelection->select( uno::Any( lclExpandToMerged( mxRange, true ) ) ); // set focus on document e.g. // ThisComponent.CurrentController.Frame.getContainerWindow.SetFocus try @@ -1990,7 +2117,6 @@ ScVbaRange::Select() throw (uno::RuntimeException) catch( uno::Exception& ) { } - } } @@ -2168,36 +2294,65 @@ ScVbaRange::Columns(const uno::Any& aIndex ) throw (uno::RuntimeException) void ScVbaRange::setMergeCells( const uno::Any& aIsMerged ) throw (script::BasicErrorException, uno::RuntimeException) { - sal_Bool bIsMerged = sal_False; - aIsMerged >>= bIsMerged; - uno::Reference< util::XMergeable > xMerge( mxRange, ::uno::UNO_QUERY_THROW ); - //FIXME need to check whether all the cell contents are retained or lost by popping up a dialog - xMerge->merge( bIsMerged ); + bool bMerge = false; + aIsMerged >>= bMerge; + + if( mxRanges.is() ) + { + sal_Int32 nCount = mxRanges->getCount(); + + // VBA does nothing (no error) if the own ranges overlap somehow + ::std::vector< table::CellRangeAddress > aList; + for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex ) + { + uno::Reference< sheet::XCellRangeAddressable > xRangeAddr( mxRanges->getByIndex( nIndex ), uno::UNO_QUERY_THROW ); + table::CellRangeAddress aAddress = xRangeAddr->getRangeAddress(); + for( ::std::vector< table::CellRangeAddress >::const_iterator aIt = aList.begin(), aEnd = aList.end(); aIt != aEnd; ++aIt ) + if( ScUnoConversion::Intersects( *aIt, aAddress ) ) + return; + aList.push_back( aAddress ); + } + + // (un)merge every range after it has been extended to intersecting merged ranges from sheet + for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex ) + { + uno::Reference< table::XCellRange > xRange( mxRanges->getByIndex( nIndex ), uno::UNO_QUERY_THROW ); + lclExpandAndMerge( xRange, bMerge ); + } + return; + } + + // otherwise, merge single range + lclExpandAndMerge( mxRange, bMerge ); } uno::Any ScVbaRange::getMergeCells() throw (script::BasicErrorException, uno::RuntimeException) { - sal_Int32 nItems = m_Areas->getCount(); - - if ( nItems > 1 ) + if( mxRanges.is() ) { - uno::Any aResult = aNULL(); - for ( sal_Int32 index=1; index != nItems; ++index ) + sal_Int32 nCount = mxRanges->getCount(); + for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex ) { - uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW ); - if ( index > 1 ) - if ( aResult != xRange->getMergeCells() ) - return aNULL(); - aResult = xRange->getMergeCells(); - if ( aNULL() == aResult ) + uno::Reference< table::XCellRange > xRange( mxRanges->getByIndex( nIndex ), uno::UNO_QUERY_THROW ); + util::TriState eMerged = lclGetMergedState( xRange ); + /* Excel always returns NULL, if one range of the range list is + partly or completely merged. Even if all ranges are completely + merged, the return value is still NULL. */ + if( eMerged != util::TriState_NO ) return aNULL(); } - return aResult; + // no range is merged anyhow, return false + return uno::Any( false ); + } + // otherwise, check single range + switch( lclGetMergedState( mxRange ) ) + { + case util::TriState_YES: return uno::Any( true ); + case util::TriState_NO: return uno::Any( false ); + default: return aNULL(); } - uno::Reference< util::XMergeable > xMerge( mxRange, ::uno::UNO_QUERY_THROW ); - return uno::makeAny( xMerge->getIsMerged() ); } void @@ -2425,7 +2580,7 @@ ScVbaRange::Range( const uno::Any &Cell1, const uno::Any &Cell2, bool bForceUseI Cell1 >>= sName; RangeHelper referRange( xReferrer ); table::CellRangeAddress referAddress = referRange.getCellRangeAddressable()->getRangeAddress(); - return getRangeForName( mxContext, sName, getScDocShell(), referAddress ); + return getRangeForName( getParent(), mxContext, sName, getScDocShell(), referAddress ); } else @@ -2488,8 +2643,7 @@ ScVbaRange::Range( const uno::Any &Cell1, const uno::Any &Cell2, bool bForceUseI // Allow access to underlying openoffice uno api ( useful for debugging // with openoffice basic ) -::com::sun::star::uno::Any SAL_CALL -ScVbaRange::getCellRange( ) throw (::com::sun::star::uno::RuntimeException) +uno::Any SAL_CALL ScVbaRange::getCellRange( ) throw (uno::RuntimeException) { uno::Any aAny; if ( mxRanges.is() ) @@ -2499,6 +2653,13 @@ ScVbaRange::getCellRange( ) throw (::com::sun::star::uno::RuntimeException) return aAny; } +/*static*/ uno::Any ScVbaRange::getCellRange( const uno::Reference< excel::XRange >& rxRange ) throw (uno::RuntimeException) +{ + if( ScVbaRange* pVbaRange = getImplementation( rxRange ) ) + return pVbaRange->getCellRange(); + throw uno::RuntimeException(); +} + static USHORT getPasteFlags (sal_Int32 Paste) { @@ -2632,14 +2793,25 @@ ScVbaRange::getEntireColumn() throw (uno::RuntimeException) uno::Reference< excel::XComment > SAL_CALL ScVbaRange::AddComment( const uno::Any& Text ) throw (uno::RuntimeException) { + // if there is already a comment in the top-left cell then throw + if( getComment().is() ) + throw uno::RuntimeException(); - uno::Reference< excel::XComment > xComment( new ScVbaComment( this, mxContext, mxRange ) ); - // if you don't pass a valid text or if there is already a comment - // associated with the range then return NULL - if ( !xComment->Text( Text, uno::Any(), uno::Any() ).getLength() - || xComment->Text( uno::Any(), uno::Any(), uno::Any() ).getLength() ) - return NULL; - return xComment; + // workaround: Excel allows to create empty comment, Calc does not + ::rtl::OUString aNoteText; + if( Text.hasValue() && !(Text >>= aNoteText) ) + throw uno::RuntimeException(); + if( aNoteText.getLength() == 0 ) + aNoteText = ::rtl::OUString( sal_Unicode( ' ' ) ); + + // try to create a new annotation + table::CellRangeAddress aRangePos = lclGetRangeAddress( mxRange ); + table::CellAddress aNotePos( aRangePos.Sheet, aRangePos.StartColumn, aRangePos.StartRow ); + uno::Reference< sheet::XSheetCellRange > xCellRange( mxRange, uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XSheetAnnotationsSupplier > xAnnosSupp( xCellRange->getSpreadsheet(), uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XSheetAnnotations > xAnnos( xAnnosSupp->getAnnotations(), uno::UNO_SET_THROW ); + xAnnos->insertNew( aNotePos, aNoteText ); + return new ScVbaComment( this, mxContext, getUnoModel(), mxRange ); } uno::Reference< excel::XComment > SAL_CALL @@ -2647,7 +2819,7 @@ ScVbaRange::getComment() throw (uno::RuntimeException) { // intentional behavior to return a null object if no // comment defined - uno::Reference< excel::XComment > xComment( new ScVbaComment( this, mxContext, mxRange ) ); + uno::Reference< excel::XComment > xComment( new ScVbaComment( this, mxContext, getUnoModel(), mxRange ) ); if ( !xComment->Text( uno::Any(), uno::Any(), uno::Any() ).getLength() ) return NULL; return xComment; @@ -2976,7 +3148,7 @@ uno::Reference< table::XCellRange > processKey( const uno::Any& Key, uno::Refere table::CellRangeAddress aRefAddr; if ( !pDocSh ) throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Range::Sort no docshell to calculate key param")), uno::Reference< uno::XInterface >() ); - xKeyRange = getRangeForName( xContext, sRangeName, pDocSh, aRefAddr ); + xKeyRange = getRangeForName( uno::Reference< XHelperInterface >(), xContext, sRangeName, pDocSh, aRefAddr ); } else throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Range::Sort illegal type value for key param")), uno::Reference< uno::XInterface >() ); @@ -4147,7 +4319,7 @@ ScVbaRange::AutoFilter( const uno::Any& Field, const uno::Any& Criteria1, const uno::Reference< excel::XRange > xCurrent( CurrentRegion() ); if ( xCurrent.is() ) { - ScVbaRange* pRange = dynamic_cast< ScVbaRange* >( xCurrent.get() ); + ScVbaRange* pRange = getImplementation( xCurrent ); if ( pRange->isSingleCellRange() ) throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Can't create AutoFilter") ), uno::Reference< uno::XInterface >() ); if ( pRange ) @@ -4569,6 +4741,27 @@ ScVbaRange::TextToColumns( const css::uno::Any& Destination, const css::uno::Any //TODO* TrailingMinusNumbers Optional Variant. Numbers that begin with a minus character. } +uno::Any SAL_CALL +ScVbaRange::Hyperlinks( const uno::Any& aIndex ) throw (uno::RuntimeException) +{ + /* The range object always returns a new Hyperlinks object containing a + fixed list of existing hyperlinks in the range. + See vbahyperlinks.hxx for more details. */ + + // get the global hyperlink object of the sheet (sheet should always be the parent of a Range object) + uno::Reference< excel::XWorksheet > xWorksheet( getParent(), uno::UNO_QUERY_THROW ); + uno::Reference< excel::XHyperlinks > xSheetHlinks( xWorksheet->Hyperlinks( uno::Any() ), uno::UNO_QUERY_THROW ); + ScVbaHyperlinksRef xScSheetHlinks( dynamic_cast< ScVbaHyperlinks* >( xSheetHlinks.get() ) ); + if( !xScSheetHlinks.is() ) + throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Cannot obtain hyperlinks implementation object" ) ), uno::Reference< uno::XInterface >() ); + + // create a new local hyperlinks object based on the sheet hyperlinks + ScVbaHyperlinksRef xHlinks( new ScVbaHyperlinks( getParent(), mxContext, xScSheetHlinks, getScRangeList() ) ); + if( aIndex.hasValue() ) + return xHlinks->Item( aIndex, uno::Any() ); + return uno::Any( uno::Reference< excel::XHyperlinks >( xHlinks.get() ) ); +} + css::uno::Reference< excel::XValidation > SAL_CALL ScVbaRange::getValidation() throw (css::uno::RuntimeException) { @@ -4577,6 +4770,97 @@ ScVbaRange::getValidation() throw (css::uno::RuntimeException) return m_xValidation; } +namespace { + +sal_Unicode lclGetPrefixChar( const uno::Reference< table::XCell >& rxCell ) throw (uno::RuntimeException) +{ + /* TODO/FIXME: We need an apostroph-prefix property at the cell to + implement this correctly. For now, return an apostroph for every text + cell. + + TODO/FIXME: When Application.TransitionNavigKeys is supported and true, + this function needs to inspect the cell formatting and return different + prefixes according to the horizontal cell alignment. + */ + return (rxCell->getType() == table::CellContentType_TEXT) ? '\'' : 0; +} + +sal_Unicode lclGetPrefixChar( const uno::Reference< table::XCellRange >& rxRange ) throw (uno::RuntimeException) +{ + /* This implementation is able to handle different prefixes (needed if + Application.TransitionNavigKeys is true). The function lclGetPrefixChar + for single cells called from here may return any prefix. If that + function returns an empty prefix (NUL character) or different non-empty + prefixes for two cells, this function returns 0. + */ + sal_Unicode cCurrPrefix = 0; + table::CellRangeAddress aRangeAddr = lclGetRangeAddress( rxRange ); + sal_Int32 nEndCol = aRangeAddr.EndColumn - aRangeAddr.StartColumn; + sal_Int32 nEndRow = aRangeAddr.EndRow - aRangeAddr.StartRow; + for( sal_Int32 nRow = 0; nRow <= nEndRow; ++nRow ) + { + for( sal_Int32 nCol = 0; nCol <= nEndCol; ++nCol ) + { + uno::Reference< table::XCell > xCell( rxRange->getCellByPosition( nCol, nRow ), uno::UNO_SET_THROW ); + sal_Unicode cNewPrefix = lclGetPrefixChar( xCell ); + if( (cNewPrefix == 0) || ((cCurrPrefix != 0) && (cNewPrefix != cCurrPrefix)) ) + return 0; + cCurrPrefix = cNewPrefix; + } + } + // all cells contain the same prefix - return it + return cCurrPrefix; +} + +sal_Unicode lclGetPrefixChar( const uno::Reference< sheet::XSheetCellRangeContainer >& rxRanges ) throw (uno::RuntimeException) +{ + sal_Unicode cCurrPrefix = 0; + uno::Reference< container::XEnumerationAccess > xRangesEA( rxRanges, uno::UNO_QUERY_THROW ); + uno::Reference< container::XEnumeration > xRangesEnum( xRangesEA->createEnumeration(), uno::UNO_SET_THROW ); + while( xRangesEnum->hasMoreElements() ) + { + uno::Reference< table::XCellRange > xRange( xRangesEnum->nextElement(), uno::UNO_QUERY_THROW ); + sal_Unicode cNewPrefix = lclGetPrefixChar( xRange ); + if( (cNewPrefix == 0) || ((cCurrPrefix != 0) && (cNewPrefix != cCurrPrefix)) ) + return 0; + cCurrPrefix = cNewPrefix; + } + // all ranges contain the same prefix - return it + return cCurrPrefix; +} + +inline uno::Any lclGetPrefixVariant( sal_Unicode cPrefixChar ) +{ + return uno::Any( (cPrefixChar == 0) ? ::rtl::OUString() : ::rtl::OUString( cPrefixChar ) ); +} + +} // namespace + +uno::Any SAL_CALL ScVbaRange::getPrefixCharacter() throw (uno::RuntimeException) +{ + /* (1) If Application.TransitionNavigKeys is false, this function returns + an apostroph character if the text cell begins with an apostroph + character (formula return values are not taken into account); otherwise + an empty string. + + (2) If Application.TransitionNavigKeys is true, this function returns + an apostroph character, if the cell is left-aligned; a double-quote + character, if the cell is right-aligned; a circumflex character, if the + cell is centered; a backslash character, if the cell is set to filled; + or an empty string, if nothing of the above. + + If a range or a list of ranges contains texts with leading apostroph + character as well as other cells, this function returns an empty + string. + */ + + if( mxRange.is() ) + return lclGetPrefixVariant( lclGetPrefixChar( mxRange ) ); + if( mxRanges.is() ) + return lclGetPrefixVariant( lclGetPrefixChar( mxRanges ) ); + throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected empty Range object" ) ), uno::Reference< uno::XInterface >() ); +} + uno::Any ScVbaRange::getShowDetail() throw ( css::uno::RuntimeException) { // #FIXME, If the specified range is in a PivotTable report @@ -4701,7 +4985,7 @@ ScVbaRange::PrintOut( const uno::Any& From, const uno::Any& To, const uno::Any& table::CellRangeAddress rangeAddress = thisRange.getCellRangeAddressable()->getRangeAddress(); if ( index == 1 ) { - ScVbaRange* pRange = dynamic_cast< ScVbaRange* >( xRange.get() ); + ScVbaRange* pRange = getImplementation( xRange ); // initialise the doc shell and the printareas pShell = getDocShellFromRange( pRange->mxRange ); xPrintAreas.set( thisRange.getSpreadSheet(), uno::UNO_QUERY_THROW ); @@ -4723,7 +5007,7 @@ void SAL_CALL ScVbaRange::AutoFill( const uno::Reference< excel::XRange >& Destination, const uno::Any& Type ) throw (uno::RuntimeException) { uno::Reference< excel::XRange > xDest( Destination, uno::UNO_QUERY_THROW ); - ScVbaRange* pRange = dynamic_cast< ScVbaRange* >( xDest.get() ); + ScVbaRange* pRange = getImplementation( xDest ); RangeHelper destRangeHelper( pRange->mxRange ); table::CellRangeAddress destAddress = destRangeHelper.getCellRangeAddressable()->getRangeAddress(); @@ -5133,7 +5417,7 @@ ScVbaRange::SpecialCells( const uno::Any& _oType, const uno::Any& _oValue) throw { uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW ); xRange = xRange->SpecialCells( _oType, _oValue); - ScVbaRange* pRange = dynamic_cast< ScVbaRange* >( xRange.get() ); + ScVbaRange* pRange = getImplementation( xRange ); if ( xRange.is() && pRange ) { sal_Int32 nElems = ( pRange->m_Areas->getCount() + 1 ); diff --git a/sc/source/ui/vba/vbarange.hxx b/sc/source/ui/vba/vbarange.hxx index 1f161a79d973..a9147a0d7840 100644 --- a/sc/source/ui/vba/vbarange.hxx +++ b/sc/source/ui/vba/vbarange.hxx @@ -60,6 +60,7 @@ class ScCellRangeObj; class ScCellRangesObj; class ScDocShell; class ScDocument; +class ScRangeList; //typedef InheritedHelperInterfaceImpl1< ov::excel::XRange > ScVbaRange_BASE; typedef ScVbaFormat< ov::excel::XRange > ScVbaRange_BASE; @@ -127,13 +128,27 @@ public: ScVbaRange( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::sheet::XSheetCellRangeContainer >& xRanges, sal_Bool bIsRows = false, sal_Bool bIsColumns = false ) throw ( css::lang::IllegalArgumentException ); ScVbaRange( css::uno::Sequence< css::uno::Any > const& aArgs, css::uno::Reference< css::uno::XComponentContext >const& xContext ) throw ( css::lang::IllegalArgumentException ); - ScDocument* getScDocument(); - ScDocShell* getScDocShell(); + ScDocument* getScDocument() throw (css::uno::RuntimeException); + ScDocShell* getScDocShell() throw (css::uno::RuntimeException); + + /** Returns the ScVbaRange implementation object for the passed VBA Range object. */ + static ScVbaRange* getImplementation( const css::uno::Reference< ov::excel::XRange >& rxRange ); + + css::uno::Reference< css::frame::XModel > getUnoModel() throw (css::uno::RuntimeException); + static css::uno::Reference< css::frame::XModel > getUnoModel( const css::uno::Reference< ov::excel::XRange >& rxRange ) throw (css::uno::RuntimeException); + + const ScRangeList& getScRangeList() throw (css::uno::RuntimeException); + static const ScRangeList& getScRangeList( const css::uno::Reference< ov::excel::XRange >& rxRange ) throw (css::uno::RuntimeException); virtual ~ScVbaRange(); virtual css::uno::Reference< ov::XHelperInterface > thisHelperIface() { return this; } bool isSingleCellRange(); - static css::uno::Reference< ov::excel::XRange > getRangeObjectForName( const css::uno::Reference< css::uno::XComponentContext >& xContext, const rtl::OUString& sRangeName, ScDocShell* pDocSh, formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_XL_A1 ) throw ( css::uno::RuntimeException ); + + static css::uno::Reference< ov::excel::XRange > getRangeObjectForName( + const css::uno::Reference< ov::XHelperInterface >& xParent, + const css::uno::Reference< css::uno::XComponentContext >& xContext, + const rtl::OUString& sRangeName, ScDocShell* pDocSh, + formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_XL_A1 ) throw ( css::uno::RuntimeException ); // Attributes virtual css::uno::Any SAL_CALL getValue() throw (css::uno::RuntimeException); @@ -173,6 +188,7 @@ public: virtual css::uno::Any SAL_CALL getPageBreak() throw (css::uno::RuntimeException); virtual void SAL_CALL setPageBreak( const css::uno::Any& _pagebreak ) throw (css::uno::RuntimeException); virtual css::uno::Reference< ov::excel::XValidation > SAL_CALL getValidation() throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL getPrefixCharacter() throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL getShowDetail() throw (css::uno::RuntimeException); virtual void SAL_CALL setShowDetail(const css::uno::Any& aShowDetail) throw (css::uno::RuntimeException); // Methods @@ -212,6 +228,7 @@ public: virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Range( const css::uno::Any &Cell1, const css::uno::Any &Cell2 ) throw (css::uno::RuntimeException); virtual css::uno::Reference< ov::excel::XRange > Range( const css::uno::Any &Cell1, const css::uno::Any &Cell2, bool bForceUseInpuRangeTab ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL getCellRange( ) throw (css::uno::RuntimeException); + static css::uno::Any getCellRange( const css::uno::Reference< ov::excel::XRange >& rxRange ) throw (css::uno::RuntimeException); virtual void SAL_CALL PasteSpecial( const css::uno::Any& Paste, const css::uno::Any& Operation, const css::uno::Any& SkipBlanks, const css::uno::Any& Transpose ) throw (css::uno::RuntimeException); virtual ::sal_Bool SAL_CALL Replace( const ::rtl::OUString& What, const ::rtl::OUString& Replacement, const css::uno::Any& LookAt, const css::uno::Any& SearchOrder, const css::uno::Any& MatchCase, const css::uno::Any& MatchByte, const css::uno::Any& SearchFormat, const css::uno::Any& ReplaceFormat ) throw (css::uno::RuntimeException); virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Find( const css::uno::Any& What, const css::uno::Any& After, const css::uno::Any& LookIn, const css::uno::Any& LookAt, const css::uno::Any& SearchOrder, const css::uno::Any& SearchDirection, const css::uno::Any& MatchCase, const css::uno::Any& MatchByte, const css::uno::Any& SearchFormat ) throw (css::uno::RuntimeException); @@ -227,6 +244,7 @@ public: const css::uno::Any& ConsecutinveDelimiter, const css::uno::Any& Tab, const css::uno::Any& Semicolon, const css::uno::Any& Comma, const css::uno::Any& Space, const css::uno::Any& Other, const css::uno::Any& OtherChar, const css::uno::Any& FieldInfo, const css::uno::Any& DecimalSeparator, const css::uno::Any& ThousandsSeparator, const css::uno::Any& TrailingMinusNumbers ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL Hyperlinks( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException); virtual void SAL_CALL AutoFilter( const css::uno::Any& Field, const css::uno::Any& Criteria1, const css::uno::Any& Operator, const css::uno::Any& Criteria2, const css::uno::Any& VisibleDropDown ) throw (css::uno::RuntimeException); virtual void SAL_CALL Insert( const css::uno::Any& Shift, const css::uno::Any& CopyOrigin ) throw (css::uno::RuntimeException); diff --git a/sc/source/ui/vba/vbawindow.cxx b/sc/source/ui/vba/vbawindow.cxx index f0aafe83908b..10dad39341b7 100644 --- a/sc/source/ui/vba/vbawindow.cxx +++ b/sc/source/ui/vba/vbawindow.cxx @@ -55,9 +55,6 @@ using namespace ::com::sun::star; using namespace ::ooo::vba; using namespace ::ooo::vba::excel::XlWindowState; -// nameExists defined in vbaworksheet.cxx -bool nameExists( uno::Reference <sheet::XSpreadsheetDocument>& xSpreadDoc, ::rtl::OUString & name, SCTAB& nTab ) throw ( lang::IllegalArgumentException ); - typedef std::hash_map< rtl::OUString, SCTAB, ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > NameIndexHash; @@ -213,18 +210,25 @@ ScVbaWindow::ScVbaWindow( uno::Sequence< uno::Any > const & args, uno::Reference { init(); } + void ScVbaWindow::init() { + /* This method is called from the constructor, thus the own refcount is + still zero. The implementation of ActivePane() uses a UNO reference of + this (to set this window as parent of the pane obejct). This requires + the own refcount to be non-zero, otherwise this instance will be + desctructed immediately! */ + osl_incrementInterlockedCount( &m_refCount ); uno::Reference< frame::XController > xController( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW ); m_xViewPane.set( xController, uno::UNO_QUERY_THROW ); m_xViewFreezable.set( xController, uno::UNO_QUERY_THROW ); m_xViewSplitable.set( xController, uno::UNO_QUERY_THROW ); m_xPane.set( ActivePane(), uno::UNO_QUERY_THROW ); m_xDevice.set( xController->getFrame()->getComponentWindow(), uno::UNO_QUERY_THROW ); + osl_decrementInterlockedCount( &m_refCount ); } - void ScVbaWindow::Scroll( const uno::Any& Down, const uno::Any& Up, const uno::Any& ToRight, const uno::Any& ToLeft, bool bLargeScroll ) throw (uno::RuntimeException) { @@ -233,11 +237,13 @@ ScVbaWindow::Scroll( const uno::Any& Down, const uno::Any& Up, const uno::Any& T else m_xPane->SmallScroll( Down, Up, ToRight, ToLeft ); } + void SAL_CALL ScVbaWindow::SmallScroll( const uno::Any& Down, const uno::Any& Up, const uno::Any& ToRight, const uno::Any& ToLeft ) throw (uno::RuntimeException) { Scroll( Down, Up, ToRight, ToLeft ); } + void SAL_CALL ScVbaWindow::LargeScroll( const uno::Any& Down, const uno::Any& Up, const uno::Any& ToRight, const uno::Any& ToLeft ) throw (uno::RuntimeException) { @@ -450,7 +456,7 @@ ScVbaWindow::Close( const uno::Any& SaveChanges, const uno::Any& FileName, const uno::Reference< excel::XPane > SAL_CALL ScVbaWindow::ActivePane() throw (script::BasicErrorException, uno::RuntimeException) { - return new ScVbaPane( mxContext, m_xViewPane ); + return new ScVbaPane( this, mxContext, m_xModel, m_xViewPane ); } uno::Reference< excel::XRange > SAL_CALL @@ -467,6 +473,14 @@ ScVbaWindow::Selection( ) throw (script::BasicErrorException, uno::RuntimeExcep return xApplication->getSelection(); } +uno::Reference< excel::XRange > SAL_CALL +ScVbaWindow::RangeSelection() throw (script::BasicErrorException, uno::RuntimeException) +{ + /* TODO / FIXME: According to documentation, this method returns the range + selection even if shapes are selected. */ + return uno::Reference< excel::XRange >( Selection(), uno::UNO_QUERY_THROW ); +} + ::sal_Bool SAL_CALL ScVbaWindow::getDisplayGridlines() throw (uno::RuntimeException) { @@ -732,9 +746,7 @@ ScVbaWindow::setZoom( const uno::Any& _zoom ) throw (uno::RuntimeException) uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( m_xModel, uno::UNO_QUERY_THROW ); uno::Reference< excel::XWorksheet > xActiveSheet = ActiveSheet(); SCTAB nTab = 0; - rtl::OUString sName = xActiveSheet->getName(); - bool bSheetExists = nameExists (xSpreadDoc, sName, nTab); - if ( !bSheetExists ) + if ( !ScVbaWorksheets::nameExists (xSpreadDoc, xActiveSheet->getName(), nTab) ) throw uno::RuntimeException(); std::vector< SCTAB > vTabs; vTabs.push_back( nTab ); @@ -778,6 +790,15 @@ ScVbaWindow::setView( const uno::Any& _view) throw (uno::RuntimeException) dispatchExecute( pViewShell, nSlot ); } +uno::Reference< excel::XRange > SAL_CALL +ScVbaWindow::getVisibleRange() throw (uno::RuntimeException) +{ + uno::Reference< container::XIndexAccess > xPanesIA( m_xViewPane, uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XViewPane > xTopLeftPane( xPanesIA->getByIndex( 0 ), uno::UNO_QUERY_THROW ); + uno::Reference< excel::XPane > xPane( new ScVbaPane( this, mxContext, m_xModel, xTopLeftPane ) ); + return xPane->getVisibleRange(); +} + sal_Int32 SAL_CALL ScVbaWindow::PointsToScreenPixelsX(sal_Int32 _points) throw (css::script::BasicErrorException, css::uno::RuntimeException) { diff --git a/sc/source/ui/vba/vbawindow.hxx b/sc/source/ui/vba/vbawindow.hxx index e72401a2baac..d58d2a07cb4b 100644 --- a/sc/source/ui/vba/vbawindow.hxx +++ b/sc/source/ui/vba/vbawindow.hxx @@ -26,6 +26,7 @@ ************************************************************************/ #ifndef SC_VBA_WINDOW_HXX #define SC_VBA_WINDOW_HXX + #include <cppuhelper/implbase1.hxx> #include <ooo/vba/excel/XWindow.hpp> #include <com/sun/star/uno/XComponentContext.hpp> @@ -40,7 +41,6 @@ #include <vbahelper/vbawindowbase.hxx> #include "vbaworkbook.hxx" -//typedef InheritedHelperInterfaceImpl1<ov::excel::XWindow > WindowImpl_BASE; typedef cppu::ImplInheritanceHelper1< VbaWindowBase, ov::excel::XWindow > WindowImpl_BASE; class ScVbaWindow : public WindowImpl_BASE @@ -96,6 +96,7 @@ public: virtual void SAL_CALL setScrollColumn( const css::uno::Any& _scrollcolumn ) throw (css::uno::RuntimeException) ; virtual css::uno::Any SAL_CALL getView() throw (css::uno::RuntimeException); virtual void SAL_CALL setView( const css::uno::Any& _view ) throw (css::uno::RuntimeException); + virtual css::uno::Reference< ov::excel::XRange > SAL_CALL getVisibleRange() throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL getWindowState() throw (css::uno::RuntimeException); virtual void SAL_CALL setWindowState( const css::uno::Any& _windowstate ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL getZoom() throw (css::uno::RuntimeException); @@ -108,11 +109,12 @@ public: virtual void SAL_CALL ScrollWorkbookTabs( const css::uno::Any& Sheets, const css::uno::Any& Position ) throw (css::uno::RuntimeException); virtual void SAL_CALL Activate( ) throw (css::uno::RuntimeException); virtual void SAL_CALL Close( const css::uno::Any& SaveChanges, const css::uno::Any& FileName, const css::uno::Any& RouteWorkBook ) throw (css::uno::RuntimeException); - virtual css::uno::Any SAL_CALL Selection( ) throw (css::script::BasicErrorException, css::uno::RuntimeException); - virtual sal_Int32 SAL_CALL PointsToScreenPixelsX(sal_Int32 _points) throw (css::script::BasicErrorException, css::uno::RuntimeException); - virtual sal_Int32 SAL_CALL PointsToScreenPixelsY(sal_Int32 _points) throw (css::script::BasicErrorException, css::uno::RuntimeException); - virtual void SAL_CALL PrintOut( const css::uno::Any& From, const css::uno::Any&To, const css::uno::Any& Copies, const css::uno::Any& Preview, const css::uno::Any& ActivePrinter, const css::uno::Any& PrintToFile, const css::uno::Any& Collate, const css::uno::Any& PrToFileName ) throw (css::script::BasicErrorException, css::uno::RuntimeException); - virtual void SAL_CALL PrintPreview( const css::uno::Any& EnableChanges ) throw (css::script::BasicErrorException, css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL Selection( ) throw (css::script::BasicErrorException, css::uno::RuntimeException); + virtual css::uno::Reference< ov::excel::XRange > SAL_CALL RangeSelection() throw (css::script::BasicErrorException, css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL PointsToScreenPixelsX(sal_Int32 _points) throw (css::script::BasicErrorException, css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL PointsToScreenPixelsY(sal_Int32 _points) throw (css::script::BasicErrorException, css::uno::RuntimeException); + virtual void SAL_CALL PrintOut( const css::uno::Any& From, const css::uno::Any&To, const css::uno::Any& Copies, const css::uno::Any& Preview, const css::uno::Any& ActivePrinter, const css::uno::Any& PrintToFile, const css::uno::Any& Collate, const css::uno::Any& PrToFileName ) throw (css::script::BasicErrorException, css::uno::RuntimeException); + virtual void SAL_CALL PrintPreview( const css::uno::Any& EnableChanges ) throw (css::script::BasicErrorException, css::uno::RuntimeException); // XHelperInterface virtual rtl::OUString& getServiceImplName(); virtual css::uno::Sequence<rtl::OUString> getServiceNames(); diff --git a/sc/source/ui/vba/vbaworkbook.cxx b/sc/source/ui/vba/vbaworkbook.cxx index 6694f4e5e135..365c8b35a00c 100644 --- a/sc/source/ui/vba/vbaworkbook.cxx +++ b/sc/source/ui/vba/vbaworkbook.cxx @@ -345,32 +345,8 @@ ScVbaWorkbook::getServiceNames() ::rtl::OUString SAL_CALL ScVbaWorkbook::getCodeName() throw (css::uno::RuntimeException) { -#ifdef VBA_OOBUILD_HACK - uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW ); - ScDocument* pDoc = excel::getDocShell( xModel )->GetDocument(); - ScExtDocOptions* pExtOptions = pDoc->GetExtDocOptions(); - ScExtDocSettings pExtSettings = pExtOptions->GetDocSettings(); - ::rtl::OUString sGlobCodeName = pExtSettings.maGlobCodeName; - return sGlobCodeName; -#else - throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Not implemented") ), uno::Reference< uno::XInterface >() ); -#endif -} -#ifdef VBA_OOBUILD_HACK -void SAL_CALL -ScVbaWorkbook::setCodeName( const ::rtl::OUString& sGlobCodeName ) throw (css::uno::RuntimeException) -{ - uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW ); - ScDocument* pDoc = excel::getDocShell( xModel )->GetDocument(); - ScExtDocOptions* pExtOptions = pDoc->GetExtDocOptions(); - ScExtDocSettings pExtSettings = pExtOptions->GetDocSettings(); - pExtSettings.maGlobCodeName = sGlobCodeName; -#else -void SAL_CALL -ScVbaWorkbook::setCodeName( const ::rtl::OUString& ) throw (css::uno::RuntimeException) -{ - throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Not implemented") ), uno::Reference< uno::XInterface >() ); -#endif + uno::Reference< beans::XPropertySet > xModelProp( getModel(), uno::UNO_QUERY_THROW ); + return xModelProp->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CodeName" ) ) ).get< ::rtl::OUString >(); } namespace workbook diff --git a/sc/source/ui/vba/vbaworkbook.hxx b/sc/source/ui/vba/vbaworkbook.hxx index 40234aca21d7..4aff58078403 100644 --- a/sc/source/ui/vba/vbaworkbook.hxx +++ b/sc/source/ui/vba/vbaworkbook.hxx @@ -71,7 +71,6 @@ public: virtual void SAL_CALL SaveCopyAs( const rtl::OUString& Filename ) throw ( css::uno::RuntimeException); // code name virtual ::rtl::OUString SAL_CALL getCodeName() throw ( css::uno::RuntimeException); - virtual void SAL_CALL setCodeName( const ::rtl::OUString& sGlobCodeName ) throw (css::uno::RuntimeException); // XHelperInterface virtual rtl::OUString& getServiceImplName(); diff --git a/sc/source/ui/vba/vbaworksheet.cxx b/sc/source/ui/vba/vbaworksheet.cxx index be988509aa68..5b1963e3d242 100644 --- a/sc/source/ui/vba/vbaworksheet.cxx +++ b/sc/source/ui/vba/vbaworksheet.cxx @@ -24,9 +24,12 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ + #include <vbahelper/helperdecl.hxx> #include <cppuhelper/queryinterface.hxx> +#include "vbaworksheet.hxx" + #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/beans/XIntrospectionAccess.hpp> #include <com/sun/star/beans/XIntrospection.hpp> @@ -60,14 +63,15 @@ #include <ooo/vba/XControlProvider.hpp> #include <comphelper/processfactory.hxx> +#include <vbahelper/vbashapes.hxx> #include <tools/string.hxx> //zhangyun showdataform #include <sfx2/sfxdlg.hxx> -#include <scabstdlg.hxx> -#include <tabvwsh.hxx> -#include <scitems.hxx> +#include "scabstdlg.hxx" +#include "tabvwsh.hxx" +#include "scitems.hxx" #include <svx/svdouno.hxx> #include <svx/svdpage.hxx> @@ -79,43 +83,22 @@ #include "vbaoutline.hxx" #include "vbarange.hxx" #include "vbacomments.hxx" -#include "vbaworksheet.hxx" #include "vbachartobjects.hxx" #include "vbapivottables.hxx" #include "vbaoleobject.hxx" #include "vbaoleobjects.hxx" -#include <vbahelper/vbashapes.hxx> #include "vbapagesetup.hxx" #include "vbapagebreaks.hxx" +#include "vbaworksheets.hxx" +#include "vbahyperlinks.hxx" +#include "vbasheetobjects.hxx" #define STANDARDWIDTH 2267 #define STANDARDHEIGHT 427 #define DOESNOTEXIST -1 + using namespace com::sun::star; using namespace ooo::vba; -bool -nameExists( uno::Reference <sheet::XSpreadsheetDocument>& xSpreadDoc, ::rtl::OUString & name, SCTAB& nTab ) throw ( lang::IllegalArgumentException ) -{ - if (!xSpreadDoc.is()) - throw lang::IllegalArgumentException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nameExists() xSpreadDoc is null" ) ), uno::Reference< uno::XInterface >(), 1 ); - uno::Reference <sheet::XSpreadsheets> xSheets = xSpreadDoc->getSheets(); - uno::Reference <container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY ); - if ( xIndex.is() ) - { - SCTAB nCount = static_cast< SCTAB >( xIndex->getCount() ); - for (SCTAB i=0; i < nCount; i++) - { - uno::Reference< sheet::XSpreadsheet > xSheet(xIndex->getByIndex(i), uno::UNO_QUERY); - uno::Reference< container::XNamed > xNamed( xSheet, uno::UNO_QUERY_THROW ); - if (xNamed->getName() == name) - { - nTab = i; - return true; - } - } - } - return false; -} static void getNewSpreadsheetName (rtl::OUString &aNewName, rtl::OUString aOldName, uno::Reference <sheet::XSpreadsheetDocument>& xSpreadDoc ) { @@ -125,7 +108,7 @@ static void getNewSpreadsheetName (rtl::OUString &aNewName, rtl::OUString aOldNa int currentNum =2; aNewName = aOldName + aUnderScre+ String::CreateFromInt32(currentNum) ; SCTAB nTab = 0; - while ( nameExists(xSpreadDoc,aNewName, nTab ) ) + while ( ScVbaWorksheets::nameExists(xSpreadDoc,aNewName, nTab ) ) { aNewName = aOldName + aUnderScre + String::CreateFromInt32(++currentNum) ; @@ -152,7 +135,8 @@ static void removeAllSheets( uno::Reference <sheet::XSpreadsheetDocument>& xSpre } } - uno::Reference< sheet::XSpreadsheet > xSheet(xIndex->getByIndex(0), uno::UNO_QUERY); uno::Reference< container::XNamed > xNamed( xSheet, uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XSpreadsheet > xSheet(xIndex->getByIndex(0), uno::UNO_QUERY); + uno::Reference< container::XNamed > xNamed( xSheet, uno::UNO_QUERY_THROW ); if (xNamed.is()) { xNamed->setName(aSheetName); @@ -196,6 +180,7 @@ openNewDoc(rtl::OUString aSheetName ) ScVbaWorksheet::ScVbaWorksheet( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext ) : WorksheetImpl_BASE( xParent, xContext ) { } + ScVbaWorksheet::ScVbaWorksheet(const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< sheet::XSpreadsheet >& xSheet, const uno::Reference< frame::XModel >& xModel ) throw (uno::RuntimeException) : WorksheetImpl_BASE( xParent, xContext ), mxSheet( xSheet ), mxModel(xModel) @@ -216,6 +201,10 @@ ScVbaWorksheet::ScVbaWorksheet( uno::Sequence< uno::Any> const & args, mxSheet.set( xNameAccess->getByName( sSheetName ), uno::UNO_QUERY_THROW ); } +ScVbaWorksheet::~ScVbaWorksheet() +{ +} + ::rtl::OUString ScVbaWorksheet::getName() throw (uno::RuntimeException) { @@ -261,9 +250,7 @@ ScVbaWorksheet::getEnableSelection() throw (uno::RuntimeException) { uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW ); SCTAB nTab = 0; - rtl::OUString aSheetName = getName(); - bool bSheetExists = nameExists (xSpreadDoc, aSheetName, nTab); - if ( bSheetExists ) + if ( ScVbaWorksheets::nameExists(xSpreadDoc, getName(), nTab) ) { uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW ); ScDocument* pDoc = excel::getDocShell( xModel )->GetDocument(); @@ -301,9 +288,7 @@ ScVbaWorksheet::setEnableSelection( sal_Int32 nSelection ) throw (uno::RuntimeEx uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW ); SCTAB nTab = 0; - rtl::OUString aSheetName = getName(); - bool bSheetExists = nameExists (xSpreadDoc, aSheetName, nTab); - if ( bSheetExists ) + if ( ScVbaWorksheets::nameExists(xSpreadDoc, getName(), nTab) ) { uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW ); ScDocument* pDoc = excel::getDocShell( xModel )->GetDocument(); @@ -426,9 +411,8 @@ ScVbaWorksheet::Select() throw (uno::RuntimeException) void ScVbaWorksheet::Move( const uno::Any& Before, const uno::Any& After ) throw (uno::RuntimeException) { - rtl::OUString aSheetName; uno::Reference<excel::XWorksheet> xSheet; - rtl::OUString aCurrSheetName =getName(); + rtl::OUString aCurrSheetName = getName(); if (!(Before >>= xSheet) && !(After >>=xSheet)&& !(Before.hasValue()) && !(After.hasValue())) { @@ -451,9 +435,7 @@ ScVbaWorksheet::Move( const uno::Any& Before, const uno::Any& After ) throw (uno uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW ); SCTAB nDest = 0; - aSheetName = xSheet->getName(); - bool bSheetExists = nameExists (xSpreadDoc, aSheetName, nDest); - if ( bSheetExists ) + if ( ScVbaWorksheets::nameExists (xSpreadDoc, xSheet->getName(), nDest) ) { sal_Bool bAfter = After.hasValue(); if (bAfter) @@ -466,7 +448,6 @@ ScVbaWorksheet::Move( const uno::Any& Before, const uno::Any& After ) throw (uno void ScVbaWorksheet::Copy( const uno::Any& Before, const uno::Any& After ) throw (uno::RuntimeException) { - rtl::OUString aSheetName; uno::Reference<excel::XWorksheet> xSheet; rtl::OUString aCurrSheetName =getName(); if (!(Before >>= xSheet) && !(After >>=xSheet)&& !(Before.hasValue()) && !(After.hasValue())) @@ -488,10 +469,8 @@ ScVbaWorksheet::Copy( const uno::Any& Before, const uno::Any& After ) throw (uno uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY ); SCTAB nDest = 0; - aSheetName = xSheet->getName(); - bool bSheetExists = nameExists (xSpreadDoc, aSheetName, nDest ); - - if ( bSheetExists ) + rtl::OUString aSheetName = xSheet->getName(); + if ( ScVbaWorksheets::nameExists (xSpreadDoc, aSheetName, nDest ) ) { sal_Bool bAfter = After.hasValue(); if(bAfter) @@ -521,7 +500,7 @@ ScVbaWorksheet::Delete() throw (uno::RuntimeException) if ( xSpreadDoc.is() ) { SCTAB nTab = 0; - if (!nameExists(xSpreadDoc, aSheetName, nTab )) + if (!ScVbaWorksheets::nameExists(xSpreadDoc, aSheetName, nTab )) { return; } @@ -539,11 +518,8 @@ ScVbaWorksheet::getSheetAtOffset(SCTAB offset) throw (uno::RuntimeException) uno::Reference <sheet::XSpreadsheets> xSheets( xSpreadDoc->getSheets(), uno::UNO_QUERY_THROW ); uno::Reference <container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY_THROW ); - rtl::OUString aName = getName(); SCTAB nIdx = 0; - bool bSheetExists = nameExists (xSpreadDoc, aName, nIdx ); - - if ( !bSheetExists ) + if ( !ScVbaWorksheets::nameExists (xSpreadDoc, getName(), nIdx ) ) return uno::Reference< excel::XWorksheet >(); nIdx = nIdx + offset; uno::Reference< sheet::XSpreadsheet > xSheet(xIndex->getByIndex(nIdx), uno::UNO_QUERY_THROW); @@ -677,13 +653,25 @@ ScVbaWorksheet::Comments( const uno::Any& Index ) throw (uno::RuntimeException) uno::Reference< sheet::XSheetAnnotationsSupplier > xAnnosSupp( xSheet, uno::UNO_QUERY_THROW ); uno::Reference< sheet::XSheetAnnotations > xAnnos( xAnnosSupp->getAnnotations(), uno::UNO_QUERY_THROW ); uno::Reference< container::XIndexAccess > xIndexAccess( xAnnos, uno::UNO_QUERY_THROW ); - uno::Reference< XCollection > xColl( new ScVbaComments( this, mxContext, xIndexAccess ) ); + uno::Reference< XCollection > xColl( new ScVbaComments( this, mxContext, mxModel, xIndexAccess ) ); if ( Index.hasValue() ) return xColl->Item( Index, uno::Any() ); return uno::makeAny( xColl ); } uno::Any SAL_CALL +ScVbaWorksheet::Hyperlinks( const uno::Any& aIndex ) throw (uno::RuntimeException) +{ + /* The worksheet always returns the same Hyperlinks object. + See vbahyperlinks.hxx for more details. */ + if( !mxHlinks.is() ) + mxHlinks.set( new ScVbaHyperlinks( this, mxContext ) ); + if( aIndex.hasValue() ) + return uno::Reference< XCollection >( mxHlinks, uno::UNO_QUERY_THROW )->Item( aIndex, uno::Any() ); + return uno::Any( mxHlinks ); +} + +uno::Any SAL_CALL ScVbaWorksheet::OLEObjects( const uno::Any& Index ) throw (uno::RuntimeException) { ScVbaOLEObjects* aOleObjects; @@ -716,6 +704,66 @@ ScVbaWorksheet::Shapes( const uno::Any& aIndex ) throw (uno::RuntimeException) return uno::makeAny( xVbaShapes ); } +uno::Any SAL_CALL +ScVbaWorksheet::Buttons( const uno::Any& rIndex ) throw (uno::RuntimeException) +{ + if( !mxButtons.is() ) + mxButtons.set( new ScVbaButtons( this, mxContext, mxModel, mxSheet ) ); + else + mxButtons->collectShapes(); + if( rIndex.hasValue() ) + return mxButtons->Item( rIndex, uno::Any() ); + return uno::Any( uno::Reference< XCollection >( mxButtons.get() ) ); +} + +uno::Any SAL_CALL +ScVbaWorksheet::CheckBoxes( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException) +{ + throw uno::RuntimeException(); +} + +uno::Any SAL_CALL +ScVbaWorksheet::DropDowns( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException) +{ + throw uno::RuntimeException(); +} + +uno::Any SAL_CALL +ScVbaWorksheet::GroupBoxes( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException) +{ + throw uno::RuntimeException(); +} + +uno::Any SAL_CALL +ScVbaWorksheet::Labels( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException) +{ + throw uno::RuntimeException(); +} + +uno::Any SAL_CALL +ScVbaWorksheet::ListBoxes( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException) +{ + throw uno::RuntimeException(); +} + +uno::Any SAL_CALL +ScVbaWorksheet::OptionButtons( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException) +{ + throw uno::RuntimeException(); +} + +uno::Any SAL_CALL +ScVbaWorksheet::ScrollBars( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException) +{ + throw uno::RuntimeException(); +} + +uno::Any SAL_CALL +ScVbaWorksheet::Spinners( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException) +{ + throw uno::RuntimeException(); +} + void SAL_CALL ScVbaWorksheet::ShowDataForm( ) throw (uno::RuntimeException) { @@ -882,52 +930,8 @@ ScVbaWorksheet::getServiceNames() rtl::OUString SAL_CALL ScVbaWorksheet::getCodeName() throw (css::uno::RuntimeException) { -#ifdef VBA_OOBUILD_HACK - uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW ); - SCTAB nTab = 0; - rtl::OUString aSheetName = getName(); - bool bSheetExists = nameExists (xSpreadDoc, aSheetName, nTab); - if ( bSheetExists ) - { - uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW ); - ScDocument* pDoc = getDocShell( xModel )->GetDocument(); - ScExtDocOptions* pExtOptions = pDoc->GetExtDocOptions(); - rtl::OUString sCodeName = pExtOptions->GetCodeName( nTab ); - return sCodeName; - } - else - throw uno::RuntimeException(::rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM( "Sheet Name does not exist. ") ), - uno::Reference< XInterface >() ); -#else - throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Not implemented") ), uno::Reference< uno::XInterface >() ); -#endif -} -#ifdef VBA_OOBUILD_HACK -void SAL_CALL -ScVbaWorksheet::setCodeName( const rtl::OUString& sCodeName ) throw (css::uno::RuntimeException) -{ - uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW ); - SCTAB nTab = 0; - rtl::OUString aSheetName = getName(); - bool bSheetExists = nameExists (xSpreadDoc, aSheetName, nTab); - if ( bSheetExists ) - { - uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW ); - ScDocument* pDoc = getDocShell( xModel )->GetDocument(); - ScExtDocOptions* pExtOptions = pDoc->GetExtDocOptions(); - pExtOptions->SetCodeName( sCodeName, nTab ); - } - else - throw uno::RuntimeException(::rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM( "Sheet Name does not exist. ") ), - uno::Reference< XInterface >() ); -#else -void SAL_CALL -ScVbaWorksheet::setCodeName( const rtl::OUString& ) throw (css::uno::RuntimeException) -{ - throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Not implemented") ), uno::Reference< uno::XInterface >() ); -#endif + uno::Reference< beans::XPropertySet > xSheetProp( mxSheet, uno::UNO_QUERY_THROW ); + return xSheetProp->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CodeName" ) ) ).get< ::rtl::OUString >(); } sal_Int16 diff --git a/sc/source/ui/vba/vbaworksheet.hxx b/sc/source/ui/vba/vbaworksheet.hxx index 5fe1343f9237..d07cc1a8d55c 100644 --- a/sc/source/ui/vba/vbaworksheet.hxx +++ b/sc/source/ui/vba/vbaworksheet.hxx @@ -42,11 +42,17 @@ #include <ooo/vba/excel/XPageSetup.hpp> #include <ooo/vba/excel/XHPageBreaks.hpp> #include <ooo/vba/excel/XVPageBreaks.hpp> -#include <ooo/vba/excel/XChartObjects.hpp> #include <vbahelper/vbahelperinterface.hxx> #include "address.hxx" +namespace ooo { namespace vba { namespace excel { + class XChartObjects; + class XHyperlinks; +} } } + +class ScVbaSheetObjectsBase; + typedef InheritedHelperInterfaceImpl1< ov::excel::XWorksheet > WorksheetImpl_BASE; class ScVbaWorksheet : public WorksheetImpl_BASE @@ -54,6 +60,8 @@ class ScVbaWorksheet : public WorksheetImpl_BASE css::uno::Reference< css::sheet::XSpreadsheet > mxSheet; css::uno::Reference< css::frame::XModel > mxModel; css::uno::Reference< ov::excel::XChartObjects > mxCharts; + css::uno::Reference< ov::excel::XHyperlinks > mxHlinks; + ::rtl::Reference< ScVbaSheetObjectsBase > mxButtons; css::uno::Reference< ov::excel::XWorksheet > getSheetAtOffset(SCTAB offset) throw (css::uno::RuntimeException); css::uno::Reference< ov::excel::XRange > getSheetRange() throw (css::uno::RuntimeException); @@ -70,7 +78,7 @@ public: const css::uno::Reference< css::frame::XModel >& xModel )throw (css::uno::RuntimeException) ; ScVbaWorksheet( css::uno::Sequence< css::uno::Any > const& aArgs, css::uno::Reference< css::uno::XComponentContext >const& xContext ) throw ( css::lang::IllegalArgumentException ); - virtual ~ScVbaWorksheet() {} + virtual ~ScVbaWorksheet(); virtual css::uno::Reference< css::frame::XModel > getModel() { return mxModel; } @@ -120,9 +128,21 @@ public: virtual css::uno::Any SAL_CALL Evaluate( const ::rtl::OUString& Name ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL PivotTables( const css::uno::Any& Index ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL Comments( const css::uno::Any& Index ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL Hyperlinks( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL OLEObjects( const css::uno::Any& Index ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL Shapes( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException); + + virtual css::uno::Any SAL_CALL Buttons( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL CheckBoxes( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL DropDowns( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL GroupBoxes( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL Labels( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL ListBoxes( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL OptionButtons( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL ScrollBars( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL Spinners( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException); + virtual void SAL_CALL setEnableCalculation( ::sal_Bool EnableCalculation ) throw ( css::script::BasicErrorException, css::uno::RuntimeException); virtual ::sal_Bool SAL_CALL getEnableCalculation( ) throw (css::script::BasicErrorException, css::uno::RuntimeException); virtual void SAL_CALL ShowDataForm( ) throw (css::uno::RuntimeException); @@ -135,7 +155,6 @@ public: virtual ::sal_Bool SAL_CALL hasProperty( const ::rtl::OUString& aName ) throw (css::uno::RuntimeException); // CodeName virtual rtl::OUString SAL_CALL getCodeName() throw (css::uno::RuntimeException); - virtual void SAL_CALL setCodeName( const rtl::OUString& sCodeName ) throw (css::uno::RuntimeException); sal_Int16 getSheetID() throw (css::uno::RuntimeException); virtual void SAL_CALL PrintOut( const css::uno::Any& From, const css::uno::Any& To, const css::uno::Any& Copies, const css::uno::Any& Preview, const css::uno::Any& ActivePrinter, const css::uno::Any& PrintToFile, const css::uno::Any& Collate, const css::uno::Any& PrToFileName, const css::uno::Any& IgnorePrintAreas ) throw (css::uno::RuntimeException); diff --git a/sc/source/ui/vba/vbaworksheets.cxx b/sc/source/ui/vba/vbaworksheets.cxx index e7de0b82fcaa..60cf7b904026 100644 --- a/sc/source/ui/vba/vbaworksheets.cxx +++ b/sc/source/ui/vba/vbaworksheets.cxx @@ -435,3 +435,24 @@ ScVbaWorksheets::getServiceNames() } return sNames; } + +/*static*/ bool ScVbaWorksheets::nameExists( uno::Reference <sheet::XSpreadsheetDocument>& xSpreadDoc, const ::rtl::OUString & name, SCTAB& nTab ) throw ( lang::IllegalArgumentException ) +{ + if (!xSpreadDoc.is()) + throw lang::IllegalArgumentException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nameExists() xSpreadDoc is null" ) ), uno::Reference< uno::XInterface >(), 1 ); + uno::Reference <container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY ); + if ( xIndex.is() ) + { + SCTAB nCount = static_cast< SCTAB >( xIndex->getCount() ); + for (SCTAB i=0; i < nCount; i++) + { + uno::Reference< container::XNamed > xNamed( xIndex->getByIndex(i), uno::UNO_QUERY_THROW ); + if (xNamed->getName() == name) + { + nTab = i; + return true; + } + } + } + return false; +} diff --git a/sc/source/ui/vba/vbaworksheets.hxx b/sc/source/ui/vba/vbaworksheets.hxx index 4c8120084b02..2ced68bc9e27 100644 --- a/sc/source/ui/vba/vbaworksheets.hxx +++ b/sc/source/ui/vba/vbaworksheets.hxx @@ -31,11 +31,14 @@ #include <ooo/vba/excel/XWorksheets.hpp> #include <com/sun/star/sheet/XSpreadsheets.hpp> +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> #include <com/sun/star/container/XEnumerationAccess.hpp> #include <com/sun/star/uno/XComponentContext.hpp> #include <vbahelper/vbacollectionimpl.hxx> +#include "address.hxx" + class ScModelObj; @@ -74,6 +77,7 @@ public: virtual rtl::OUString& getServiceImplName(); virtual css::uno::Sequence<rtl::OUString> getServiceNames(); + static bool nameExists( css::uno::Reference <css::sheet::XSpreadsheetDocument>& xSpreadDoc, const ::rtl::OUString & name, SCTAB& nTab ) throw ( css::lang::IllegalArgumentException ); }; #endif /* SC_VBA_WORKSHEETS_HXX */ diff --git a/sc/source/ui/vba/vbawsfunction.cxx b/sc/source/ui/vba/vbawsfunction.cxx index c355244f6815..60daa7303f2e 100644 --- a/sc/source/ui/vba/vbawsfunction.cxx +++ b/sc/source/ui/vba/vbawsfunction.cxx @@ -31,6 +31,7 @@ #include <com/sun/star/beans/XIntrospectionAccess.hpp> #include <com/sun/star/sheet/XFunctionAccess.hpp> #include <com/sun/star/sheet/XCellRangesQuery.hpp> +#include <com/sun/star/sheet/XCellRangeAddressable.hpp> #include <com/sun/star/sheet/CellFlags.hpp> #include <com/sun/star/reflection/XIdlMethod.hpp> #include <com/sun/star/beans/MethodConcept.hpp> @@ -44,10 +45,27 @@ using namespace com::sun::star; using namespace ooo::vba; -ScVbaWSFunction::ScVbaWSFunction( const uno::Reference< XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext): ScVbaWSFunction_BASE( xParent, xContext ) +namespace { + +void lclConvertDoubleToBoolean( uno::Any& rAny ) { + if( rAny.has< double >() ) + { + double fValue = rAny.get< double >(); + if( fValue == 0.0 ) + rAny <<= false; + else if( fValue == 1.0 ) + rAny <<= true; + // do nothing for other values or types + } } +} // namespace + +ScVbaWSFunction::ScVbaWSFunction( const uno::Reference< XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext ) : + ScVbaWSFunction_BASE( xParent, xContext ) +{ +} uno::Reference< beans::XIntrospectionAccess > ScVbaWSFunction::getIntrospection(void) throw(uno::RuntimeException) @@ -58,33 +76,101 @@ ScVbaWSFunction::getIntrospection(void) throw(uno::RuntimeException) uno::Any SAL_CALL ScVbaWSFunction::invoke(const rtl::OUString& FunctionName, const uno::Sequence< uno::Any >& Params, uno::Sequence< sal_Int16 >& /*OutParamIndex*/, uno::Sequence< uno::Any >& /*OutParam*/) throw(lang::IllegalArgumentException, script::CannotConvertException, reflection::InvocationTargetException, uno::RuntimeException) { - uno::Reference< lang::XMultiComponentFactory > xSMgr( mxContext->getServiceManager(), uno::UNO_QUERY_THROW ); - uno::Reference< sheet::XFunctionAccess > xFunctionAccess( - xSMgr->createInstanceWithContext(::rtl::OUString::createFromAscii( - "com.sun.star.sheet.FunctionAccess"), mxContext), - ::uno::UNO_QUERY_THROW); - uno::Sequence< uno::Any > aParamTemp; - sal_Int32 nParamCount = Params.getLength(); - aParamTemp.realloc(nParamCount); - const uno::Any* aArray = Params.getConstArray(); - uno::Any* aArrayTemp = aParamTemp.getArray(); - - for (int i=0; i < Params.getLength();i++) + // create copy of parameters, replace Excel range objects with UNO range objects + uno::Sequence< uno::Any > aParamTemp( Params ); + if( aParamTemp.hasElements() ) + { + uno::Any* pArray = aParamTemp.getArray(); + uno::Any* pArrayEnd = pArray + aParamTemp.getLength(); + for( ; pArray < pArrayEnd; ++pArray ) + { + uno::Reference< excel::XRange > myRange( *pArray, uno::UNO_QUERY ); + if( myRange.is() ) + *pArray = myRange->getCellRange(); + OSL_TRACE("Param[%d] is %s", (int)(pArray - aParamTemp.getConstArray()), rtl::OUStringToOString( comphelper::anyToString( *pArray ), RTL_TEXTENCODING_UTF8 ).getStr() ); + } + } + + uno::Any aRet; + bool bAsArray = true; + + // special handing for some functions that don't work correctly in FunctionAccess + ScCompiler aCompiler( 0, ScAddress() ); + OpCode eOpCode = aCompiler.GetEnglishOpCode( FunctionName.toAsciiUpperCase() ); + switch( eOpCode ) { - uno::Reference<excel::XRange> myRange( aArray[ i ], uno::UNO_QUERY ); - if ( myRange.is() ) + // ISLOGICAL does not work in array formula mode + case ocIsLogical: { - aArrayTemp[i] = myRange->getCellRange(); - continue; + if( aParamTemp.getLength() != 1 ) + throw lang::IllegalArgumentException(); + const uno::Any& rParam = aParamTemp[ 0 ]; + if( rParam.has< bool >() ) + { + aRet <<= true; + } + else if( rParam.has< uno::Reference< table::XCellRange > >() ) try + { + uno::Reference< sheet::XCellRangeAddressable > xRangeAddr( rParam, uno::UNO_QUERY_THROW ); + table::CellRangeAddress aRangeAddr = xRangeAddr->getRangeAddress(); + bAsArray = (aRangeAddr.StartColumn != aRangeAddr.EndColumn) || (aRangeAddr.StartRow != aRangeAddr.EndRow); + } + catch( uno::Exception& ) + { + } } - aArrayTemp[i]= aArray[i]; + break; + default:; } - for ( int count=0; count < aParamTemp.getLength(); ++count ) - OSL_TRACE("Param[%d] is %s", - count, rtl::OUStringToOString( comphelper::anyToString( aParamTemp[count] ), RTL_TEXTENCODING_UTF8 ).getStr() ); + if( !aRet.hasValue() ) + { + uno::Reference< lang::XMultiComponentFactory > xSMgr( mxContext->getServiceManager(), uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XFunctionAccess > xFunctionAccess( xSMgr->createInstanceWithContext( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.FunctionAccess" ) ), mxContext ), + uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xPropSet( xFunctionAccess, uno::UNO_QUERY_THROW ); + xPropSet->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsArrayFunction" ) ), uno::Any( bAsArray ) ); + aRet = xFunctionAccess->callFunction( FunctionName, aParamTemp ); + } - uno::Any aRet = xFunctionAccess->callFunction(FunctionName,aParamTemp); + /* Convert return value from double to to Boolean for some functions that + return Booleans. */ + typedef uno::Sequence< uno::Sequence< uno::Any > > AnySeqSeq; + if( (eOpCode == ocIsEmpty) || (eOpCode == ocIsString) || (eOpCode == ocIsNonString) || (eOpCode == ocIsLogical) || + (eOpCode == ocIsRef) || (eOpCode == ocIsValue) || (eOpCode == ocIsFormula) || (eOpCode == ocIsNA) || + (eOpCode == ocIsErr) || (eOpCode == ocIsError) || (eOpCode == ocIsEven) || (eOpCode == ocIsOdd) || + (eOpCode == ocAnd) || (eOpCode == ocOr) || (eOpCode == ocNot) || (eOpCode == ocTrue) || (eOpCode == ocFalse) ) + { + if( aRet.has< AnySeqSeq >() ) + { + AnySeqSeq aAnySeqSeq = aRet.get< AnySeqSeq >(); + for( sal_Int32 nRow = 0; nRow < aAnySeqSeq.getLength(); ++nRow ) + for( sal_Int32 nCol = 0; nCol < aAnySeqSeq[ nRow ].getLength(); ++nCol ) + lclConvertDoubleToBoolean( aAnySeqSeq[ nRow ][ nCol ] ); + aRet <<= aAnySeqSeq; + } + else + { + lclConvertDoubleToBoolean( aRet ); + } + } + + /* Hack/workaround (?): shorten single-row matrix to simple array, shorten + 1x1 matrix to single value. */ + if( aRet.has< AnySeqSeq >() ) + { + AnySeqSeq aAnySeqSeq = aRet.get< AnySeqSeq >(); + if( aAnySeqSeq.getLength() == 1 ) + { + if( aAnySeqSeq[ 0 ].getLength() == 1 ) + aRet = aAnySeqSeq[ 0 ][ 0 ]; + else + aRet <<= aAnySeqSeq[ 0 ]; + } + } + +#if 0 // MATCH function should alwayse return a double value, but currently if the first argument is XCellRange, MATCH function returns an array instead of a double value. Don't know why? // To fix this issue in safe, current solution is to convert this array to a double value just for MATCH function. String aUpper( FunctionName ); @@ -101,6 +187,8 @@ ScVbaWSFunction::invoke(const rtl::OUString& FunctionName, const uno::Sequence< throw uno::RuntimeException(); aRet <<= fVal; } +#endif + return aRet; } @@ -122,7 +210,7 @@ ScVbaWSFunction::hasMethod(const rtl::OUString& Name) throw(uno::RuntimeExcepti sal_Bool bIsFound = sal_False; try { - // the function name contained in the com.sun.star.sheet.FunctionDescription service is alwayse localized. + // the function name contained in the com.sun.star.sheet.FunctionDescription service is alwayse localized. // but the function name used in WorksheetFunction is a programmatic name (seems English). // So m_xNameAccess->hasByName( Name ) may fail to find name when a function name has a localized name. ScCompiler aCompiler( NULL, ScAddress() ); diff --git a/sc/source/ui/vba/vbawsfunction.hxx b/sc/source/ui/vba/vbawsfunction.hxx index 58a895f6d47b..ffd33849afe5 100644 --- a/sc/source/ui/vba/vbawsfunction.hxx +++ b/sc/source/ui/vba/vbawsfunction.hxx @@ -52,7 +52,6 @@ public: // XHelperInterface virtual rtl::OUString& getServiceImplName(); virtual css::uno::Sequence<rtl::OUString> getServiceNames(); - }; #endif diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index 87740a88e4df..ff40bdeb7390 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -2405,6 +2405,7 @@ void lcl_InitMouseEvent( ::com::sun::star::awt::MouseEvent& rEvent, const MouseE long ScGridWindow::PreNotify( NotifyEvent& rNEvt ) { + bool bDone = false; USHORT nType = rNEvt.GetType(); if ( nType == EVENT_MOUSEBUTTONUP || nType == EVENT_MOUSEBUTTONDOWN ) { @@ -2425,16 +2426,31 @@ long ScGridWindow::PreNotify( NotifyEvent& rNEvt ) if ( rNEvt.GetWindow() ) aEvent.Source = rNEvt.GetWindow()->GetComponentInterface(); if ( nType == EVENT_MOUSEBUTTONDOWN) - pImp->MousePressed( aEvent ); + bDone = pImp->MousePressed( aEvent ); else - pImp->MouseReleased( aEvent ); + bDone = pImp->MouseReleased( aEvent ); } } } } } + if (bDone) // event consumed by a listener + { + if ( nType == EVENT_MOUSEBUTTONDOWN ) + { + const MouseEvent* pMouseEvent = rNEvt.GetMouseEvent(); + if ( pMouseEvent->IsRight() && pMouseEvent->GetClicks() == 1 ) + { + // If a listener returned true for a right-click call, also prevent opening the context menu + // (this works only if the context menu is opened on mouse-down) + nMouseStatus = SC_GM_IGNORE; + } + } - return Window::PreNotify( rNEvt ); + return 1; + } + else + return Window::PreNotify( rNEvt ); } void ScGridWindow::Tracking( const TrackingEvent& rTEvt ) @@ -2678,6 +2694,10 @@ void __EXPORT ScGridWindow::Command( const CommandEvent& rCEvt ) if ( nCmd == COMMAND_CONTEXTMENU && !SC_MOD()->GetIsWaterCan() ) { + BOOL bMouse = rCEvt.IsMouseEvent(); + if ( bMouse && nMouseStatus == SC_GM_IGNORE ) + return; + if (pViewData->IsAnyFillMode()) { pViewData->GetView()->StopRefMode(); @@ -2688,7 +2708,6 @@ void __EXPORT ScGridWindow::Command( const CommandEvent& rCEvt ) Point aPosPixel = rCEvt.GetMousePosPixel(); Point aMenuPos = aPosPixel; - BOOL bMouse = rCEvt.IsMouseEvent(); if ( bMouse ) { diff --git a/sc/source/ui/view/tabvwshf.cxx b/sc/source/ui/view/tabvwshf.cxx index 68a852c4a3b7..82da92820ab1 100644 --- a/sc/source/ui/view/tabvwshf.cxx +++ b/sc/source/ui/view/tabvwshf.cxx @@ -34,12 +34,14 @@ #include "scitems.hxx" #include <sfx2/request.hxx> +#include <sfx2/viewfrm.hxx> #include <basic/sbstar.hxx> #include <layout/layout.hxx> #include <svl/languageoptions.hxx> #include <svl/stritem.hxx> #include <svl/whiter.hxx> #include <vcl/msgbox.hxx> +#include <svx/svxdlg.hxx> #include "tabvwsh.hxx" #include "sc.hrc" @@ -52,9 +54,12 @@ //CHINA001 #include "strindlg.hxx" //CHINA001 #include "mvtabdlg.hxx" #include "docfunc.hxx" +#include "eventuno.hxx" #include "scabstdlg.hxx" //CHINA001 +using namespace com::sun::star; + #define IS_AVAILABLE(WhichId,ppItem) \ (pReqArgs->GetItemState((WhichId), TRUE, ppItem ) == SFX_ITEM_SET) @@ -683,6 +688,26 @@ void ScTabViewShell::ExecuteTable( SfxRequest& rReq ) } break; + case FID_TAB_EVENTS: + { + ScDocShell* pDocSh = pViewData->GetDocShell(); + uno::Reference<container::XNameReplace> xEvents( new ScSheetEventsObj( pDocSh, nCurrentTab ) ); + + uno::Reference<frame::XFrame> xFrame = GetViewFrame()->GetFrame().GetFrameInterface(); + + SvxAbstractDialogFactory* pDlgFactory = SvxAbstractDialogFactory::Create(); + if (pDlgFactory) + { + std::auto_ptr<VclAbstractDialog> pDialog( pDlgFactory->CreateSvxMacroAssignDlg( + GetDialogParent(), xFrame, false, xEvents, 0 ) ); + if ( pDialog.get() && pDialog->Execute() == RET_OK ) + { + // the dialog modifies the settings directly + } + } + } + break; + default: DBG_ERROR("Unbekannte Message bei ViewShell"); break; diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx index 11ecfa5aae8c..8ac03829127e 100644 --- a/sc/source/ui/view/viewfun2.cxx +++ b/sc/source/ui/view/viewfun2.cxx @@ -2201,6 +2201,7 @@ BOOL ScViewFunc::DeleteTables(const SvShorts &TheTabs, BOOL bRecord ) pUndoDoc->SetActiveScenario( nTab, bActive ); } pUndoDoc->SetVisible( nTab, pDoc->IsVisible( nTab ) ); + pUndoDoc->SetSheetEvents( nTab, pDoc->GetSheetEvents( nTab ) ); if ( pDoc->IsTabProtected( nTab ) ) pUndoDoc->SetTabProtection(nTab, pDoc->GetTabProtection(nTab)); diff --git a/sc/util/makefile.mk b/sc/util/makefile.mk index b7b12e07ee6a..722f04542551 100644 --- a/sc/util/makefile.mk +++ b/sc/util/makefile.mk @@ -314,7 +314,7 @@ SHL9STDLIBS= \ $(ISCLIB) \ $(VCLLIB) \ $(TKLIB) \ - $(SVXMSFILTERLIB) \ + $(MSFILTERLIB) \ $(FORLIB) SHL9DEPN=$(SHL1TARGETN) $(SHL8TARGETN) |