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