/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * 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 . */ #if defined UNX #include #else // UNX #include #ifndef PATH_MAX #define PATH_MAX _MAX_PATH #endif #endif // UNX #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "sfx2/sfxhelp.hxx" #include #include "sfxtypes.hxx" #include "sfx2/sfxresid.hxx" #include "arrdecl.hxx" #include #include #include #include #include #include "fltfnc.hxx" #include "nfltdlg.hxx" #include #include #include #include #include #include #include "appdata.hxx" #include "openflag.hxx" #include "app.hrc" #include "virtmenu.hxx" #include #include #include "imestatuswindow.hxx" #include "workwin.hxx" #include #include #include "sfx2/stbitem.hxx" #include "eventsupplier.hxx" #include #ifdef DBG_UTIL #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace ::com::sun::star; // Static member SfxApplication* SfxApplication::pApp = NULL; #ifndef DISABLE_SCRIPTING static BasicDLL* pBasic = NULL; #endif static SfxHelp* pSfxHelp = NULL; namespace { class theApplicationMutex : public rtl::Static {}; } #include #include #include "sfx2/imagemgr.hxx" #include "fwkhelper.hxx" SfxApplication* SfxApplication::GetOrCreate() { // SFX on demand ::osl::MutexGuard aGuard(theApplicationMutex::get()); if (!pApp) { RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mb93783) ::SfxApplication::SetApp" ); pApp = new SfxApplication; // at the moment a bug may occur when Initialize_Impl returns FALSE, // but this is only temporary because all code that may cause such // a fault will be moved outside the SFX pApp->Initialize_Impl(); ::framework::SetImageProducer( GetImage ); ::framework::SetRefreshToolbars( RefreshToolbars ); ::framework::SetToolBoxControllerCreator( SfxToolBoxControllerFactory ); ::framework::SetStatusBarControllerCreator( SfxStatusBarControllerFactory ); ::framework::SetDockingWindowCreator( SfxDockingWindowFactory ); ::framework::SetIsDockingWindowVisible( IsDockingWindowVisible ); ::framework::SetActivateToolPanel( &SfxViewFrame::ActivateToolPanel ); Application::SetHelp( pSfxHelp ); if ( SvtHelpOptions().IsHelpTips() ) Help::EnableQuickHelp(); else Help::DisableQuickHelp(); if ( SvtHelpOptions().IsHelpTips() && SvtHelpOptions().IsExtendedHelp() ) Help::EnableBalloonHelp(); else Help::DisableBalloonHelp(); } return pApp; } SfxApplication::SfxApplication() : pAppData_Impl( 0 ) { RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mb93783) ::SfxApplication::SfxApplication" ); SetName( DEFINE_CONST_UNICODE("StarOffice") ); SvtViewOptions::AcquireOptions(); pAppData_Impl = new SfxAppData_Impl( this ); pAppData_Impl->m_xImeStatusWindow->init(); pApp->PreInit(); RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ initialize DDE" ); sal_Bool bOk = InitializeDde(); #ifdef DBG_UTIL if( !bOk ) { rtl::OStringBuffer aStr( RTL_CONSTASCII_STRINGPARAM("No DDE-Service possible. Error: ")); if( GetDdeService() ) aStr.append(static_cast(GetDdeService()->GetError())); else aStr.append('?'); DBG_ASSERT( sal_False, aStr.getStr() ); } #else (void)bOk; #endif pSfxHelp = new SfxHelp; #ifndef DISABLE_SCRIPTING pBasic = new BasicDLL; StarBASIC::SetGlobalErrorHdl( LINK( this, SfxApplication, GlobalBasicErrorHdl_Impl ) ); #endif RTL_LOGFILE_CONTEXT_TRACE( aLog, "} initialize DDE" ); } SfxApplication::~SfxApplication() { OSL_ENSURE( GetObjectShells_Impl().size() == 0, "Memory leak: some object shells were not removed!" ); Broadcast( SfxSimpleHint(SFX_HINT_DYING) ); SfxModule::DestroyModules_Impl(); delete pSfxHelp; Application::SetHelp( NULL ); // delete global options SvtViewOptions::ReleaseOptions(); #ifndef DISABLE_SCRIPTING delete pBasic; #endif if ( !pAppData_Impl->bDowning ) Deinitialize(); delete pAppData_Impl; pApp = 0; } //==================================================================== const String& SfxApplication::GetLastDir_Impl() const /* [Description] Internal method by which the last set directory with the method in SFX is returned. This is usually the most recently addressed by the SfxFileDialog directory. [Cross-reference] */ { return pAppData_Impl->aLastDir; } const String& SfxApplication::GetLastSaveDirectory() const /* [Description] As , only external [Cross-reference] */ { return GetLastDir_Impl(); } //-------------------------------------------------------------------- void SfxApplication::SetLastDir_Impl ( const String& rNewDir /* Complete directory path as a string */ ) /* [Description] Internal Method, by which a directory path is set that was last addressed (eg by the SfxFileDialog). [Cross-reference] */ { pAppData_Impl->aLastDir = rNewDir; } //-------------------------------------------------------------------- void SfxApplication::ResetLastDir() { String aEmpty; pAppData_Impl->aLastDir = aEmpty; } //-------------------------------------------------------------------- SfxDispatcher* SfxApplication::GetDispatcher_Impl() { return pAppData_Impl->pViewFrame? pAppData_Impl->pViewFrame->GetDispatcher(): pAppData_Impl->pAppDispat; } //-------------------------------------------------------------------- void SfxApplication::SetViewFrame_Impl( SfxViewFrame *pFrame ) { if ( pFrame != pAppData_Impl->pViewFrame ) { // get the containerframes ( if one of the frames is an InPlaceFrame ) SfxViewFrame *pOldContainerFrame = pAppData_Impl->pViewFrame; while ( pOldContainerFrame && pOldContainerFrame->GetParentViewFrame_Impl() ) pOldContainerFrame = pOldContainerFrame->GetParentViewFrame_Impl(); SfxViewFrame *pNewContainerFrame = pFrame; while ( pNewContainerFrame && pNewContainerFrame->GetParentViewFrame_Impl() ) pNewContainerFrame = pNewContainerFrame->GetParentViewFrame_Impl(); // DocWinActivate : both frames belong to the same TopWindow // TopWinActivate : both frames belong to different TopWindows sal_Bool bTaskActivate = pOldContainerFrame != pNewContainerFrame; if ( pOldContainerFrame ) { if ( bTaskActivate ) NotifyEvent( SfxViewEventHint( SFX_EVENT_DEACTIVATEDOC, GlobalEventConfig::GetEventName(STR_EVENT_DEACTIVATEDOC), pOldContainerFrame->GetObjectShell(), pOldContainerFrame->GetFrame().GetController() ) ); pOldContainerFrame->DoDeactivate( bTaskActivate, pFrame ); if( pOldContainerFrame->GetProgress() ) pOldContainerFrame->GetProgress()->Suspend(); } pAppData_Impl->pViewFrame = pFrame; if( pNewContainerFrame ) { pNewContainerFrame->DoActivate( bTaskActivate ); if ( bTaskActivate && pNewContainerFrame->GetObjectShell() ) { pNewContainerFrame->GetObjectShell()->PostActivateEvent_Impl( pNewContainerFrame ); NotifyEvent(SfxViewEventHint(SFX_EVENT_ACTIVATEDOC, GlobalEventConfig::GetEventName(STR_EVENT_ACTIVATEDOC), pNewContainerFrame->GetObjectShell(), pNewContainerFrame->GetFrame().GetController() ) ); } SfxProgress *pProgress = pNewContainerFrame->GetProgress(); if ( pProgress ) { if( pProgress->IsSuspended() ) pProgress->Resume(); else pProgress->SetState( pProgress->GetState() ); } if ( pAppData_Impl->pViewFrame->GetViewShell() ) { SfxDispatcher* pDisp = pAppData_Impl->pViewFrame->GetDispatcher(); pDisp->Flush(); pDisp->Update_Impl(sal_True); } } } // even if the frame actually didn't change, ensure its document is forwarded // to SfxObjectShell::SetCurrentComponent. // Otherwise, the CurrentComponent might not be correct, in case it has meanwhile // been reset to some other document, by some non-SFX component. // #i49133# / 2007-12-19 / frank.schoenheit@sun.com if ( pFrame && pFrame->GetViewShell() ) pFrame->GetViewShell()->SetCurrentDocument(); } //--------------------------------------------------------------------- ResMgr* SfxApplication::CreateResManager( const char *pPrefix ) { return ResMgr::CreateResMgr(pPrefix); } //-------------------------------------------------------------------- ResMgr* SfxApplication::GetSfxResManager() { return SfxResId::GetResMgr(); } //------------------------------------------------------------------------ void SfxApplication::SetProgress_Impl ( SfxProgress *pProgress ) { DBG_ASSERT( ( !pAppData_Impl->pProgress && pProgress ) || ( pAppData_Impl->pProgress && !pProgress ), "Progress acitivation/deacitivation mismatch" ); if ( pAppData_Impl->pProgress && pProgress ) { pAppData_Impl->pProgress->Suspend(); pAppData_Impl->pProgress->UnLock(); delete pAppData_Impl->pProgress; } pAppData_Impl->pProgress = pProgress; } //------------------------------------------------------------------------ sal_uInt16 SfxApplication::GetFreeIndex() { return pAppData_Impl->aIndexBitSet.GetFreeIndex()+1; } //------------------------------------------------------------------------ void SfxApplication::ReleaseIndex(sal_uInt16 i) { pAppData_Impl->aIndexBitSet.ReleaseIndex(i-1); } //-------------------------------------------------------------------- Window* SfxApplication::GetTopWindow() const { SfxWorkWindow* pWork = GetWorkWindow_Impl( SfxViewFrame::Current() ); return pWork ? pWork->GetWindow() : NULL; } SfxTbxCtrlFactArr_Impl& SfxApplication::GetTbxCtrlFactories_Impl() const { return *pAppData_Impl->pTbxCtrlFac; } SfxStbCtrlFactArr_Impl& SfxApplication::GetStbCtrlFactories_Impl() const { return *pAppData_Impl->pStbCtrlFac; } SfxMenuCtrlFactArr_Impl& SfxApplication::GetMenuCtrlFactories_Impl() const { return *pAppData_Impl->pMenuCtrlFac; } SfxViewFrameArr_Impl& SfxApplication::GetViewFrames_Impl() const { return *pAppData_Impl->pViewFrames; } SfxViewShellArr_Impl& SfxApplication::GetViewShells_Impl() const { return *pAppData_Impl->pViewShells; } SfxObjectShellArr_Impl& SfxApplication::GetObjectShells_Impl() const { return *pAppData_Impl->pObjShells; } void SfxApplication::Invalidate( sal_uInt16 nId ) { for( SfxViewFrame* pFrame = SfxViewFrame::GetFirst(); pFrame; pFrame = SfxViewFrame::GetNext( *pFrame ) ) Invalidate_Impl( pFrame->GetBindings(), nId ); } #define DOSTRING( x ) #x #define STRING( x ) DOSTRING( x ) #ifndef DISABLE_SCRIPTING typedef long (SAL_CALL *basicide_handle_basic_error)(void*); typedef rtl_uString* (SAL_CALL *basicide_choose_macro)(void*, sal_Bool, rtl_uString*); typedef void* (SAL_CALL *basicide_macro_organizer)(sal_Int16); extern "C" { static void SAL_CALL thisModule() {} } #endif IMPL_LINK( SfxApplication, GlobalBasicErrorHdl_Impl, StarBASIC*, pStarBasic ) { #ifdef DISABLE_SCRIPTING (void) pStarBasic; return 0; #else // get basctl dllname static ::rtl::OUString aLibName( SVLIBRARY( "basctl" ) ); // load module oslModule handleMod = osl_loadModuleRelative( &thisModule, aLibName.pData, 0 ); // get symbol ::rtl::OUString aSymbol( "basicide_handle_basic_error" ); basicide_handle_basic_error pSymbol = (basicide_handle_basic_error) osl_getFunctionSymbol( handleMod, aSymbol.pData ); // call basicide_handle_basic_error in basctl long nRet = pSymbol ? pSymbol( pStarBasic ) : 0; return nRet; #endif } sal_Bool SfxApplication::IsXScriptURL( const String& rScriptURL ) { sal_Bool result = sal_False; #ifdef DISABLE_SCRIPTING (void) rScriptURL; #else ::com::sun::star::uno::Reference < ::com::sun::star::lang::XMultiServiceFactory > xSMgr = ::comphelper::getProcessServiceFactory(); ::com::sun::star::uno::Reference < ::com::sun::star::uri::XUriReferenceFactory > xFactory( xSMgr->createInstance( ::rtl::OUString( "com.sun.star.uri.UriReferenceFactory" ) ), ::com::sun::star::uno::UNO_QUERY ); if ( xFactory.is() ) { try { ::com::sun::star::uno::Reference < ::com::sun::star::uri::XVndSunStarScriptUrl > xUrl( xFactory->parse( rScriptURL ), ::com::sun::star::uno::UNO_QUERY ); if ( xUrl.is() ) { result = sal_True; } } catch (const ::com::sun::star::uno::RuntimeException&) { // ignore, will just return FALSE } } #endif return result; } ::rtl::OUString SfxApplication::ChooseScript() { ::rtl::OUString aScriptURL; #ifndef DISABLE_SCRIPTING SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create(); if ( pFact ) { OSL_TRACE("create selector dialog"); const SfxViewFrame* pViewFrame = SfxViewFrame::Current(); const SfxFrame* pFrame = pViewFrame ? &pViewFrame->GetFrame() : NULL; uno::Reference< frame::XFrame > xFrame( pFrame ? pFrame->GetFrameInterface() : uno::Reference< frame::XFrame >() ); AbstractScriptSelectorDialog* pDlg = pFact->CreateScriptSelectorDialog( NULL, sal_False, xFrame ); OSL_TRACE("done, now exec it"); sal_uInt16 nRet = pDlg->Execute(); OSL_TRACE("has returned"); if ( nRet == RET_OK ) { aScriptURL = pDlg->GetScriptURL(); } delete pDlg; } #endif return aScriptURL; } void SfxApplication::MacroOrganizer( sal_Int16 nTabId ) { #ifdef DISABLE_SCRIPTING (void) nTabId; #else // get basctl dllname static ::rtl::OUString aLibName( SVLIBRARY( "basctl" ) ); // load module oslModule handleMod = osl_loadModuleRelative( &thisModule, aLibName.pData, 0 ); // get symbol ::rtl::OUString aSymbol( "basicide_macro_organizer" ); basicide_macro_organizer pSymbol = (basicide_macro_organizer) osl_getFunctionSymbol( handleMod, aSymbol.pData ); // call basicide_choose_macro in basctl pSymbol( nTabId ); #endif } ErrCode SfxApplication::CallBasic( const String& rCode, BasicManager* pMgr, SbxArray* pArgs, SbxValue* pRet ) { #ifdef DISABLE_SCRIPTING (void) rCode; (void) pMgr; (void) pArgs; (void) pRet; return ERRCODE_BASIC_CANNOT_LOAD; #else return pMgr->ExecuteMacro( rCode, pArgs, pRet); #endif } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */