1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sc.hxx" 30 31 32 33 #include <tools/debug.hxx> 34 #include <sfx2/objsh.hxx> 35 36 37 #include "addinlis.hxx" 38 #include "miscuno.hxx" // SC_IMPL_SERVICE_INFO 39 #include "document.hxx" 40 #include "brdcst.hxx" 41 #include "unoguard.hxx" 42 #include "sc.hrc" 43 44 using namespace com::sun::star; 45 46 //------------------------------------------------------------------------ 47 48 //SMART_UNO_IMPLEMENTATION( ScAddInListener, UsrObject ); 49 50 SC_SIMPLE_SERVICE_INFO( ScAddInListener, "ScAddInListener", "stardiv.one.sheet.AddInListener" ) 51 52 //------------------------------------------------------------------------ 53 54 List ScAddInListener::aAllListeners; 55 56 //------------------------------------------------------------------------ 57 58 // static 59 ScAddInListener* ScAddInListener::CreateListener( 60 uno::Reference<sheet::XVolatileResult> xVR, ScDocument* pDoc ) 61 { 62 ScAddInListener* pNew = new ScAddInListener( xVR, pDoc ); 63 64 pNew->acquire(); // for aAllListeners 65 aAllListeners.Insert( pNew, LIST_APPEND ); 66 67 if ( xVR.is() ) 68 xVR->addResultListener( pNew ); // after at least 1 ref exists! 69 70 return pNew; 71 } 72 73 ScAddInListener::ScAddInListener( uno::Reference<sheet::XVolatileResult> xVR, ScDocument* pDoc ) : 74 xVolRes( xVR ) 75 { 76 pDocs = new ScAddInDocs( 1, 1 ); 77 pDocs->Insert( pDoc ); 78 } 79 80 ScAddInListener::~ScAddInListener() 81 { 82 delete pDocs; 83 } 84 85 // static 86 ScAddInListener* ScAddInListener::Get( uno::Reference<sheet::XVolatileResult> xVR ) 87 { 88 sheet::XVolatileResult* pComp = xVR.get(); 89 90 sal_uLong nCount = aAllListeners.Count(); 91 for (sal_uLong nPos=0; nPos<nCount; nPos++) 92 { 93 ScAddInListener* pLst = (ScAddInListener*)aAllListeners.GetObject(nPos); 94 if ( pComp == (sheet::XVolatileResult*)pLst->xVolRes.get() ) 95 return pLst; 96 } 97 return NULL; // not found 98 } 99 100 //! move to some container object? 101 // static 102 void ScAddInListener::RemoveDocument( ScDocument* pDocumentP ) 103 { 104 sal_uLong nPos = aAllListeners.Count(); 105 while (nPos) 106 { 107 // loop backwards because elements are removed 108 --nPos; 109 ScAddInListener* pLst = (ScAddInListener*)aAllListeners.GetObject(nPos); 110 ScAddInDocs* p = pLst->pDocs; 111 sal_uInt16 nFoundPos; 112 if ( p->Seek_Entry( pDocumentP, &nFoundPos ) ) 113 { 114 p->Remove( nFoundPos ); 115 if ( p->Count() == 0 ) 116 { 117 // this AddIn is no longer used 118 // dont delete, just remove the ref for the list 119 120 aAllListeners.Remove( nPos ); 121 122 if ( pLst->xVolRes.is() ) 123 pLst->xVolRes->removeResultListener( pLst ); 124 125 pLst->release(); // Ref for aAllListeners - pLst may be deleted here 126 } 127 } 128 } 129 } 130 131 //------------------------------------------------------------------------ 132 133 // XResultListener 134 135 void SAL_CALL ScAddInListener::modified( const ::com::sun::star::sheet::ResultEvent& aEvent ) 136 throw(::com::sun::star::uno::RuntimeException) 137 { 138 ScUnoGuard aGuard; //! or generate a UserEvent 139 140 aResult = aEvent.Value; // store result 141 142 if ( !HasListeners() ) 143 { 144 //! remove from list and removeListener, as in RemoveDocument ??? 145 146 #if 0 147 //! this will crash if called before first StartListening !!! 148 aAllListeners.Remove( this ); 149 if ( xVolRes.is() ) 150 xVolRes->removeResultListener( this ); 151 release(); // Ref for aAllListeners - this may be deleted here 152 return; 153 #endif 154 } 155 156 // notify document of changes 157 158 Broadcast( ScHint( SC_HINT_DATACHANGED, ScAddress(), NULL ) ); 159 160 const ScDocument** ppDoc = (const ScDocument**) pDocs->GetData(); 161 sal_uInt16 nCount = pDocs->Count(); 162 for ( sal_uInt16 j=0; j<nCount; j++, ppDoc++ ) 163 { 164 ScDocument* pDoc = (ScDocument*)*ppDoc; 165 pDoc->TrackFormulas(); 166 pDoc->GetDocumentShell()->Broadcast( SfxSimpleHint( FID_DATACHANGED ) ); 167 pDoc->ResetChanged( ScRange(0,0,0,MAXCOL,MAXROW,MAXTAB) ); 168 } 169 } 170 171 // XEventListener 172 173 void SAL_CALL ScAddInListener::disposing( const ::com::sun::star::lang::EventObject& /* Source */ ) 174 throw(::com::sun::star::uno::RuntimeException) 175 { 176 // hold a ref so this is not deleted at removeResultListener 177 uno::Reference<sheet::XResultListener> xRef( this ); 178 179 if ( xVolRes.is() ) 180 { 181 xVolRes->removeResultListener( this ); 182 xVolRes = NULL; 183 } 184 } 185 186 187 //------------------------------------------------------------------------ 188 189 190 191