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 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 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