summaryrefslogtreecommitdiffstats
path: root/sc
diff options
context:
space:
mode:
authorMichael E. Bohn <mbn@openoffice.org>2010-09-17 02:15:05 +0200
committerMichael E. Bohn <mbn@openoffice.org>2010-09-17 02:15:05 +0200
commitf2f1a87565e69576235588e99bf84089ed21df17 (patch)
treea4d8e9556d7430fbfa33f2c1e4ead18c0fb10221 /sc
parentmib19: #163560# use default cell font and RefDevice for column width (diff)
parentmib19: #163641# use clipboard content in ScVbaRange::Insert only if it was co... (diff)
downloadcore-f2f1a87565e69576235588e99bf84089ed21df17.tar.gz
core-f2f1a87565e69576235588e99bf84089ed21df17.zip
merged heads
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/document.hxx1
-rw-r--r--sc/source/core/data/documen3.cxx8
-rw-r--r--sc/source/ui/app/transobj.cxx8
-rw-r--r--sc/source/ui/docshell/docfunc.cxx4
-rw-r--r--sc/source/ui/inc/inputhdl.hxx2
-rw-r--r--sc/source/ui/inc/transobj.hxx3
-rw-r--r--sc/source/ui/unoobj/docuno.cxx17
-rw-r--r--sc/source/ui/vba/excelvbahelper.cxx17
-rw-r--r--sc/source/ui/vba/vbaapplication.cxx49
-rw-r--r--sc/source/ui/vba/vbaapplication.hxx10
-rwxr-xr-xsc/source/ui/vba/vbaeventshelper.cxx109
-rwxr-xr-xsc/source/ui/vba/vbaeventshelper.hxx8
-rwxr-xr-xsc/source/ui/vba/vbarange.cxx35
-rw-r--r--sc/source/ui/vba/vbarange.hxx6
-rw-r--r--sc/source/ui/vba/vbaworkbooks.cxx66
-rw-r--r--sc/source/ui/vba/vbaworkbooks.hxx5
-rw-r--r--sc/source/ui/vba/vbaworksheet.cxx5
17 files changed, 255 insertions, 98 deletions
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 02a6ee5b4c00..90aac02aab7f 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -748,6 +748,7 @@ public:
bool HasSheetEventScript( SCTAB nTab, sal_Int32 nEvent, bool bWithVbaEvents = false ) const;
bool HasAnySheetEventScript( sal_Int32 nEvent, bool bWithVbaEvents = false ) const; // on any sheet
+ bool HasAnyCalcNotification() const;
BOOL HasCalcNotification( SCTAB nTab ) const;
void SetCalcNotification( SCTAB nTab );
void ResetCalcNotifications();
diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx
index 8fea4b8af2b9..f3b3f1ab32c6 100644
--- a/sc/source/core/data/documen3.cxx
+++ b/sc/source/core/data/documen3.cxx
@@ -544,6 +544,14 @@ bool ScDocument::HasAnySheetEventScript( sal_Int32 nEvent, bool bWithVbaEvents )
return false;
}
+bool ScDocument::HasAnyCalcNotification() const
+{
+ for (SCTAB nTab = 0; nTab <= MAXTAB; nTab++)
+ if (pTab[nTab] && pTab[nTab]->GetCalcNotification())
+ return true;
+ return false;
+}
+
BOOL ScDocument::HasCalcNotification( SCTAB nTab ) const
{
if (VALIDTAB(nTab) && pTab[nTab])
diff --git a/sc/source/ui/app/transobj.cxx b/sc/source/ui/app/transobj.cxx
index 4b268b9da791..e6b8b3b5049a 100644
--- a/sc/source/ui/app/transobj.cxx
+++ b/sc/source/ui/app/transobj.cxx
@@ -134,7 +134,8 @@ ScTransferObj::ScTransferObj( ScDocument* pClipDoc, const TransferableObjectDesc
nDragHandleY( 0 ),
nDragSourceFlags( 0 ),
bDragWasInternal( FALSE ),
- bUsedForLink( FALSE )
+ bUsedForLink( FALSE ),
+ bUseInApi( false )
{
DBG_ASSERT(pDoc->IsClipboard(), "wrong document");
@@ -540,6 +541,11 @@ void ScTransferObj::SetDragWasInternal()
bDragWasInternal = TRUE;
}
+void ScTransferObj::SetUseInApi( bool bSet )
+{
+ bUseInApi = bSet;
+}
+
ScDocument* ScTransferObj::GetSourceDocument()
{
ScDocShell* pSourceDocSh = GetSourceDocShell();
diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx
index 27112d8c62c2..adbe26abf157 100644
--- a/sc/source/ui/docshell/docfunc.cxx
+++ b/sc/source/ui/docshell/docfunc.cxx
@@ -851,13 +851,13 @@ BOOL ScDocFunc::PutCell( const ScAddress& rPos, ScBaseCell* pNewCell, BOOL bApi
return TRUE;
}
-void ScDocFunc::NotifyInputHandler( const ScAddress& /* rPos */ )
+void ScDocFunc::NotifyInputHandler( const ScAddress& rPos )
{
ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
if ( pViewSh && pViewSh->GetViewData()->GetDocShell() == &rDocShell )
{
ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl();
- if ( pInputHdl )
+ if ( pInputHdl && pInputHdl->GetCursorPos() == rPos )
{
sal_Bool bIsEditMode(pInputHdl->IsEditMode());
diff --git a/sc/source/ui/inc/inputhdl.hxx b/sc/source/ui/inc/inputhdl.hxx
index 61974cf7464d..f3eba8b26f6b 100644
--- a/sc/source/ui/inc/inputhdl.hxx
+++ b/sc/source/ui/inc/inputhdl.hxx
@@ -168,6 +168,8 @@ public:
const String& GetEditString();
const String& GetFormString() const { return aFormText; }
+ const ScAddress& GetCursorPos() const { return aCursorPos; }
+
BOOL GetTextAndFields( ScEditEngineDefaulter& rDestEngine );
BOOL KeyInput( const KeyEvent& rKEvt, BOOL bStartEdit = FALSE );
diff --git a/sc/source/ui/inc/transobj.hxx b/sc/source/ui/inc/transobj.hxx
index e2dbad485812..546637c726d0 100644
--- a/sc/source/ui/inc/transobj.hxx
+++ b/sc/source/ui/inc/transobj.hxx
@@ -64,6 +64,7 @@ private:
BOOL bDragWasInternal;
BOOL bUsedForLink;
bool bHasFiltered; // if has filtered rows
+ bool bUseInApi; // to recognize clipboard content copied from API
void InitDocShell();
static void StripRefs( ScDocument* pDoc, SCCOL nStartX, SCROW nStartY,
@@ -93,6 +94,7 @@ public:
SCTAB GetVisibleTab() const { return nVisibleTab; }
USHORT GetDragSourceFlags() const { return nDragSourceFlags; }
bool HasFilteredRows() const { return bHasFiltered; }
+ bool GetUseInApi() const { return bUseInApi; }
ScDocShell* GetSourceDocShell();
ScDocument* GetSourceDocument();
ScMarkData GetSourceMarkData();
@@ -103,6 +105,7 @@ public:
void SetDragSource( ScDocShell* pSourceShell, const ScMarkData& rMark );
void SetDragSourceFlags( USHORT nFlags );
void SetDragWasInternal();
+ SC_DLLPUBLIC void SetUseInApi( bool bSet );
static SC_DLLPUBLIC ScTransferObj* GetOwnClipboard( Window* pUIWin );
diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx
index 3d3f0f479601..89193ad8ddf0 100644
--- a/sc/source/ui/unoobj/docuno.cxx
+++ b/sc/source/ui/unoobj/docuno.cxx
@@ -590,8 +590,21 @@ void ScModelObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
DELETEZ( pPrintFuncCache );
// handle "OnCalculate" sheet events (search also for VBA event handlers)
- if ( pDocShell && pDocShell->GetDocument()->HasAnySheetEventScript( SC_SHEETEVENT_CALCULATE, true ) )
- HandleCalculateEvents();
+ if ( pDocShell )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ if ( pDoc->GetVbaEventProcessor().is() )
+ {
+ // If the VBA event processor is set, HasAnyCalcNotification is much faster than HasAnySheetEventScript
+ if ( pDoc->HasAnyCalcNotification() && pDoc->HasAnySheetEventScript( SC_SHEETEVENT_CALCULATE, true ) )
+ HandleCalculateEvents();
+ }
+ else
+ {
+ if ( pDoc->HasAnySheetEventScript( SC_SHEETEVENT_CALCULATE ) )
+ HandleCalculateEvents();
+ }
+ }
}
}
else if ( rHint.ISA( ScPointerChangedHint ) )
diff --git a/sc/source/ui/vba/excelvbahelper.cxx b/sc/source/ui/vba/excelvbahelper.cxx
index 2c39d7154b4b..2813d928eba8 100644
--- a/sc/source/ui/vba/excelvbahelper.cxx
+++ b/sc/source/ui/vba/excelvbahelper.cxx
@@ -150,7 +150,14 @@ implnCopy( const uno::Reference< frame::XModel>& xModel )
{
ScTabViewShell* pViewShell = getBestViewShell( xModel );
if ( pViewShell )
+ {
pViewShell->CopyToClip(NULL,false,false,true);
+
+ // mark the copied transfer object so it is used in ScVbaRange::Insert
+ ScTransferObj* pClipObj = ScTransferObj::GetOwnClipboard( NULL );
+ if (pClipObj)
+ pClipObj->SetUseInApi( true );
+ }
}
void
@@ -158,7 +165,14 @@ implnCut( const uno::Reference< frame::XModel>& xModel )
{
ScTabViewShell* pViewShell = getBestViewShell( xModel );
if ( pViewShell )
+ {
pViewShell->CutToClip( NULL, TRUE );
+
+ // mark the copied transfer object so it is used in ScVbaRange::Insert
+ ScTransferObj* pClipObj = ScTransferObj::GetOwnClipboard( NULL );
+ if (pClipObj)
+ pClipObj->SetUseInApi( true );
+ }
}
void implnPasteSpecial( const uno::Reference< frame::XModel>& xModel, USHORT nFlags,USHORT nFunction,sal_Bool bSkipEmpty, sal_Bool bTranspose)
@@ -181,7 +195,10 @@ void implnPasteSpecial( const uno::Reference< frame::XModel>& xModel, USHORT nFl
ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pWin );
ScDocument* pDoc = NULL;
if ( pOwnClip )
+ {
pDoc = pOwnClip->GetDocument();
+ pOwnClip->SetUseInApi( false ); // don't use in Insert after it was pasted once
+ }
pTabViewShell->PasteFromClip( nFlags, pDoc,
nFunction, bSkipEmpty, bTranspose, bAsLink,
eMoveMode, IDF_NONE, TRUE );
diff --git a/sc/source/ui/vba/vbaapplication.cxx b/sc/source/ui/vba/vbaapplication.cxx
index f3965393e919..30d4bd4d39a0 100644
--- a/sc/source/ui/vba/vbaapplication.cxx
+++ b/sc/source/ui/vba/vbaapplication.cxx
@@ -60,6 +60,7 @@
#include "sc.hrc"
#include <osl/file.hxx>
+#include <rtl/instance.hxx>
#include <sfx2/request.hxx>
#include <sfx2/objsh.hxx>
@@ -108,11 +109,32 @@ public:
ActiveWorkbook( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext) : ScVbaWorkbook( xParent, xContext ){}
};
+// ============================================================================
+
+/** Global application settings shared by all open workbooks. */
+struct ScVbaAppSettings
+{
+ sal_Int32 mnCalculation;
+ sal_Bool mbDisplayAlerts;
+ sal_Bool mbEnableEvents;
+
+ explicit ScVbaAppSettings();
+};
+
+ScVbaAppSettings::ScVbaAppSettings() :
+ mnCalculation( excel::XlCalculation::xlCalculationAutomatic ),
+ mbDisplayAlerts( sal_True ),
+ mbEnableEvents( sal_True )
+{
+}
+
+struct ScVbaStaticAppSettings : public ::rtl::Static< ScVbaAppSettings, ScVbaStaticAppSettings > {};
+
+// ============================================================================
+
ScVbaApplication::ScVbaApplication( const uno::Reference<uno::XComponentContext >& xContext ) :
ScVbaApplication_BASE( xContext ),
- m_xCalculation( excel::XlCalculation::xlCalculationAutomatic ),
- m_bDisplayAlerts( sal_True ),
- m_bEnableEvents( sal_True )
+ mrAppSettings( ScVbaStaticAppSettings::get() )
{
}
@@ -120,6 +142,11 @@ ScVbaApplication::~ScVbaApplication()
{
}
+/*static*/ bool ScVbaApplication::getDocumentEventsEnabled()
+{
+ return ScVbaStaticAppSettings::get().mbEnableEvents;
+}
+
SfxObjectShell* ScVbaApplication::GetDocShell( const uno::Reference< frame::XModel >& xModel ) throw (uno::RuntimeException)
{
return static_cast< SfxObjectShell* >( excel::getDocShell( xModel ) );
@@ -396,8 +423,10 @@ ScVbaApplication::setStatusBar( const uno::Any& _statusbar ) throw (uno::Runtime
if( _statusbar >>= sText )
{
setDisplayStatusBar( sal_True );
- xStatusIndicator->start( sText, 100 );
- //xStatusIndicator->setText( sText );
+ if ( sText.getLength() )
+ xStatusIndicator->start( sText, 100 );
+ else
+ xStatusIndicator->end(); // restore normal state for empty text
}
else if( _statusbar >>= bDefault )
{
@@ -415,6 +444,7 @@ ScVbaApplication::setStatusBar( const uno::Any& _statusbar ) throw (uno::Runtime
::sal_Int32 SAL_CALL
ScVbaApplication::getCalculation() throw (uno::RuntimeException)
{
+ // TODO: in Excel, this is an application-wide setting
uno::Reference<sheet::XCalculatable> xCalc(getCurrentDocument(), uno::UNO_QUERY_THROW);
if(xCalc->isAutomaticCalculationEnabled())
return excel::XlCalculation::xlCalculationAutomatic;
@@ -425,6 +455,7 @@ ScVbaApplication::getCalculation() throw (uno::RuntimeException)
void SAL_CALL
ScVbaApplication::setCalculation( ::sal_Int32 _calculation ) throw (uno::RuntimeException)
{
+ // TODO: in Excel, this is an application-wide setting
uno::Reference< sheet::XCalculatable > xCalc(getCurrentDocument(), uno::UNO_QUERY_THROW);
switch(_calculation)
{
@@ -704,25 +735,25 @@ ScVbaApplication::getName() throw (uno::RuntimeException)
void SAL_CALL
ScVbaApplication::setDisplayAlerts(sal_Bool displayAlerts) throw (uno::RuntimeException)
{
- m_bDisplayAlerts = displayAlerts;
+ mrAppSettings.mbDisplayAlerts = displayAlerts;
}
sal_Bool SAL_CALL
ScVbaApplication::getDisplayAlerts() throw (uno::RuntimeException)
{
- return m_bDisplayAlerts;
+ return mrAppSettings.mbDisplayAlerts;
}
void SAL_CALL
ScVbaApplication::setEnableEvents(sal_Bool bEnable) throw (uno::RuntimeException)
{
- m_bEnableEvents = bEnable;
+ mrAppSettings.mbEnableEvents = bEnable;
}
sal_Bool SAL_CALL
ScVbaApplication::getEnableEvents() throw (uno::RuntimeException)
{
- return m_bEnableEvents;
+ return mrAppSettings.mbEnableEvents;
}
void SAL_CALL
diff --git a/sc/source/ui/vba/vbaapplication.hxx b/sc/source/ui/vba/vbaapplication.hxx
index a7be5feb1d27..bb696c967a37 100644
--- a/sc/source/ui/vba/vbaapplication.hxx
+++ b/sc/source/ui/vba/vbaapplication.hxx
@@ -39,12 +39,13 @@
//typedef InheritedHelperInterfaceImpl1< ov::excel::XApplication > ScVbaApplication_BASE;
typedef cppu::ImplInheritanceHelper1< VbaApplicationBase, ov::excel::XApplication > ScVbaApplication_BASE;
+struct ScVbaAppSettings;
+
class ScVbaApplication : public ScVbaApplication_BASE
{
private:
- sal_Int32 m_xCalculation;
- sal_Bool m_bDisplayAlerts;
- sal_Bool m_bEnableEvents;
+ // note: member variables moved to struct "ScVbaAppSettings", see cxx file, to be shared by all application instances
+ ScVbaAppSettings& mrAppSettings;
rtl::OUString getOfficePath( const rtl::OUString& sPath ) throw ( css::uno::RuntimeException );
@@ -55,6 +56,9 @@ public:
ScVbaApplication( const css::uno::Reference< css::uno::XComponentContext >& m_xContext );
virtual ~ScVbaApplication();
+ /** Returns true, if VBA document events are enabled. */
+ static bool getDocumentEventsEnabled();
+
virtual SfxObjectShell* GetDocShell( const css::uno::Reference< css::frame::XModel >& xModel ) throw (css::uno::RuntimeException);
// XExactName
diff --git a/sc/source/ui/vba/vbaeventshelper.cxx b/sc/source/ui/vba/vbaeventshelper.cxx
index 996bf52e0794..86d5f643a8b2 100755
--- a/sc/source/ui/vba/vbaeventshelper.cxx
+++ b/sc/source/ui/vba/vbaeventshelper.cxx
@@ -48,6 +48,7 @@
#include "cellsuno.hxx"
#include "convuno.hxx"
+#include "vbaapplication.hxx"
using namespace ::com::sun::star;
using namespace ::com::sun::star::script::vba::VBAEventId;
@@ -55,6 +56,40 @@ using namespace ::ooo::vba;
// ============================================================================
+namespace {
+
+/** Extracts a sheet index from the specified element of the passed sequence.
+ The element may be an integer, or a Calc range or ranges object. */
+SCTAB lclGetTabFromArgs( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) throw (lang::IllegalArgumentException)
+{
+ VbaEventsHelperBase::checkArgument( rArgs, nIndex );
+
+ // first try to extract a sheet index
+ SCTAB nTab = -1;
+ if( rArgs[ nIndex ] >>= nTab )
+ return nTab;
+
+ // next, try single range object
+ uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable = getXSomethingFromArgs< sheet::XCellRangeAddressable >( rArgs, nIndex );
+ if( xCellRangeAddressable.is() )
+ return xCellRangeAddressable->getRangeAddress().Sheet;
+
+ // at last, try range list
+ uno::Reference< sheet::XSheetCellRangeContainer > xRanges = getXSomethingFromArgs< sheet::XSheetCellRangeContainer >( rArgs, nIndex );
+ if( xRanges.is() )
+ {
+ uno::Sequence< table::CellRangeAddress > aRangeAddresses = xRanges->getRangeAddresses();
+ if( aRangeAddresses.getLength() > 0 )
+ return aRangeAddresses[ 0 ].Sheet;
+ }
+
+ throw lang::IllegalArgumentException();
+}
+
+} // namespace
+
+// ============================================================================
+
typedef ::cppu::WeakImplHelper4<
awt::XWindowListener, util::XCloseListener, frame::XBorderResizeListener, util::XChangesListener > ScVbaEventsListener_BASE;
@@ -475,25 +510,13 @@ bool ScVbaEventsHelper::implPrepareEvent( EventQueue& rEventQueue,
if( (rInfo.maUserData >>= bSheetEvent) && bSheetEvent )
rEventQueue.push_back( EventQueueEntry( rInfo.mnEventId + USERDEFINED_START, rArgs ) );
- /* For document events: get Application object and check if events are
- enabled via EnableEvents symbol (this is an Excel-only attribute).
+ /* For document events: check if events are enabled via the
+ Application.EnableEvents symbol (this is an Excel-only attribute).
Check this again for every event, as the event handler may change
the state of the EnableEvents symbol. Global events such as
AUTO_OPEN and AUTO_CLOSE are always enabled. */
if( rInfo.meType == EVENTHANDLER_DOCUMENT )
- {
- // reference to application is held weakly, get application on first try
- uno::Reference< excel::XApplication > xApplication( mxApplication.get(), uno::UNO_QUERY );
- if( !xApplication.is() )
- {
- uno::Any aVBAGlobals;
- mpShell->GetBasicManager()->GetGlobalUNOConstant( "VBAGlobals", aVBAGlobals );
- uno::Reference< XHelperInterface > xHelperInterface( aVBAGlobals, uno::UNO_QUERY_THROW );
- xApplication.set( xHelperInterface->Application(), uno::UNO_QUERY_THROW );
- mxApplication = xApplication;
- }
- bExecuteEvent = xApplication->getEnableEvents();
- }
+ bExecuteEvent = ScVbaApplication::getDocumentEventsEnabled();
}
return bExecuteEvent;
@@ -618,7 +641,7 @@ void ScVbaEventsHelper::implPostProcessEvent( EventQueue& rEventQueue,
{
bool bSheetEvent = false;
rInfo.maUserData >>= bSheetEvent;
- SCTAB nTab = bSheetEvent ? getTabFromArgs( rArgs, 0 ) : -1;
+ SCTAB nTab = bSheetEvent ? lclGetTabFromArgs( rArgs, 0 ) : -1;
if( bSheetEvent && (nTab < 0) )
throw lang::IllegalArgumentException();
@@ -632,43 +655,37 @@ void ScVbaEventsHelper::implPostProcessEvent( EventQueue& rEventQueue,
// private --------------------------------------------------------------------
-SCTAB ScVbaEventsHelper::getTabFromArgs( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) throw (lang::IllegalArgumentException)
-{
- checkArgument( rArgs, nIndex );
-
- // first try to extract a sheet index
- SCTAB nTab = -1;
- if( rArgs[ nIndex ] >>= nTab )
- return nTab;
+namespace {
- // next, try single range object
- uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable = getXSomethingFromArgs< sheet::XCellRangeAddressable >( rArgs, nIndex );
- if( xCellRangeAddressable.is() )
- return xCellRangeAddressable->getRangeAddress().Sheet;
+/** Compares the passed range lists representing sheet selections. Ignores
+ selections that refer to different sheets (returns false in this case). */
+bool lclSelectionChanged( const ScRangeList& rLeft, const ScRangeList& rRight )
+{
+ // one of the range lists empty? -> return false, if both lists empty
+ bool bLeftEmpty = rLeft.Count() == 0;
+ bool bRightEmpty = rRight.Count() == 0;
+ if( bLeftEmpty || bRightEmpty )
+ return !(bLeftEmpty && bRightEmpty);
- // at last, try range list
- uno::Reference< sheet::XSheetCellRangeContainer > xRanges = getXSomethingFromArgs< sheet::XSheetCellRangeContainer >( rArgs, nIndex );
- if( xRanges.is() )
- {
- uno::Sequence< table::CellRangeAddress > aRangeAddresses = xRanges->getRangeAddresses();
- if( aRangeAddresses.getLength() > 0 )
- return aRangeAddresses[ 0 ].Sheet;
- }
+ // check sheet indexes of the range lists (assuming that all ranges in a list are on the same sheet)
+ if( rLeft.GetObject( 0 )->aStart.Tab() != rRight.GetObject( 0 )->aStart.Tab() )
+ return false;
- throw lang::IllegalArgumentException();
+ // compare all ranges
+ return rLeft != rRight;
}
+} // namespace
+
bool ScVbaEventsHelper::isSelectionChanged( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) throw (lang::IllegalArgumentException, uno::RuntimeException)
{
+ uno::Reference< uno::XInterface > xOldSelection( maOldSelection, uno::UNO_QUERY );
uno::Reference< uno::XInterface > xNewSelection = getXSomethingFromArgs< uno::XInterface >( rArgs, nIndex, false );
- if( ScCellRangesBase* pNewCellRanges = ScCellRangesBase::getImplementation( xNewSelection ) )
- {
- bool bChanged = maOldSelection != pNewCellRanges->GetRangeList();
- maOldSelection = pNewCellRanges->GetRangeList();
- return bChanged;
- }
- maOldSelection.Clear();
- return true;
+ ScCellRangesBase* pOldCellRanges = ScCellRangesBase::getImplementation( xOldSelection );
+ ScCellRangesBase* pNewCellRanges = ScCellRangesBase::getImplementation( xNewSelection );
+ bool bChanged = !pOldCellRanges || !pNewCellRanges || lclSelectionChanged( pOldCellRanges->GetRangeList(), pNewCellRanges->GetRangeList() );
+ maOldSelection <<= xNewSelection;
+ return bChanged;
}
uno::Any ScVbaEventsHelper::createWorksheet( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) const
@@ -678,7 +695,7 @@ uno::Any ScVbaEventsHelper::createWorksheet( const uno::Sequence< uno::Any >& rA
// directly from basic and register them as listeners
// extract sheet index, will throw, if parameter is invalid
- SCTAB nTab = getTabFromArgs( rArgs, nIndex );
+ SCTAB nTab = lclGetTabFromArgs( rArgs, nIndex );
// create Workbook
uno::Sequence< uno::Any > aArgs( 2 );
diff --git a/sc/source/ui/vba/vbaeventshelper.hxx b/sc/source/ui/vba/vbaeventshelper.hxx
index eaac96117d32..f1e8a4fb712d 100755
--- a/sc/source/ui/vba/vbaeventshelper.hxx
+++ b/sc/source/ui/vba/vbaeventshelper.hxx
@@ -33,8 +33,6 @@
#include "excelvbahelper.hxx"
#include "rangelst.hxx"
-namespace ooo { namespace vba { namespace excel { class XApplication; } } }
-
class ScVbaEventsListener;
// ============================================================================
@@ -57,9 +55,6 @@ protected:
virtual ::rtl::OUString implGetDocumentModuleName( const EventHandlerInfo& rInfo, const css::uno::Sequence< css::uno::Any >& rArgs ) const throw (css::lang::IllegalArgumentException);
private:
- /** Extracts a sheet index from the first element of the passed sequence. The
- element may be an integer, or a Calc range or ranges object. */
- static SCTAB getTabFromArgs( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) throw (css::lang::IllegalArgumentException);
/** Checks if selection has been changed compared to selection of last call.
@return true, if the selection has been changed. */
bool isSelectionChanged( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) throw (css::lang::IllegalArgumentException, css::uno::RuntimeException);
@@ -74,11 +69,10 @@ private:
css::uno::Any createWindow() const throw (css::uno::RuntimeException);
private:
- mutable css::uno::WeakReference< ov::excel::XApplication > mxApplication;
::rtl::Reference< ScVbaEventsListener > mxListener;
+ css::uno::Any maOldSelection;
ScDocShell* mpDocShell;
ScDocument* mpDoc;
- ScRangeList maOldSelection;
bool mbOpened;
};
diff --git a/sc/source/ui/vba/vbarange.cxx b/sc/source/ui/vba/vbarange.cxx
index d32ad0a4b41e..891a5a36ecfd 100755
--- a/sc/source/ui/vba/vbarange.cxx
+++ b/sc/source/ui/vba/vbarange.cxx
@@ -123,6 +123,7 @@
#include <cellsuno.hxx>
#include <dbcolect.hxx>
#include "docfunc.hxx"
+#include "transobj.hxx"
#include <sfx2/dispatch.hxx>
#include <sfx2/app.hxx>
@@ -2060,6 +2061,18 @@ ScVbaRange::Cells( const uno::Any &nRowIndex, const uno::Any &nColumnIndex ) thr
return xRange->Cells( nRowIndex, nColumnIndex );
}
+ // Performance: Use a common helper method for ScVbaRange::Cells and ScVbaWorksheet::Cells,
+ // instead of creating a new ScVbaRange object in often-called ScVbaWorksheet::Cells
+ return CellsHelper( mxParent, mxContext, mxRange, nRowIndex, nColumnIndex );
+}
+
+// static
+uno::Reference< excel::XRange >
+ScVbaRange::CellsHelper( const uno::Reference< ov::XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext >& xContext,
+ const uno::Reference< css::table::XCellRange >& xRange,
+ const uno::Any &nRowIndex, const uno::Any &nColumnIndex ) throw(uno::RuntimeException)
+{
sal_Int32 nRow = 0, nColumn = 0;
sal_Bool bIsIndex = nRowIndex.hasValue();
@@ -2071,7 +2084,7 @@ ScVbaRange::Cells( const uno::Any &nRowIndex, const uno::Any &nColumnIndex ) thr
// convertion routine e.g. bSuccess = getValueFromAny( nRow, nRowIndex, getCppuType((sal_Int32*)0) )
if ( nRowIndex.hasValue() && !( nRowIndex >>= nRow ) )
{
- uno::Reference< script::XTypeConverter > xConverter = getTypeConverter( mxContext );
+ uno::Reference< script::XTypeConverter > xConverter = getTypeConverter( xContext );
uno::Any aConverted;
try
{
@@ -2082,7 +2095,7 @@ ScVbaRange::Cells( const uno::Any &nRowIndex, const uno::Any &nColumnIndex ) thr
}
if ( bIsColumnIndex && !( nColumnIndex >>= nColumn ) )
{
- uno::Reference< script::XTypeConverter > xConverter = getTypeConverter( mxContext );
+ uno::Reference< script::XTypeConverter > xConverter = getTypeConverter( xContext );
uno::Any aConverted;
try
{
@@ -2092,17 +2105,17 @@ ScVbaRange::Cells( const uno::Any &nRowIndex, const uno::Any &nColumnIndex ) thr
catch( uno::Exception& ) {} // silence any errors
}
- RangeHelper thisRange( mxRange );
+ RangeHelper thisRange( xRange );
table::CellRangeAddress thisRangeAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
uno::Reference< table::XCellRange > xSheetRange = thisRange.getCellRangeFromSheet();
if( !bIsIndex && !bIsColumnIndex ) // .Cells
// #FIXE needs proper parent ( Worksheet )
- return uno::Reference< excel::XRange >( new ScVbaRange( mxParent, mxContext, mxRange ) );
+ return uno::Reference< excel::XRange >( new ScVbaRange( xParent, xContext, xRange ) );
sal_Int32 nIndex = --nRow;
if( bIsIndex && !bIsColumnIndex ) // .Cells(n)
{
- uno::Reference< table::XColumnRowRange > xColumnRowRange(mxRange, ::uno::UNO_QUERY_THROW);
+ uno::Reference< table::XColumnRowRange > xColumnRowRange(xRange, ::uno::UNO_QUERY_THROW);
sal_Int32 nColCount = xColumnRowRange->getColumns()->getCount();
if ( !nIndex || nIndex < 0 )
@@ -2115,7 +2128,7 @@ ScVbaRange::Cells( const uno::Any &nRowIndex, const uno::Any &nColumnIndex ) thr
--nColumn;
nRow = nRow + thisRangeAddress.StartRow;
nColumn = nColumn + thisRangeAddress.StartColumn;
- return new ScVbaRange( mxParent, mxContext, xSheetRange->getCellRangeByPosition( nColumn, nRow, nColumn, nRow ) );
+ return new ScVbaRange( xParent, xContext, xSheetRange->getCellRangeByPosition( nColumn, nRow, nColumn, nRow ) );
}
void
@@ -4535,10 +4548,8 @@ ScVbaRange::AutoFilter( const uno::Any& Field, const uno::Any& Criteria1, const
}
void SAL_CALL
-ScVbaRange::Insert( const uno::Any& Shift, const uno::Any& CopyOrigin ) throw (uno::RuntimeException)
+ScVbaRange::Insert( const uno::Any& Shift, const uno::Any& /* CopyOrigin */ ) throw (uno::RuntimeException)
{
- sal_Bool bCopyOrigin = sal_True;
- CopyOrigin >>= bCopyOrigin;
// It appears ( from the web ) that the undocumented CopyOrigin
// param should contain member of enum XlInsertFormatOrigin
// which can have values xlFormatFromLeftOrAbove or xlFormatFromRightOrBelow
@@ -4573,7 +4584,11 @@ ScVbaRange::Insert( const uno::Any& Shift, const uno::Any& CopyOrigin ) throw (u
table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress();
uno::Reference< sheet::XCellRangeMovement > xCellRangeMove( thisRange.getSpreadSheet(), uno::UNO_QUERY_THROW );
xCellRangeMove->insertCells( thisAddress, mode );
- if ( bCopyOrigin )
+
+ // Paste from clipboard only if the clipboard content was copied via VBA, and not already pasted via VBA again.
+ // "Insert" behavior should not depend on random clipboard content previously copied by the user.
+ ScTransferObj* pClipObj = ScTransferObj::GetOwnClipboard( NULL );
+ if ( pClipObj && pClipObj->GetUseInApi() )
{
// After the insert ( this range ) actually has moved
ScRange aRange( static_cast< SCCOL >( thisAddress.StartColumn ), static_cast< SCROW >( thisAddress.StartRow ), static_cast< SCTAB >( thisAddress.Sheet ), static_cast< SCCOL >( thisAddress.EndColumn ), static_cast< SCROW >( thisAddress.EndRow ), static_cast< SCTAB >( thisAddress.Sheet ) );
diff --git a/sc/source/ui/vba/vbarange.hxx b/sc/source/ui/vba/vbarange.hxx
index e7488e434f30..a8aada649575 100644
--- a/sc/source/ui/vba/vbarange.hxx
+++ b/sc/source/ui/vba/vbarange.hxx
@@ -149,6 +149,12 @@ public:
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 > CellsHelper(
+ const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::table::XCellRange >& xRange,
+ const css::uno::Any &nRowIndex, const css::uno::Any &nColumnIndex ) throw(css::uno::RuntimeException);
+
// Attributes
virtual css::uno::Any SAL_CALL getValue() throw (css::uno::RuntimeException);
virtual void SAL_CALL setValue( const css::uno::Any& aValue ) throw ( css::uno::RuntimeException);
diff --git a/sc/source/ui/vba/vbaworkbooks.cxx b/sc/source/ui/vba/vbaworkbooks.cxx
index 7efee1505dcb..194d3d1b9656 100644
--- a/sc/source/ui/vba/vbaworkbooks.cxx
+++ b/sc/source/ui/vba/vbaworkbooks.cxx
@@ -46,7 +46,9 @@
#include <com/sun/star/document/XTypeDetection.hpp>
#include <com/sun/star/uri/XUriReference.hpp>
#include <com/sun/star/uri/XUriReferenceFactory.hpp>
+#include <com/sun/star/script/vba/VBAEventId.hpp>
#include <com/sun/star/script/vba/XVBACompatibility.hpp>
+#include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
#include <com/sun/star/script/vba/XVBAModuleInfo.hpp>
#include <com/sun/star/script/ModuleInfo.hpp>
#include <com/sun/star/script/ModuleType.hpp>
@@ -81,7 +83,7 @@ void setUpDocumentModules( const uno::Reference< sheet::XSpreadsheetDocument >&
if( xLibContainer.is() )
{
- if( !xLibContainer->hasByName( aPrjName ) )
+ if( !xLibContainer->hasByName( aPrjName ) )
xLibContainer->createLibrary( aPrjName );
uno::Any aLibAny = xLibContainer->getByName( aPrjName );
uno::Reference< container::XNameContainer > xLib;
@@ -130,6 +132,18 @@ void setUpDocumentModules( const uno::Reference< sheet::XSpreadsheetDocument >&
}
}
}
+
+ /* Trigger the Workbook_Open event, event processor will register
+ itself as listener for specific events. */
+ try
+ {
+ uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( pShell->GetDocument()->GetVbaEventProcessor(), uno::UNO_SET_THROW );
+ uno::Sequence< uno::Any > aArgs;
+ xVbaEvents->processVbaEvent( script::vba::VBAEventId::WORKBOOK_OPEN, aArgs );
+ }
+ catch( uno::Exception& )
+ {
+ }
}
}
@@ -200,9 +214,41 @@ ScVbaWorkbooks::createCollectionObject( const css::uno::Any& aSource )
uno::Any SAL_CALL
-ScVbaWorkbooks::Add() throw (uno::RuntimeException)
+ScVbaWorkbooks::Add( const uno::Any& Template ) throw (uno::RuntimeException)
{
- uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( VbaDocumentsBase::Add() , uno::UNO_QUERY_THROW );
+ uno::Reference< sheet::XSpreadsheetDocument > xSpreadDoc;
+ sal_Int32 nWorkbookType = 0;
+ ::rtl::OUString aTemplateFileName;
+ if( Template >>= nWorkbookType )
+ {
+ // nWorkbookType is a constant from XlWBATemplate (added in Excel 2007)
+ // TODO: create chart-sheet if supported by Calc
+
+ xSpreadDoc.set( createDocument(), uno::UNO_QUERY_THROW );
+ // create a document with one sheet only
+ uno::Reference< sheet::XSpreadsheets > xSheets( xSpreadDoc->getSheets(), uno::UNO_SET_THROW );
+ uno::Reference< container::XIndexAccess > xSheetsIA( xSheets, uno::UNO_QUERY_THROW );
+ while( xSheetsIA->getCount() > 1 )
+ {
+ uno::Reference< container::XNamed > xSheetName( xSheetsIA->getByIndex( xSheetsIA->getCount() - 1 ), uno::UNO_QUERY_THROW );
+ xSheets->removeByName( xSheetName->getName() );
+ }
+ }
+ else if( Template >>= aTemplateFileName )
+ {
+ // TODO: create document from template
+ xSpreadDoc.set( createDocument(), uno::UNO_QUERY_THROW );
+ }
+ else if( !Template.hasValue() )
+ {
+ // regular spreadsheet document with configured number of sheets
+ xSpreadDoc.set( createDocument(), uno::UNO_QUERY_THROW );
+ }
+ else
+ {
+ // illegal argument
+ throw uno::RuntimeException();
+ }
// need to set up the document modules ( and vba mode ) here
setUpDocumentModules( xSpreadDoc );
@@ -211,10 +257,10 @@ ScVbaWorkbooks::Add() throw (uno::RuntimeException)
return uno::Any();
}
-void
+void SAL_CALL
ScVbaWorkbooks::Close() throw (uno::RuntimeException)
{
- VbaDocumentsBase::Close();
+ closeDocuments();
}
bool
@@ -254,7 +300,7 @@ ScVbaWorkbooks::getFileFilterType( const rtl::OUString& rFileName )
}
// #TODO# #FIXME# can any of the unused params below be used?
-uno::Any
+uno::Any SAL_CALL
ScVbaWorkbooks::Open( const rtl::OUString& rFileName, const uno::Any& /*UpdateLinks*/, const uno::Any& ReadOnly, const uno::Any& Format, const uno::Any& /*Password*/, const uno::Any& /*WriteResPassword*/, const uno::Any& /*IgnoreReadOnlyRecommended*/, const uno::Any& /*Origin*/, const uno::Any& Delimiter, const uno::Any& /*Editable*/, const uno::Any& /*Notify*/, const uno::Any& /*Converter*/, const uno::Any& /*AddToMru*/ ) throw (uno::RuntimeException)
{
// we need to detect if this is a URL, if not then assume its a file path
@@ -333,7 +379,7 @@ ScVbaWorkbooks::Open( const rtl::OUString& rFileName, const uno::Any& /*UpdateLi
else if ( !isSpreadSheetFile( sType ) )
throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Bad Format")), uno::Reference< uno::XInterface >() );
- uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( VbaDocumentsBase::Open( rFileName, ReadOnly, sProps ), uno::UNO_QUERY_THROW );
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( openDocument( rFileName, ReadOnly, sProps ), uno::UNO_QUERY_THROW );
uno::Any aRet = getWorkbook( mxContext, xSpreadDoc, mxParent );
uno::Reference< excel::XWorkbook > xWBook( aRet, uno::UNO_QUERY );
if ( xWBook.is() )
@@ -341,12 +387,6 @@ ScVbaWorkbooks::Open( const rtl::OUString& rFileName, const uno::Any& /*UpdateLi
return aRet;
}
-uno::Any
-ScVbaWorkbooks::Open( const rtl::OUString& Filename, const uno::Any& ReadOnly, const uno::Sequence< beans::PropertyValue >& rProps ) throw (css::uno::RuntimeException)
-{
- return VbaDocumentsBase::Open( Filename, ReadOnly, rProps );
-}
-
rtl::OUString&
ScVbaWorkbooks::getServiceImplName()
{
diff --git a/sc/source/ui/vba/vbaworkbooks.hxx b/sc/source/ui/vba/vbaworkbooks.hxx
index 5d6210244d80..3392829f1a05 100644
--- a/sc/source/ui/vba/vbaworkbooks.hxx
+++ b/sc/source/ui/vba/vbaworkbooks.hxx
@@ -60,12 +60,9 @@ public:
virtual css::uno::Sequence<rtl::OUString> getServiceNames();
// XWorkbooks
- virtual css::uno::Any SAL_CALL Add() throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL Add( const css::uno::Any& Template ) throw (css::uno::RuntimeException);
virtual void SAL_CALL Close( ) throw (css::uno::RuntimeException);
virtual css::uno::Any SAL_CALL Open( const ::rtl::OUString& Filename, const css::uno::Any& UpdateLinks, const css::uno::Any& ReadOnly, const css::uno::Any& Format, const css::uno::Any& Password, const css::uno::Any& WriteResPassword, const css::uno::Any& IgnoreReadOnlyRecommended, const css::uno::Any& Origin, const css::uno::Any& Delimiter, const css::uno::Any& Editable, const css::uno::Any& Notify, const css::uno::Any& Converter, const css::uno::Any& AddToMru ) throw (css::uno::RuntimeException);
-
- // VbaDocumentsBase / XDocumentsBase (to avoid warning C4266 for hiding function on wntmsci)
- virtual css::uno::Any SAL_CALL Open( const ::rtl::OUString& Filename, const css::uno::Any& ReadOnly, const css::uno::Sequence< css::beans::PropertyValue >& rProps ) throw (css::uno::RuntimeException);
};
#endif /* SC_VBA_WORKBOOKS_HXX */
diff --git a/sc/source/ui/vba/vbaworksheet.cxx b/sc/source/ui/vba/vbaworksheet.cxx
index 1f31cb7e19ce..c57048d5b148 100644
--- a/sc/source/ui/vba/vbaworksheet.cxx
+++ b/sc/source/ui/vba/vbaworksheet.cxx
@@ -658,7 +658,10 @@ uno::Reference< excel::XRange >
ScVbaWorksheet::Cells( const ::uno::Any &nRow, const ::uno::Any &nCol )
throw (uno::RuntimeException)
{
- return getSheetRange()->Cells( nRow, nCol );
+ // Performance optimization for often-called Cells method:
+ // Use a common helper method instead of creating a new ScVbaRange object
+ uno::Reference< table::XCellRange > xRange( getSheet(), uno::UNO_QUERY_THROW );
+ return ScVbaRange::CellsHelper( mxParent, mxContext, xRange, nRow, nCol );
}
uno::Reference< excel::XRange >