Update to m13
[ooovba.git] / applied_patches / 0412-vba-worksheet-change-event-fix.diff
blobf94845cc61c12fe0edebe54f3d0d4cc45c6349e7
1 diff --git sc/source/ui/vba/vbaeventshelper.cxx sc/source/ui/vba/vbaeventshelper.cxx
2 index 8248d48..794cb84 100644
3 --- sc/source/ui/vba/vbaeventshelper.cxx
4 +++ sc/source/ui/vba/vbaeventshelper.cxx
5 @@ -56,8 +56,12 @@
6 #include <com/sun/star/util/XCloseBroadcaster.hpp>
7 #include <com/sun/star/frame/XControllerBorder.hpp>
8 #include <com/sun/star/frame/XBorderResizeListener.hpp>
9 -#include "cellsuno.hxx"
11 +#include <com/sun/star/util/XChangesListener.hpp>
12 +#include <com/sun/star/util/ElementChange.hpp>
13 +#include <com/sun/star/util/XChangesNotifier.hpp>
14 +#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
15 +#include <cellsuno.hxx>
16 +#include <convuno.hxx>
17 #include <map>
19 using namespace std;
20 @@ -69,6 +73,70 @@ const static rtl::OUString sUrlPart0 = rtl::OUString::createFromAscii( "vnd.sun.
21 const static rtl::OUString sUrlPart1 = rtl::OUString::createFromAscii( "vnd.sun.star.script:Standard.");
22 const static rtl::OUString sUrlPart2 = rtl::OUString::createFromAscii( "?language=Basic&location=document");
24 +typedef ::cppu::WeakImplHelper1< util::XChangesListener > WorksheetChangeListener_BASE;
26 +class WorksheetChangeListener : public WorksheetChangeListener_BASE
28 +private:
29 + ScVbaEventsHelper* pVbaEventsHelper;
30 +public:
31 + WorksheetChangeListener(ScVbaEventsHelper* pHelper ) : pVbaEventsHelper( pHelper ){}
32 + virtual void SAL_CALL changesOccurred(const util::ChangesEvent& aEvent) throw (uno::RuntimeException);
33 + virtual void SAL_CALL disposing(const lang::EventObject& aSource) throw(uno::RuntimeException){}
34 +};
36 +void WorksheetChangeListener::changesOccurred(const util::ChangesEvent& aEvent) throw (uno::RuntimeException)
38 + sal_Int32 nCount = aEvent.Changes.getLength();
39 + if( nCount == 0 )
40 + return;
42 + util::ElementChange aChange = aEvent.Changes[ 0 ];
43 + rtl::OUString sOperation;
44 + aChange.Accessor >>= sOperation;
45 + if( !sOperation.equalsIgnoreAsciiCaseAscii("cell-change") )
46 + return;
48 + if( nCount == 1 )
49 + {
50 + uno::Reference< table::XCellRange > xRangeObj;
51 + aChange.ReplacedElement >>= xRangeObj;
52 + if( xRangeObj.is() )
53 + {
54 + uno::Sequence< uno::Any > aArgs(1);
55 + aArgs[0] <<= xRangeObj;
56 + pVbaEventsHelper->ProcessCompatibleVbaEvent( VBAEVENT_WORKSHEET_CHANGE, aArgs );
57 + }
58 + return;
59 + }
61 + ScRangeList aRangeList;
62 + for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
63 + {
64 + aChange = aEvent.Changes[ nIndex ];
65 + aChange.Accessor >>= sOperation;
66 + uno::Reference< table::XCellRange > xRangeObj;
67 + aChange.ReplacedElement >>= xRangeObj;
68 + if( xRangeObj.is() && sOperation.equalsIgnoreAsciiCaseAscii("cell-change") )
69 + {
70 + uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable( xRangeObj, uno::UNO_QUERY );
71 + if( xCellRangeAddressable.is() )
72 + {
73 + ScRange aRange;
74 + ScUnoConversion::FillScRange( aRange, xCellRangeAddressable->getRangeAddress() );
75 + aRangeList.Append( aRange );
76 + }
77 + }
78 + }
80 + if( aRangeList.Count() > 0 )
81 + {
82 + uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pVbaEventsHelper->getDocumentShell(), aRangeList ) );
83 + uno::Sequence< uno::Any > aArgs(1);
84 + aArgs[0] <<= xRanges;
85 + pVbaEventsHelper->ProcessCompatibleVbaEvent( VBAEVENT_WORKSHEET_CHANGE, aArgs );
86 + }
89 typedef ::cppu::WeakImplHelper3< awt::XWindowListener, util::XCloseListener, frame::XBorderResizeListener > WindowListener_BASE;
91 @@ -394,8 +462,12 @@ ScVbaEventsHelper::ScVbaEventsHelper( uno::Sequence< css::uno::Any > const& aArg
92 : m_xContext( xContext ), mpVbaEventsListener( NULL ), mbOpened( sal_False ), mbIgnoreEvents( sal_False )
94 uno::Reference< frame::XModel > xModel ( getXSomethingFromArgs< frame::XModel >( aArgs, 0 ), uno::UNO_QUERY );
95 - ScDocShell* pDocShell = excel::getDocShell( xModel );
96 + pDocShell = excel::getDocShell( xModel );
97 pDoc = pDocShell->GetDocument();
98 + // Add worksheet change listener
99 + uno::Reference< util::XChangesNotifier > xChangesNotifier( xModel, uno::UNO_QUERY );
100 + if( xChangesNotifier.is() )
101 + xChangesNotifier->addChangesListener( uno::Reference< util::XChangesListener >( new WorksheetChangeListener( this ) ) );
104 ScVbaEventsHelper::~ScVbaEventsHelper()
105 @@ -782,6 +854,18 @@ SCTAB ScVbaEventsHelper::getTabFromArgs( const uno::Sequence< uno::Any > aArgs,
106 table::CellRangeAddress aAddress = xCellRangeAddressable->getRangeAddress();
107 nTab = aAddress.Sheet;
109 + else
111 + uno::Reference< sheet::XSheetCellRangeContainer > xRanges( getXSomethingFromArgs< sheet::XSheetCellRangeContainer >( aArgs, nPos ), uno::UNO_QUERY );
112 + if( xRanges.is() )
114 + uno::Sequence< table::CellRangeAddress > aRangeAddresses = xRanges->getRangeAddresses();
115 + if( aRangeAddresses.getLength() > 0 )
117 + nTab = aRangeAddresses[ 0 ].Sheet;
121 return nTab;
124 diff --git sc/source/ui/vba/vbaeventshelper.hxx sc/source/ui/vba/vbaeventshelper.hxx
125 index e8c41d3..e812aa0 100644
126 --- sc/source/ui/vba/vbaeventshelper.hxx
127 +++ sc/source/ui/vba/vbaeventshelper.hxx
128 @@ -47,10 +47,12 @@
129 typedef ::cppu::WeakImplHelper1< com::sun::star::document::XVbaEventsHelper > VBAWorkbookEvent_BASE;
131 class VbaEventsListener;
132 +class ScDocShell;
133 class ScVbaEventsHelper : public VBAWorkbookEvent_BASE
135 private:
136 ScDocument* pDoc;
137 + ScDocShell* pDocShell;
138 css::uno::Reference< css::uno::XComponentContext > m_xContext;
139 VbaEventsListener* mpVbaEventsListener;
140 sal_Bool mbOpened;
141 @@ -72,6 +74,7 @@ public:
142 ScVbaEventsHelper( css::uno::Sequence< css::uno::Any > const& aArgs, css::uno::Reference< css::uno::XComponentContext > const& xContext );
143 ~ScVbaEventsHelper();
144 ScDocument* getDocument() { return pDoc; };
145 + ScDocShell* getDocumentShell() { return pDocShell; };
146 // XVBAWorkbookEventHelper
147 virtual sal_Bool SAL_CALL ProcessCompatibleVbaEvent( sal_Int32 nEventId, const css::uno::Sequence< css::uno::Any >& aArgs ) throw (css::uno::RuntimeException);
148 virtual void SAL_CALL setIgnoreEvents( ::sal_Bool _ignoreevents ) throw (css::uno::RuntimeException);