xref: /AOO41X/main/sc/source/core/tool/addinlis.cxx (revision b3f79822e811ac3493b185030a72c3c5a51f32d8)
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