1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20 #include <config_features.h>
21 #include <com/sun/star/drawing/ModuleDispatcher.hpp>
22 #include <com/sun/star/frame/Desktop.hpp>
23 #include <com/sun/star/frame/DispatchResultEvent.hpp>
24 #include <com/sun/star/frame/DispatchResultState.hpp>
25 #include <com/sun/star/frame/DispatchHelper.hpp>
26 #include <com/sun/star/frame/UnknownModuleException.hpp>
27 #include <com/sun/star/frame/XLayoutManager.hpp>
28 #include <com/sun/star/frame/XSynchronousFrameLoader.hpp>
29 #include <com/sun/star/sdbc/DriverManager.hpp>
30 #include <com/sun/star/text/ModuleDispatcher.hpp>
31 #include <com/sun/star/task/OfficeRestartManager.hpp>
32 #include <com/sun/star/task/XInteractionHandler.hpp>
33 #include <com/sun/star/ui/dialogs/AddressBookSourcePilot.hpp>
34 #include <com/sun/star/ui/UIElementType.hpp>
35 #include <com/sun/star/ui/XUIElement.hpp>
36 #include <com/sun/star/uno/Reference.hxx>
37 #include <com/sun/star/util/XCloseable.hpp>
38 #include <com/sun/star/util/CloseVetoException.hpp>
39 #include <org/freedesktop/PackageKit/SyncDbusSessionHelper.hpp>
40
41 #include <comphelper/dispatchcommand.hxx>
42 #include <comphelper/lok.hxx>
43 #include <comphelper/namedvaluecollection.hxx>
44 #include <comphelper/processfactory.hxx>
45 #include <comphelper/propertysequence.hxx>
46 #include <comphelper/sequence.hxx>
47
48 #include <svtools/addresstemplate.hxx>
49 #include <svtools/miscopt.hxx>
50 #include <svtools/restartdialog.hxx>
51 #include <svl/visitem.hxx>
52
53 #include <unotools/configmgr.hxx>
54 #include <tools/diagnose_ex.h>
55 #include <vcl/weld.hxx>
56 #include <svl/intitem.hxx>
57 #include <svl/eitem.hxx>
58 #include <svl/stritem.hxx>
59 #include <basic/sbstar.hxx>
60 #include <basic/basrdll.hxx>
61 #include <basic/sberrors.hxx>
62 #include <vcl/help.hxx>
63 #include <rtl/ustrbuf.hxx>
64 #include <sal/log.hxx>
65 #include <osl/file.hxx>
66 #include <vcl/EnumContext.hxx>
67 #include <vcl/toolbox.hxx>
68
69 #include <unotools/moduleoptions.hxx>
70 #include <svtools/helpopt.hxx>
71 #include <rtl/bootstrap.hxx>
72
73 #include <com/sun/star/frame/ModuleManager.hpp>
74 #include <com/sun/star/beans/XPropertySet.hpp>
75
76 #include <sfx2/app.hxx>
77 #include <sfx2/request.hxx>
78 #include <sfx2/dispatch.hxx>
79 #include <sfx2/bindings.hxx>
80 #include <sfx2/msg.hxx>
81 #include <sfx2/objface.hxx>
82 #include <sfx2/objsh.hxx>
83 #include <sfx2/viewsh.hxx>
84 #include <sfx2/docfac.hxx>
85 #include <sfx2/strings.hrc>
86 #include <sfx2/sfxresid.hxx>
87 #include <appdata.hxx>
88 #include <sfx2/viewfrm.hxx>
89 #include <sfx2/sfxdlg.hxx>
90 #include <sfx2/sfxsids.hrc>
91 #include <sorgitm.hxx>
92 #include <sfx2/sfxhelp.hxx>
93 #include <sfx2/zoomitem.hxx>
94 #include <sfx2/templatedlg.hxx>
95 #include <sfx2/notebookbar/SfxNotebookBar.hxx>
96 #include <sfx2/sidebar/SidebarController.hxx>
97 #include <sfx2/safemode.hxx>
98 #include <sfx2/sfxuno.hxx>
99 #include <sfx2/devtools/DevelopmentToolDockingWindow.hxx>
100
101 #include <comphelper/types.hxx>
102 #include <officecfg/Office/Common.hxx>
103 #include <unotools/confignode.hxx>
104 #include <memory>
105
106 #include <openuriexternally.hxx>
107
108 #include "getbasctlfunction.hxx"
109
110 using namespace ::com::sun::star;
111 using namespace ::com::sun::star::beans;
112 using namespace ::com::sun::star::uno;
113 using namespace ::com::sun::star::frame;
114 using namespace ::com::sun::star::container;
115 using namespace ::com::sun::star::util;
116 using namespace ::com::sun::star::lang;
117 using namespace ::com::sun::star::ui;
118
119 namespace
120 {
lcl_getAppName(vcl::EnumContext::Application eApp)121 OUString lcl_getAppName( vcl::EnumContext::Application eApp )
122 {
123 switch ( eApp )
124 {
125 case vcl::EnumContext::Application::Writer:
126 return "Writer";
127 case vcl::EnumContext::Application::Calc:
128 return "Calc";
129 case vcl::EnumContext::Application::Impress:
130 return "Impress";
131 case vcl::EnumContext::Application::Draw:
132 return "Draw";
133 case vcl::EnumContext::Application::Formula:
134 return "Formula";
135 case vcl::EnumContext::Application::Base:
136 return "Base";
137 default:
138 return OUString();
139 }
140 }
141
142 // lp#527938, debian#602953, fdo#33266, i#105408
lcl_isBaseAvailable()143 bool lcl_isBaseAvailable()
144 {
145 try
146 {
147 // if we get css::sdbc::DriverManager, libsdbc2 is there
148 // and the bibliography is assumed to work
149 return css::sdbc::DriverManager::create(comphelper::getProcessComponentContext()).is();
150 }
151 catch (const Exception &)
152 {
153 TOOLS_INFO_EXCEPTION("sfx.appl", "assuming Base to be missing");
154 return false;
155 }
156 }
lcl_tryLoadBibliography()157 void lcl_tryLoadBibliography()
158 {
159 // lp#527938, debian#602953, fdo#33266, i#105408
160 // make sure we actually can instantiate services from base first
161 if(!lcl_isBaseAvailable())
162 {
163 if (officecfg::Office::Common::PackageKit::EnableBaseInstallation::get())
164 {
165 try
166 {
167 using namespace org::freedesktop::PackageKit;
168 using namespace svtools;
169 Reference< XSyncDbusSessionHelper > xSyncDbusSessionHelper(SyncDbusSessionHelper::create(comphelper::getProcessComponentContext()));
170 Sequence< OUString > vPackages { "libreoffice-base" };
171 xSyncDbusSessionHelper->InstallPackageNames(vPackages, OUString());
172 // I'll be back (hopefully)!
173 SolarMutexGuard aGuard;
174 executeRestartDialog(comphelper::getProcessComponentContext(), nullptr, RESTART_REASON_BIBLIOGRAPHY_INSTALL);
175 }
176 catch (const Exception &)
177 {
178 TOOLS_INFO_EXCEPTION("sfx.appl", "trying to install LibreOffice Base");
179 }
180 }
181 return;
182 }
183
184 try // fdo#48775
185 {
186 SfxStringItem aURL(SID_FILE_NAME, ".component:Bibliography/View1");
187 SfxStringItem aRef(SID_REFERER, "private:user");
188 SfxStringItem aTarget(SID_TARGETNAME, "_blank");
189 SfxViewFrame::Current()->GetDispatcher()->ExecuteList(SID_OPENDOC,
190 SfxCallMode::ASYNCHRON, { &aURL, &aRef, &aTarget });
191 }
192 catch (const Exception &)
193 {
194 TOOLS_INFO_EXCEPTION( "sfx.appl", "trying to load bibliography database");
195 }
196 }
197 }
198 /// Find the correct location of the document (CREDITS.fodt, etc.), and return
199 /// it in rURL if found.
checkURL(const char * pName,const char * pExt,OUString & rURL)200 static bool checkURL( const char *pName, const char *pExt, OUString &rURL )
201 {
202 using namespace osl;
203 DirectoryItem aDirItem;
204
205 #ifdef MACOSX
206 rURL = "$BRAND_BASE_DIR/Resources/" + OUString::createFromAscii( pName ) +
207 OUString::createFromAscii( pExt );
208 #else
209 rURL = "$BRAND_BASE_DIR/" + OUString::createFromAscii( pName ) +
210 OUString::createFromAscii( pExt );
211 #endif
212 rtl::Bootstrap::expandMacros( rURL );
213
214 if (!rURL.isEmpty())
215 return DirectoryItem::get( rURL, aDirItem ) == DirectoryItem::E_None;
216 else
217 return false;
218 }
219
220 /// Displays CREDITS or LICENSE in any of the available version
showDocument(const char * pBaseName)221 static void showDocument( const char* pBaseName )
222 {
223 try {
224 Reference < XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
225 auto args(::comphelper::InitPropertySequence({
226 {"ViewOnly", makeAny(true)},
227 {"ReadOnly", makeAny(true)}
228 }));
229
230 OUString aURL;
231 if ( checkURL ( pBaseName, ".fodt", aURL ) ||
232 checkURL ( pBaseName, ".html", aURL ) ||
233 checkURL ( pBaseName, "", aURL ) ) {
234 xDesktop->loadComponentFromURL( aURL, "_blank", 0, args );
235 }
236 } catch (const css::uno::Exception &) {
237 }
238 }
239
240 namespace
241 {
GetRequestFrame(const SfxRequest & rReq)242 Reference<XFrame> GetRequestFrame(const SfxRequest& rReq)
243 {
244 const SfxItemSet* pArgs = rReq.GetInternalArgs_Impl();
245 const SfxPoolItem* pItem = nullptr;
246 Reference <XFrame> xFrame;
247 if (pArgs && pArgs->GetItemState(SID_FILLFRAME, false, &pItem) == SfxItemState::SET)
248 {
249 OSL_ENSURE( dynamic_cast< const SfxUnoFrameItem *>( pItem ) != nullptr, "SfxApplication::OfaExec_Impl: XFrames are to be transported via SfxUnoFrameItem by now!" );
250 xFrame = static_cast< const SfxUnoFrameItem*>( pItem )->GetFrame();
251 }
252 return xFrame;
253 }
254
255 class LicenseDialog : public weld::GenericDialogController
256 {
257 public:
LicenseDialog(weld::Window * pParent)258 LicenseDialog(weld::Window* pParent)
259 : GenericDialogController(pParent, "sfx/ui/licensedialog.ui", "LicenseDialog")
260 {
261 }
262
run()263 virtual short run() override
264 {
265 short nRet = GenericDialogController::run();
266 if (nRet == RET_OK)
267 showDocument("LICENSE");
268 return nRet;
269 }
270 };
271
272 class SafeModeQueryDialog : public weld::MessageDialogController
273 {
274 public:
SafeModeQueryDialog(weld::Window * pParent)275 SafeModeQueryDialog(weld::Window* pParent)
276 : MessageDialogController(pParent, "sfx/ui/safemodequerydialog.ui", "SafeModeQueryDialog")
277 {
278 }
279
run()280 virtual short run() override
281 {
282 short nRet = MessageDialogController::run();
283 if (nRet == RET_OK)
284 {
285 sfx2::SafeMode::putFlag();
286 uno::Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext();
287 css::task::OfficeRestartManager::get(xContext)->requestRestart(
288 css::uno::Reference< css::task::XInteractionHandler >());
289 }
290 return nRet;
291 }
292 };
293 }
294
GetFrameWeld() const295 weld::Window* SfxRequest::GetFrameWeld() const
296 {
297 const SfxItemSet* pIntArgs = GetInternalArgs_Impl();
298 const SfxPoolItem* pItem = nullptr;
299 if (pIntArgs && pIntArgs->GetItemState(SID_DIALOG_PARENT, false, &pItem) == SfxItemState::SET)
300 {
301 assert(dynamic_cast<const SfxUnoAnyItem*>(pItem));
302 auto aAny = static_cast<const SfxUnoAnyItem*>(pItem)->GetValue();
303 Reference<awt::XWindow> xWindow;
304 aAny >>= xWindow;
305 return Application::GetFrameWeld(xWindow);
306 }
307
308 Reference<XFrame> xFrame(GetRequestFrame(*this));
309 if (!xFrame)
310 {
311 SAL_WARN("sfx.appl", "no parent for dialogs");
312 return nullptr;
313 }
314 return Application::GetFrameWeld(xFrame->getContainerWindow());
315 }
316
MiscExec_Impl(SfxRequest & rReq)317 void SfxApplication::MiscExec_Impl( SfxRequest& rReq )
318 {
319 bool bDone = false;
320 switch ( rReq.GetSlot() )
321 {
322 case SID_SETOPTIONS:
323 {
324 if( rReq.GetArgs() )
325 SetOptions_Impl( *rReq.GetArgs() );
326 break;
327 }
328
329 case SID_QUITAPP:
330 case SID_LOGOUT:
331 {
332 // protect against reentrant calls
333 if ( pImpl->bInQuit )
334 return;
335
336 if ( rReq.GetSlot() == SID_LOGOUT )
337 {
338 for ( SfxObjectShell *pObjSh = SfxObjectShell::GetFirst();
339 pObjSh; pObjSh = SfxObjectShell::GetNext( *pObjSh ) )
340 {
341 if ( !pObjSh->IsModified() )
342 continue;
343
344 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pObjSh );
345 if ( !pFrame || !pFrame->GetWindow().IsReallyVisible() )
346 continue;
347
348 if (pObjSh->PrepareClose())
349 pObjSh->SetModified( false );
350 else
351 return;
352 }
353
354 SfxStringItem aNameItem( SID_FILE_NAME, "vnd.sun.star.cmd:logout" );
355 SfxStringItem aReferer( SID_REFERER, "private/user" );
356 pImpl->pAppDispat->ExecuteList(SID_OPENDOC,
357 SfxCallMode::SLOT, { &aNameItem, &aReferer });
358 return;
359 }
360
361 // try from nested requests again after 100ms
362 if( Application::GetDispatchLevel() > 1 )
363 {
364 /* Don't save the request for closing the application and try it later
365 again. This is an UI bound functionality ... and the user will try it again
366 if the dialog is closed. But we should not close the application automatically
367 if this dialog is closed by the user ...
368 So we ignore this request now and wait for a new user decision.
369 */
370 SAL_INFO("sfx.appl", "QueryExit => sal_False, DispatchLevel == " << Application::GetDispatchLevel() );
371 return;
372 }
373
374 // block reentrant calls
375 pImpl->bInQuit = true;
376 Reference < XDesktop2 > xDesktop = Desktop::create ( ::comphelper::getProcessComponentContext() );
377
378 rReq.ForgetAllArgs();
379
380 // if terminate() failed, pImpl->bInQuit will now be sal_False, allowing further calls of SID_QUITAPP
381 bool bTerminated = xDesktop->terminate();
382 if (!bTerminated)
383 // if terminate() was successful, SfxApplication is now dead!
384 pImpl->bInQuit = false;
385
386 // Set return value, terminate if possible
387 rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), bTerminated ) );
388 return;
389 }
390
391 case SID_CONFIG:
392 case SID_TOOLBOXOPTIONS:
393 case SID_CONFIGSTATUSBAR:
394 case SID_CONFIGMENU:
395 case SID_CONFIGACCEL:
396 case SID_CONFIGEVENT:
397 {
398 SfxAbstractDialogFactory* pFact =
399 SfxAbstractDialogFactory::Create();
400
401 const SfxStringItem* pStringItem = rReq.GetArg<SfxStringItem>(SID_CONFIG);
402
403 SfxItemSet aSet(
404 GetPool(), svl::Items<SID_CONFIG, SID_CONFIG>{} );
405
406 if ( pStringItem )
407 {
408 aSet.Put( SfxStringItem(
409 SID_CONFIG, pStringItem->GetValue() ) );
410 }
411
412 Reference <XFrame> xFrame(GetRequestFrame(rReq));
413 ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateCustomizeTabDialog(rReq.GetFrameWeld(),
414 &aSet, xFrame ));
415
416 const short nRet = pDlg->Execute();
417
418 if ( nRet )
419 bDone = true;
420 break;
421 }
422
423 case SID_CLOSEDOCS:
424 {
425
426 Reference < XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
427 Reference< XIndexAccess > xTasks = xDesktop->getFrames();
428 if ( !xTasks.is() )
429 break;
430
431 sal_Int32 n=0;
432 do
433 {
434 if ( xTasks->getCount() <= n )
435 break;
436
437 Any aAny = xTasks->getByIndex(n);
438 Reference < XCloseable > xTask;
439 aAny >>= xTask;
440 try
441 {
442 xTask->close(true);
443 n++;
444 }
445 catch( CloseVetoException& )
446 {
447 }
448 }
449 while( true );
450
451 bool bOk = ( n == 0);
452 rReq.SetReturnValue( SfxBoolItem( 0, bOk ) );
453 bDone = true;
454 break;
455 }
456
457 case SID_SAVEDOCS:
458 {
459 bool bOK = true;
460 for ( SfxObjectShell *pObjSh = SfxObjectShell::GetFirst();
461 pObjSh;
462 pObjSh = SfxObjectShell::GetNext( *pObjSh ) )
463 {
464 SfxRequest aReq( SID_SAVEDOC, SfxCallMode::SLOT, pObjSh->GetPool() );
465 if ( pObjSh->IsModified() )
466 {
467 pObjSh->ExecuteSlot( aReq );
468 const SfxBoolItem *pItem = dynamic_cast<const SfxBoolItem*>( aReq.GetReturnValue() );
469 if ( !pItem || !pItem->GetValue() )
470 bOK = false;
471 }
472 }
473
474 rReq.SetReturnValue( SfxBoolItem( 0, bOK ) );
475 rReq.Done();
476 break;
477 }
478
479 case SID_SEND_FEEDBACK:
480 {
481 OUString module = SfxHelp::GetCurrentModuleIdentifier();
482 OUString sURL(officecfg::Office::Common::Menus::SendFeedbackURL::get() + //officecfg/registry/data/org/openoffice/Office/Common.xcu => https://hub.libreoffice.org/send-feedback/
483 "?LOversion=" + utl::ConfigManager::getAboutBoxProductVersion() +
484 "&LOlocale=" + utl::ConfigManager::getUILocale() +
485 "&LOmodule=" + module.subView(module.lastIndexOf('.') + 1 ) );
486 sfx2::openUriExternally(sURL, false);
487 break;
488 }
489
490 case SID_Q_AND_A:
491 {
492 // Askbot has URL's normalized to languages, not locales
493 // Get language from locale: ll or lll or ll-CC or lll-CC
494
495 OUString sURL(officecfg::Office::Common::Menus::QA_URL::get() + //https://hub.libreoffice.org/forum/
496 "?LOlocale=" + utl::ConfigManager::getUILocale());
497 sfx2::openUriExternally(sURL, false);
498 break;
499 }
500 case SID_DOCUMENTATION:
501 {
502 // Open documentation page based on locales
503 OUString sURL(officecfg::Office::Common::Menus::DocumentationURL::get() + //https://hub.libreoffice.org/documentation/
504 "?LOlocale=" + utl::ConfigManager::getUILocale());
505 sfx2::openUriExternally(sURL, false);
506 break;
507 }
508 case SID_GETINVOLVED:
509 {
510 // Open get involved/join us page based on locales
511 OUString sURL(officecfg::Office::Common::Menus::GetInvolvedURL::get() + //https://hub.libreoffice.org/joinus/
512 "?LOlocale=" + utl::ConfigManager::getUILocale());
513 sfx2::openUriExternally(sURL, false);
514 break;
515 }
516 case SID_DONATION:
517 {
518 // Open donation page based on language + script (BCP47) with language as fall back.
519 OUString aLang = LanguageTag(utl::ConfigManager::getUILocale()).getLanguage();
520 OUString aBcp47 = LanguageTag(utl::ConfigManager::getUILocale()).getBcp47();
521 OUString sURL(officecfg::Office::Common::Menus::DonationURL::get() + //https://hub.libreoffice.org/donation/
522 "?BCP47=" + aBcp47 + "&LOlang=" + aLang );
523 sfx2::openUriExternally(sURL, false);
524 break;
525 }
526 case SID_WHATSNEW:
527 {
528 // Open release notes depending on version and locale
529 OUString sURL(officecfg::Office::Common::Menus::ReleaseNotesURL::get() + //https://hub.libreoffice.org/ReleaseNotes/
530 "?LOvers=" + utl::ConfigManager::getProductVersion() +
531 "&LOlocale=" + LanguageTag(utl::ConfigManager::getUILocale()).getBcp47() );
532 sfx2::openUriExternally(sURL, false);
533 break;
534 }
535 case SID_SHOW_LICENSE:
536 {
537 LicenseDialog aDialog(rReq.GetFrameWeld());
538 aDialog.run();
539 break;
540 }
541
542 case SID_SHOW_CREDITS:
543 {
544 showDocument( "CREDITS" );
545 break;
546 }
547
548 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
549 case SID_HELPINDEX:
550 {
551 Help* pHelp = Application::GetHelp();
552 if ( pHelp )
553 {
554 pHelp->Start(".uno:HelpIndex", rReq.GetFrameWeld()); // show start page
555 bDone = true;
556 }
557 break;
558 }
559
560 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
561 case SID_HELPTIPS:
562 {
563 // Evaluate Parameter
564 const SfxBoolItem* pOnItem = rReq.GetArg<SfxBoolItem>(SID_HELPTIPS);
565 bool bOn = pOnItem
566 ? pOnItem->GetValue()
567 : !Help::IsQuickHelpEnabled();
568
569 if ( bOn )
570 Help::EnableQuickHelp();
571 else
572 Help::DisableQuickHelp();
573 SvtHelpOptions().SetHelpTips( bOn );
574 Invalidate(SID_HELPTIPS);
575 bDone = true;
576
577 // Record if possible
578 if ( !rReq.IsAPI() )
579 rReq.AppendItem( SfxBoolItem( SID_HELPTIPS, bOn) );
580 break;
581 }
582 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
583 case SID_EXTENDEDHELP:
584 {
585 Help::StartExtHelp();
586 break;
587 }
588 case SID_HELPBALLOONS:
589 {
590 // Evaluate Parameter
591 const SfxBoolItem* pOnItem = rReq.GetArg<SfxBoolItem>(SID_HELPBALLOONS);
592 bool bOn = pOnItem
593 ? pOnItem->GetValue()
594 : !Help::IsBalloonHelpEnabled();
595
596 if ( bOn )
597 Help::EnableBalloonHelp();
598 else
599 Help::DisableBalloonHelp();
600 SvtHelpOptions().SetExtendedHelp( bOn );
601 Invalidate(SID_HELPBALLOONS);
602 bDone = true;
603
604 // Record if possible
605 if ( !rReq.IsAPI() )
606 rReq.AppendItem( SfxBoolItem( SID_HELPBALLOONS, bOn) );
607 break;
608 }
609 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
610 case SID_TIPOFTHEDAY:
611 {
612 SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
613 ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateTipOfTheDayDialog(rReq.GetFrameWeld()));
614 pDlg->StartExecuteAsync(nullptr);
615 bDone = true;
616 break;
617 }
618
619 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
620 case SID_ABOUT:
621 {
622 SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
623 ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateAboutDialog(rReq.GetFrameWeld()));
624 pDlg->Execute();
625 bDone = true;
626 break;
627 }
628
629 case SID_TEMPLATE_MANAGER:
630 {
631 SfxTemplateManagerDlg aDialog(rReq.GetFrameWeld());
632 aDialog.run();
633 bDone = true;
634 break;
635 }
636
637 case SID_TEMPLATE_ADDRESSBOOKSOURCE:
638 {
639 svt::AddressBookSourceDialog aDialog(rReq.GetFrameWeld(), ::comphelper::getProcessComponentContext());
640 aDialog.run();
641 bDone = true;
642 break;
643 }
644
645 #if HAVE_FEATURE_SCRIPTING
646 case SID_BASICSTOP:
647 StarBASIC::Stop();
648 break;
649
650 case SID_BASICBREAK :
651 BasicDLL::BasicBreak();
652 break;
653 #endif
654
655 case SID_ZOOM_50_PERCENT:
656 case SID_ZOOM_75_PERCENT:
657 case SID_ZOOM_100_PERCENT:
658 case SID_ZOOM_150_PERCENT:
659 case SID_ZOOM_200_PERCENT:
660 case SID_ZOOM_OPTIMAL:
661 case SID_ZOOM_ENTIRE_PAGE:
662 case SID_ZOOM_PAGE_WIDTH:
663 {
664 SfxObjectShell* pCurrentShell = SfxObjectShell::Current();
665 if (!pCurrentShell)
666 return;
667
668 // make sure aZoom is initialized with a proper value if SetType
669 // doesn't work
670 SvxZoomItem aZoom( SvxZoomType::PERCENT, 100 );
671
672 switch (rReq.GetSlot())
673 {
674 case SID_ZOOM_50_PERCENT:
675 aZoom.SetValue(50);
676 break;
677 case SID_ZOOM_75_PERCENT:
678 aZoom.SetValue(75);
679 break;
680 case SID_ZOOM_100_PERCENT:
681 aZoom.SetValue(100);
682 break;
683 case SID_ZOOM_150_PERCENT:
684 aZoom.SetValue(150);
685 break;
686 case SID_ZOOM_200_PERCENT:
687 aZoom.SetValue(200);
688 break;
689 case SID_ZOOM_OPTIMAL:
690 aZoom.SetType( SvxZoomType::OPTIMAL );
691 break;
692 case SID_ZOOM_ENTIRE_PAGE:
693 aZoom.SetType( SvxZoomType::WHOLEPAGE );
694 break;
695 case SID_ZOOM_PAGE_WIDTH:
696 aZoom.SetType( SvxZoomType::PAGEWIDTH );
697 break;
698 }
699
700 pCurrentShell->GetDispatcher()->ExecuteList(SID_ATTR_ZOOM, SfxCallMode::ASYNCHRON, { &aZoom });
701
702 break;
703 }
704 case SID_TOOLBAR_MODE:
705 {
706 const SfxStringItem* pModeName = rReq.GetArg<SfxStringItem>( SID_TOOLBAR_MODE );
707
708 if ( !pModeName )
709 {
710 bDone = true;
711 break;
712 }
713
714 OUString aNewName(pModeName->GetValue());
715 uno::Reference< uno::XComponentContext > xContext =
716 ::comphelper::getProcessComponentContext();
717
718 // Get information about current frame and module
719 Reference<XFrame> xCurrentFrame;
720 vcl::EnumContext::Application eCurrentApp = vcl::EnumContext::Application::NONE;
721 OUString aCurrentMode;
722
723 SfxViewFrame* pViewFrame = SfxViewFrame::Current();
724 if( pViewFrame )
725 {
726 xCurrentFrame = pViewFrame->GetFrame().GetFrameInterface();
727
728 const Reference<frame::XModuleManager> xModuleManager = frame::ModuleManager::create( xContext );
729 eCurrentApp = vcl::EnumContext::GetApplicationEnum( xModuleManager->identify( xCurrentFrame ) );
730
731 OUString aPath = "org.openoffice.Office.UI.ToolbarMode/Applications/" +
732 lcl_getAppName( eCurrentApp );
733
734 const utl::OConfigurationTreeRoot aAppNode(
735 xContext,
736 aPath,
737 true);
738 if ( !aAppNode.isValid() )
739 {
740 bDone = true;
741 break;
742 }
743
744 aCurrentMode = comphelper::getString( aAppNode.getNodeValue( "Active" ) );
745
746 if ( aCurrentMode == aNewName )
747 {
748 bDone = true;
749 break;
750 }
751
752 // Save new toolbar mode for a current module
753 aAppNode.setNodeValue( "Active", makeAny( aNewName ) );
754 aAppNode.commit();
755 }
756
757 // Apply settings for all frames
758 pViewFrame = SfxViewFrame::GetFirst();
759 while( pViewFrame )
760 {
761 Reference<XFrame> xFrame = pViewFrame->GetFrame().GetFrameInterface();
762
763 // We want to change mode only for a current app module, ignore other apps
764 const Reference<frame::XModuleManager> xModuleManager = frame::ModuleManager::create( xContext );
765 vcl::EnumContext::Application eApp = vcl::EnumContext::GetApplicationEnum( xModuleManager->identify( xFrame ) );
766 if ( eApp != eCurrentApp )
767 {
768 pViewFrame = SfxViewFrame::GetNext( *pViewFrame );
769 continue;
770 }
771
772 Reference<css::beans::XPropertySet> xPropSet( xFrame, UNO_QUERY );
773 Reference<css::frame::XLayoutManager> xLayoutManager;
774 if ( xPropSet.is() )
775 {
776 try
777 {
778 Any aValue = xPropSet->getPropertyValue( "LayoutManager" );
779 aValue >>= xLayoutManager;
780 }
781 catch ( const css::uno::RuntimeException& )
782 {
783 throw;
784 }
785 catch ( css::uno::Exception& )
786 {
787 }
788 }
789
790 if ( xLayoutManager.is() )
791 {
792 css::uno::Sequence<OUString> aMandatoryToolbars;
793 css::uno::Sequence<OUString> aUserToolbars;
794 std::vector<OUString> aBackupList;
795 OUString aSidebarMode;
796
797 OUString aPath = "org.openoffice.Office.UI.ToolbarMode/Applications/" +
798 lcl_getAppName( eApp ) +
799 "/Modes";
800
801 // Read mode settings
802 const utl::OConfigurationTreeRoot aModesNode(
803 xContext,
804 aPath,
805 true);
806 if ( !aModesNode.isValid() )
807 {
808 bDone = true;
809 break;
810 }
811
812 const Sequence<OUString> aModeNodeNames( aModesNode.getNodeNames() );
813
814 for ( const auto& rModeNodeName : aModeNodeNames )
815 {
816 const utl::OConfigurationNode aModeNode( aModesNode.openNode( rModeNodeName ) );
817 if ( !aModeNode.isValid() )
818 continue;
819
820 OUString aCommandArg = comphelper::getString( aModeNode.getNodeValue( "CommandArg" ) );
821
822 if ( aCommandArg == aNewName )
823 {
824 aMandatoryToolbars = aModeNode.getNodeValue( "Toolbars" ).get< uno::Sequence<OUString> >();
825 aUserToolbars = aModeNode.getNodeValue( "UserToolbars" ).get< uno::Sequence<OUString> >();
826 aSidebarMode = comphelper::getString( aModeNode.getNodeValue( "Sidebar" ) );
827 break;
828 }
829 }
830
831 // Backup visible toolbar list and hide all toolbars
832 const Sequence<Reference<XUIElement>> aUIElements = xLayoutManager->getElements();
833 for ( const Reference< XUIElement >& xUIElement : aUIElements )
834 {
835 Reference< XPropertySet > xPropertySet( xUIElement, UNO_QUERY );
836 if ( xPropertySet.is() && xUIElement.is() )
837 {
838 try
839 {
840 OUString aResName;
841 sal_Int16 nType( -1 );
842 xPropertySet->getPropertyValue( "Type" ) >>= nType;
843 xPropertySet->getPropertyValue( "ResourceURL" ) >>= aResName;
844
845 if (( nType == css::ui::UIElementType::TOOLBAR ) &&
846 !aResName.isEmpty() )
847 {
848 if ( xLayoutManager->isElementVisible( aResName ) )
849 {
850 aBackupList.push_back( aResName );
851 }
852 xLayoutManager->hideElement( aResName );
853 }
854 }
855 catch ( const Exception& )
856 {
857 }
858 }
859 }
860
861 // Show/Hide the Notebookbar
862 const SfxStringItem pItem(SID_NOTEBOOKBAR, aNewName);
863 pViewFrame->GetDispatcher()->ExecuteList(SID_NOTEBOOKBAR, SfxCallMode::SYNCHRON, {&pItem});
864
865 // Show toolbars
866 for ( const OUString& rName : std::as_const(aMandatoryToolbars) )
867 {
868 xLayoutManager->createElement( rName );
869 xLayoutManager->showElement( rName );
870 }
871
872 for ( const OUString& rName : std::as_const(aUserToolbars) )
873 {
874 xLayoutManager->createElement( rName );
875 xLayoutManager->showElement( rName );
876 }
877
878 // Sidebar
879 pViewFrame->ShowChildWindow( SID_SIDEBAR );
880
881 sfx2::sidebar::SidebarController* pSidebar =
882 sfx2::sidebar::SidebarController::GetSidebarControllerForFrame( xFrame );
883 if ( pSidebar )
884 {
885 if ( aSidebarMode == "Arrow" )
886 {
887 pSidebar->FadeOut();
888 }
889 else if ( aSidebarMode == "Tabs" )
890 {
891 pSidebar->FadeIn();
892 pSidebar->RequestOpenDeck();
893 pSidebar->RequestCloseDeck();
894 }
895 else if ( aSidebarMode == "Opened" )
896 {
897 pSidebar->FadeIn();
898 pSidebar->RequestOpenDeck();
899 }
900 }
901
902 // Save settings
903 if ( pViewFrame == SfxViewFrame::Current() )
904 {
905 css::uno::Sequence<OUString> aBackup( comphelper::containerToSequence(aBackupList) );
906
907 for ( const auto& rModeNodeName : aModeNodeNames )
908 {
909 const utl::OConfigurationNode aModeNode( aModesNode.openNode( rModeNodeName ) );
910 if ( !aModeNode.isValid() )
911 continue;
912
913 OUString aCommandArg = comphelper::getString( aModeNode.getNodeValue( "CommandArg" ) );
914
915 if ( aCommandArg == aCurrentMode )
916 {
917 aModeNode.setNodeValue( "UserToolbars", makeAny( aBackup ) );
918 break;
919 }
920 }
921 aModesNode.commit();
922 }
923 }
924
925 pViewFrame = SfxViewFrame::GetNext(*pViewFrame);
926 }
927
928 bDone = true;
929 break;
930 }
931 case SID_TOOLBAR_MODE_UI:
932 {
933 SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
934 ScopedVclPtr<VclAbstractDialog> pDlg(
935 pFact->CreateToolbarmodeDialog(rReq.GetFrameWeld()));
936 pDlg->Execute();
937 bDone = true;
938 break;
939 }
940 case SID_AVAILABLE_TOOLBARS:
941 {
942 const SfxStringItem* pToolbarName = rReq.GetArg<SfxStringItem>(SID_AVAILABLE_TOOLBARS);
943
944 if ( pToolbarName )
945 {
946 Reference < XDesktop2 > xDesktop = Desktop::create ( ::comphelper::getProcessComponentContext() );
947 Reference< XFrame > xFrame = xDesktop->getActiveFrame();
948
949 Reference< css::beans::XPropertySet > xPropSet( xFrame, UNO_QUERY );
950 Reference< css::frame::XLayoutManager > xLayoutManager;
951 if ( xPropSet.is() )
952 {
953 try
954 {
955 Any aValue = xPropSet->getPropertyValue("LayoutManager");
956 aValue >>= xLayoutManager;
957 }
958 catch ( const css::uno::RuntimeException& )
959 {
960 throw;
961 }
962 catch ( css::uno::Exception& )
963 {
964 }
965 }
966
967 if ( xLayoutManager.is() )
968 {
969 OUString aToolbarName = "private:resource/toolbar/" +
970 pToolbarName->GetValue();
971
972 // Evaluate Parameter
973 bool bShow( !xLayoutManager->isElementVisible( aToolbarName ));
974
975 if ( bShow )
976 {
977 xLayoutManager->createElement( aToolbarName );
978 xLayoutManager->showElement( aToolbarName );
979 }
980 else
981 xLayoutManager->hideElement( aToolbarName );
982 }
983 }
984
985 bDone = true;
986 break;
987 }
988 case SID_MENUBAR:
989 {
990 sfx2::SfxNotebookBar::ToggleMenubar();
991 bDone = true;
992 break;
993 }
994 case SID_DEVELOPMENT_TOOLS_DOCKING_WINDOW:
995 {
996 SfxViewShell* pViewShell = SfxViewShell::Current();
997 SfxViewFrame* pViewFrame = pViewShell->GetViewFrame();
998 auto nID = rReq.GetSlot();
999 pViewFrame->ToggleChildWindow(nID);
1000
1001 bDone = true;
1002 break;
1003 }
1004 case SID_INSPECT_SELECTED_OBJECT:
1005 {
1006 SfxViewShell* pViewShell = SfxViewShell::Current();
1007 SfxViewFrame* pViewFrame = pViewShell->GetViewFrame();
1008
1009 pViewFrame->ShowChildWindow(SID_DEVELOPMENT_TOOLS_DOCKING_WINDOW, true);
1010
1011 SfxChildWindow* pChild = pViewFrame->GetChildWindow(SID_DEVELOPMENT_TOOLS_DOCKING_WINDOW);
1012 if (!pChild)
1013 return;
1014
1015 auto pDockingWin = dynamic_cast<DevelopmentToolDockingWindow*>(pChild->GetWindow());
1016 if (pDockingWin)
1017 {
1018 pDockingWin->changeToCurrentSelection();
1019 }
1020
1021 bDone = true;
1022 break;
1023 }
1024 case SID_SAFE_MODE:
1025 {
1026 SafeModeQueryDialog aDialog(rReq.GetFrameWeld());
1027 aDialog.run();
1028 break;
1029 }
1030 case SID_TOOLBAR_LOCK:
1031 {
1032 SfxViewFrame* pViewFrame = SfxViewFrame::Current();
1033 if (pViewFrame)
1034 {
1035 Reference<XFrame> xCurrentFrame;
1036 uno::Reference<uno::XComponentContext> xContext
1037 = ::comphelper::getProcessComponentContext();
1038 xCurrentFrame = pViewFrame->GetFrame().GetFrameInterface();
1039 const Reference<frame::XModuleManager> xModuleManager
1040 = frame::ModuleManager::create(xContext);
1041 const utl::OConfigurationTreeRoot aAppNode(
1042 xContext, "org.openoffice.Office.UI.GlobalSettings/Toolbars/States", true);
1043 if (aAppNode.isValid())
1044 {
1045 bool isLocked = comphelper::getBOOL(aAppNode.getNodeValue("Locked"));
1046 aAppNode.setNodeValue("Locked", makeAny(!isLocked));
1047 aAppNode.commit();
1048 //TODO: apply immediately w/o restart needed
1049 SolarMutexGuard aGuard;
1050 svtools::executeRestartDialog(comphelper::getProcessComponentContext(), nullptr,
1051 svtools::RESTART_REASON_UI_CHANGE);
1052 }
1053 }
1054 break;
1055 }
1056 default:
1057 break;
1058 }
1059
1060 if ( bDone )
1061 rReq.Done();
1062 }
1063
MiscState_Impl(SfxItemSet & rSet)1064 void SfxApplication::MiscState_Impl(SfxItemSet &rSet)
1065 {
1066 const sal_uInt16 *pRanges = rSet.GetRanges();
1067 DBG_ASSERT(pRanges && *pRanges, "Set without range");
1068 while ( *pRanges )
1069 {
1070 for(sal_uInt16 nWhich = *pRanges++; nWhich <= *pRanges; ++nWhich)
1071 {
1072 switch(nWhich)
1073 {
1074 case SID_TEMPLATE_ADDRESSBOOKSOURCE:
1075 if ( !SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::EModule::DATABASE) )
1076 rSet.Put(SfxVisibilityItem(nWhich, false));
1077 break;
1078 case SID_QUITAPP:
1079 {
1080 if ( pImpl->nDocModalMode )
1081 rSet.DisableItem(nWhich);
1082 else
1083 rSet.Put(SfxStringItem(nWhich, SfxResId(STR_QUITAPP)));
1084 break;
1085 }
1086
1087 case SID_CONFIG:
1088 case SID_TOOLBOXOPTIONS:
1089 case SID_CONFIGSTATUSBAR:
1090 case SID_CONFIGMENU:
1091 case SID_CONFIGACCEL:
1092 case SID_CONFIGEVENT:
1093 {
1094 if( SvtMiscOptions().DisableUICustomization() )
1095 rSet.DisableItem(nWhich);
1096 break;
1097 }
1098
1099 #if HAVE_FEATURE_SCRIPTING
1100 case SID_BASICSTOP:
1101 if ( !StarBASIC::IsRunning() )
1102 rSet.DisableItem(nWhich);
1103 break;
1104 #endif
1105
1106 case SID_HELPTIPS:
1107 {
1108 rSet.Put( SfxBoolItem( SID_HELPTIPS, Help::IsQuickHelpEnabled() ) );
1109 }
1110 break;
1111 case SID_HELPBALLOONS:
1112 {
1113 rSet.Put( SfxBoolItem( SID_HELPBALLOONS, Help::IsBalloonHelpEnabled() ) );
1114 }
1115 break;
1116
1117 case SID_EXTENDEDHELP:
1118 {
1119 }
1120 break;
1121
1122 case SID_CLOSEDOCS:
1123 {
1124 Reference < XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
1125 Reference< XIndexAccess > xTasks = xDesktop->getFrames();
1126 if ( !xTasks.is() || !xTasks->getCount() )
1127 rSet.DisableItem(nWhich);
1128 break;
1129 }
1130
1131 case SID_SAVEDOCS:
1132 {
1133 bool bModified = false;
1134 for ( SfxObjectShell *pObjSh = SfxObjectShell::GetFirst();
1135 pObjSh;
1136 pObjSh = SfxObjectShell::GetNext( *pObjSh ) )
1137 {
1138 if ( pObjSh->IsModified() )
1139 {
1140 bModified = true;
1141 break;
1142 }
1143 }
1144
1145 if ( !bModified )
1146 rSet.DisableItem( nWhich );
1147 break;
1148 }
1149
1150 case SID_TEMPLATE_MANAGER:
1151 {
1152 if ( !officecfg::Office::Common::Misc::ExperimentalMode::get() )
1153 {
1154 rSet.DisableItem( nWhich );
1155 rSet.Put( SfxVisibilityItem( nWhich, false ) );
1156 }
1157 }
1158 break;
1159
1160 case SID_ZOOM_50_PERCENT:
1161 case SID_ZOOM_75_PERCENT:
1162 case SID_ZOOM_100_PERCENT:
1163 case SID_ZOOM_150_PERCENT:
1164 case SID_ZOOM_200_PERCENT:
1165 case SID_ZOOM_OPTIMAL:
1166 case SID_ZOOM_ENTIRE_PAGE:
1167 case SID_ZOOM_PAGE_WIDTH:
1168 {
1169 SfxObjectShell* pCurrentShell = SfxObjectShell::Current();
1170
1171 const SfxPoolItem *pItem;
1172 SfxItemState aState = pCurrentShell ?
1173 pCurrentShell->GetDispatcher()->QueryState(SID_ATTR_ZOOM, pItem) : SfxItemState::DISABLED;
1174 if ( aState == SfxItemState::DISABLED )
1175 rSet.DisableItem( nWhich );
1176 }
1177 break;
1178
1179 case SID_MENUBAR:
1180 {
1181 Reference < XDesktop2 > xDesktop = Desktop::create ( ::comphelper::getProcessComponentContext() );
1182 Reference< XFrame > xFrame = xDesktop->getActiveFrame();
1183
1184 Reference< css::beans::XPropertySet > xPropSet( xFrame, UNO_QUERY );
1185 Reference< css::frame::XLayoutManager > xLayoutManager;
1186 if ( xPropSet.is() )
1187 {
1188 try
1189 {
1190 Any aValue = xPropSet->getPropertyValue("LayoutManager");
1191 aValue >>= xLayoutManager;
1192 }
1193 catch ( const css::uno::RuntimeException& )
1194 {
1195 throw;
1196 }
1197 catch ( css::uno::Exception& )
1198 {
1199 }
1200 }
1201
1202 if ( xLayoutManager.is() )
1203 {
1204 const bool bState
1205 = xLayoutManager->getElement("private:resource/menubar/menubar").is()
1206 && xLayoutManager->isElementVisible(
1207 "private:resource/menubar/menubar");
1208
1209 SfxBoolItem aItem( SID_MENUBAR, bState );
1210 rSet.Put( aItem );
1211 }
1212 break;
1213 }
1214 case SID_SAFE_MODE:
1215 {
1216 // no restart in safe mode when already in safe mode
1217 if ( Application::IsSafeModeEnabled() )
1218 rSet.DisableItem( SID_SAFE_MODE );
1219 break;
1220 }
1221 case SID_DEVELOPMENT_TOOLS_DOCKING_WINDOW:
1222 {
1223 bool bSuccess = false;
1224 auto* pViewShell = SfxViewShell::Current();
1225 if (pViewShell)
1226 {
1227 auto* pViewFrame = pViewShell->GetViewFrame();
1228 if (pViewFrame && pViewFrame->KnowsChildWindow(nWhich))
1229 {
1230 rSet.Put(SfxBoolItem(nWhich, pViewFrame->HasChildWindow(nWhich)));
1231 bSuccess = true;
1232 }
1233 }
1234
1235 if (!bSuccess)
1236 rSet.DisableItem(nWhich);
1237 }
1238 break;
1239 case SID_INSPECT_SELECTED_OBJECT:
1240 {
1241 bool bSuccess = false;
1242 auto* pViewShell = SfxViewShell::Current();
1243 if (pViewShell)
1244 {
1245 auto* pViewFrame = pViewShell->GetViewFrame();
1246 if (pViewFrame && pViewFrame->KnowsChildWindow(SID_DEVELOPMENT_TOOLS_DOCKING_WINDOW))
1247 {
1248 bSuccess = true;
1249 }
1250 }
1251 if (!bSuccess)
1252 rSet.DisableItem(nWhich);
1253 }
1254 break;
1255 case SID_TOOLBAR_LOCK:
1256 {
1257 rSet.Put( SfxBoolItem( SID_TOOLBAR_LOCK, ToolBox::AlwaysLocked() ));
1258 }
1259 break;
1260 default:
1261 break;
1262 }
1263 }
1264
1265 ++pRanges;
1266 }
1267 }
1268
1269 #if HAVE_FEATURE_SCRIPTING
1270
1271 #ifndef DISABLE_DYNLOADING
1272
1273 typedef rtl_uString* (*basicide_choose_macro)(void*, void*, void*, sal_Bool);
1274
1275 #else
1276
1277 extern "C" rtl_uString* basicide_choose_macro(void*, void*, void*, sal_Bool);
1278
1279 #endif
1280
ChooseMacro(weld::Window * pParent,const Reference<XModel> & rxLimitToDocument,const Reference<XFrame> & xDocFrame,bool bChooseOnly)1281 static OUString ChooseMacro(weld::Window* pParent, const Reference<XModel>& rxLimitToDocument, const Reference<XFrame>& xDocFrame, bool bChooseOnly)
1282 {
1283 #ifndef DISABLE_DYNLOADING
1284 basicide_choose_macro pSymbol = reinterpret_cast<basicide_choose_macro>(sfx2::getBasctlFunction("basicide_choose_macro"));
1285 #else
1286 #define pSymbol basicide_choose_macro
1287 #endif
1288
1289 // call basicide_choose_macro in basctl
1290 rtl_uString* pScriptURL = pSymbol(pParent, rxLimitToDocument.get(), xDocFrame.get(), bChooseOnly);
1291 OUString aScriptURL( pScriptURL );
1292 rtl_uString_release( pScriptURL );
1293 return aScriptURL;
1294
1295 #ifdef DISABLE_DYNLOADING
1296 #undef pSymbol
1297 #endif
1298 }
1299
1300 #endif
1301
1302 namespace
1303 {
1304 #if HAVE_FEATURE_SCRIPTING
lcl_getDialogParent(const Reference<XFrame> & rxFrame)1305 weld::Window* lcl_getDialogParent(const Reference<XFrame>& rxFrame)
1306 {
1307 Reference<awt::XWindow> xContainerWindow;
1308 if (rxFrame.is())
1309 xContainerWindow = rxFrame->getContainerWindow();
1310 return Application::GetFrameWeld(xContainerWindow);
1311 }
1312
lcl_getBasicIDEViewFrame(SfxObjectShell const * i_pBasicIDE)1313 SfxViewFrame* lcl_getBasicIDEViewFrame( SfxObjectShell const * i_pBasicIDE )
1314 {
1315 SfxViewFrame* pView = SfxViewFrame::GetFirst( i_pBasicIDE );
1316 while ( pView )
1317 {
1318 if ( pView->GetObjectShell()->GetFactory().GetDocumentServiceName() == "com.sun.star.script.BasicIDE" )
1319 break;
1320 pView = SfxViewFrame::GetNext( *pView, i_pBasicIDE );
1321 }
1322 return pView;
1323 }
lcl_findStartModuleFrame(const Reference<XComponentContext> & rxContext)1324 Reference< XFrame > lcl_findStartModuleFrame( const Reference<XComponentContext> & rxContext )
1325 {
1326 try
1327 {
1328 Reference < XDesktop2 > xDesktop = Desktop::create( rxContext );
1329 Reference < XIndexAccess > xContainer( xDesktop->getFrames(), UNO_QUERY_THROW );
1330
1331 Reference< XModuleManager2 > xCheck = ModuleManager::create(rxContext);
1332
1333 sal_Int32 nCount = xContainer->getCount();
1334 for ( sal_Int32 i=0; i<nCount; ++i )
1335 {
1336 try
1337 {
1338 Reference < XFrame > xFrame( xContainer->getByIndex(i), UNO_QUERY_THROW );
1339 OUString sModule = xCheck->identify( xFrame );
1340 if ( sModule == "com.sun.star.frame.StartModule" )
1341 return xFrame;
1342 }
1343 catch( const UnknownModuleException& )
1344 {
1345 // silence
1346 }
1347 catch(const Exception&)
1348 {
1349 // re-throw, caught below
1350 throw;
1351 }
1352 }
1353 }
1354 catch( const Exception& )
1355 {
1356 DBG_UNHANDLED_EXCEPTION("sfx.appl");
1357 }
1358 return nullptr;
1359 }
1360 #endif // HAVE_FEATURE_SCRIPTING
1361 }
1362
OfaExec_Impl(SfxRequest & rReq)1363 void SfxApplication::OfaExec_Impl( SfxRequest& rReq )
1364 {
1365 switch ( rReq.GetSlot() )
1366 {
1367 case SID_OPTIONS_TREEDIALOG:
1368 {
1369 OUString sPageURL;
1370 const SfxStringItem* pURLItem = rReq.GetArg<SfxStringItem>(SID_OPTIONS_PAGEURL);
1371 if ( pURLItem )
1372 sPageURL = pURLItem->GetValue();
1373 Reference <XFrame> xFrame(GetRequestFrame(rReq));
1374 SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
1375 VclPtr<VclAbstractDialog> pDlg =
1376 pFact->CreateFrameDialog(rReq.GetFrameWeld(), xFrame, rReq.GetSlot(), sPageURL );
1377 short nRet = pDlg->Execute();
1378 pDlg.disposeAndClear();
1379 SfxViewFrame* pView = SfxViewFrame::GetFirst();
1380 while ( pView )
1381 {
1382 if (nRet == RET_OK)
1383 {
1384 SfxObjectShell* pObjSh = pView->GetObjectShell();
1385 if (pObjSh)
1386 pObjSh->SetConfigOptionsChecked(false);
1387 }
1388 pView->GetBindings().InvalidateAll(false);
1389 pView = SfxViewFrame::GetNext( *pView );
1390 }
1391 break;
1392 }
1393
1394 case SID_MORE_DICTIONARIES:
1395 {
1396 uno::Sequence<beans::PropertyValue> aArgs(1);
1397 aArgs[0].Name = "AdditionsTag";
1398 aArgs[0].Value <<= OUString("Dictionary");
1399 comphelper::dispatchCommand(".uno:AdditionsDialog", aArgs);
1400 break;
1401 }
1402 #if HAVE_FEATURE_SCRIPTING
1403 case SID_BASICIDE_APPEAR:
1404 {
1405 SfxViewFrame* pView = lcl_getBasicIDEViewFrame( nullptr );
1406 if ( !pView )
1407 {
1408 SfxObjectShell* pBasicIDE = SfxObjectShell::CreateObject( "com.sun.star.script.BasicIDE" );
1409 pBasicIDE->DoInitNew();
1410 pBasicIDE->SetModified( false );
1411 try
1412 {
1413 // load the Basic IDE via direct access to the SFX frame loader. A generic loadComponentFromURL
1414 // (which could be done via SfxViewFrame::LoadDocumentIntoFrame) is not feasible here, since the Basic IDE
1415 // does not really play nice with the framework's concept. For instance, it is a "singleton document",
1416 // which conflicts, at the latest, with the framework's concept of loading into _blank frames.
1417 // So, since we know that our frame loader can handle it, we skip the generic framework loader
1418 // mechanism, and the type detection (which doesn't know about the Basic IDE).
1419 Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
1420 Reference< XSynchronousFrameLoader > xLoader(
1421 xContext->getServiceManager()->createInstanceWithContext("com.sun.star.comp.office.FrameLoader", xContext),
1422 UNO_QUERY_THROW );
1423 ::comphelper::NamedValueCollection aLoadArgs;
1424 aLoadArgs.put( "Model", pBasicIDE->GetModel() );
1425 aLoadArgs.put( "URL", OUString( "private:factory/sbasic" ) );
1426
1427 Reference< XFrame > xTargetFrame( lcl_findStartModuleFrame( xContext ) );
1428 if ( !xTargetFrame.is() )
1429 xTargetFrame = SfxFrame::CreateBlankFrame();
1430 ENSURE_OR_THROW( xTargetFrame.is(), "could not obtain a frameto load the Basic IDE into!" );
1431
1432 xLoader->load( aLoadArgs.getPropertyValues(), xTargetFrame );
1433 }
1434 catch( const Exception& )
1435 {
1436 DBG_UNHANDLED_EXCEPTION("sfx.appl");
1437 }
1438
1439 pView = lcl_getBasicIDEViewFrame( pBasicIDE );
1440 if ( pView )
1441 pView->SetName( "BASIC:1" );
1442 }
1443
1444 if ( pView )
1445 pView->GetFrame().Appear();
1446
1447 const SfxItemSet* pArgs = rReq.GetArgs();
1448 if ( pArgs && pView )
1449 {
1450 SfxViewShell* pViewShell = pView->GetViewShell();
1451 SfxObjectShell* pObjShell = pView->GetObjectShell();
1452 if ( pViewShell && pObjShell )
1453 {
1454 SfxRequest aReq( SID_BASICIDE_SHOWWINDOW, SfxCallMode::SYNCHRON, pObjShell->GetPool() );
1455 aReq.SetArgs( *pArgs );
1456 pViewShell->ExecuteSlot( aReq );
1457 }
1458 }
1459
1460 rReq.Done();
1461 }
1462 break;
1463
1464 case SID_BASICCHOOSER:
1465 {
1466 const SfxItemSet* pArgs = rReq.GetArgs();
1467 const SfxPoolItem* pItem;
1468 bool bChooseOnly = false;
1469 Reference< XModel > xLimitToModel;
1470 if(pArgs && SfxItemState::SET == pArgs->GetItemState(SID_RECORDMACRO, false, &pItem) )
1471 {
1472 bool bRecord = static_cast<const SfxBoolItem*>(pItem)->GetValue();
1473 if ( bRecord )
1474 {
1475 // !Hack
1476 bChooseOnly = false;
1477 SfxObjectShell* pCurrentShell = SfxObjectShell::Current();
1478 OSL_ENSURE( pCurrentShell, "macro recording outside an SFX document?" );
1479 if ( pCurrentShell )
1480 xLimitToModel = pCurrentShell->GetModel();
1481 }
1482 }
1483
1484 Reference <XFrame> xFrame(GetRequestFrame(rReq));
1485 rReq.SetReturnValue(SfxStringItem(rReq.GetSlot(), ChooseMacro(rReq.GetFrameWeld(), xLimitToModel, xFrame, bChooseOnly)));
1486 rReq.Done();
1487 }
1488 break;
1489
1490 case SID_MACROORGANIZER:
1491 {
1492 SAL_INFO("sfx.appl", "handling SID_MACROORGANIZER");
1493 const SfxItemSet* pArgs = rReq.GetArgs();
1494 const SfxPoolItem* pItem;
1495 sal_Int16 nTabId = 0;
1496 if(pArgs && SfxItemState::SET == pArgs->GetItemState(SID_MACROORGANIZER, false, &pItem) )
1497 {
1498 nTabId = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
1499 }
1500
1501 SfxApplication::MacroOrganizer(rReq.GetFrameWeld(), nTabId);
1502 rReq.Done();
1503 }
1504 break;
1505
1506 case SID_RUNMACRO:
1507 {
1508 SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
1509 SAL_INFO("sfx.appl", "SfxApplication::OfaExec_Impl: case ScriptOrg");
1510
1511 Reference <XFrame> xFrame(GetRequestFrame(rReq));
1512 if ( !xFrame.is() )
1513 {
1514 const SfxViewFrame* pViewFrame = SfxViewFrame::Current();
1515 if ( pViewFrame )
1516 xFrame = pViewFrame->GetFrame().GetFrameInterface();
1517 }
1518
1519 do // artificial loop for flow control
1520 {
1521 VclPtr<AbstractScriptSelectorDialog> pDlg(pFact->CreateScriptSelectorDialog(lcl_getDialogParent(xFrame), xFrame));
1522 OSL_ENSURE( pDlg, "SfxApplication::OfaExec_Impl( SID_RUNMACRO ): no dialog!" );
1523 if ( !pDlg )
1524 break;
1525 pDlg->SetRunLabel();
1526
1527 pDlg->StartExecuteAsync([pDlg, xFrame](sal_Int32 nDialogResult) {
1528 if ( !nDialogResult )
1529 {
1530 pDlg->disposeOnce();
1531 return;
1532 }
1533
1534 Sequence< Any > args;
1535 Sequence< sal_Int16 > outIndex;
1536 Sequence< Any > outArgs;
1537 Any ret;
1538
1539 Reference< XInterface > xScriptContext;
1540
1541 Reference< XController > xController;
1542 if ( xFrame.is() )
1543 xController = xFrame->getController();
1544 if ( xController.is() )
1545 xScriptContext = xController->getModel();
1546 if ( !xScriptContext.is() )
1547 xScriptContext = xController;
1548
1549 SfxObjectShell::CallXScript( xScriptContext, pDlg->GetScriptURL(), args, ret, outIndex, outArgs );
1550 pDlg->disposeOnce();
1551 });
1552 }
1553 while ( false );
1554 rReq.Done();
1555 }
1556 break;
1557
1558 case SID_SCRIPTORGANIZER:
1559 {
1560 SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
1561 SAL_INFO("sfx.appl", "SfxApplication::OfaExec_Impl: case ScriptOrg");
1562 const SfxItemSet* pArgs = rReq.GetArgs();
1563 const SfxPoolItem* pItem;
1564 OUString aLanguage;
1565 if(pArgs && SfxItemState::SET == pArgs->GetItemState(SID_SCRIPTORGANIZER, false, &pItem) )
1566 {
1567 aLanguage = static_cast<const SfxScriptOrganizerItem*>(pItem)->getLanguage();
1568 }
1569
1570 OUString aLang( aLanguage );
1571 SAL_INFO("sfx.appl", "SfxApplication::OfaExec_Impl: about to create dialog for: " << aLang);
1572 ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateSvxScriptOrgDialog(rReq.GetFrameWeld(), aLanguage));
1573 if( pDlg )
1574 {
1575 pDlg->Execute();
1576 }
1577 else
1578 {
1579 SAL_WARN("sfx.appl", "no dialog!!!");
1580 }
1581 rReq.Done();
1582 }
1583 break;
1584 #endif // HAVE_FEATURE_SCRIPTING
1585
1586 case SID_OFFICE_CHECK_PLZ:
1587 {
1588 bool bRet = false;
1589 const SfxStringItem* pStringItem = rReq.GetArg<SfxStringItem>(rReq.GetSlot());
1590
1591 if ( pStringItem )
1592 {
1593 bRet = true /*!!!SfxIniManager::CheckPLZ( aPLZ )*/;
1594 }
1595 #if HAVE_FEATURE_SCRIPTING
1596 else
1597 SbxBase::SetError( ERRCODE_BASIC_WRONG_ARGS );
1598 #endif
1599 rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), bRet ) );
1600 }
1601 break;
1602
1603 case SID_AUTO_CORRECT_DLG:
1604 {
1605 SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
1606 SfxItemSet aSet(GetPool(), svl::Items<SID_AUTO_CORRECT_DLG, SID_AUTO_CORRECT_DLG>{});
1607 const SfxPoolItem* pItem=nullptr;
1608 const SfxItemSet* pSet = rReq.GetArgs();
1609 SfxItemPool* pSetPool = pSet ? pSet->GetPool() : nullptr;
1610 if ( pSet && pSet->GetItemState( pSetPool->GetWhich( SID_AUTO_CORRECT_DLG ), false, &pItem ) == SfxItemState::SET )
1611 aSet.Put( *pItem );
1612
1613 ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateAutoCorrTabDialog(rReq.GetFrameWeld(), &aSet));
1614 pDlg->Execute();
1615
1616 break;
1617 }
1618
1619 case SID_NEWSD :
1620 {
1621 SvtModuleOptions aModuleOpt;
1622 if ( !aModuleOpt.IsImpress() )
1623 {
1624 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(rReq.GetFrameWeld(),
1625 VclMessageType::Warning, VclButtonsType::Ok,
1626 SfxResId(STR_MODULENOTINSTALLED)));
1627 xBox->run();
1628 return;
1629 }
1630
1631 Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
1632 Reference< frame::XDispatchProvider > xProv = drawing::ModuleDispatcher::create( xContext );
1633
1634 OUString aCmd = OUString::createFromAscii( GetInterface()->GetSlot( rReq.GetSlot() )->GetUnoName() );
1635 Reference< frame::XDispatchHelper > xHelper( frame::DispatchHelper::create(xContext) );
1636 Sequence < beans::PropertyValue > aSeq;
1637 if ( rReq.GetArgs() )
1638 TransformItems( rReq.GetSlot(), *rReq.GetArgs(), aSeq );
1639 Any aResult = xHelper->executeDispatch( xProv, aCmd, OUString(), 0, aSeq );
1640 frame::DispatchResultEvent aEvent;
1641 bool bSuccess = (aResult >>= aEvent) &&
1642 (aEvent.State == frame::DispatchResultState::SUCCESS);
1643 rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), bSuccess ) );
1644 }
1645 break;
1646
1647 case FN_LABEL :
1648 case FN_BUSINESS_CARD :
1649 case FN_XFORMS_INIT :
1650 {
1651 Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
1652 Reference< frame::XDispatchProvider > xProv = text::ModuleDispatcher::create( xContext );
1653
1654 OUString aCmd = OUString::createFromAscii( GetInterface()->GetSlot( rReq.GetSlot() )->GetUnoName() );
1655 Reference< frame::XDispatchHelper > xHelper( frame::DispatchHelper::create(xContext) );
1656 Sequence < beans::PropertyValue > aSeq;
1657 if ( rReq.GetArgs() )
1658 TransformItems( rReq.GetSlot(), *rReq.GetArgs(), aSeq );
1659 Any aResult = xHelper->executeDispatch( xProv, aCmd, OUString(), 0, aSeq );
1660 frame::DispatchResultEvent aEvent;
1661 bool bSuccess = (aResult >>= aEvent) &&
1662 (aEvent.State == frame::DispatchResultState::SUCCESS);
1663 rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), bSuccess ) );
1664 }
1665 break;
1666
1667 case SID_ADDRESS_DATA_SOURCE:
1668 {
1669 try
1670 {
1671 Reference< uno::XComponentContext > xORB = ::comphelper::getProcessComponentContext();
1672 Reference< ui::dialogs::XExecutableDialog > xDialog = ui::dialogs::AddressBookSourcePilot::createWithParent(xORB, nullptr);
1673 xDialog->execute();
1674 }
1675 catch(const css::uno::Exception&)
1676 {
1677 DBG_UNHANDLED_EXCEPTION("sfx.appl");
1678 }
1679 }
1680 break;
1681
1682 case SID_COMP_BIBLIOGRAPHY:
1683 lcl_tryLoadBibliography();
1684 break;
1685 }
1686 }
1687
OfaState_Impl(SfxItemSet & rSet)1688 void SfxApplication::OfaState_Impl(SfxItemSet &rSet)
1689 {
1690 SvtModuleOptions aModuleOpt;
1691
1692 if( !aModuleOpt.IsWriter())
1693 {
1694 rSet.DisableItem( FN_LABEL );
1695 rSet.DisableItem( FN_BUSINESS_CARD );
1696 rSet.DisableItem( FN_XFORMS_INIT );
1697 }
1698 if ( comphelper::LibreOfficeKit::isActive() )
1699 rSet.DisableItem( SID_AUTO_CORRECT_DLG );
1700
1701 bool bMacrosDisabled
1702 = officecfg::Office::Common::Security::Scripting::DisableMacrosExecution::get();
1703 if (bMacrosDisabled)
1704 {
1705 rSet.DisableItem(SID_RUNMACRO);
1706 rSet.DisableItem(SID_MACROORGANIZER);
1707 rSet.DisableItem(SID_SCRIPTORGANIZER);
1708 rSet.DisableItem(SID_BASICIDE_APPEAR);
1709 }
1710 }
1711
1712 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1713