Branch libreoffice-5-0-4
[LibreOffice.git] / sfx2 / source / appl / appserv.cxx
blob7ff0da288f8086e94071a9abff9e922e729faa00
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <config_features.h>
22 #include <com/sun/star/document/XEmbeddedScripts.hpp>
23 #include <com/sun/star/drawing/ModuleDispatcher.hpp>
24 #include <com/sun/star/embed/XStorage.hpp>
25 #include <com/sun/star/embed/ElementModes.hpp>
26 #include <com/sun/star/frame/Desktop.hpp>
27 #include <com/sun/star/frame/DispatchResultEvent.hpp>
28 #include <com/sun/star/frame/DispatchResultState.hpp>
29 #include <com/sun/star/frame/DispatchHelper.hpp>
30 #include <com/sun/star/frame/XDesktop.hpp>
31 #include <com/sun/star/frame/XFramesSupplier.hpp>
32 #include <com/sun/star/frame/XLayoutManager.hpp>
33 #include <com/sun/star/frame/XSynchronousFrameLoader.hpp>
34 #include <com/sun/star/sdbc/DriverManager.hpp>
35 #include <com/sun/star/system/SystemShellExecute.hpp>
36 #include <com/sun/star/system/SystemShellExecuteFlags.hpp>
37 #include <com/sun/star/system/SystemShellExecuteException.hpp>
38 #include <com/sun/star/task/XJobExecutor.hpp>
39 #include <com/sun/star/text/ModuleDispatcher.hpp>
40 #include <com/sun/star/ui/dialogs/AddressBookSourcePilot.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>
46 #include <com/sun/star/frame/XComponentLoader.hpp>
48 #include <comphelper/processfactory.hxx>
49 #include <comphelper/storagehelper.hxx>
51 #include <svtools/addresstemplate.hxx>
52 #include <svtools/miscopt.hxx>
53 #include <svtools/restartdialog.hxx>
54 #include <svl/visitem.hxx>
55 #include <unotools/intlwrapper.hxx>
57 #include <unotools/configmgr.hxx>
58 #include <tools/diagnose_ex.h>
59 #include <vcl/layout.hxx>
60 #include <svl/intitem.hxx>
61 #include <svl/eitem.hxx>
62 #include <svl/stritem.hxx>
63 #include <basic/sbstar.hxx>
64 #include <basic/basmgr.hxx>
65 #include <basic/basrdll.hxx>
66 #include <svtools/sfxecode.hxx>
67 #include <svtools/ehdl.hxx>
68 #include <vcl/help.hxx>
69 #include <vcl/stdtext.hxx>
70 #include <rtl/ustrbuf.hxx>
71 #include <osl/file.hxx>
73 #include <unotools/pathoptions.hxx>
74 #include <unotools/moduleoptions.hxx>
75 #include <svtools/helpopt.hxx>
76 #include <toolkit/helper/vclunohelper.hxx>
77 #include <unotools/bootstrap.hxx>
78 #include <rtl/bootstrap.hxx>
79 #include <cppuhelper/exc_hlp.hxx>
81 #include <com/sun/star/script/provider/XScriptProviderFactory.hpp>
82 #include <com/sun/star/frame/ModuleManager.hpp>
83 #include <com/sun/star/beans/XPropertySet.hpp>
85 #include <sfx2/app.hxx>
86 #include <sfx2/request.hxx>
87 #include <sfx2/dispatch.hxx>
88 #include <sfx2/bindings.hxx>
89 #include <sfx2/msg.hxx>
90 #include <sfx2/objface.hxx>
91 #include <sfx2/objitem.hxx>
92 #include <sfx2/objsh.hxx>
93 #include <sfx2/hintpost.hxx>
94 #include <sfx2/viewsh.hxx>
95 #include <sfx2/docfac.hxx>
96 #include <sfx2/docfile.hxx>
97 #include <sfx2/docfilt.hxx>
98 #include <sfx2/new.hxx>
99 #include "sfxtypes.hxx"
100 #include <sfx2/tabdlg.hxx>
101 #include "arrdecl.hxx"
102 #include <sfx2/sfx.hrc>
103 #include "app.hrc"
104 #include <sfx2/passwd.hxx>
105 #include <sfx2/sfxresid.hxx>
106 #include <sfx2/childwin.hxx>
107 #include "appdata.hxx"
108 #include <sfx2/minfitem.hxx>
109 #include <sfx2/event.hxx>
110 #include <sfx2/module.hxx>
111 #include <sfx2/viewfrm.hxx>
112 #include "sfxpicklist.hxx"
113 #include "imestatuswindow.hxx"
114 #include <sfx2/sfxdlg.hxx>
115 #include <sfx2/dialogs.hrc>
116 #include "sorgitm.hxx"
117 #include <sfx2/sfxhelp.hxx>
118 #include <sfx2/zoomitem.hxx>
119 #include <sfx2/templatedlg.hxx>
121 #include <officecfg/Office/Common.hxx>
122 #include <officecfg/Setup.hxx>
123 #include <boost/scoped_ptr.hpp>
125 using namespace ::com::sun::star;
126 using namespace ::com::sun::star::beans;
127 using namespace ::com::sun::star::uno;
128 using namespace ::com::sun::star::frame;
129 using namespace ::com::sun::star::container;
130 using namespace ::com::sun::star::util;
131 using namespace ::com::sun::star::script;
132 using namespace ::com::sun::star::system;
133 using namespace ::com::sun::star::lang;
134 using namespace ::com::sun::star::document;
136 namespace
138 // lp#527938, debian#602953, fdo#33266, i#105408
139 static bool lcl_isBaseAvailable()
143 // if we get com::sun::star::sdbc::DriverManager, libsdbc2 is there
144 // and the bibliography is assumed to work
145 return com::sun::star::sdbc::DriverManager::create(comphelper::getProcessComponentContext()).is();
147 catch (Exception & e)
149 SAL_INFO(
150 "sfx.appl",
151 "assuming Base to be missing; caught " << e.Message);
152 return false;
155 static void lcl_tryLoadBibliography()
157 // lp#527938, debian#602953, fdo#33266, i#105408
158 // make sure we actually can instanciate services from base first
159 if(!lcl_isBaseAvailable())
163 using namespace org::freedesktop::PackageKit;
164 using namespace svtools;
165 Reference< XSyncDbusSessionHelper > xSyncDbusSessionHelper(SyncDbusSessionHelper::create(comphelper::getProcessComponentContext()));
166 Sequence< OUString > vPackages(1);
167 vPackages[0] = "libreoffice-base";
168 OUString sInteraction;
169 xSyncDbusSessionHelper->InstallPackageNames(0, vPackages, sInteraction);
170 // Ill be back (hopefully)!
171 SolarMutexGuard aGuard;
172 executeRestartDialog(comphelper::getProcessComponentContext(), NULL, RESTART_REASON_BIBLIOGRAPHY_INSTALL);
174 catch (const Exception & e)
176 SAL_INFO(
177 "sfx.appl",
178 "trying to install LibreOffice Base, caught " << e.Message);
180 return;
183 try // fdo#48775
185 SfxStringItem aURL(SID_FILE_NAME, OUString(".component:Bibliography/View1"));
186 SfxStringItem aRef(SID_REFERER, OUString("private:user"));
187 SfxStringItem aTarget(SID_TARGETNAME, OUString("_blank"));
188 SfxViewFrame::Current()->GetDispatcher()->Execute( SID_OPENDOC, SfxCallMode::ASYNCHRON, &aURL, &aRef, &aTarget, 0L);
190 catch (const Exception & e)
192 SAL_INFO( "sfx.appl",
193 "trying to load bibliography database, caught " << e.Message);
197 /// Find the correct location of the document (LICENSE.fodt, etc.), and return
198 /// it in rURL if found.
199 static bool checkURL( const char *pName, const char *pExt, OUString &rURL )
201 using namespace osl;
202 DirectoryItem aDirItem;
204 #ifdef MACOSX
205 rURL = "$BRAND_BASE_DIR/Resources/" + OUString::createFromAscii( pName ) +
206 OUString::createFromAscii( pExt );
207 #else
208 rURL = "$BRAND_BASE_DIR/" + OUString::createFromAscii( pName ) +
209 OUString::createFromAscii( pExt );
210 #endif
211 rtl::Bootstrap::expandMacros( rURL );
213 if (!rURL.isEmpty())
214 return DirectoryItem::get( rURL, aDirItem ) == DirectoryItem::E_None;
215 else
216 return false;
219 /// Displays CREDITS or LICENSE in any of the available version
220 static void showDocument( const char* pBaseName )
222 try {
223 Reference < XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
224 Sequence < com::sun::star::beans::PropertyValue > args(2);
225 args[0].Name = "ViewOnly";
226 args[0].Value <<= sal_True;
227 args[1].Name = "ReadOnly";
228 args[1].Value <<= sal_True;
230 OUString aURL;
231 if ( checkURL ( pBaseName, ".fodt", aURL ) ||
232 checkURL ( pBaseName, ".html", aURL ) ||
233 checkURL ( pBaseName, "", aURL ) ) {
234 xDesktop->loadComponentFromURL( aURL, OUString("_blank"), 0, args );
236 } catch (const ::com::sun::star::uno::Exception &) {
240 namespace
242 class LicenseDialog : public ModalDialog
244 private:
245 DECL_LINK(ShowHdl, void *);
246 public:
247 LicenseDialog(vcl::Window *pParent=NULL);
250 LicenseDialog::LicenseDialog(vcl::Window *pParent)
251 : ModalDialog(pParent, "LicenseDialog", "sfx/ui/licensedialog.ui")
253 get<PushButton>("show")->SetClickHdl(LINK(this, LicenseDialog, ShowHdl));
256 IMPL_LINK_NOARG(LicenseDialog, ShowHdl)
258 EndDialog(RET_OK);
259 showDocument("LICENSE");
260 return 0;
264 void SfxApplication::MiscExec_Impl( SfxRequest& rReq )
266 bool bDone = false;
267 switch ( rReq.GetSlot() )
269 case SID_SETOPTIONS:
271 if( rReq.GetArgs() )
272 SetOptions_Impl( *rReq.GetArgs() );
273 break;
276 case SID_QUITAPP:
277 case SID_EXITANDRETURN:
278 case SID_LOGOUT:
280 // protect against reentrant calls
281 if ( pAppData_Impl->bInQuit )
282 return;
284 if ( rReq.GetSlot() == SID_LOGOUT )
286 for ( SfxObjectShell *pObjSh = SfxObjectShell::GetFirst();
287 pObjSh; pObjSh = SfxObjectShell::GetNext( *pObjSh ) )
289 if ( !pObjSh->IsModified() )
290 continue;
292 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pObjSh );
293 if ( !pFrame || !pFrame->GetWindow().IsReallyVisible() )
294 continue;
296 if (pObjSh->PrepareClose(true))
297 pObjSh->SetModified( false );
298 else
299 return;
302 SfxStringItem aNameItem( SID_FILE_NAME, OUString("vnd.sun.star.cmd:logout") );
303 SfxStringItem aReferer( SID_REFERER, "private/user" );
304 pAppData_Impl->pAppDispat->Execute( SID_OPENDOC, SfxCallMode::SLOT, &aNameItem, &aReferer, 0L );
305 return;
308 // aus verschachtelten Requests nach 100ms nochmal probieren
309 if( Application::GetDispatchLevel() > 1 )
311 /* Dont save the request for closing the application and try it later
312 again. This is an UI bound functionality ... and the user will try it again
313 if the dialog is closed. But we should not close the application automatically
314 if this dialog is closed by the user ...
315 So we ignore this request now and wait for a new user decision.
317 OSL_TRACE( "QueryExit => sal_False (DispatchLevel == %u)", Application::GetDispatchLevel() );
318 return;
321 // block reentrant calls
322 pAppData_Impl->bInQuit = true;
323 Reference < XDesktop2 > xDesktop = Desktop::create ( ::comphelper::getProcessComponentContext() );
325 rReq.ForgetAllArgs();
327 // if terminate() failed, pAppData_Impl->bInQuit will now be sal_False, allowing further calls of SID_QUITAPP
328 bool bTerminated = xDesktop->terminate();
329 if (!bTerminated)
330 // if terminate() was successful, SfxApplication is now dead!
331 pAppData_Impl->bInQuit = false;
333 // Set return value, terminate if possible
334 rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), bTerminated ) );
335 return;
338 case SID_CONFIG:
339 case SID_TOOLBOXOPTIONS:
340 case SID_CONFIGSTATUSBAR:
341 case SID_CONFIGMENU:
342 case SID_CONFIGACCEL:
343 case SID_CONFIGEVENT:
345 SfxAbstractDialogFactory* pFact =
346 SfxAbstractDialogFactory::Create();
348 if ( pFact )
350 SFX_REQUEST_ARG(rReq, pStringItem,
351 SfxStringItem, SID_CONFIG, false);
353 SfxItemSet aSet(
354 GetPool(), SID_CONFIG, SID_CONFIG );
356 if ( pStringItem )
358 aSet.Put( SfxStringItem(
359 SID_CONFIG, pStringItem->GetValue() ) );
362 Reference< XFrame > xFrame;
363 const SfxItemSet* pIntSet = rReq.GetInternalArgs_Impl();
364 SFX_ITEMSET_ARG( pIntSet, pFrameItem, SfxUnoFrameItem, SID_FILLFRAME, false );
365 if ( pFrameItem )
366 xFrame = pFrameItem->GetFrame();
368 boost::scoped_ptr<SfxAbstractTabDialog> pDlg(pFact->CreateTabDialog(
369 RID_SVXDLG_CUSTOMIZE,
370 NULL, &aSet, xFrame ));
372 if ( pDlg )
374 const short nRet = pDlg->Execute();
376 if ( nRet )
377 bDone = true;
380 break;
383 case SID_CLOSEDOCS:
384 case SID_CLOSEWINS:
387 Reference < XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
388 Reference< XIndexAccess > xTasks( xDesktop->getFrames(), UNO_QUERY );
389 if ( !xTasks.is() )
390 break;
392 sal_Int32 n=0;
395 if ( xTasks->getCount() <= n )
396 break;
398 Any aAny = xTasks->getByIndex(n);
399 Reference < XCloseable > xTask;
400 aAny >>= xTask;
403 xTask->close(sal_True);
404 n++;
406 catch( CloseVetoException& )
410 while( true );
412 bool bOk = ( n == 0);
413 rReq.SetReturnValue( SfxBoolItem( 0, bOk ) );
414 bDone = true;
415 break;
418 case SID_SAVEDOCS:
420 bool bOK = true;
421 for ( SfxObjectShell *pObjSh = SfxObjectShell::GetFirst();
422 pObjSh;
423 pObjSh = SfxObjectShell::GetNext( *pObjSh ) )
425 SfxRequest aReq( SID_SAVEDOC, SfxCallMode::SLOT, pObjSh->GetPool() );
426 if ( pObjSh->IsModified() )
428 pObjSh->ExecuteSlot( aReq );
429 const SfxBoolItem *pItem = PTR_CAST( SfxBoolItem, aReq.GetReturnValue() );
430 if ( !pItem || !pItem->GetValue() )
431 bOK = false;
435 rReq.SetReturnValue( SfxBoolItem( 0, bOK ) );
436 rReq.Done();
437 break;
440 case SID_SEND_FEEDBACK:
442 OUString module = SfxHelp::GetCurrentModuleIdentifier();
443 OUString sURL("http://hub.libreoffice.org/send-feedback/?LOversion=" + utl::ConfigManager::getAboutBoxProductVersion() +
444 "&LOlocale=" + utl::ConfigManager::getLocale() + "&LOmodule=" + module.copy(module.lastIndexOf('.') + 1 ) );
447 uno::Reference< com::sun::star::system::XSystemShellExecute > xSystemShellExecute(
448 com::sun::star::system::SystemShellExecute::create(::comphelper::getProcessComponentContext()) );
449 xSystemShellExecute->execute( sURL, OUString(), com::sun::star::system::SystemShellExecuteFlags::URIS_ONLY );
451 catch ( uno::Exception& )
454 break;
457 case SID_SHOW_LICENSE:
459 ScopedVclPtrInstance< LicenseDialog > aDialog;
460 aDialog->Execute();
461 break;
464 case SID_SHOW_CREDITS:
466 showDocument( "CREDITS" );
467 break;
470 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
471 case SID_HELPINDEX:
473 Help* pHelp = Application::GetHelp();
474 if ( pHelp )
476 pHelp->Start( OUString(".uno:HelpIndex"), NULL ); // show start page
477 bDone = true;
479 break;
482 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
483 case SID_HELPTIPS:
485 // Evaluate Parameter
486 SFX_REQUEST_ARG(rReq, pOnItem, SfxBoolItem, SID_HELPTIPS, false);
487 bool bOn = pOnItem
488 ? pOnItem->GetValue()
489 : !Help::IsQuickHelpEnabled();
491 if ( bOn )
492 Help::EnableQuickHelp();
493 else
494 Help::DisableQuickHelp();
495 SvtHelpOptions().SetHelpTips( bOn );
496 Invalidate(SID_HELPTIPS);
497 bDone = true;
499 // Record if possible
500 if ( !rReq.IsAPI() )
501 rReq.AppendItem( SfxBoolItem( SID_HELPTIPS, bOn) );
502 break;
504 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
505 case SID_EXTENDEDHELP:
507 Help::StartExtHelp();
508 break;
510 case SID_HELPBALLOONS:
512 // Evaluate Parameter
513 SFX_REQUEST_ARG(rReq, pOnItem, SfxBoolItem, SID_HELPBALLOONS, false);
514 bool bOn = pOnItem
515 ? pOnItem->GetValue()
516 : !Help::IsBalloonHelpEnabled();
518 if ( bOn )
519 Help::EnableBalloonHelp();
520 else
521 Help::DisableBalloonHelp();
522 SvtHelpOptions().SetExtendedHelp( bOn );
523 Invalidate(SID_HELPBALLOONS);
524 bDone = true;
526 // Record if possible
527 if ( !rReq.IsAPI() )
528 rReq.AppendItem( SfxBoolItem( SID_HELPBALLOONS, bOn) );
529 break;
532 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
533 case SID_ABOUT:
535 SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
536 if ( pFact )
538 boost::scoped_ptr<VclAbstractDialog> pDlg(pFact->CreateVclDialog( 0, RID_DEFAULTABOUT ));
539 pDlg->Execute();
540 bDone = true;
542 break;
545 case SID_TEMPLATE_MANAGER:
547 ScopedVclPtrInstance< SfxTemplateManagerDlg > dlg;
548 dlg->Execute();
549 bDone = true;
550 break;
553 case SID_TEMPLATE_ADDRESSBOKSOURCE:
555 ScopedVclPtrInstance< svt::AddressBookSourceDialog > aDialog(GetTopWindow(), ::comphelper::getProcessComponentContext());
556 aDialog->Execute();
557 bDone = true;
558 break;
561 #if HAVE_FEATURE_SCRIPTING
562 case SID_BASICSTOP:
563 StarBASIC::Stop();
564 break;
566 case SID_BASICBREAK :
567 BasicDLL::BasicBreak();
568 break;
569 #endif
571 case SID_SHOW_IME_STATUS_WINDOW:
572 if (sfx2::appl::ImeStatusWindow::canToggle())
574 SfxBoolItem const * pItem = static_cast< SfxBoolItem const * >(
575 rReq.GetArg(SID_SHOW_IME_STATUS_WINDOW, false,
576 TYPE(SfxBoolItem)));
577 bool bShow = pItem == 0
578 ? !pAppData_Impl->m_xImeStatusWindow->isShowing()
579 : pItem->GetValue();
580 pAppData_Impl->m_xImeStatusWindow->show(bShow);
581 if (pItem == 0)
582 rReq.AppendItem(SfxBoolItem(SID_SHOW_IME_STATUS_WINDOW,
583 bShow));
585 bDone = true;
586 break;
588 case SID_ZOOM_50_PERCENT:
589 case SID_ZOOM_75_PERCENT:
590 case SID_ZOOM_100_PERCENT:
591 case SID_ZOOM_150_PERCENT:
592 case SID_ZOOM_200_PERCENT:
593 case SID_ZOOM_OPTIMAL:
594 case SID_ZOOM_ENTIRE_PAGE:
595 case SID_ZOOM_PAGE_WIDTH:
597 SfxObjectShell* pCurrentShell = SfxObjectShell::Current();
598 if (!pCurrentShell)
599 return;
601 // make sure aZoom is initialized with a proper value if SetType
602 // doesn't work
603 SvxZoomItem aZoom( SvxZoomType::PERCENT, 100 );
605 switch (rReq.GetSlot())
607 case SID_ZOOM_50_PERCENT:
608 aZoom.SetValue(50);
609 break;
610 case SID_ZOOM_75_PERCENT:
611 aZoom.SetValue(75);
612 break;
613 case SID_ZOOM_100_PERCENT:
614 aZoom.SetValue(100);
615 break;
616 case SID_ZOOM_150_PERCENT:
617 aZoom.SetValue(150);
618 break;
619 case SID_ZOOM_200_PERCENT:
620 aZoom.SetValue(200);
621 break;
622 case SID_ZOOM_OPTIMAL:
623 aZoom.SetType( SvxZoomType::OPTIMAL );
624 break;
625 case SID_ZOOM_ENTIRE_PAGE:
626 aZoom.SetType( SvxZoomType::WHOLEPAGE );
627 break;
628 case SID_ZOOM_PAGE_WIDTH:
629 aZoom.SetType( SvxZoomType::PAGEWIDTH );
630 break;
633 pCurrentShell->GetDispatcher()->Execute(SID_ATTR_ZOOM, SfxCallMode::ASYNCHRON, &aZoom, 0L);
635 break;
637 case SID_AVAILABLE_TOOLBARS:
639 SfxStringItem const * pToolbarName = static_cast< SfxStringItem const *>(
640 rReq.GetArg(SID_AVAILABLE_TOOLBARS, false, TYPE(SfxStringItem)));
642 if ( pToolbarName )
644 Reference < XDesktop2 > xDesktop = Desktop::create ( ::comphelper::getProcessComponentContext() );
645 Reference< XFrame > xFrame = xDesktop->getActiveFrame();
647 Reference< com::sun::star::beans::XPropertySet > xPropSet( xFrame, UNO_QUERY );
648 Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager;
649 if ( xPropSet.is() )
653 Any aValue = xPropSet->getPropertyValue("LayoutManager");
654 aValue >>= xLayoutManager;
656 catch ( const ::com::sun::star::uno::RuntimeException& )
658 throw;
660 catch ( ::com::sun::star::uno::Exception& )
665 if ( xLayoutManager.is() )
667 OUString aToolbarResName( "private:resource/toolbar/" );
668 OUStringBuffer aBuf( aToolbarResName );
669 aBuf.append( pToolbarName->GetValue() );
671 // Evaluate Parameter
672 OUString aToolbarName( aBuf.makeStringAndClear() );
673 bool bShow( !xLayoutManager->isElementVisible( aToolbarName ));
675 if ( bShow )
677 xLayoutManager->createElement( aToolbarName );
678 xLayoutManager->showElement( aToolbarName );
680 else
681 xLayoutManager->hideElement( aToolbarName );
685 bDone = true;
686 break;
689 default:
690 break;
693 if ( bDone )
694 rReq.Done();
699 void SfxApplication::MiscState_Impl(SfxItemSet &rSet)
701 const sal_uInt16 *pRanges = rSet.GetRanges();
702 DBG_ASSERT(pRanges && *pRanges, "Set without range");
703 while ( *pRanges )
705 for(sal_uInt16 nWhich = *pRanges++; nWhich <= *pRanges; ++nWhich)
707 switch(nWhich)
709 case SID_TEMPLATE_ADDRESSBOKSOURCE:
710 if ( !SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::EModule::DATABASE) )
711 rSet.Put(SfxVisibilityItem(nWhich, false));
712 break;
713 case SID_EXITANDRETURN:
714 case SID_QUITAPP:
716 if ( pAppData_Impl->nDocModalMode )
717 rSet.DisableItem(nWhich);
718 else
719 rSet.Put(SfxStringItem(nWhich, SfxResId(STR_QUITAPP).toString()));
720 break;
723 case SID_CONFIG:
724 case SID_TOOLBOXOPTIONS:
725 case SID_CONFIGSTATUSBAR:
726 case SID_CONFIGMENU:
727 case SID_CONFIGACCEL:
728 case SID_CONFIGEVENT:
730 if( SvtMiscOptions().DisableUICustomization() )
731 rSet.DisableItem(nWhich);
732 break;
735 #if HAVE_FEATURE_SCRIPTING
736 case SID_BASICSTOP:
737 if ( !StarBASIC::IsRunning() )
738 rSet.DisableItem(nWhich);
739 break;
740 #endif
742 case SID_HELPTIPS:
744 rSet.Put( SfxBoolItem( SID_HELPTIPS, Help::IsQuickHelpEnabled() ) );
746 break;
747 case SID_HELPBALLOONS:
749 rSet.Put( SfxBoolItem( SID_HELPBALLOONS, Help::IsBalloonHelpEnabled() ) );
751 break;
753 case SID_EXTENDEDHELP:
756 break;
758 case SID_CLOSEDOCS:
759 case SID_CLOSEWINS:
761 Reference < XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
762 Reference< XIndexAccess > xTasks( xDesktop->getFrames(), UNO_QUERY );
763 if ( !xTasks.is() || !xTasks->getCount() )
764 rSet.DisableItem(nWhich);
765 break;
768 case SID_SAVEDOCS:
770 bool bModified = false;
771 for ( SfxObjectShell *pObjSh = SfxObjectShell::GetFirst();
772 pObjSh;
773 pObjSh = SfxObjectShell::GetNext( *pObjSh ) )
775 if ( pObjSh->IsModified() )
777 bModified = true;
778 break;
782 if ( !bModified )
783 rSet.DisableItem( nWhich );
784 break;
787 case SID_SHOW_IME_STATUS_WINDOW:
788 if (sfx2::appl::ImeStatusWindow::canToggle())
789 rSet.Put(SfxBoolItem(
790 SID_SHOW_IME_STATUS_WINDOW,
791 pAppData_Impl->m_xImeStatusWindow->
792 isShowing()));
793 else
794 rSet.DisableItem(SID_SHOW_IME_STATUS_WINDOW);
795 break;
797 case SID_TEMPLATE_MANAGER:
799 SvtMiscOptions aMiscOptions;
800 if ( !aMiscOptions.IsExperimentalMode() )
802 rSet.DisableItem( nWhich );
803 rSet.Put( SfxVisibilityItem( nWhich, false ) );
806 break;
808 case SID_ZOOM_50_PERCENT:
809 case SID_ZOOM_75_PERCENT:
810 case SID_ZOOM_100_PERCENT:
811 case SID_ZOOM_150_PERCENT:
812 case SID_ZOOM_200_PERCENT:
813 case SID_ZOOM_OPTIMAL:
814 case SID_ZOOM_ENTIRE_PAGE:
815 case SID_ZOOM_PAGE_WIDTH:
817 SfxObjectShell* pCurrentShell = SfxObjectShell::Current();
819 const SfxPoolItem *pItem;
820 SfxItemState aState = pCurrentShell ?
821 pCurrentShell->GetDispatcher()->QueryState(SID_ATTR_ZOOM, pItem) : SfxItemState::DISABLED;
822 if ( aState == SfxItemState::DISABLED )
823 rSet.DisableItem( nWhich );
825 break;
827 default:
828 break;
832 ++pRanges;
836 #if HAVE_FEATURE_SCRIPTING
838 #ifndef DISABLE_DYNLOADING
840 typedef rtl_uString* (SAL_CALL *basicide_choose_macro)(XModel*, sal_Bool, rtl_uString*);
841 typedef void (SAL_CALL *basicide_macro_organizer)( sal_Int16 );
843 extern "C" { static void SAL_CALL thisModule() {} }
845 #else
847 extern "C" rtl_uString* basicide_choose_macro(XModel*, sal_Bool, rtl_uString*);
848 extern "C" void basicide_macro_organizer( sal_Int16 );
850 #endif
852 OUString ChooseMacro( const Reference< XModel >& rxLimitToDocument, bool bChooseOnly, const OUString& rMacroDesc = OUString() )
854 #ifndef DISABLE_DYNLOADING
855 osl::Module aMod;
857 // load basctl module
858 aMod.loadRelative(&thisModule, SVLIBRARY("basctl"), 0);
860 // get symbol
861 basicide_choose_macro pSymbol = reinterpret_cast<basicide_choose_macro>(aMod.getFunctionSymbol("basicide_choose_macro"));
862 SAL_WARN_IF(!pSymbol, "sfx.doc", "SfxApplication::MacroOrganizer, no symbol!");
863 if (!pSymbol)
864 return OUString();
865 aMod.release();
866 #else
867 #define pSymbol basicide_choose_macro
868 #endif
870 // call basicide_choose_macro in basctl
871 rtl_uString* pScriptURL = pSymbol( rxLimitToDocument.get(), bChooseOnly, rMacroDesc.pData );
872 OUString aScriptURL( pScriptURL );
873 rtl_uString_release( pScriptURL );
874 return aScriptURL;
876 #ifdef DISABLE_DYNLOADING
877 #undef pSymbol
878 #endif
881 #endif
883 namespace
885 #if HAVE_FEATURE_SCRIPTING
886 vcl::Window* lcl_getDialogParent( const Reference< XFrame >& _rxFrame, vcl::Window* _pFallback )
888 if ( !_rxFrame.is() )
889 return _pFallback;
893 Reference< awt::XWindow > xContainerWindow( _rxFrame->getContainerWindow(), UNO_SET_THROW );
894 vcl::Window* pWindow = VCLUnoHelper::GetWindow( xContainerWindow );
895 OSL_ENSURE( pWindow, "lcl_getDialogParent: cool, somebody implemented a VCL-less toolkit!" );
897 if ( pWindow )
898 return pWindow->GetSystemWindow();
900 catch( const Exception& )
902 DBG_UNHANDLED_EXCEPTION();
904 return _pFallback;
907 static OUString lcl_getBasicIDEServiceName()
909 return OUString( "com.sun.star.script.BasicIDE");
912 SfxViewFrame* lcl_getBasicIDEViewFrame( SfxObjectShell* i_pBasicIDE )
914 SfxViewFrame* pView = SfxViewFrame::GetFirst( i_pBasicIDE );
915 while ( pView )
917 if ( pView->GetObjectShell()->GetFactory().GetDocumentServiceName() == lcl_getBasicIDEServiceName() )
918 break;
919 pView = SfxViewFrame::GetNext( *pView, i_pBasicIDE );
921 return pView;
923 Reference< XFrame > lcl_findStartModuleFrame( const Reference<XComponentContext> & rxContext )
927 Reference < XDesktop2 > xDesktop = Desktop::create( rxContext );
928 Reference < XIndexAccess > xContainer( xDesktop->getFrames(), UNO_QUERY_THROW );
930 Reference< XModuleManager2 > xCheck = ModuleManager::create(rxContext);
932 sal_Int32 nCount = xContainer->getCount();
933 for ( sal_Int32 i=0; i<nCount; ++i )
937 Reference < XFrame > xFrame( xContainer->getByIndex(i), UNO_QUERY_THROW );
938 OUString sModule = xCheck->identify( xFrame );
939 if ( sModule == "com.sun.star.frame.StartModule" )
940 return xFrame;
942 catch( const UnknownModuleException& )
944 // silence
946 catch(const Exception&)
948 // re-throw, caught below
949 throw;
953 catch( const Exception& )
955 DBG_UNHANDLED_EXCEPTION();
957 return NULL;
959 #endif // HAVE_FEATURE_SCRIPTING
962 void SfxApplication::OfaExec_Impl( SfxRequest& rReq )
964 switch ( rReq.GetSlot() )
966 case SID_OPTIONS_TREEDIALOG:
968 OUString sPageURL;
969 SFX_REQUEST_ARG( rReq, pURLItem, SfxStringItem, SID_OPTIONS_PAGEURL, false );
970 if ( pURLItem )
971 sPageURL = pURLItem->GetValue();
972 const SfxItemSet* pArgs = rReq.GetInternalArgs_Impl();
973 const SfxPoolItem* pItem = NULL;
974 Reference < XFrame > xFrame;
975 if ( pArgs && pArgs->GetItemState( SID_FILLFRAME, false, &pItem ) == SfxItemState::SET )
977 OSL_ENSURE( pItem->ISA( SfxUnoFrameItem ), "SfxApplication::OfaExec_Impl: XFrames are to be transported via SfxUnoFrameItem by now!" );
978 xFrame = static_cast< const SfxUnoFrameItem*>( pItem )->GetFrame();
980 SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
981 if ( pFact )
983 VclAbstractDialog* pDlg =
984 pFact->CreateFrameDialog( NULL, xFrame, rReq.GetSlot(), sPageURL );
985 short nRet = pDlg->Execute();
986 delete pDlg;
987 SfxViewFrame* pView = SfxViewFrame::GetFirst();
988 while ( pView )
990 if (nRet == RET_OK)
992 SfxObjectShell* pObjSh = pView->GetObjectShell();
993 if (pObjSh)
994 pObjSh->SetConfigOptionsChecked(false);
996 pView->GetBindings().InvalidateAll(false);
997 pView = SfxViewFrame::GetNext( *pView );
1000 break;
1003 case SID_MORE_DICTIONARIES:
1007 uno::Reference< uno::XComponentContext > xContext =
1008 ::comphelper::getProcessComponentContext();
1009 uno::Reference< css::system::XSystemShellExecute > xSystemShell(
1010 css::system::SystemShellExecute::create(xContext) );
1012 // read repository URL from configuration
1013 OUString sTemplRepoURL(officecfg::Office::Common::Dictionaries::RepositoryURL::get());
1015 if ( xSystemShell.is() && !sTemplRepoURL.isEmpty() )
1017 OUStringBuffer aURLBuf( sTemplRepoURL );
1018 aURLBuf.append("?lang=");
1020 // read locale from configuration
1021 OUString sLocale(officecfg::Setup::L10N::ooLocale::get());
1022 if (sLocale.isEmpty())
1023 sLocale = "en-US";
1025 aURLBuf.append( sLocale );
1026 xSystemShell->execute(
1027 aURLBuf.makeStringAndClear(),
1028 OUString(),
1029 css::system::SystemShellExecuteFlags::URIS_ONLY );
1032 catch( const ::com::sun::star::uno::Exception& )
1034 SAL_WARN( "sfx.appl", "SfxApplication::OfaExec_Impl(SID_MORE_DICTIONARIES): caught an exception!" );
1036 break;
1038 #if HAVE_FEATURE_SCRIPTING
1039 case SID_BASICIDE_APPEAR:
1041 SfxViewFrame* pView = lcl_getBasicIDEViewFrame( NULL );
1042 if ( !pView )
1044 SfxObjectShell* pBasicIDE = SfxObjectShell::CreateObject( lcl_getBasicIDEServiceName() );
1045 pBasicIDE->DoInitNew( 0 );
1046 pBasicIDE->SetModified( false );
1049 // load the Basic IDE via direct access to the SFX frame loader. A generic loadComponentFromURL
1050 // (which could be done via SfxViewFrame::LoadDocumentIntoFrame) is not feasible here, since the Basic IDE
1051 // does not really play nice with the framework's concept. For instance, it is a "singleton document",
1052 // which conflicts, at the latest, with the framework's concept of loading into _blank frames.
1053 // So, since we know that our frame loader can handle it, we skip the generic framework loader
1054 // mechanism, and the type detection (which doesn't know about the Basic IDE).
1055 Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
1056 Reference< XSynchronousFrameLoader > xLoader(
1057 xContext->getServiceManager()->createInstanceWithContext("com.sun.star.comp.office.FrameLoader", xContext),
1058 UNO_QUERY_THROW );
1059 ::comphelper::NamedValueCollection aLoadArgs;
1060 aLoadArgs.put( "Model", pBasicIDE->GetModel() );
1061 aLoadArgs.put( "URL", OUString( "private:factory/sbasic" ) );
1063 Reference< XFrame > xTargetFrame( lcl_findStartModuleFrame( xContext ) );
1064 if ( !xTargetFrame.is() )
1065 xTargetFrame = SfxFrame::CreateBlankFrame();
1066 ENSURE_OR_THROW( xTargetFrame.is(), "could not obtain a frameto load the Basic IDE into!" );
1068 xLoader->load( aLoadArgs.getPropertyValues(), xTargetFrame );
1070 catch( const Exception& )
1072 DBG_UNHANDLED_EXCEPTION();
1075 pView = lcl_getBasicIDEViewFrame( pBasicIDE );
1076 if ( pView )
1077 pView->SetName( OUString( "BASIC:1" ) );
1080 if ( pView )
1081 pView->GetFrame().Appear();
1083 const SfxItemSet* pArgs = rReq.GetArgs();
1084 if ( pArgs && pView )
1086 SfxViewShell* pViewShell = pView->GetViewShell();
1087 SfxObjectShell* pObjShell = pView->GetObjectShell();
1088 if ( pViewShell && pObjShell )
1090 SfxRequest aReq( SID_BASICIDE_SHOWWINDOW, SfxCallMode::SYNCHRON, pObjShell->GetPool() );
1091 aReq.SetArgs( *pArgs );
1092 pViewShell->ExecuteSlot( aReq );
1096 rReq.Done();
1098 break;
1100 case SID_BASICCHOOSER:
1102 const SfxItemSet* pArgs = rReq.GetArgs();
1103 const SfxPoolItem* pItem;
1104 bool bChooseOnly = false;
1105 Reference< XModel > xLimitToModel;
1106 if(pArgs && SfxItemState::SET == pArgs->GetItemState(SID_RECORDMACRO, false, &pItem) )
1108 bool bRecord = static_cast<const SfxBoolItem*>(pItem)->GetValue();
1109 if ( bRecord )
1111 // !Hack
1112 bChooseOnly = false;
1113 SfxObjectShell* pCurrentShell = SfxObjectShell::Current();
1114 OSL_ENSURE( pCurrentShell, "macro recording outside an SFX document?" );
1115 if ( pCurrentShell )
1116 xLimitToModel = pCurrentShell->GetModel();
1120 rReq.SetReturnValue( SfxStringItem( rReq.GetSlot(), ChooseMacro( xLimitToModel, bChooseOnly ) ) );
1121 rReq.Done();
1123 break;
1125 case SID_MACROORGANIZER:
1127 OSL_TRACE("handling SID_MACROORGANIZER");
1128 const SfxItemSet* pArgs = rReq.GetArgs();
1129 const SfxPoolItem* pItem;
1130 sal_Int16 nTabId = 0;
1131 if(pArgs && SfxItemState::SET == pArgs->GetItemState(SID_MACROORGANIZER, false, &pItem) )
1133 nTabId = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
1136 SfxApplication::MacroOrganizer( nTabId );
1137 rReq.Done();
1139 break;
1141 case SID_RUNMACRO:
1143 SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
1144 OSL_TRACE("SfxApplication::OfaExec_Impl: case ScriptOrg");
1146 Reference< XFrame > xFrame;
1147 const SfxItemSet* pIntSet = rReq.GetInternalArgs_Impl();
1148 SFX_ITEMSET_ARG( pIntSet, pFrameItem, SfxUnoFrameItem, SID_FILLFRAME, false );
1149 if ( pFrameItem )
1150 xFrame = pFrameItem->GetFrame();
1152 if ( !xFrame.is() )
1154 const SfxViewFrame* pViewFrame = SfxViewFrame::Current();
1155 if ( pViewFrame )
1156 xFrame = pViewFrame->GetFrame().GetFrameInterface();
1159 do // artificial loop for flow control
1161 boost::scoped_ptr<AbstractScriptSelectorDialog> pDlg(pFact->CreateScriptSelectorDialog(
1162 lcl_getDialogParent( xFrame, GetTopWindow() ), false, xFrame ));
1163 OSL_ENSURE( pDlg, "SfxApplication::OfaExec_Impl( SID_RUNMACRO ): no dialog!" );
1164 if ( !pDlg )
1165 break;
1166 pDlg->SetRunLabel();
1168 short nDialogResult = pDlg->Execute();
1169 if ( !nDialogResult )
1170 break;
1172 Sequence< Any > args;
1173 Sequence< sal_Int16 > outIndex;
1174 Sequence< Any > outArgs;
1175 Any ret;
1177 Reference< XInterface > xScriptContext;
1179 Reference< XController > xController;
1180 if ( xFrame.is() )
1181 xController = xFrame->getController();
1182 if ( xController.is() )
1183 xScriptContext = xController->getModel();
1184 if ( !xScriptContext.is() )
1185 xScriptContext = xController;
1187 SfxObjectShell::CallXScript( xScriptContext, pDlg->GetScriptURL(), args, ret, outIndex, outArgs );
1189 while ( false );
1190 rReq.Done();
1192 break;
1194 case SID_SCRIPTORGANIZER:
1196 SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
1197 OSL_TRACE("SfxApplication::OfaExec_Impl: case ScriptOrg");
1198 const SfxItemSet* pArgs = rReq.GetArgs();
1199 const SfxPoolItem* pItem;
1200 OUString aLanguage;
1201 if(pArgs && SfxItemState::SET == pArgs->GetItemState(SID_SCRIPTORGANIZER, false, &pItem) )
1203 aLanguage = static_cast<const SfxScriptOrganizerItem*>(pItem)->getLanguage();
1206 OUString aLang( aLanguage );
1207 OSL_TRACE("SfxApplication::OfaExec_Impl: about to create dialog for: %s", OUStringToOString( aLang , RTL_TEXTENCODING_ASCII_US ).pData->buffer);
1208 // not sure about the vcl::Window*
1209 VclAbstractDialog* pDlg = pFact->CreateSvxScriptOrgDialog( GetTopWindow(), aLanguage );
1210 if( pDlg )
1212 pDlg->Execute();
1213 delete pDlg;
1215 else
1217 OSL_TRACE("no dialog!!!");
1219 rReq.Done();
1221 break;
1222 #endif // HAVE_FEATURE_SCRIPTING
1224 case SID_OFFICE_CHECK_PLZ:
1226 bool bRet = false;
1227 SFX_REQUEST_ARG(rReq, pStringItem, SfxStringItem, rReq.GetSlot(), false);
1229 if ( pStringItem )
1231 bRet = true /*!!!SfxIniManager::CheckPLZ( aPLZ )*/;
1233 #if HAVE_FEATURE_SCRIPTING
1234 else
1235 SbxBase::SetError( SbxERR_WRONG_ARGS );
1236 #endif
1237 rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), bRet ) );
1239 break;
1241 case SID_AUTO_CORRECT_DLG:
1243 SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
1244 if ( pFact )
1246 SfxItemSet aSet(GetPool(), SID_AUTO_CORRECT_DLG, SID_AUTO_CORRECT_DLG);
1247 const SfxPoolItem* pItem=NULL;
1248 const SfxItemSet* pSet = rReq.GetArgs();
1249 SfxItemPool* pSetPool = pSet ? pSet->GetPool() : NULL;
1250 if ( pSet && pSet->GetItemState( pSetPool->GetWhich( SID_AUTO_CORRECT_DLG ), false, &pItem ) == SfxItemState::SET )
1251 aSet.Put( *pItem );
1253 boost::scoped_ptr<SfxAbstractTabDialog> pDlg(pFact->CreateTabDialog( RID_OFA_AUTOCORR_DLG, NULL, &aSet, NULL ));
1254 pDlg->Execute();
1257 break;
1260 case SID_SD_AUTOPILOT :
1261 case SID_NEWSD :
1263 SvtModuleOptions aModuleOpt;
1264 if ( !aModuleOpt.IsImpress() )
1266 ScopedVclPtrInstance<MessageDialog>::Create( nullptr, SFX2_RESSTR( STR_MODULENOTINSTALLED ))->Execute();
1267 return;
1270 Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
1271 Reference< frame::XDispatchProvider > xProv = drawing::ModuleDispatcher::create( xContext );
1273 OUString aCmd = OUString::createFromAscii( GetInterface()->GetSlot( rReq.GetSlot() )->GetUnoName() );
1274 Reference< frame::XDispatchHelper > xHelper( frame::DispatchHelper::create(xContext) );
1275 Sequence < beans::PropertyValue > aSeq;
1276 if ( rReq.GetArgs() )
1277 TransformItems( rReq.GetSlot(), *rReq.GetArgs(), aSeq );
1278 Any aResult = xHelper->executeDispatch( xProv, aCmd, OUString(), 0, aSeq );
1279 frame::DispatchResultEvent aEvent;
1280 bool bSuccess = (aResult >>= aEvent) &&
1281 (aEvent.State == frame::DispatchResultState::SUCCESS);
1282 rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), bSuccess ) );
1284 break;
1286 case FN_LABEL :
1287 case FN_BUSINESS_CARD :
1288 case FN_XFORMS_INIT :
1290 Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
1291 Reference< frame::XDispatchProvider > xProv = text::ModuleDispatcher::create( xContext );
1293 OUString aCmd = OUString::createFromAscii( GetInterface()->GetSlot( rReq.GetSlot() )->GetUnoName() );
1294 Reference< frame::XDispatchHelper > xHelper( frame::DispatchHelper::create(xContext) );
1295 Sequence < beans::PropertyValue > aSeq;
1296 if ( rReq.GetArgs() )
1297 TransformItems( rReq.GetSlot(), *rReq.GetArgs(), aSeq );
1298 Any aResult = xHelper->executeDispatch( xProv, aCmd, OUString(), 0, aSeq );
1299 frame::DispatchResultEvent aEvent;
1300 bool bSuccess = (aResult >>= aEvent) &&
1301 (aEvent.State == frame::DispatchResultState::SUCCESS);
1302 rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), bSuccess ) );
1304 break;
1306 case SID_ADDRESS_DATA_SOURCE:
1310 Reference< uno::XComponentContext > xORB = ::comphelper::getProcessComponentContext();
1311 Reference< ui::dialogs::XExecutableDialog > xDialog;
1312 xDialog = ui::dialogs::AddressBookSourcePilot::createWithParent(xORB, 0);
1313 xDialog->execute();
1315 catch(const ::com::sun::star::uno::Exception&)
1317 DBG_UNHANDLED_EXCEPTION();
1320 break;
1322 case SID_COMP_BIBLIOGRAPHY:
1323 lcl_tryLoadBibliography();
1324 break;
1328 void SfxApplication::OfaState_Impl(SfxItemSet &rSet)
1330 SvtModuleOptions aModuleOpt;
1332 if( !aModuleOpt.IsWriter())
1334 rSet.DisableItem( FN_LABEL );
1335 rSet.DisableItem( FN_BUSINESS_CARD );
1336 rSet.DisableItem( FN_XFORMS_INIT );
1339 if ( !aModuleOpt.IsImpress() )
1340 rSet.DisableItem( SID_SD_AUTOPILOT );
1343 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */