1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26
27
28
29 #include <tools/debug.hxx>
30 #include <sfx2/objsh.hxx>
31
32
33 #include "addinlis.hxx"
34 #include "miscuno.hxx" // SC_IMPL_SERVICE_INFO
35 #include "document.hxx"
36 #include "brdcst.hxx"
37 #include "unoguard.hxx"
38 #include "sc.hrc"
39
40 using namespace com::sun::star;
41
42 //------------------------------------------------------------------------
43
44 //SMART_UNO_IMPLEMENTATION( ScAddInListener, UsrObject );
45
46 SC_SIMPLE_SERVICE_INFO( ScAddInListener, "ScAddInListener", "stardiv.one.sheet.AddInListener" )
47
48 //------------------------------------------------------------------------
49
50 List ScAddInListener::aAllListeners;
51
52 //------------------------------------------------------------------------
53
54 // static
CreateListener(uno::Reference<sheet::XVolatileResult> xVR,ScDocument * pDoc)55 ScAddInListener* ScAddInListener::CreateListener(
56 uno::Reference<sheet::XVolatileResult> xVR, ScDocument* pDoc )
57 {
58 ScAddInListener* pNew = new ScAddInListener( xVR, pDoc );
59
60 pNew->acquire(); // for aAllListeners
61 aAllListeners.Insert( pNew, LIST_APPEND );
62
63 if ( xVR.is() )
64 xVR->addResultListener( pNew ); // after at least 1 ref exists!
65
66 return pNew;
67 }
68
ScAddInListener(uno::Reference<sheet::XVolatileResult> xVR,ScDocument * pDoc)69 ScAddInListener::ScAddInListener( uno::Reference<sheet::XVolatileResult> xVR, ScDocument* pDoc ) :
70 xVolRes( xVR )
71 {
72 pDocs = new ScAddInDocs( 1, 1 );
73 pDocs->Insert( pDoc );
74 }
75
~ScAddInListener()76 ScAddInListener::~ScAddInListener()
77 {
78 delete pDocs;
79 }
80
81 // static
Get(uno::Reference<sheet::XVolatileResult> xVR)82 ScAddInListener* ScAddInListener::Get( uno::Reference<sheet::XVolatileResult> xVR )
83 {
84 sheet::XVolatileResult* pComp = xVR.get();
85
86 sal_uLong nCount = aAllListeners.Count();
87 for (sal_uLong nPos=0; nPos<nCount; nPos++)
88 {
89 ScAddInListener* pLst = (ScAddInListener*)aAllListeners.GetObject(nPos);
90 if ( pComp == (sheet::XVolatileResult*)pLst->xVolRes.get() )
91 return pLst;
92 }
93 return NULL; // not found
94 }
95
96 //! move to some container object?
97 // static
RemoveDocument(ScDocument * pDocumentP)98 void ScAddInListener::RemoveDocument( ScDocument* pDocumentP )
99 {
100 sal_uLong nPos = aAllListeners.Count();
101 while (nPos)
102 {
103 // loop backwards because elements are removed
104 --nPos;
105 ScAddInListener* pLst = (ScAddInListener*)aAllListeners.GetObject(nPos);
106 ScAddInDocs* p = pLst->pDocs;
107 sal_uInt16 nFoundPos;
108 if ( p->Seek_Entry( pDocumentP, &nFoundPos ) )
109 {
110 p->Remove( nFoundPos );
111 if ( p->Count() == 0 )
112 {
113 // this AddIn is no longer used
114 // dont delete, just remove the ref for the list
115
116 aAllListeners.Remove( nPos );
117
118 if ( pLst->xVolRes.is() )
119 pLst->xVolRes->removeResultListener( pLst );
120
121 pLst->release(); // Ref for aAllListeners - pLst may be deleted here
122 }
123 }
124 }
125 }
126
127 //------------------------------------------------------------------------
128
129 // XResultListener
130
modified(const::com::sun::star::sheet::ResultEvent & aEvent)131 void SAL_CALL ScAddInListener::modified( const ::com::sun::star::sheet::ResultEvent& aEvent )
132 throw(::com::sun::star::uno::RuntimeException)
133 {
134 ScUnoGuard aGuard; //! or generate a UserEvent
135
136 aResult = aEvent.Value; // store result
137
138 if ( !HasListeners() )
139 {
140 //! remove from list and removeListener, as in RemoveDocument ???
141
142 #if 0
143 //! this will crash if called before first StartListening !!!
144 aAllListeners.Remove( this );
145 if ( xVolRes.is() )
146 xVolRes->removeResultListener( this );
147 release(); // Ref for aAllListeners - this may be deleted here
148 return;
149 #endif
150 }
151
152 // notify document of changes
153
154 Broadcast( ScHint( SC_HINT_DATACHANGED, ScAddress(), NULL ) );
155
156 const ScDocument** ppDoc = (const ScDocument**) pDocs->GetData();
157 sal_uInt16 nCount = pDocs->Count();
158 for ( sal_uInt16 j=0; j<nCount; j++, ppDoc++ )
159 {
160 ScDocument* pDoc = (ScDocument*)*ppDoc;
161 pDoc->TrackFormulas();
162 pDoc->GetDocumentShell()->Broadcast( SfxSimpleHint( FID_DATACHANGED ) );
163 pDoc->ResetChanged( ScRange(0,0,0,MAXCOL,MAXROW,MAXTAB) );
164 }
165 }
166
167 // XEventListener
168
disposing(const::com::sun::star::lang::EventObject &)169 void SAL_CALL ScAddInListener::disposing( const ::com::sun::star::lang::EventObject& /* Source */ )
170 throw(::com::sun::star::uno::RuntimeException)
171 {
172 // hold a ref so this is not deleted at removeResultListener
173 uno::Reference<sheet::XResultListener> xRef( this );
174
175 if ( xVolRes.is() )
176 {
177 xVolRes->removeResultListener( this );
178 xVolRes = NULL;
179 }
180 }
181
182
183 //------------------------------------------------------------------------
184
185
186
187