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 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 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 76 ScAddInListener::~ScAddInListener() 77 { 78 delete pDocs; 79 } 80 81 // static 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 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 131 void SAL_CALL ScAddInListener::modified( const ::com::sun::star::sheet::ResultEvent& aEvent ) 132 { 133 ScUnoGuard aGuard; //! or generate a UserEvent 134 135 aResult = aEvent.Value; // store result 136 137 if ( !HasListeners() ) 138 { 139 //! remove from list and removeListener, as in RemoveDocument ??? 140 141 #if 0 142 //! this will crash if called before first StartListening !!! 143 aAllListeners.Remove( this ); 144 if ( xVolRes.is() ) 145 xVolRes->removeResultListener( this ); 146 release(); // Ref for aAllListeners - this may be deleted here 147 return; 148 #endif 149 } 150 151 // notify document of changes 152 153 Broadcast( ScHint( SC_HINT_DATACHANGED, ScAddress(), NULL ) ); 154 155 const ScDocument** ppDoc = (const ScDocument**) pDocs->GetData(); 156 sal_uInt16 nCount = pDocs->Count(); 157 for ( sal_uInt16 j=0; j<nCount; j++, ppDoc++ ) 158 { 159 ScDocument* pDoc = (ScDocument*)*ppDoc; 160 pDoc->TrackFormulas(); 161 pDoc->GetDocumentShell()->Broadcast( SfxSimpleHint( FID_DATACHANGED ) ); 162 pDoc->ResetChanged( ScRange(0,0,0,MAXCOL,MAXROW,MAXTAB) ); 163 } 164 } 165 166 // XEventListener 167 168 void SAL_CALL ScAddInListener::disposing( const ::com::sun::star::lang::EventObject& /* Source */ ) 169 { 170 // hold a ref so this is not deleted at removeResultListener 171 uno::Reference<sheet::XResultListener> xRef( this ); 172 173 if ( xVolRes.is() ) 174 { 175 xVolRes->removeResultListener( this ); 176 xVolRes = NULL; 177 } 178 } 179 180 181 //------------------------------------------------------------------------ 182