| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sc.hxx" |
| |
| |
| |
| #include <tools/debug.hxx> |
| #include <sfx2/objsh.hxx> |
| |
| |
| #include "addinlis.hxx" |
| #include "miscuno.hxx" // SC_IMPL_SERVICE_INFO |
| #include "document.hxx" |
| #include "brdcst.hxx" |
| #include "unoguard.hxx" |
| #include "sc.hrc" |
| |
| using namespace com::sun::star; |
| |
| //------------------------------------------------------------------------ |
| |
| //SMART_UNO_IMPLEMENTATION( ScAddInListener, UsrObject ); |
| |
| SC_SIMPLE_SERVICE_INFO( ScAddInListener, "ScAddInListener", "stardiv.one.sheet.AddInListener" ) |
| |
| //------------------------------------------------------------------------ |
| |
| List ScAddInListener::aAllListeners; |
| |
| //------------------------------------------------------------------------ |
| |
| // static |
| ScAddInListener* ScAddInListener::CreateListener( |
| uno::Reference<sheet::XVolatileResult> xVR, ScDocument* pDoc ) |
| { |
| ScAddInListener* pNew = new ScAddInListener( xVR, pDoc ); |
| |
| pNew->acquire(); // for aAllListeners |
| aAllListeners.Insert( pNew, LIST_APPEND ); |
| |
| if ( xVR.is() ) |
| xVR->addResultListener( pNew ); // after at least 1 ref exists! |
| |
| return pNew; |
| } |
| |
| ScAddInListener::ScAddInListener( uno::Reference<sheet::XVolatileResult> xVR, ScDocument* pDoc ) : |
| xVolRes( xVR ) |
| { |
| pDocs = new ScAddInDocs( 1, 1 ); |
| pDocs->Insert( pDoc ); |
| } |
| |
| ScAddInListener::~ScAddInListener() |
| { |
| delete pDocs; |
| } |
| |
| // static |
| ScAddInListener* ScAddInListener::Get( uno::Reference<sheet::XVolatileResult> xVR ) |
| { |
| sheet::XVolatileResult* pComp = xVR.get(); |
| |
| sal_uLong nCount = aAllListeners.Count(); |
| for (sal_uLong nPos=0; nPos<nCount; nPos++) |
| { |
| ScAddInListener* pLst = (ScAddInListener*)aAllListeners.GetObject(nPos); |
| if ( pComp == (sheet::XVolatileResult*)pLst->xVolRes.get() ) |
| return pLst; |
| } |
| return NULL; // not found |
| } |
| |
| //! move to some container object? |
| // static |
| void ScAddInListener::RemoveDocument( ScDocument* pDocumentP ) |
| { |
| sal_uLong nPos = aAllListeners.Count(); |
| while (nPos) |
| { |
| // loop backwards because elements are removed |
| --nPos; |
| ScAddInListener* pLst = (ScAddInListener*)aAllListeners.GetObject(nPos); |
| ScAddInDocs* p = pLst->pDocs; |
| sal_uInt16 nFoundPos; |
| if ( p->Seek_Entry( pDocumentP, &nFoundPos ) ) |
| { |
| p->Remove( nFoundPos ); |
| if ( p->Count() == 0 ) |
| { |
| // this AddIn is no longer used |
| // dont delete, just remove the ref for the list |
| |
| aAllListeners.Remove( nPos ); |
| |
| if ( pLst->xVolRes.is() ) |
| pLst->xVolRes->removeResultListener( pLst ); |
| |
| pLst->release(); // Ref for aAllListeners - pLst may be deleted here |
| } |
| } |
| } |
| } |
| |
| //------------------------------------------------------------------------ |
| |
| // XResultListener |
| |
| void SAL_CALL ScAddInListener::modified( const ::com::sun::star::sheet::ResultEvent& aEvent ) |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| ScUnoGuard aGuard; //! or generate a UserEvent |
| |
| aResult = aEvent.Value; // store result |
| |
| if ( !HasListeners() ) |
| { |
| //! remove from list and removeListener, as in RemoveDocument ??? |
| |
| #if 0 |
| //! this will crash if called before first StartListening !!! |
| aAllListeners.Remove( this ); |
| if ( xVolRes.is() ) |
| xVolRes->removeResultListener( this ); |
| release(); // Ref for aAllListeners - this may be deleted here |
| return; |
| #endif |
| } |
| |
| // notify document of changes |
| |
| Broadcast( ScHint( SC_HINT_DATACHANGED, ScAddress(), NULL ) ); |
| |
| const ScDocument** ppDoc = (const ScDocument**) pDocs->GetData(); |
| sal_uInt16 nCount = pDocs->Count(); |
| for ( sal_uInt16 j=0; j<nCount; j++, ppDoc++ ) |
| { |
| ScDocument* pDoc = (ScDocument*)*ppDoc; |
| pDoc->TrackFormulas(); |
| pDoc->GetDocumentShell()->Broadcast( SfxSimpleHint( FID_DATACHANGED ) ); |
| pDoc->ResetChanged( ScRange(0,0,0,MAXCOL,MAXROW,MAXTAB) ); |
| } |
| } |
| |
| // XEventListener |
| |
| void SAL_CALL ScAddInListener::disposing( const ::com::sun::star::lang::EventObject& /* Source */ ) |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| // hold a ref so this is not deleted at removeResultListener |
| uno::Reference<sheet::XResultListener> xRef( this ); |
| |
| if ( xVolRes.is() ) |
| { |
| xVolRes->removeResultListener( this ); |
| xVolRes = NULL; |
| } |
| } |
| |
| |
| //------------------------------------------------------------------------ |
| |
| |
| |