LanguageTool: don't crash if REST protocol isn't set
[LibreOffice.git] / sfx2 / source / appl / app.cxx
blobaabdd2e83cce0c341bf7c8f1392eda2c4facc6ec
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
28 #include <svl/svdde.hxx>
29 #include <unotools/configmgr.hxx>
30 #include <com/sun/star/frame/XFrame.hpp>
31 #include <comphelper/lok.hxx>
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 <vcl/weld.hxx>
38 #include <sfx2/sfxhelp.hxx>
39 #include <sfx2/progress.hxx>
40 #include <sfx2/objsh.hxx>
41 #include <sfx2/dispatch.hxx>
42 #include <sfx2/viewsh.hxx>
43 #include <sfx2/viewfrm.hxx>
44 #include <appdata.hxx>
45 #include <sfx2/module.hxx>
46 #include <sfx2/event.hxx>
47 #include <workwin.hxx>
48 #include <sfx2/sidebar/Theme.hxx>
49 #include <sfx2/tbxctrl.hxx>
50 #include <sfx2/sfxdlg.hxx>
51 #include <sfx2/stbitem.hxx>
52 #include <sfx2/dockwin.hxx>
53 #include <sidebar/ControllerFactory.hxx>
55 #include <officecfg/Office/Common.hxx>
56 #include <unotools/viewoptions.hxx>
57 #include <rtl/strbuf.hxx>
58 #include <memory>
59 #include <framework/sfxhelperfunctions.hxx>
60 #include <fwkhelper.hxx>
62 #include "getbasctlfunction.hxx"
64 using namespace ::com::sun::star;
66 static SfxApplication* g_pSfxApplication = nullptr;
68 #if HAVE_FEATURE_XMLHELP
69 static SfxHelp* pSfxHelp = nullptr;
70 #endif
72 SfxApplication* SfxApplication::Get()
74 return g_pSfxApplication;
77 void SfxApplication::SetModule(SfxToolsModule nSharedLib, std::unique_ptr<SfxModule> pModule)
79 assert(g_pSfxApplication != nullptr);
81 g_pSfxApplication->pImpl->aModules[nSharedLib] = std::move(pModule);
84 SfxModule* SfxApplication::GetModule(SfxToolsModule nSharedLib)
86 if (!g_pSfxApplication) // It is possible GetModule is called before SfxApplication is initialised via GetOrCreate()
87 return nullptr;
88 return g_pSfxApplication->pImpl->aModules[nSharedLib].get();
91 namespace {
92 css::uno::Reference<css::frame::XToolbarController> SfxWeldToolBoxControllerFactory( const css::uno::Reference< css::frame::XFrame >& rFrame, weld::Toolbar* pToolbar, weld::Builder* pBuilder, const OUString& aCommandURL )
94 SolarMutexGuard aGuard;
96 return sfx2::sidebar::ControllerFactory::CreateToolBoxController(
97 *pToolbar, *pBuilder, aCommandURL, rFrame, rFrame->getController(), false);
101 SfxApplication* SfxApplication::GetOrCreate()
103 static osl::Mutex theApplicationMutex;
105 // SFX on demand
106 ::osl::MutexGuard aGuard(theApplicationMutex);
107 if (!g_pSfxApplication)
109 SAL_INFO( "sfx.appl", "SfxApplication::SetApp" );
111 g_pSfxApplication = new SfxApplication;
113 // at the moment a bug may occur when Initialize_Impl returns FALSE,
114 // but this is only temporary because all code that may cause such
115 // a fault will be moved outside the SFX
116 g_pSfxApplication->Initialize_Impl();
118 ::framework::SetRefreshToolbars( RefreshToolbars );
119 ::framework::SetToolBoxControllerCreator( SfxToolBoxControllerFactory );
120 ::framework::SetWeldToolBoxControllerCreator( SfxWeldToolBoxControllerFactory );
121 ::framework::SetStatusBarControllerCreator( SfxStatusBarControllerFactory );
122 ::framework::SetDockingWindowCreator( SfxDockingWindowFactory );
123 ::framework::SetIsDockingWindowVisible( IsDockingWindowVisible );
124 #if HAVE_FEATURE_XMLHELP
125 Application::SetHelp( pSfxHelp );
126 bool bHelpTip = officecfg::Office::Common::Help::Tip::get();
127 bool bExtendedHelpTip = officecfg::Office::Common::Help::ExtendedTip::get();
128 if (!utl::ConfigManager::IsFuzzing() && bHelpTip)
129 Help::EnableQuickHelp();
130 else
131 Help::DisableQuickHelp();
132 if (!utl::ConfigManager::IsFuzzing() && bHelpTip && bExtendedHelpTip)
133 Help::EnableBalloonHelp();
134 else
135 Help::DisableBalloonHelp();
136 #endif
138 return g_pSfxApplication;
141 SfxApplication::SfxApplication()
142 : pImpl( new SfxAppData_Impl )
144 SetName( "StarOffice" );
146 SAL_INFO( "sfx.appl", "{ initialize DDE" );
148 bool bOk = InitializeDde();
150 #ifdef DBG_UTIL
151 if( !bOk )
153 OStringBuffer aStr("No DDE-Service possible. Error: ");
154 if( GetDdeService() )
155 aStr.append(static_cast<sal_Int32>(GetDdeService()->GetError()));
156 else
157 aStr.append('?');
158 SAL_WARN( "sfx.appl", aStr.getStr() );
160 #else
161 (void)bOk;
162 #endif
164 #if HAVE_FEATURE_XMLHELP
165 pSfxHelp = new SfxHelp;
166 #endif
168 #if HAVE_FEATURE_SCRIPTING
169 StarBASIC::SetGlobalErrorHdl( LINK( this, SfxApplication, GlobalBasicErrorHdl_Impl ) );
170 #endif
172 SAL_INFO( "sfx.appl", "} initialize DDE" );
175 SfxApplication::~SfxApplication()
177 SAL_WARN_IF(GetObjectShells_Impl().size() != 0, "sfx.appl", "Memory leak: some object shells were not removed!");
179 Broadcast( SfxHint(SfxHintId::Dying) );
181 for (auto &module : pImpl->aModules) // Clear modules
182 module.reset();
184 #if HAVE_FEATURE_XMLHELP
185 delete pSfxHelp;
186 Application::SetHelp();
187 #endif
189 if ( !pImpl->bDowning )
190 Deinitialize();
192 g_pSfxApplication = nullptr;
196 const OUString& SfxApplication::GetLastDir_Impl() const
198 /* [Description]
200 Internal method by which the last set directory with the method
201 <SfxApplication::SetLastDir_Impl()> in SFX is returned.
203 This is usually the most recently addressed by the
204 SfxFileDialog directory.
206 [Cross-reference]
207 <SfxApplication::SetLastDir_Impl()>
211 return pImpl->aLastDir;
214 void SfxApplication::SetLastDir_Impl
216 const OUString& rNewDir /* Complete directory path as a string */
219 /* [Description]
221 Internal Method, by which a directory path is set that was last addressed
222 (eg by the SfxFileDialog).
224 [Cross-reference]
225 <SfxApplication::GetLastDir_Impl()>
229 pImpl->aLastDir = rNewDir;
233 void SfxApplication::ResetLastDir()
235 pImpl->aLastDir.clear();
239 SfxDispatcher* SfxApplication::GetDispatcher_Impl()
241 return pImpl->pViewFrame ? pImpl->pViewFrame->GetDispatcher() : &*pImpl->pAppDispat;
245 void SfxApplication::SetViewFrame_Impl( SfxViewFrame *pFrame )
247 if ( pFrame != pImpl->pViewFrame )
249 SfxViewFrame *pOldFrame = pImpl->pViewFrame;
251 // DocWinActivate : both frames belong to the same TopWindow
252 // TopWinActivate : both frames belong to different TopWindows
254 bool bTaskActivate = pOldFrame != pFrame;
256 if ( pOldFrame )
258 if ( bTaskActivate )
259 NotifyEvent( SfxViewEventHint( SfxEventHintId::DeactivateDoc, GlobalEventConfig::GetEventName(GlobalEventId::DEACTIVATEDOC), pOldFrame->GetObjectShell(), pOldFrame->GetFrame().GetController() ) );
261 pOldFrame->DoDeactivate( bTaskActivate, pFrame );
263 if( pOldFrame->GetProgress() )
264 pOldFrame->GetProgress()->Suspend();
267 pImpl->pViewFrame = pFrame;
269 if( pFrame )
271 pFrame->DoActivate( bTaskActivate );
272 if ( bTaskActivate && pFrame->GetObjectShell() )
274 pFrame->GetObjectShell()->PostActivateEvent_Impl( pFrame );
275 NotifyEvent(SfxViewEventHint(SfxEventHintId::ActivateDoc, GlobalEventConfig::GetEventName(GlobalEventId::ACTIVATEDOC), pFrame->GetObjectShell(), pFrame->GetFrame().GetController() ) );
278 SfxProgress *pProgress = pFrame->GetProgress();
279 if ( pProgress )
281 if( pProgress->IsSuspended() )
282 pProgress->Resume();
283 else
284 pProgress->SetState( pProgress->GetState() );
287 if ( pImpl->pViewFrame->GetViewShell() )
289 SfxDispatcher* pDisp = pImpl->pViewFrame->GetDispatcher();
290 pDisp->Flush();
291 pDisp->Update_Impl(true);
296 // even if the frame actually didn't change, ensure its document is forwarded
297 // to SfxObjectShell::SetCurrentComponent.
298 // Otherwise, the CurrentComponent might not be correct, in case it has meanwhile
299 // been reset to some other document, by some non-SFX component. #i49133#
300 if ( pFrame && pFrame->GetViewShell() )
301 pFrame->GetViewShell()->SetCurrentDocument();
304 void SfxApplication::SetProgress_Impl
306 SfxProgress *pProgress
309 DBG_ASSERT( ( !pImpl->pProgress && pProgress ) ||
310 ( pImpl->pProgress && !pProgress ),
311 "Progress activation/deactivation mismatch" );
313 if ( pImpl->pProgress && pProgress )
315 pImpl->pProgress->Suspend();
316 delete pImpl->pProgress;
319 pImpl->pProgress = pProgress;
323 sal_uInt16 SfxApplication::GetFreeIndex()
325 return pImpl->aIndexBitSet.GetFreeIndex()+1;
329 void SfxApplication::ReleaseIndex(sal_uInt16 i)
331 pImpl->aIndexBitSet.ReleaseIndex(i-1);
335 weld::Window* SfxApplication::GetTopWindow() const
337 SfxWorkWindow* pWork = GetWorkWindow_Impl( SfxViewFrame::Current() );
338 if (!pWork)
339 return nullptr;
340 vcl::Window* pWindow = pWork->GetWindow();
341 if (!pWindow)
342 return nullptr;
343 return pWindow->GetFrameWeld();
346 SfxTbxCtrlFactory* SfxApplication::GetTbxCtrlFactory(const std::type_info& rSlotType, sal_uInt16 nSlotID) const
348 // search for a factory with the given slot id
349 for (auto& rFactory : pImpl->maTbxCtrlFactories)
350 if( rFactory.nTypeId == rSlotType && rFactory.nSlotId == nSlotID )
351 return &rFactory;
353 // if no factory exists for the given slot id, see if we
354 // have a generic factory with the correct slot type and slot id == 0
355 for (auto& rFactory : pImpl->maTbxCtrlFactories)
356 if( rFactory.nTypeId == rSlotType && rFactory.nSlotId == 0 )
357 return &rFactory;
359 return nullptr;
362 SfxStbCtrlFactory* SfxApplication::GetStbCtrlFactory(const std::type_info& rSlotType, sal_uInt16 nSlotID) const
364 for (auto& rFactory : pImpl->maStbCtrlFactories)
365 if ( rFactory.nTypeId == rSlotType &&
366 ( rFactory.nSlotId == 0 || rFactory.nSlotId == nSlotID ) )
367 return &rFactory;
368 return nullptr;
371 std::vector<SfxViewFrame*>& SfxApplication::GetViewFrames_Impl() const
373 return pImpl->maViewFrames;
376 std::vector<SfxViewShell*>& SfxApplication::GetViewShells_Impl() const
378 return pImpl->maViewShells;
381 std::vector<SfxObjectShell*>& SfxApplication::GetObjectShells_Impl() const
383 return pImpl->maObjShells;
386 void SfxApplication::Invalidate( sal_uInt16 nId )
388 for( SfxViewFrame* pFrame = SfxViewFrame::GetFirst(); pFrame; pFrame = SfxViewFrame::GetNext( *pFrame ) )
389 Invalidate_Impl( pFrame->GetBindings(), nId );
392 #if HAVE_FEATURE_SCRIPTING
394 #ifndef DISABLE_DYNLOADING
396 typedef long (*basicide_handle_basic_error)(void const *);
397 typedef void (*basicide_macro_organizer)(void *, sal_Int16);
399 #else
401 extern "C" long basicide_handle_basic_error(void const*);
402 extern "C" void basicide_macro_organizer(void*, sal_Int16);
404 #endif
406 #endif
408 IMPL_STATIC_LINK( SfxApplication, GlobalBasicErrorHdl_Impl, StarBASIC*, pStarBasic, bool )
410 #if !HAVE_FEATURE_SCRIPTING
411 (void) pStarBasic;
412 return false;
413 #else
415 if (comphelper::LibreOfficeKit::isActive())
417 OUString aError;
418 std::unique_ptr<ErrorInfo> pErrorInfo = ErrorInfo::GetErrorInfo(StarBASIC::GetErrorCode());
419 if (ErrorStringFactory::CreateString(pErrorInfo.get(), aError))
421 const SfxViewFrame* pViewFrame = SfxViewFrame::Current();
422 std::shared_ptr<weld::MessageDialog> xBox;
423 xBox.reset(Application::CreateMessageDialog(
424 pViewFrame->GetFrameWeld(),
425 VclMessageType::Error,
426 VclButtonsType::Ok,
427 aError));
429 xBox->runAsync(xBox, [](sal_Int32 /*nResult*/) {});
431 return true;
434 #ifndef DISABLE_DYNLOADING
435 basicide_handle_basic_error pSymbol = reinterpret_cast<basicide_handle_basic_error>(sfx2::getBasctlFunction("basicide_handle_basic_error"));
437 // call basicide_handle_basic_error in basctl
438 bool bRet = pSymbol( pStarBasic );
440 #else
442 bool bRet = basicide_handle_basic_error( pStarBasic );
444 #endif
446 return bRet;
448 #endif
451 bool SfxApplication::IsXScriptURL( const OUString& rScriptURL )
453 bool result = false;
455 #if !HAVE_FEATURE_SCRIPTING
456 (void) rScriptURL;
457 #else
458 css::uno::Reference< css::uno::XComponentContext > xContext =
459 ::comphelper::getProcessComponentContext();
461 css::uno::Reference< css::uri::XUriReferenceFactory >
462 xFactory = css::uri::UriReferenceFactory::create( xContext );
466 css::uno::Reference< css::uri::XVndSunStarScriptUrl >
467 xUrl( xFactory->parse( rScriptURL ), css::uno::UNO_QUERY );
469 if ( xUrl.is() )
471 result = true;
474 catch (const css::uno::RuntimeException&)
476 // ignore, will just return FALSE
478 #endif
479 return result;
482 OUString
483 SfxApplication::ChooseScript(weld::Window *pParent)
485 OUString aScriptURL;
487 #if HAVE_FEATURE_SCRIPTING
488 SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
489 SAL_INFO( "sfx.appl", "create selector dialog");
491 const SfxViewFrame* pViewFrame = SfxViewFrame::Current();
492 const SfxFrame* pFrame = pViewFrame ? &pViewFrame->GetFrame() : nullptr;
493 uno::Reference< frame::XFrame > xFrame( pFrame ? pFrame->GetFrameInterface() : uno::Reference< frame::XFrame >() );
495 ScopedVclPtr<AbstractScriptSelectorDialog> pDlg(pFact->CreateScriptSelectorDialog(pParent, xFrame));
497 SAL_INFO( "sfx.appl", "done, now exec it");
499 sal_uInt16 nRet = pDlg->Execute();
501 SAL_INFO( "sfx.appl", "has returned");
503 if ( nRet == RET_OK )
505 aScriptURL = pDlg->GetScriptURL();
507 #else
508 (void) pParent;
509 #endif
510 return aScriptURL;
513 void SfxApplication::MacroOrganizer(weld::Window* pParent, sal_Int16 nTabId)
515 #if !HAVE_FEATURE_SCRIPTING
516 (void) pParent;
517 (void) nTabId;
518 #else
520 #ifndef DISABLE_DYNLOADING
521 basicide_macro_organizer pSymbol = reinterpret_cast<basicide_macro_organizer>(sfx2::getBasctlFunction("basicide_macro_organizer"));
523 // call basicide_macro_organizer in basctl
524 pSymbol(pParent, nTabId);
526 #else
528 basicide_macro_organizer(pParent, nTabId);
530 #endif
532 #endif
535 ErrCode SfxApplication::CallBasic( const OUString& rCode, BasicManager* pMgr, SbxArray* pArgs, SbxValue* pRet )
537 #if !HAVE_FEATURE_SCRIPTING
538 (void) rCode;
539 (void) pMgr;
540 (void) pArgs;
541 (void) pRet;
542 return ERRCODE_BASIC_CANNOT_LOAD;
543 #else
544 (void) ERRCODE_BASIC_CANNOT_LOAD; // So that the !HAVE_FEATURE_SCRIPTING case isn't broken again by IWYU
545 return pMgr->ExecuteMacro( rCode, pArgs, pRet);
546 #endif
549 sfx2::sidebar::Theme & SfxApplication::GetSidebarTheme()
551 if (!pImpl->m_pSidebarTheme.is())
553 pImpl->m_pSidebarTheme.set(new sfx2::sidebar::Theme);
554 pImpl->m_pSidebarTheme->InitializeTheme();
556 return *pImpl->m_pSidebarTheme;
559 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */