1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <config_feature_desktop.h>
21 #include <sal/log.hxx>
22 #include <tools/debug.hxx>
24 #include <sfx2/app.hxx>
25 #include <sfx2/frame.hxx>
26 #include <basic/sberrors.hxx>
27 #include <tools/svlibrary.h>
29 #include <svl/svdde.hxx>
30 #include <unotools/configmgr.hxx>
31 #include <com/sun/star/frame/XFrame.hpp>
32 #include <comphelper/processfactory.hxx>
33 #include <com/sun/star/uri/UriReferenceFactory.hpp>
34 #include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
35 #include <basic/basmgr.hxx>
36 #include <vcl/svapp.hxx>
37 #include <sfx2/sfxhelp.hxx>
38 #include <sfx2/progress.hxx>
39 #include <sfx2/objsh.hxx>
40 #include <sfx2/dispatch.hxx>
41 #include <sfx2/viewsh.hxx>
42 #include <sfx2/viewfrm.hxx>
43 #include <appdata.hxx>
44 #include <sfx2/module.hxx>
45 #include <sfx2/event.hxx>
46 #include <workwin.hxx>
47 #include <sfx2/sidebar/Theme.hxx>
48 #include <sfx2/tbxctrl.hxx>
49 #include <sfx2/sfxdlg.hxx>
50 #include <sfx2/stbitem.hxx>
51 #include <sfx2/dockwin.hxx>
52 #include <shellimpl.hxx>
53 #include <comphelper/lok.hxx>
55 #include <svtools/helpopt.hxx>
56 #include <unotools/viewoptions.hxx>
57 #include <rtl/instance.hxx>
58 #include <rtl/strbuf.hxx>
60 #include <framework/sfxhelperfunctions.hxx>
61 #include <fwkhelper.hxx>
63 #include "getbasctlfunction.hxx"
65 using namespace ::com::sun::star
;
67 static SfxApplication
* g_pSfxApplication
= nullptr;
69 #if HAVE_FEATURE_DESKTOP
70 static SfxHelp
* pSfxHelp
= nullptr;
75 class theApplicationMutex
76 : public rtl::Static
<osl::Mutex
, theApplicationMutex
> {};
79 SfxApplication
* SfxApplication::Get()
81 return g_pSfxApplication
;
84 void SfxApplication::SetModule(SfxToolsModule nSharedLib
, std::unique_ptr
<SfxModule
> pModule
)
86 assert(g_pSfxApplication
!= nullptr);
88 g_pSfxApplication
->pImpl
->aModules
[nSharedLib
] = std::move(pModule
);
91 SfxModule
* SfxApplication::GetModule(SfxToolsModule nSharedLib
)
93 if (!g_pSfxApplication
) // It is possible GetModule is called before SfxApplication is initialised via GetOrCreate()
95 return g_pSfxApplication
->pImpl
->aModules
[nSharedLib
].get();
98 SfxApplication
* SfxApplication::GetOrCreate()
101 ::osl::MutexGuard
aGuard(theApplicationMutex::get());
102 if (!g_pSfxApplication
)
104 SAL_INFO( "sfx.appl", "SfxApplication::SetApp" );
106 g_pSfxApplication
= new SfxApplication
;
108 // at the moment a bug may occur when Initialize_Impl returns FALSE,
109 // but this is only temporary because all code that may cause such
110 // a fault will be moved outside the SFX
111 g_pSfxApplication
->Initialize_Impl();
113 ::framework::SetRefreshToolbars( RefreshToolbars
);
114 ::framework::SetToolBoxControllerCreator( SfxToolBoxControllerFactory
);
115 ::framework::SetStatusBarControllerCreator( SfxStatusBarControllerFactory
);
116 ::framework::SetDockingWindowCreator( SfxDockingWindowFactory
);
117 ::framework::SetIsDockingWindowVisible( IsDockingWindowVisible
);
118 #if HAVE_FEATURE_DESKTOP
119 Application::SetHelp( pSfxHelp
);
120 if (!utl::ConfigManager::IsFuzzing() && SvtHelpOptions().IsHelpTips())
121 Help::EnableQuickHelp();
123 Help::DisableQuickHelp();
124 if (!utl::ConfigManager::IsFuzzing() && SvtHelpOptions().IsHelpTips() && SvtHelpOptions().IsExtendedHelp())
125 Help::EnableBalloonHelp();
127 Help::DisableBalloonHelp();
130 return g_pSfxApplication
;
133 SfxApplication::SfxApplication()
134 : pImpl( new SfxAppData_Impl
)
136 SetName( "StarOffice" );
137 if (!utl::ConfigManager::IsFuzzing())
138 SvtViewOptions::AcquireOptions();
140 SAL_INFO( "sfx.appl", "{ initialize DDE" );
142 bool bOk
= InitializeDde();
147 OStringBuffer
aStr("No DDE-Service possible. Error: ");
148 if( GetDdeService() )
149 aStr
.append(static_cast<sal_Int32
>(GetDdeService()->GetError()));
152 SAL_WARN( "sfx.appl", aStr
.getStr() );
158 #if HAVE_FEATURE_DESKTOP
159 pSfxHelp
= new SfxHelp
;
162 #if HAVE_FEATURE_SCRIPTING
163 StarBASIC::SetGlobalErrorHdl( LINK( this, SfxApplication
, GlobalBasicErrorHdl_Impl
) );
166 SAL_INFO( "sfx.appl", "} initialize DDE" );
169 SfxApplication::~SfxApplication()
171 SAL_WARN_IF(GetObjectShells_Impl().size() != 0, "sfx.appl", "Memory leak: some object shells were not removed!");
173 Broadcast( SfxHint(SfxHintId::Dying
) );
175 for (auto &module
: pImpl
->aModules
) // Clear modules
178 #if HAVE_FEATURE_DESKTOP
180 Application::SetHelp();
183 // delete global options
184 if (!utl::ConfigManager::IsFuzzing())
185 SvtViewOptions::ReleaseOptions();
187 if ( !pImpl
->bDowning
)
190 g_pSfxApplication
= nullptr;
194 const OUString
& SfxApplication::GetLastDir_Impl() const
198 Internal method by which the last set directory with the method
199 <SfxApplication::SetLastDir_Impl()> in SFX is returned.
201 This is usually the most recently addressed by the
202 SfxFileDialog directory.
205 <SfxApplication::SetLastDir_Impl()>
209 return pImpl
->aLastDir
;
212 void SfxApplication::SetLastDir_Impl
214 const OUString
& rNewDir
/* Complete directory path as a string */
219 Internal Method, by which a directory path is set that was last addressed
220 (eg by the SfxFileDialog).
223 <SfxApplication::GetLastDir_Impl()>
227 pImpl
->aLastDir
= rNewDir
;
231 void SfxApplication::ResetLastDir()
233 pImpl
->aLastDir
.clear();
237 SfxDispatcher
* SfxApplication::GetDispatcher_Impl()
239 return pImpl
->pViewFrame
? pImpl
->pViewFrame
->GetDispatcher() : pImpl
->pAppDispat
.get();
243 void SfxApplication::SetViewFrame_Impl( SfxViewFrame
*pFrame
)
245 if ( pFrame
!= pImpl
->pViewFrame
)
247 SfxViewFrame
*pOldFrame
= pImpl
->pViewFrame
;
249 // DocWinActivate : both frames belong to the same TopWindow
250 // TopWinActivate : both frames belong to different TopWindows
252 bool bTaskActivate
= pOldFrame
!= pFrame
;
257 NotifyEvent( SfxViewEventHint( SfxEventHintId::DeactivateDoc
, GlobalEventConfig::GetEventName(GlobalEventId::DEACTIVATEDOC
), pOldFrame
->GetObjectShell(), pOldFrame
->GetFrame().GetController() ) );
259 pOldFrame
->DoDeactivate( bTaskActivate
, pFrame
);
261 if( pOldFrame
->GetProgress() )
262 pOldFrame
->GetProgress()->Suspend();
265 pImpl
->pViewFrame
= pFrame
;
269 pFrame
->DoActivate( bTaskActivate
);
270 if ( bTaskActivate
&& pFrame
->GetObjectShell() )
272 pFrame
->GetObjectShell()->PostActivateEvent_Impl( pFrame
);
273 NotifyEvent(SfxViewEventHint(SfxEventHintId::ActivateDoc
, GlobalEventConfig::GetEventName(GlobalEventId::ACTIVATEDOC
), pFrame
->GetObjectShell(), pFrame
->GetFrame().GetController() ) );
276 SfxProgress
*pProgress
= pFrame
->GetProgress();
279 if( pProgress
->IsSuspended() )
282 pProgress
->SetState( pProgress
->GetState() );
285 if ( pImpl
->pViewFrame
->GetViewShell() )
287 SfxDispatcher
* pDisp
= pImpl
->pViewFrame
->GetDispatcher();
289 pDisp
->Update_Impl(true);
294 // even if the frame actually didn't change, ensure its document is forwarded
295 // to SfxObjectShell::SetCurrentComponent.
296 // Otherwise, the CurrentComponent might not be correct, in case it has meanwhile
297 // been reset to some other document, by some non-SFX component. #i49133#
298 if ( pFrame
&& pFrame
->GetViewShell() )
299 pFrame
->GetViewShell()->SetCurrentDocument();
302 void SfxApplication::SetProgress_Impl
304 SfxProgress
*pProgress
307 DBG_ASSERT( ( !pImpl
->pProgress
&& pProgress
) ||
308 ( pImpl
->pProgress
&& !pProgress
),
309 "Progress activation/deactivation mismatch" );
311 if ( pImpl
->pProgress
&& pProgress
)
313 pImpl
->pProgress
->Suspend();
314 delete pImpl
->pProgress
;
317 pImpl
->pProgress
= pProgress
;
321 sal_uInt16
SfxApplication::GetFreeIndex()
323 return pImpl
->aIndexBitSet
.GetFreeIndex()+1;
327 void SfxApplication::ReleaseIndex(sal_uInt16 i
)
329 pImpl
->aIndexBitSet
.ReleaseIndex(i
-1);
333 vcl::Window
* SfxApplication::GetTopWindow() const
335 SfxWorkWindow
* pWork
= GetWorkWindow_Impl( SfxViewFrame::Current() );
336 return pWork
? pWork
->GetWindow() : nullptr;
339 SfxTbxCtrlFactArr_Impl
& SfxApplication::GetTbxCtrlFactories_Impl() const
341 return *pImpl
->pTbxCtrlFac
;
344 SfxStbCtrlFactArr_Impl
& SfxApplication::GetStbCtrlFactories_Impl() const
346 return *pImpl
->pStbCtrlFac
;
349 SfxViewFrameArr_Impl
& SfxApplication::GetViewFrames_Impl() const
351 return *pImpl
->pViewFrames
;
354 SfxViewShellArr_Impl
& SfxApplication::GetViewShells_Impl() const
356 return *pImpl
->pViewShells
;
359 SfxObjectShellArr_Impl
& SfxApplication::GetObjectShells_Impl() const
361 return *pImpl
->pObjShells
;
364 void SfxApplication::Invalidate( sal_uInt16 nId
)
366 for( SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst(); pFrame
; pFrame
= SfxViewFrame::GetNext( *pFrame
) )
367 Invalidate_Impl( pFrame
->GetBindings(), nId
);
370 #if HAVE_FEATURE_SCRIPTING
372 #ifndef DISABLE_DYNLOADING
374 typedef long (*basicide_handle_basic_error
)(void const *);
375 typedef void (*basicide_macro_organizer
)(void *, sal_Int16
);
379 extern "C" long basicide_handle_basic_error(void const*);
380 extern "C" void basicide_macro_organizer(void*, sal_Int16
);
386 IMPL_STATIC_LINK( SfxApplication
, GlobalBasicErrorHdl_Impl
, StarBASIC
*, pStarBasic
, bool )
388 #if !HAVE_FEATURE_SCRIPTING
393 #ifndef DISABLE_DYNLOADING
394 basicide_handle_basic_error pSymbol
= reinterpret_cast<basicide_handle_basic_error
>(sfx2::getBasctlFunction("basicide_handle_basic_error"));
396 // call basicide_handle_basic_error in basctl
397 bool bRet
= pSymbol( pStarBasic
);
401 bool bRet
= basicide_handle_basic_error( pStarBasic
);
410 bool SfxApplication::IsXScriptURL( const OUString
& rScriptURL
)
414 #if !HAVE_FEATURE_SCRIPTING
417 css::uno::Reference
< css::uno::XComponentContext
> xContext
=
418 ::comphelper::getProcessComponentContext();
420 css::uno::Reference
< css::uri::XUriReferenceFactory
>
421 xFactory
= css::uri::UriReferenceFactory::create( xContext
);
425 css::uno::Reference
< css::uri::XVndSunStarScriptUrl
>
426 xUrl( xFactory
->parse( rScriptURL
), css::uno::UNO_QUERY
);
433 catch (const css::uno::RuntimeException
&)
435 // ignore, will just return FALSE
442 SfxApplication::ChooseScript(weld::Window
*pParent
)
446 #if HAVE_FEATURE_SCRIPTING
447 SfxAbstractDialogFactory
* pFact
= SfxAbstractDialogFactory::Create();
448 SAL_INFO( "sfx.appl", "create selector dialog");
450 const SfxViewFrame
* pViewFrame
= SfxViewFrame::Current();
451 const SfxFrame
* pFrame
= pViewFrame
? &pViewFrame
->GetFrame() : nullptr;
452 uno::Reference
< frame::XFrame
> xFrame( pFrame
? pFrame
->GetFrameInterface() : uno::Reference
< frame::XFrame
>() );
454 ScopedVclPtr
<AbstractScriptSelectorDialog
> pDlg(pFact
->CreateScriptSelectorDialog(pParent
, xFrame
));
456 SAL_INFO( "sfx.appl", "done, now exec it");
458 sal_uInt16 nRet
= pDlg
->Execute();
460 SAL_INFO( "sfx.appl", "has returned");
462 if ( nRet
== RET_OK
)
464 aScriptURL
= pDlg
->GetScriptURL();
472 void SfxApplication::MacroOrganizer(weld::Window
* pParent
, sal_Int16 nTabId
)
474 #if !HAVE_FEATURE_SCRIPTING
479 #ifndef DISABLE_DYNLOADING
480 basicide_macro_organizer pSymbol
= reinterpret_cast<basicide_macro_organizer
>(sfx2::getBasctlFunction("basicide_macro_organizer"));
482 // call basicide_macro_organizer in basctl
483 pSymbol(pParent
, nTabId
);
487 basicide_macro_organizer(pParent
, nTabId
);
494 ErrCode
SfxApplication::CallBasic( const OUString
& rCode
, BasicManager
* pMgr
, SbxArray
* pArgs
, SbxValue
* pRet
)
496 #if !HAVE_FEATURE_SCRIPTING
501 return ERRCODE_BASIC_CANNOT_LOAD
;
503 (void) ERRCODE_BASIC_CANNOT_LOAD
; // So that the !HAVE_FEATURE_SCRIPTING case isn't broken again by IWYU
504 return pMgr
->ExecuteMacro( rCode
, pArgs
, pRet
);
508 sfx2::sidebar::Theme
& SfxApplication::GetSidebarTheme()
510 if (!pImpl
->m_pSidebarTheme
.is())
512 pImpl
->m_pSidebarTheme
.set(new sfx2::sidebar::Theme
);
513 pImpl
->m_pSidebarTheme
->InitializeTheme();
515 return *pImpl
->m_pSidebarTheme
;
518 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */