1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_desktop.hxx"
26
27 #include <cstdlib>
28 #include <vector>
29
30 #include <memory>
31 #include <unistd.h>
32 #include "app.hxx"
33 #include "desktop.hrc"
34 #include "appinit.hxx"
35 #include "officeipcthread.hxx"
36 #include "cmdlineargs.hxx"
37 #include "desktopresid.hxx"
38 #include "dispatchwatcher.hxx"
39 #include "configinit.hxx"
40 #include "lockfile.hxx"
41 #include "checkinstall.hxx"
42 #include "cmdlinehelp.hxx"
43 #include "userinstall.hxx"
44 #include "desktopcontext.hxx"
45 #include "exithelper.hxx"
46 #include "../migration/pages.hxx"
47
48 #include <svtools/javacontext.hxx>
49 #include <com/sun/star/frame/XSessionManagerListener.hpp>
50 #include <com/sun/star/frame/XSynchronousDispatch.hpp>
51 #include <com/sun/star/document/CorruptedFilterConfigurationException.hpp>
52 #include <com/sun/star/configuration/CorruptedConfigurationException.hpp>
53 #include <com/sun/star/frame/XStorable.hpp>
54 #include <com/sun/star/util/XModifiable.hpp>
55 #include <com/sun/star/util/XFlushable.hpp>
56 #include <com/sun/star/system/SystemShellExecuteFlags.hpp>
57 #include <com/sun/star/beans/XPropertySet.hpp>
58 #include <com/sun/star/lang/XComponent.hpp>
59 #include <com/sun/star/uno/RuntimeException.hpp>
60 #include <com/sun/star/io/IOException.hpp>
61 #include <com/sun/star/lang/IllegalArgumentException.hpp>
62 #include <com/sun/star/lang/WrappedTargetException.hpp>
63 #include <com/sun/star/frame/XDesktop.hpp>
64 #include <com/sun/star/frame/XComponentLoader.hpp>
65 #include <com/sun/star/view/XPrintable.hpp>
66 #include <com/sun/star/lang/XInitialization.hpp>
67 #include <com/sun/star/frame/XFramesSupplier.hpp>
68 #include <com/sun/star/awt/XTopWindow.hpp>
69 #include <com/sun/star/util/XURLTransformer.hpp>
70 #include <com/sun/star/util/URL.hpp>
71 #include <com/sun/star/util/XCloseable.hpp>
72 #include <com/sun/star/frame/XDispatch.hpp>
73 #include <com/sun/star/frame/XDispatchProvider.hpp>
74 #include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
75 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
76 #include <com/sun/star/configuration/MissingBootstrapFileException.hpp>
77 #include <com/sun/star/configuration/InvalidBootstrapFileException.hpp>
78 #include <com/sun/star/configuration/InstallationIncompleteException.hpp>
79 #include <com/sun/star/configuration/backend/BackendSetupException.hpp>
80 #include <com/sun/star/configuration/backend/BackendAccessException.hpp>
81 #include <com/sun/star/container/XEnumeration.hpp>
82 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
83 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
84 #include <com/sun/star/task/XJobExecutor.hpp>
85 #include <com/sun/star/task/XRestartManager.hpp>
86 #ifndef _COM_SUN_STAR_TASK_XJOBEXECUTOR_HPP_
87 #include <com/sun/star/task/XJob.hpp>
88 #endif
89 #include <com/sun/star/beans/XPropertySet.hpp>
90 #include <com/sun/star/beans/NamedValue.hpp>
91 #include <com/sun/star/task/XJob.hpp>
92 #include <com/sun/star/document/XEventListener.hpp>
93 #include <com/sun/star/ui/XUIElementFactoryRegistration.hpp>
94 #include <com/sun/star/frame/XUIControllerRegistration.hpp>
95
96 #include <com/sun/star/java/XJavaVM.hpp>
97 #include <tools/testtoolloader.hxx>
98 #include <tools/solar.h>
99 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
100 #include <toolkit/helper/vclunohelper.hxx>
101 #endif
102 #include <vos/security.hxx>
103 #include <vos/ref.hxx>
104 #include <comphelper/processfactory.hxx>
105 #include <comphelper/componentcontext.hxx>
106 #include <comphelper/configurationhelper.hxx>
107 #ifndef _UTL__HXX_
108 #include <unotools/configmgr.hxx>
109 #endif
110 #include <unotools/configitem.hxx>
111 #include <unotools/confignode.hxx>
112 #include <unotools/ucbhelper.hxx>
113 #include <tools/tempfile.hxx>
114 #include <tools/urlobj.hxx>
115 #include <unotools/moduleoptions.hxx>
116 #include <osl/module.h>
117 #include <osl/file.hxx>
118 #include <osl/signal.h>
119 #include <osl/thread.hxx>
120 #include <rtl/uuid.h>
121 #include <rtl/uri.hxx>
122 #include <unotools/pathoptions.hxx>
123 #include <svl/languageoptions.hxx>
124 #include <unotools/internaloptions.hxx>
125 #include <svtools/miscopt.hxx>
126 #include <svtools/menuoptions.hxx>
127 #include <unotools/syslocaleoptions.hxx>
128 #include <unotools/syslocale.hxx>
129 #include <svl/folderrestriction.hxx>
130 #include <svl/eitem.hxx>
131 #include <svl/itemset.hxx>
132 #include <unotools/tempfile.hxx>
133 #include <rtl/logfile.hxx>
134 #include <rtl/ustrbuf.hxx>
135 #include <rtl/strbuf.hxx>
136 #include <rtl/bootstrap.hxx>
137 #include <rtl/instance.hxx>
138 #include <unotools/configmgr.hxx>
139 #include <vcl/help.hxx>
140 #include <vcl/msgbox.hxx>
141 #include <vcl/bitmap.hxx>
142 #include <vcl/stdtext.hxx>
143 #include <vcl/msgbox.hxx>
144 #include <sfx2/sfx.hrc>
145 #include <sfx2/app.hxx>
146 #include <ucbhelper/contentbroker.hxx>
147 #include <unotools/bootstrap.hxx>
148 #include <cppuhelper/bootstrap.hxx>
149
150 #include "vos/process.hxx"
151
152 #include <svtools/fontsubstconfig.hxx>
153 #include <svtools/accessibilityoptions.hxx>
154 #include <svtools/apearcfg.hxx>
155 #include <unotools/misccfg.hxx>
156 #include <svtools/filter.hxx>
157
158 #include "langselect.hxx"
159
160 #include "com/sun/star/deployment/ExtensionManager.hpp"
161 #include "com/sun/star/deployment/XExtensionManager.hpp"
162 #include "com/sun/star/task/XInteractionApprove.hpp"
163 #include "com/sun/star/task/XInteractionAbort.hpp"
164 #include "cppuhelper/compbase3.hxx"
165 #include <hash_set>
166
167 #include "com/sun/star/deployment/VersionException.hpp"
168 #include <dp_gui_handleversionexception.hxx>
169
170 #if defined MACOSX
171 #include <errno.h>
172 #include <sys/wait.h>
173 #endif
174
175 #define DEFINE_CONST_UNICODE(CONSTASCII) UniString(RTL_CONSTASCII_USTRINGPARAM(CONSTASCII))
176 #define OUSTR(x) ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(x))
177 #define U2S(STRING) ::rtl::OUStringToOString(STRING, RTL_TEXTENCODING_UTF8)
178
179 using namespace vos;
180 using namespace rtl;
181
182 using namespace ::com::sun::star::uno;
183 using namespace ::com::sun::star::util;
184 using namespace ::com::sun::star::lang;
185 using namespace ::com::sun::star::beans;
186 using namespace ::com::sun::star::frame;
187 using namespace ::com::sun::star::document;
188 using namespace ::com::sun::star::view;
189 using namespace ::com::sun::star::task;
190 using namespace ::com::sun::star::system;
191 using namespace ::com::sun::star::ui::dialogs;
192 using namespace ::com::sun::star::container;
193
194 namespace css = ::com::sun::star;
195
196 ResMgr* desktop::Desktop::pResMgr = 0;
197
198 namespace {
199
200 /** Write a marker file that is basically empty (just a single
201 character to prevent it from being deleted.) Its time of last
202 modification is its only important feature.
203
204 This is a simplified version of the function in
205 dp_extensionmanager.cxx. It uses direct file access instead of
206 the UCB. May prove to be too simple, but then again, it may not.
207 */
writeLastModified(::rtl::OUString & rsURL)208 bool writeLastModified (::rtl::OUString& rsURL)
209 {
210 try
211 {
212 // Remove the file if it already exists.
213 ::osl::File::remove(rsURL);
214
215 ::osl::File aFile (rsURL);
216 if (aFile.open(OpenFlag_Create | OpenFlag_Write) != ::osl::File::E_None)
217 return false;
218
219 const char aBuffer[] = "1";
220 sal_uInt64 nBytesWritten (0);
221 if (aFile.write(aBuffer, strlen(aBuffer), nBytesWritten) != ::osl::File::E_None)
222 return false;
223
224 if (aFile.close() != ::osl::File::E_None)
225 return false;
226
227 return true;
228 }
229 catch(...)
230 {
231 }
232 return false;
233 }
234
235 } // end of anonymous namespace
236
237
238
239 namespace desktop
240 {
241
242 static SalMainPipeExchangeSignalHandler* pSignalHandler = 0;
243 static sal_Bool _bCrashReporterEnabled = sal_True;
244
245 static const ::rtl::OUString CFG_PACKAGE_COMMON_HELP ( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.Office.Common/Help"));
246
247 static ::rtl::OUString getBrandSharePreregBundledPathURL();
248 // #i119950# Add a option that not to display the "Fatal Error" on dialog title
249 void FatalError(const ::rtl::OUString& sMessage, const sal_Bool isDisplayErrorString = sal_True);
250 // ----------------------------------------------------------------------------
251
GetDesktopResManager()252 ResMgr* Desktop::GetDesktopResManager()
253 {
254 if ( !Desktop::pResMgr )
255 {
256 const char* pMgrName = "dkt";
257
258 // Create desktop resource manager and bootstrap process
259 // was successful. Use default way to get language specific message.
260 if ( Application::IsInExecute() )
261 Desktop::pResMgr = ResMgr::CreateResMgr( pMgrName);
262
263 if ( !Desktop::pResMgr )
264 {
265 // Use VCL to get the correct language specific message as we
266 // are in the bootstrap process and not able to get the installed
267 // language!!
268 /*
269 LanguageType aLanguageType = LANGUAGE_DONTKNOW;
270
271 Desktop::pResMgr = ResMgr::SearchCreateResMgr( pMgrName, aLanguageType );
272 AllSettings as = GetSettings();
273 as.SetUILanguage(aLanguageType);
274 SetSettings(as);
275 */
276 // LanguageSelection langselect;
277 OUString aUILocaleString = LanguageSelection::getLanguageString();
278 sal_Int32 nIndex = 0;
279 OUString aLanguage = aUILocaleString.getToken( 0, '-', nIndex);
280 OUString aCountry = aUILocaleString.getToken( 0, '-', nIndex);
281 OUString aVariant = aUILocaleString.getToken( 0, '-', nIndex);
282
283 ::com::sun::star::lang::Locale aLocale( aLanguage, aCountry, aVariant );
284
285 Desktop::pResMgr = ResMgr::SearchCreateResMgr( pMgrName, aLocale);
286 AllSettings as = GetSettings();
287 as.SetUILocale(aLocale);
288 SetSettings(as);
289 }
290 }
291
292 return Desktop::pResMgr;
293 }
294
295 // ----------------------------------------------------------------------------
296 // Get a message string securely. There is a fallback string if the resource
297 // is not available.
298
GetMsgString(sal_uInt16 nId,const OUString & aFaultBackMsg)299 OUString Desktop::GetMsgString( sal_uInt16 nId, const OUString& aFaultBackMsg )
300 {
301 ResMgr* resMgr = GetDesktopResManager();
302 if ( !resMgr )
303 return aFaultBackMsg;
304 else
305 return OUString( String( ResId( nId, *resMgr )));
306 }
307
MakeStartupErrorMessage(OUString const & aErrorMessage)308 OUString MakeStartupErrorMessage(OUString const & aErrorMessage)
309 {
310 OUStringBuffer aDiagnosticMessage( 100 );
311
312 ResMgr* pResMgr = Desktop::GetDesktopResManager();
313 if ( pResMgr )
314 aDiagnosticMessage.append( OUString(String(ResId(STR_BOOTSTRAP_ERR_CANNOT_START, *pResMgr))) );
315 else
316 aDiagnosticMessage.appendAscii( "The program cannot be started." );
317
318 aDiagnosticMessage.appendAscii( "\n" );
319
320 aDiagnosticMessage.append( aErrorMessage );
321
322 return aDiagnosticMessage.makeStringAndClear();
323 }
324
MakeStartupConfigAccessErrorMessage(OUString const & aInternalErrMsg)325 OUString MakeStartupConfigAccessErrorMessage( OUString const & aInternalErrMsg )
326 {
327 OUStringBuffer aDiagnosticMessage( 200 );
328
329 ResMgr* pResMgr = Desktop::GetDesktopResManager();
330 if ( pResMgr )
331 aDiagnosticMessage.append( OUString(String(ResId(STR_BOOTSTRAP_ERR_CFG_DATAACCESS, *pResMgr ))) );
332 else
333 aDiagnosticMessage.appendAscii( "The program cannot be started." );
334
335 if ( aInternalErrMsg.getLength() > 0 )
336 {
337 aDiagnosticMessage.appendAscii( "\n\n" );
338 if ( pResMgr )
339 aDiagnosticMessage.append( OUString(String(ResId(STR_INTERNAL_ERRMSG, *pResMgr ))) );
340 else
341 aDiagnosticMessage.appendAscii( "The following internal error has occurred:\n\n" );
342 aDiagnosticMessage.append( aInternalErrMsg );
343 }
344
345 return aDiagnosticMessage.makeStringAndClear();
346 }
347
348 //=============================================================================
349 // shows a simple error box with the given message ... but exits from these process !
350 //
351 // Fatal errors can't be solved by the process ... nor any recovery can help.
352 // Mostly the installation was damaged and must be repaired manually .. or by calling
353 // setup again.
354 //
355 // On the other side we must make sure that no further actions will be possible within
356 // the current office process ! No pipe requests, no menu/toolbar/shortcut actions
357 // are allowed. Otherwise we will force a "crash inside a crash".
358 //
359 // That's why we have to use a special native message box here which does not use yield :-)
360 //=============================================================================
FatalError(const::rtl::OUString & sMessage,const sal_Bool isDisplayErrorString)361 void FatalError(const ::rtl::OUString& sMessage, const sal_Bool isDisplayErrorString)
362 {
363 ::rtl::OUString sProductKey = ::utl::Bootstrap::getProductKey();
364 if ( ! sProductKey.getLength())
365 {
366 ::vos::OStartupInfo aInfo;
367 aInfo.getExecutableFile( sProductKey );
368
369 ::sal_uInt32 nLastIndex = sProductKey.lastIndexOf('/');
370 if ( nLastIndex > 0 )
371 sProductKey = sProductKey.copy( nLastIndex+1 );
372 }
373
374 ::rtl::OUStringBuffer sTitle (128);
375 sTitle.append (sProductKey );
376 if (isDisplayErrorString) {
377 sTitle.appendAscii (" - Fatal Error");
378 }
379 Application::ShowNativeErrorBox (sTitle.makeStringAndClear (), sMessage);
380 _exit(ExitHelper::E_FATAL_ERROR);
381 }
382
ShouldSuppressUI(CommandLineArgs * pCmdLine)383 static bool ShouldSuppressUI(CommandLineArgs* pCmdLine)
384 {
385 return pCmdLine->IsInvisible() ||
386 pCmdLine->IsHeadless() ||
387 pCmdLine->IsQuickstart();
388 }
389
GetCommandLineArgs()390 CommandLineArgs* Desktop::GetCommandLineArgs()
391 {
392 static CommandLineArgs* pArgs = 0;
393 if ( !pArgs )
394 {
395 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
396 if ( !pArgs )
397 pArgs = new CommandLineArgs;
398 }
399
400 return pArgs;
401 }
402
InitConfiguration()403 sal_Bool InitConfiguration()
404 {
405 RTL_LOGFILE_CONTEXT( aLog, "desktop (jb99855) ::InitConfiguration" );
406
407 Reference< XMultiServiceFactory > xProvider( CreateApplicationConfigurationProvider( ) );
408 return xProvider.is();
409 }
410
411 namespace
412 {
413 struct BrandName
414 : public rtl::Static< String, BrandName > {};
415 struct FullProductname
416 : public rtl::Static< String, FullProductname > {};
417 struct Version
418 : public rtl::Static< String, Version > {};
419 struct AboutBoxVersion
420 : public rtl::Static< String, AboutBoxVersion > {};
421 struct OOOVendor
422 : public rtl::Static< String, OOOVendor > {};
423 struct Extension
424 : public rtl::Static< String, Extension > {};
425 struct XMLFileFormatName
426 : public rtl::Static< String, XMLFileFormatName > {};
427 struct XMLFileFormatVersion
428 : public rtl::Static< String, XMLFileFormatVersion > {};
429 struct WriterCompatibilityVersionOOo11
430 : public rtl::Static< String, WriterCompatibilityVersionOOo11 > {};
431 }
432
ReplaceStringHookProc(UniString & rStr)433 void ReplaceStringHookProc( UniString& rStr )
434 {
435 static int nAll = 0, nPro = 0;
436
437 nAll++;
438 if ( ( rStr.SearchAscii( "%PRODUCT" ) != STRING_NOTFOUND ) ||
439 ( rStr.SearchAscii( "%FULLPRODUCT" ) != STRING_NOTFOUND ) )
440 {
441 String &rBrandName = BrandName::get();
442 String& rFullProductname = FullProductname::get();
443 String &rVersion = Version::get();
444 String &rAboutBoxVersion = AboutBoxVersion::get();
445 String &rExtension = Extension::get();
446 String &rXMLFileFormatName = XMLFileFormatName::get();
447 String &rXMLFileFormatVersion = XMLFileFormatVersion::get();
448
449 if ( !rBrandName.Len() )
450 {
451 rtl::OUString aTmp;
452 Any aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTNAME );
453 aRet >>= aTmp;
454 rBrandName = aTmp;
455
456 aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::FULLPRODUCTNAME );
457 aRet >>= aTmp;
458 rFullProductname = aTmp;
459
460 aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTXMLFILEFORMATNAME );
461 aRet >>= aTmp;
462 rXMLFileFormatName = aTmp;
463
464 aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTXMLFILEFORMATVERSION );
465 aRet >>= aTmp;
466 rXMLFileFormatVersion = aTmp;
467
468 aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTVERSION );
469 aRet >>= aTmp;
470 rVersion = aTmp;
471
472 aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::ABOUTBOXPRODUCTVERSION );
473 aRet >>= aTmp;
474 rAboutBoxVersion = aTmp;
475
476 if ( !rExtension.Len() )
477 {
478 aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTEXTENSION );
479 aRet >>= aTmp;
480 rExtension = aTmp;
481 }
482 }
483
484 nPro++;
485 rStr.SearchAndReplaceAllAscii( "%PRODUCTNAME", rBrandName );
486 rStr.SearchAndReplaceAllAscii( "%FULLPRODUCTNAME", rFullProductname );
487 rStr.SearchAndReplaceAllAscii( "%PRODUCTVERSION", rVersion );
488 rStr.SearchAndReplaceAllAscii( "%ABOUTBOXPRODUCTVERSION", rAboutBoxVersion );
489 rStr.SearchAndReplaceAllAscii( "%PRODUCTEXTENSION", rExtension );
490 rStr.SearchAndReplaceAllAscii( "%PRODUCTXMLFILEFORMATNAME", rXMLFileFormatName );
491 rStr.SearchAndReplaceAllAscii( "%PRODUCTXMLFILEFORMATVERSION", rXMLFileFormatVersion );
492 }
493 if ( rStr.SearchAscii( "%OOOVENDOR" ) != STRING_NOTFOUND )
494 {
495 String &rOOOVendor = OOOVendor::get();
496
497 if ( !rOOOVendor.Len() )
498 {
499 rtl::OUString aTmp;
500 Any aRet = ::utl::ConfigManager::GetDirectConfigProperty(
501 ::utl::ConfigManager::OOOVENDOR );
502 aRet >>= aTmp;
503 rOOOVendor = aTmp;
504
505 }
506 rStr.SearchAndReplaceAllAscii( "%OOOVENDOR" ,rOOOVendor );
507 }
508
509 if ( rStr.SearchAscii( "%WRITERCOMPATIBILITYVERSIONOOO11" ) != STRING_NOTFOUND )
510 {
511 String &rWriterCompatibilityVersionOOo11 = WriterCompatibilityVersionOOo11::get();
512 if ( !rWriterCompatibilityVersionOOo11.Len() )
513 {
514 rtl::OUString aTmp;
515 Any aRet = ::utl::ConfigManager::GetDirectConfigProperty(
516 ::utl::ConfigManager::WRITERCOMPATIBILITYVERSIONOOO11 );
517 aRet >>= aTmp;
518 rWriterCompatibilityVersionOOo11 = aTmp;
519 }
520
521 rStr.SearchAndReplaceAllAscii( "%WRITERCOMPATIBILITYVERSIONOOO11",
522 rWriterCompatibilityVersionOOo11 );
523 }
524 }
525
526 static const char pLastSyncFileName[] = "lastsynchronized";
527 static const sal_Int32 nStrLenLastSync = 16;
528
needsSynchronization(::rtl::OUString const & baseSynchronizedURL,::rtl::OUString const & userSynchronizedURL)529 static bool needsSynchronization(
530 ::rtl::OUString const & baseSynchronizedURL, ::rtl::OUString const & userSynchronizedURL )
531 {
532 bool bNeedsSync( false );
533
534 ::osl::DirectoryItem itemUserFile;
535 ::osl::File::RC err1 =
536 ::osl::DirectoryItem::get(userSynchronizedURL, itemUserFile);
537
538 //If it does not exist, then there is nothing to be done
539 if (err1 == ::osl::File::E_NOENT)
540 {
541 return true;
542 }
543 else if (err1 != ::osl::File::E_None)
544 {
545 OSL_ENSURE(0, "Cannot access lastsynchronized in user layer");
546 return true; //sync just in case
547 }
548
549 //If last synchronized does not exist in base layer, then do nothing
550 ::osl::DirectoryItem itemBaseFile;
551 ::osl::File::RC err2 = ::osl::DirectoryItem::get(baseSynchronizedURL, itemBaseFile);
552 if (err2 == ::osl::File::E_NOENT)
553 {
554 return true;
555
556 }
557 else if (err2 != ::osl::File::E_None)
558 {
559 OSL_ENSURE(0, "Cannot access file lastsynchronized in base layer");
560 return true; //sync just in case
561 }
562
563 //compare the modification time of the extension folder and the last
564 //modified file
565 ::osl::FileStatus statUser(FileStatusMask_ModifyTime);
566 ::osl::FileStatus statBase(FileStatusMask_ModifyTime);
567 if (itemUserFile.getFileStatus(statUser) == ::osl::File::E_None)
568 {
569 if (itemBaseFile.getFileStatus(statBase) == ::osl::File::E_None)
570 {
571 TimeValue timeUser = statUser.getModifyTime();
572 TimeValue timeBase = statBase.getModifyTime();
573
574 if (timeUser.Seconds < timeBase.Seconds)
575 bNeedsSync = true;
576 }
577 else
578 {
579 OSL_ASSERT(0);
580 bNeedsSync = true;
581 }
582 }
583 else
584 {
585 OSL_ASSERT(0);
586 bNeedsSync = true;
587 }
588
589 return bNeedsSync;
590 }
591
getBrandSharePreregBundledPathURL()592 static ::rtl::OUString getBrandSharePreregBundledPathURL()
593 {
594 ::rtl::OUString url(
595 RTL_CONSTASCII_USTRINGPARAM("$OOO_BASE_DIR/share/prereg/bundled"));
596
597 ::rtl::Bootstrap::expandMacros(url);
598 return url;
599 }
600
getUserBundledExtPathURL()601 static ::rtl::OUString getUserBundledExtPathURL()
602 {
603 ::rtl::OUString folder( RTL_CONSTASCII_USTRINGPARAM( "$BUNDLED_EXTENSIONS_USER" ));
604 ::rtl::Bootstrap::expandMacros(folder);
605
606 return folder;
607 }
608
getLastSyncFileURLFromBrandInstallation()609 static ::rtl::OUString getLastSyncFileURLFromBrandInstallation()
610 {
611 ::rtl::OUString aURL = getBrandSharePreregBundledPathURL();
612 ::sal_Int32 nLastIndex = aURL.lastIndexOf('/');
613
614 ::rtl::OUStringBuffer aTmp( aURL );
615
616 if ( nLastIndex != aURL.getLength()-1 )
617 aTmp.appendAscii( "/" );
618 aTmp.appendAscii( pLastSyncFileName );
619
620 return aTmp.makeStringAndClear();
621 }
622
getLastSyncFileURLFromUserInstallation()623 static ::rtl::OUString getLastSyncFileURLFromUserInstallation()
624 {
625 ::rtl::OUString aUserBundledPathURL = getUserBundledExtPathURL();
626 ::sal_Int32 nLastIndex = aUserBundledPathURL.lastIndexOf('/');
627
628 ::rtl::OUStringBuffer aTmp( aUserBundledPathURL );
629
630 if ( nLastIndex != aUserBundledPathURL.getLength()-1 )
631 aTmp.appendAscii( "/" );
632 aTmp.appendAscii( pLastSyncFileName );
633
634 return aTmp.makeStringAndClear();
635 }
636 //Checks if the argument src is the folder of the help or configuration
637 //backend in the prereg folder
excludeTmpFilesAndFolders(const rtl::OUString & src)638 static bool excludeTmpFilesAndFolders(const rtl::OUString & src)
639 {
640 const char helpBackend[] = "com.sun.star.comp.deployment.help.PackageRegistryBackend";
641 const char configBackend[] = "com.sun.star.comp.deployment.configuration.PackageRegistryBackend";
642 if (src.endsWithAsciiL(helpBackend, sizeof(helpBackend) - 1 )
643 || src.endsWithAsciiL(configBackend, sizeof(configBackend) - 1))
644 {
645 return true;
646 }
647 return false;
648 }
649
650 //If we are about to copy the contents of some special folder as determined
651 //by excludeTmpFilesAndFolders, then we omit those files or folders with a name
652 //derived from temporary folders.
isExcludedFileOrFolder(const rtl::OUString & name)653 static bool isExcludedFileOrFolder( const rtl::OUString & name)
654 {
655 char const * allowed[] = {
656 "backenddb.xml",
657 "configmgr.ini",
658 "registered_packages.db"
659 };
660
661 const unsigned int size = sizeof(allowed) / sizeof (char const *);
662 bool bExclude = true;
663 for (unsigned int i= 0; i < size; i ++)
664 {
665 ::rtl::OUString allowedName = ::rtl::OUString::createFromAscii(allowed[i]);
666 if (allowedName.equals(name))
667 {
668 bExclude = false;
669 break;
670 }
671 }
672 return bExclude;
673 }
674
copy_prereg_bundled_recursive(const rtl::OUString & srcUnqPath,const rtl::OUString & dstUnqPath,sal_Int32 TypeToCopy)675 static osl::FileBase::RC copy_prereg_bundled_recursive(
676 const rtl::OUString& srcUnqPath,
677 const rtl::OUString& dstUnqPath,
678 sal_Int32 TypeToCopy )
679 throw()
680 {
681 osl::FileBase::RC err = osl::FileBase::E_None;
682
683 if( TypeToCopy == -1 ) // Document
684 {
685 err = osl::File::copy( srcUnqPath,dstUnqPath );
686 }
687 else if( TypeToCopy == +1 ) // Folder
688 {
689 osl::Directory aDir( srcUnqPath );
690 err = aDir.open();
691 if ( err != osl::FileBase::E_None )
692 return err;
693
694 err = osl::Directory::create( dstUnqPath );
695 osl::FileBase::RC next = err;
696 if( err == osl::FileBase::E_None ||
697 err == osl::FileBase::E_EXIST )
698 {
699 err = osl::FileBase::E_None;
700 sal_Int32 n_Mask = FileStatusMask_FileURL | FileStatusMask_FileName | FileStatusMask_Type;
701
702 osl::DirectoryItem aDirItem;
703 bool bExcludeFiles = excludeTmpFilesAndFolders(srcUnqPath);
704
705 while( err == osl::FileBase::E_None && ( next = aDir.getNextItem( aDirItem ) ) == osl::FileBase::E_None )
706 {
707 sal_Bool IsDoc = false;
708 sal_Bool bFilter = false;
709 osl::FileStatus aFileStatus( n_Mask );
710 aDirItem.getFileStatus( aFileStatus );
711 if( aFileStatus.isValid( FileStatusMask_Type ) )
712 IsDoc = aFileStatus.getFileType() == osl::FileStatus::Regular;
713
714 // Getting the information for the next recursive copy
715 sal_Int32 newTypeToCopy = IsDoc ? -1 : +1;
716
717 rtl::OUString newSrcUnqPath;
718 if( aFileStatus.isValid( FileStatusMask_FileURL ) )
719 newSrcUnqPath = aFileStatus.getFileURL();
720
721 rtl::OUString newDstUnqPath = dstUnqPath;
722 rtl::OUString tit;
723 if( aFileStatus.isValid( FileStatusMask_FileName ) )
724 {
725 ::rtl::OUString aFileName = aFileStatus.getFileName();
726 tit = rtl::Uri::encode( aFileName,
727 rtl_UriCharClassPchar,
728 rtl_UriEncodeIgnoreEscapes,
729 RTL_TEXTENCODING_UTF8 );
730
731 // Special treatment for "lastsychronized" file. Must not be
732 // copied from the bundled folder!
733 //Also do not copy *.tmp files and *.tmp_ folders. This affects the files/folders
734 //from the help and configuration backend
735 if ( IsDoc && (aFileName.equalsAscii( pLastSyncFileName )
736 || bExcludeFiles && isExcludedFileOrFolder(aFileName)))
737 bFilter = true;
738 else if (!IsDoc && bExcludeFiles && isExcludedFileOrFolder(aFileName))
739 bFilter = true;
740 }
741
742 if( newDstUnqPath.lastIndexOf( sal_Unicode('/') ) != newDstUnqPath.getLength()-1 )
743 newDstUnqPath += rtl::OUString::createFromAscii( "/" );
744
745 newDstUnqPath += tit;
746
747 if (( newSrcUnqPath != dstUnqPath ) && !bFilter )
748 err = copy_prereg_bundled_recursive( newSrcUnqPath,newDstUnqPath, newTypeToCopy );
749 }
750
751 if( err == osl::FileBase::E_None && next != osl::FileBase::E_NOENT )
752 err = next;
753 }
754 aDir.close();
755 }
756
757 return err;
758 }
759
760
761 //====================================================================================
762
763 // MinimalCommandEnv: a tribute owed to ExtensionManager being an UNO stronghold
764 class MinimalCommandEnv
765 : public ::cppu::WeakImplHelper3< css::ucb::XCommandEnvironment,
766 css::task::XInteractionHandler,
767 css::ucb::XProgressHandler >
768 {
769 public:
770 // XCommandEnvironment
getInteractionHandler()771 virtual css::uno::Reference< css::task::XInteractionHandler> SAL_CALL getInteractionHandler()
772 throw (css::uno::RuntimeException)
773 { return this;}
getProgressHandler()774 virtual css::uno::Reference< css::ucb::XProgressHandler> SAL_CALL getProgressHandler()
775 throw (css::uno::RuntimeException)
776 { return this;}
777
778 // XInteractionHandler
779 virtual void SAL_CALL handle( const css::uno::Reference< css::task::XInteractionRequest>&)
780 throw (css::uno::RuntimeException);
781
782 // XProgressHandler
push(const css::uno::Any &)783 virtual void SAL_CALL push( const css::uno::Any& /*Status*/)
784 throw (css::uno::RuntimeException)
785 {}
update(const css::uno::Any &)786 virtual void SAL_CALL update( const css::uno::Any& /*Status*/)
787 throw (css::uno::RuntimeException)
788 {}
pop()789 virtual void SAL_CALL pop()
790 throw (css::uno::RuntimeException)
791 {}
792 };
793
794 // MinimalCommandEnv's XInteractionHandler simply approves
handle(css::uno::Reference<css::task::XInteractionRequest> const & xRequest)795 void MinimalCommandEnv::handle(
796 css::uno::Reference< css::task::XInteractionRequest> const& xRequest)
797 throw ( css::uno::RuntimeException )
798 {
799 bool bApprove = true;
800
801 css::deployment::VersionException verExc;
802 if ( xRequest->getRequest() >>= verExc )
803 {
804 // choose newest version, if an extension is already been installed.
805 const bool bChooseNewestVersion = true;
806 bApprove = handleVersionException( verExc, 0, bChooseNewestVersion );
807 }
808
809 const css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > > conts( xRequest->getContinuations());
810 const css::uno::Reference< css::task::XInteractionContinuation>* pConts = conts.getConstArray();
811 const sal_Int32 len = conts.getLength();
812 for( sal_Int32 pos = 0; pos < len; ++pos )
813 {
814 if ( bApprove )
815 {
816 css::uno::Reference< css::task::XInteractionApprove> xInteractionApprove( pConts[ pos ], css::uno::UNO_QUERY);
817 if( xInteractionApprove.is())
818 {
819 xInteractionApprove->select();
820 // don't query again for ongoing continuations:
821 break;
822 }
823 }
824 else
825 {
826 css::uno::Reference< css::task::XInteractionAbort > xInteractionAbort( pConts[ pos ], css::uno::UNO_QUERY );
827 if (xInteractionAbort.is())
828 {
829 xInteractionAbort->select();
830 // don't query again for ongoing continuations:
831 break;
832 }
833 }
834 }
835 }
836
837
838 /** Check if installBundledExtensionBlobs() has to be run.
839 It uses the time stamps of a marker file (rsMarkerURL) on the one
840 hand and of the files in the given directory on the other.
841 Returns </TRUE> when either the marker does not yet exist or any
842 file in the given directory is newer than the marker.
843 */
needsInstallBundledExtensionBlobs(const::rtl::OUString & rsMarkerURL,const::rtl::OUString & rsDirectoryURL)844 static bool needsInstallBundledExtensionBlobs (
845 const ::rtl::OUString& rsMarkerURL,
846 const ::rtl::OUString& rsDirectoryURL)
847 {
848 ::osl::DirectoryItem aMarkerItem;
849 if (::osl::DirectoryItem::get(rsMarkerURL, aMarkerItem) == ::osl::File::E_NOENT)
850 {
851 // Marker does not exist. Extensions where never installed.
852 return true;
853 }
854
855 ::osl::FileStatus aMarkerStat (FileStatusMask_ModifyTime);
856 if (aMarkerItem.getFileStatus(aMarkerStat) != ::osl::File::E_None)
857 {
858 // Can not get marker state. Reason?
859 return true;
860 }
861
862 const TimeValue aMarkerModifyTime (aMarkerStat.getModifyTime());
863
864 ::osl::Directory aDirectory (rsDirectoryURL);
865 if (aDirectory.open() != osl::File::E_None)
866 {
867 // No extension directory. Nothing to be done.
868 return false;
869 }
870
871 // Check the date of each extension in the given directory. If
872 // any of them is newer than the marker file then an installation
873 // is necessary.
874 ::osl::DirectoryItem aDirectoryItem;
875 while (aDirectory.getNextItem(aDirectoryItem) == osl::File::E_None)
876 {
877 ::osl::FileStatus aFileStat (FileStatusMask_ModifyTime);
878 if (aDirectoryItem.getFileStatus(aFileStat) != ::osl::File::E_None)
879 continue;
880 if (aFileStat.getFileType() != ::osl::FileStatus::Regular)
881 continue;
882 if (aFileStat.getModifyTime().Seconds > aMarkerModifyTime.Seconds)
883 {
884 aDirectory.close();
885 return true;
886 }
887 }
888 aDirectory.close();
889
890 // Also check the last modification time of the containing
891 // directory. This ensures installation after an update of
892 // OpenOffice. Without it the extensions have the date on which
893 // they where built, not the date on which they where installed.
894 if (::osl::DirectoryItem::get(rsDirectoryURL, aDirectoryItem) == osl::File::E_None)
895 {
896 ::osl::FileStatus aDirectoryStat (FileStatusMask_ModifyTime);
897 const ::osl::FileBase::RC eResult (aDirectoryItem.getFileStatus(aDirectoryStat));
898 if (eResult == ::osl::File::E_None)
899 {
900 if (aDirectoryStat.getModifyTime().Seconds > aMarkerModifyTime.Seconds)
901 return true;
902 }
903 }
904
905 // No file in the directory is newer than the marker.
906 return false;
907 }
908
909
910 // install bundled but non-pre-registered extension blobs
installBundledExtensionBlobs()911 static void installBundledExtensionBlobs()
912 {
913 rtl::OUString aDirUrl( OUSTR("$OOO_BASE_DIR/share/extensions/install"));
914 ::rtl::Bootstrap::expandMacros( aDirUrl);
915
916 // Find out if we can exit early: only when there is an extension file newer
917 // than the marker we have to install any extension.
918 ::rtl::OUString sMarkerURL (RTL_CONSTASCII_USTRINGPARAM("$BUNDLED_EXTENSIONS_USER/lastsynchronized.bundled"));
919 ::rtl::Bootstrap::expandMacros(sMarkerURL);
920 if ( ! needsInstallBundledExtensionBlobs(sMarkerURL, aDirUrl))
921 return;
922 writeLastModified(sMarkerURL);
923
924 // get the ExtensionManager
925 ::css::uno::Reference< ::css::uno::XComponentContext> xContext = comphelper::getProcessComponentContext();
926 ::css::uno::Reference< ::css::deployment::XExtensionManager> xEM = ::css::deployment::ExtensionManager::get( xContext);
927 // provide the minimal set of requirements to call ExtensionManager's methods
928 MinimalCommandEnv* pMiniCmdEnv = new MinimalCommandEnv;
929 ::css::uno::Reference< css::ucb::XCommandEnvironment> xCmdEnv( static_cast< cppu::OWeakObject*>(pMiniCmdEnv), css::uno::UNO_QUERY);
930 ::css::uno::Reference< ::css::task::XAbortChannel> xAbortChannel;
931
932 const ::css::beans::NamedValue aNamedProps( OUSTR("SUPPRESS_LICENSE"), ::css::uno::makeAny( OUSTR("1")));
933 const ::css::uno::Sequence< ::css::beans::NamedValue> xProperties( &aNamedProps, 1);
934
935 // iterate over the bundled extension blobs
936 ::osl::Directory aDir( aDirUrl);
937 ::osl::File::RC rc = aDir.open();
938 while( rc == osl::File::E_None)
939 {
940 ::osl::DirectoryItem aDI;
941 if( aDir.getNextItem( aDI) != osl::File::E_None)
942 break;
943 ::osl::FileStatus aFileStat( FileStatusMask_Type | FileStatusMask_FileURL);
944 if( aDI.getFileStatus( aFileStat) != ::osl::File::E_None)
945 continue;
946 if( aFileStat.getFileType() != ::osl::FileStatus::Regular)
947 continue;
948 try
949 {
950 // request to install the extension blob
951 xEM->addExtension( aFileStat.getFileURL(), xProperties, OUSTR("user"), xAbortChannel, xCmdEnv);
952 }
953 // ExtensionManager problems are not worth to die for here
954 catch( css::uno::RuntimeException&)
955 {}
956 catch( css::deployment::DeploymentException&)
957 {}
958 catch ( css::ucb::CommandFailedException& )
959 {
960 }
961 catch ( css::ucb::CommandAbortedException& )
962 {
963 }
964 catch ( css::lang::IllegalArgumentException& )
965 {
966 }
967 }
968 }
969
970 //=============================================================================
971
Desktop()972 Desktop::Desktop()
973 : m_bServicesRegistered( false )
974 , m_aBootstrapError( BE_OK )
975 , m_pLockfile( NULL )
976 {
977 RTL_LOGFILE_TRACE( "desktop (cd100003) ::Desktop::Desktop" );
978 }
979
~Desktop()980 Desktop::~Desktop()
981 {
982 }
983
Init()984 void Desktop::Init()
985 {
986 RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::Init" );
987 SetBootstrapStatus(BS_OK);
988
989 // Check for lastsynchronized file for pre-registered bundled extensions in the user directory
990 // and test if synchronization is necessary!
991 {
992 ::rtl::OUString aUserLastSyncFilePathURL = getLastSyncFileURLFromUserInstallation();
993 ::rtl::OUString aPreregSyncFilePathURL = getLastSyncFileURLFromBrandInstallation();
994
995 if ( needsSynchronization( aPreregSyncFilePathURL, aUserLastSyncFilePathURL ))
996 {
997 rtl::OUString aUserPath = getUserBundledExtPathURL();
998 rtl::OUString aPreregBundledPath = getBrandSharePreregBundledPathURL();
999
1000 // copy bundled folder to the user directory
1001 osl::FileBase::RC rc = osl::Directory::createPath(aUserPath);
1002 (void) rc;
1003 copy_prereg_bundled_recursive( aPreregBundledPath, aUserPath, +1 );
1004 }
1005 }
1006
1007 // create service factory...
1008 Reference < XMultiServiceFactory > rSMgr = CreateApplicationServiceManager();
1009 if( rSMgr.is() )
1010 {
1011 ::comphelper::setProcessServiceFactory( rSMgr );
1012 }
1013 else
1014 {
1015 SetBootstrapError( BE_UNO_SERVICEMANAGER );
1016 }
1017
1018 if ( GetBootstrapError() == BE_OK )
1019 {
1020 // prepare language
1021 if ( !LanguageSelection::prepareLanguage() )
1022 {
1023 if ( LanguageSelection::getStatus() == LanguageSelection::LS_STATUS_CANNOT_DETERMINE_LANGUAGE )
1024 SetBootstrapError( BE_LANGUAGE_MISSING );
1025 else
1026 SetBootstrapError( BE_OFFICECONFIG_BROKEN );
1027 }
1028 }
1029
1030 if ( GetBootstrapError() == BE_OK )
1031 {
1032 CommandLineArgs* pCmdLineArgs = GetCommandLineArgs();
1033 #ifdef UNX
1034 // check whether we need to print cmdline help
1035 if ( pCmdLineArgs->IsHelp() ) {
1036 displayCmdlineHelp();
1037 SetBootstrapStatus(BS_TERMINATE);
1038 }
1039 #endif
1040 // start ipc thread only for non-remote offices
1041 RTL_LOGFILE_CONTEXT( aLog2, "desktop (cd100003) ::OfficeIPCThread::EnableOfficeIPCThread" );
1042 OfficeIPCThread::Status aStatus = OfficeIPCThread::EnableOfficeIPCThread();
1043 if ( aStatus == OfficeIPCThread::IPC_STATUS_BOOTSTRAP_ERROR )
1044 {
1045 SetBootstrapError( BE_PATHINFO_MISSING );
1046
1047 }
1048 else if ( aStatus == OfficeIPCThread::IPC_STATUS_MULTI_TS_ERROR )
1049 {
1050 SetBootstrapError( BE_MUTLISESSION_NOT_SUPPROTED );
1051 }
1052 else if ( aStatus == OfficeIPCThread::IPC_STATUS_2ND_OFFICE )
1053 {
1054 // 2nd office startup should terminate after sending cmdlineargs through pipe
1055 SetBootstrapStatus(BS_TERMINATE);
1056 }
1057 else if ( pCmdLineArgs->IsHelp() )
1058 {
1059 // disable IPC thread in an instance that is just showing a help message
1060 OfficeIPCThread::DisableOfficeIPCThread();
1061 }
1062 pSignalHandler = new SalMainPipeExchangeSignalHandler;
1063 }
1064 }
1065
DeInit()1066 void Desktop::DeInit()
1067 {
1068 RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::DeInit" );
1069
1070 try {
1071 // instead of removing of the configManager just let it commit all the changes
1072 RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
1073 utl::ConfigManager::GetConfigManager()->StoreConfigItems();
1074 FlushConfiguration();
1075 RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
1076
1077 // close splashscreen if it's still open
1078 CloseSplashScreen();
1079 Reference<XMultiServiceFactory> xXMultiServiceFactory(::comphelper::getProcessServiceFactory());
1080 DestroyApplicationServiceManager( xXMultiServiceFactory );
1081 // nobody should get a destroyd service factory...
1082 ::comphelper::setProcessServiceFactory( NULL );
1083
1084 // clear lockfile
1085 if (m_pLockfile != NULL)
1086 m_pLockfile->clean();
1087
1088 OfficeIPCThread::DisableOfficeIPCThread();
1089 if( pSignalHandler )
1090 DELETEZ( pSignalHandler );
1091 } catch (RuntimeException&) {
1092 // someone threw an exception during shutdown
1093 // this will leave some garbage behind..
1094 }
1095
1096 RTL_LOGFILE_CONTEXT_TRACE( aLog, "FINISHED WITH Destop::DeInit" );
1097 }
1098
QueryExit()1099 sal_Bool Desktop::QueryExit()
1100 {
1101 try
1102 {
1103 RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
1104 utl::ConfigManager::GetConfigManager()->StoreConfigItems();
1105 RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
1106 }
1107 catch ( RuntimeException& )
1108 {
1109 }
1110
1111 const sal_Char SUSPEND_QUICKSTARTVETO[] = "SuspendQuickstartVeto";
1112
1113 Reference< ::com::sun::star::frame::XDesktop >
1114 xDesktop( ::comphelper::getProcessServiceFactory()->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
1115 UNO_QUERY );
1116
1117 Reference < ::com::sun::star::beans::XPropertySet > xPropertySet( xDesktop, UNO_QUERY );
1118 if ( xPropertySet.is() )
1119 {
1120 Any a;
1121 a <<= (sal_Bool)sal_True;
1122 xPropertySet->setPropertyValue( OUSTRING(RTL_CONSTASCII_USTRINGPARAM( SUSPEND_QUICKSTARTVETO )), a );
1123 }
1124
1125 sal_Bool bExit = ( !xDesktop.is() || xDesktop->terminate() );
1126
1127
1128 if ( !bExit && xPropertySet.is() )
1129 {
1130 Any a;
1131 a <<= (sal_Bool)sal_False;
1132 xPropertySet->setPropertyValue( OUSTRING(RTL_CONSTASCII_USTRINGPARAM( SUSPEND_QUICKSTARTVETO )), a );
1133 }
1134 else
1135 {
1136 FlushConfiguration();
1137 try
1138 {
1139 // it is no problem to call DisableOfficeIPCThread() more than once
1140 // it also looks to be threadsafe
1141 OfficeIPCThread::DisableOfficeIPCThread();
1142 }
1143 catch ( RuntimeException& )
1144 {
1145 }
1146
1147 if (m_pLockfile != NULL) m_pLockfile->clean();
1148 }
1149
1150 return bExit;
1151 }
1152
HandleBootstrapPathErrors(::utl::Bootstrap::Status aBootstrapStatus,const OUString & aDiagnosticMessage)1153 void Desktop::HandleBootstrapPathErrors( ::utl::Bootstrap::Status aBootstrapStatus, const OUString& aDiagnosticMessage )
1154 {
1155 if ( aBootstrapStatus != ::utl::Bootstrap::DATA_OK )
1156 {
1157 sal_Bool bWorkstationInstallation = sal_False;
1158 ::rtl::OUString aBaseInstallURL;
1159 ::rtl::OUString aUserInstallURL;
1160 ::rtl::OUString aProductKey;
1161 ::rtl::OUString aTemp;
1162 ::vos::OStartupInfo aInfo;
1163
1164 aInfo.getExecutableFile( aProductKey );
1165 sal_uInt32 lastIndex = aProductKey.lastIndexOf('/');
1166 if ( lastIndex > 0 )
1167 aProductKey = aProductKey.copy( lastIndex+1 );
1168
1169 aTemp = ::utl::Bootstrap::getProductKey( aProductKey );
1170 if ( aTemp.getLength() > 0 )
1171 aProductKey = aTemp;
1172
1173 ::utl::Bootstrap::PathStatus aBaseInstallStatus = ::utl::Bootstrap::locateBaseInstallation( aBaseInstallURL );
1174 ::utl::Bootstrap::PathStatus aUserInstallStatus = ::utl::Bootstrap::locateUserInstallation( aUserInstallURL );
1175
1176 if (( aBaseInstallStatus == ::utl::Bootstrap::PATH_EXISTS &&
1177 aUserInstallStatus == ::utl::Bootstrap::PATH_EXISTS ))
1178 {
1179 if ( aBaseInstallURL != aUserInstallURL )
1180 bWorkstationInstallation = sal_True;
1181 }
1182
1183 OUString aMessage;
1184 OUStringBuffer aBuffer( 100 );
1185 aBuffer.append( aDiagnosticMessage );
1186
1187 aBuffer.appendAscii( "\n" );
1188
1189 ErrorBox aBootstrapFailedBox( NULL, WB_OK, aMessage );
1190 aBootstrapFailedBox.SetText( aProductKey );
1191 aBootstrapFailedBox.Execute();
1192 }
1193 }
1194
1195 // Create a error message depending on bootstrap failure code and an optional file url
CreateErrorMsgString(utl::Bootstrap::FailureCode nFailureCode,const::rtl::OUString & aFileURL)1196 ::rtl::OUString Desktop::CreateErrorMsgString(
1197 utl::Bootstrap::FailureCode nFailureCode,
1198 const ::rtl::OUString& aFileURL )
1199 {
1200 OUString aMsg;
1201 OUString aFilePath;
1202 sal_Bool bFileInfo = sal_True;
1203
1204 switch ( nFailureCode )
1205 {
1206 /// the shared installation directory could not be located
1207 case ::utl::Bootstrap::MISSING_INSTALL_DIRECTORY:
1208 {
1209 aMsg = GetMsgString( STR_BOOTSTRAP_ERR_PATH_INVALID,
1210 OUString( RTL_CONSTASCII_USTRINGPARAM( "The installation path is not available." )) );
1211 bFileInfo = sal_False;
1212 }
1213 break;
1214
1215 /// the bootstrap INI file could not be found or read
1216 case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE:
1217 {
1218 aMsg = GetMsgString( STR_BOOTSTRAP_ERR_FILE_MISSING,
1219 OUString( RTL_CONSTASCII_USTRINGPARAM( "The configuration file \"$1\" is missing." )) );
1220 }
1221 break;
1222
1223 /// the bootstrap INI is missing a required entry
1224 /// the bootstrap INI contains invalid data
1225 case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE_ENTRY:
1226 case ::utl::Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY:
1227 {
1228 aMsg = GetMsgString( STR_BOOTSTRAP_ERR_FILE_CORRUPT,
1229 OUString( RTL_CONSTASCII_USTRINGPARAM( "The configuration file \"$1\" is corrupt." )) );
1230 }
1231 break;
1232
1233 /// the version locator INI file could not be found or read
1234 case ::utl::Bootstrap::MISSING_VERSION_FILE:
1235 {
1236 aMsg = GetMsgString( STR_BOOTSTRAP_ERR_FILE_MISSING,
1237 OUString( RTL_CONSTASCII_USTRINGPARAM( "The configuration file \"$1\" is missing." )) );
1238 }
1239 break;
1240
1241 /// the version locator INI has no entry for this version
1242 case ::utl::Bootstrap::MISSING_VERSION_FILE_ENTRY:
1243 {
1244 aMsg = GetMsgString( STR_BOOTSTRAP_ERR_NO_SUPPORT,
1245 OUString( RTL_CONSTASCII_USTRINGPARAM( "The main configuration file \"$1\" does not support the current version." )) );
1246 }
1247 break;
1248
1249 /// the user installation directory does not exist
1250 case ::utl::Bootstrap::MISSING_USER_DIRECTORY:
1251 {
1252 aMsg = GetMsgString( STR_BOOTSTRAP_ERR_DIR_MISSING,
1253 OUString( RTL_CONSTASCII_USTRINGPARAM( "The configuration directory \"$1\" is missing." )) );
1254 }
1255 break;
1256
1257 /// some bootstrap data was invalid in unexpected ways
1258 case ::utl::Bootstrap::INVALID_BOOTSTRAP_DATA:
1259 {
1260 aMsg = GetMsgString( STR_BOOTSTRAP_ERR_INTERNAL,
1261 OUString( RTL_CONSTASCII_USTRINGPARAM( "An internal failure occurred." )) );
1262 bFileInfo = sal_False;
1263 }
1264 break;
1265
1266 case ::utl::Bootstrap::INVALID_VERSION_FILE_ENTRY:
1267 {
1268 // This needs to be improved, see #i67575#:
1269 aMsg = OUString(
1270 RTL_CONSTASCII_USTRINGPARAM( "Invalid version file entry" ) );
1271 bFileInfo = sal_False;
1272 }
1273 break;
1274
1275 case ::utl::Bootstrap::NO_FAILURE:
1276 {
1277 OSL_ASSERT(false);
1278 }
1279 break;
1280 }
1281
1282 if ( bFileInfo )
1283 {
1284 String aMsgString( aMsg );
1285
1286 osl::File::getSystemPathFromFileURL( aFileURL, aFilePath );
1287
1288 aMsgString.SearchAndReplaceAscii( "$1", aFilePath );
1289 aMsg = aMsgString;
1290 }
1291
1292 return MakeStartupErrorMessage( aMsg );
1293 }
1294
HandleBootstrapErrors(BootstrapError aBootstrapError)1295 void Desktop::HandleBootstrapErrors( BootstrapError aBootstrapError )
1296 {
1297 if ( aBootstrapError == BE_MUTLISESSION_NOT_SUPPROTED ) {
1298 OUString aMessage;
1299 aMessage = GetMsgString( STR_BOOTSTRAP_ERR_MULTISESSION,
1300 OUString( RTL_CONSTASCII_USTRINGPARAM( "You have another instance running in a different terminal session. Close that instance and then try again." )) );
1301 FatalError(aMessage,sal_False);
1302
1303 } else if ( aBootstrapError == BE_PATHINFO_MISSING )
1304 {
1305 OUString aErrorMsg;
1306 OUString aBuffer;
1307 utl::Bootstrap::Status aBootstrapStatus;
1308 utl::Bootstrap::FailureCode nFailureCode;
1309
1310 aBootstrapStatus = ::utl::Bootstrap::checkBootstrapStatus( aBuffer, nFailureCode );
1311 if ( aBootstrapStatus != ::utl::Bootstrap::DATA_OK )
1312 {
1313 switch ( nFailureCode )
1314 {
1315 case ::utl::Bootstrap::MISSING_INSTALL_DIRECTORY:
1316 case ::utl::Bootstrap::INVALID_BOOTSTRAP_DATA:
1317 {
1318 aErrorMsg = CreateErrorMsgString( nFailureCode, OUString() );
1319 }
1320 break;
1321
1322 /// the bootstrap INI file could not be found or read
1323 /// the bootstrap INI is missing a required entry
1324 /// the bootstrap INI contains invalid data
1325 case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE_ENTRY:
1326 case ::utl::Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY:
1327 case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE:
1328 {
1329 OUString aBootstrapFileURL;
1330
1331 utl::Bootstrap::locateBootstrapFile( aBootstrapFileURL );
1332 aErrorMsg = CreateErrorMsgString( nFailureCode, aBootstrapFileURL );
1333 }
1334 break;
1335
1336 /// the version locator INI file could not be found or read
1337 /// the version locator INI has no entry for this version
1338 /// the version locator INI entry is not a valid directory URL
1339 case ::utl::Bootstrap::INVALID_VERSION_FILE_ENTRY:
1340 case ::utl::Bootstrap::MISSING_VERSION_FILE_ENTRY:
1341 case ::utl::Bootstrap::MISSING_VERSION_FILE:
1342 {
1343 OUString aVersionFileURL;
1344
1345 utl::Bootstrap::locateVersionFile( aVersionFileURL );
1346 aErrorMsg = CreateErrorMsgString( nFailureCode, aVersionFileURL );
1347 }
1348 break;
1349
1350 /// the user installation directory does not exist
1351 case ::utl::Bootstrap::MISSING_USER_DIRECTORY:
1352 {
1353 OUString aUserInstallationURL;
1354
1355 utl::Bootstrap::locateUserInstallation( aUserInstallationURL );
1356 aErrorMsg = CreateErrorMsgString( nFailureCode, aUserInstallationURL );
1357 }
1358 break;
1359
1360 case ::utl::Bootstrap::NO_FAILURE:
1361 {
1362 OSL_ASSERT(false);
1363 }
1364 break;
1365 }
1366
1367 HandleBootstrapPathErrors( aBootstrapStatus, aErrorMsg );
1368 }
1369 }
1370 else if ( aBootstrapError == BE_UNO_SERVICEMANAGER || aBootstrapError == BE_UNO_SERVICE_CONFIG_MISSING )
1371 {
1372 // Uno service manager is not available. VCL needs a uno service manager to display a message box!!!
1373 // Currently we are not able to display a message box with a service manager due to this limitations inside VCL.
1374
1375 // When UNO is not properly initialized, all kinds of things can fail
1376 // and cause the process to crash (e.g., a call to GetMsgString may
1377 // crash when somewhere deep within that call Any::operator <= is used
1378 // with a PropertyValue, and no binary UNO type description for
1379 // PropertyValue is available). To give the user a hint even if
1380 // generating and displaying a message box below crashes, print a
1381 // hard-coded message on stderr first:
1382 fputs(
1383 aBootstrapError == BE_UNO_SERVICEMANAGER
1384 ? ("The application cannot be started. " "\n"
1385 "The component manager is not available." "\n")
1386 // STR_BOOTSTRAP_ERR_CANNOT_START, STR_BOOTSTRAP_ERR_NO_SERVICE
1387 : ("The application cannot be started. " "\n"
1388 "The configuration service is not available." "\n"),
1389 // STR_BOOTSTRAP_ERR_CANNOT_START,
1390 // STR_BOOTSTRAP_ERR_NO_CFG_SERVICE
1391 stderr);
1392
1393 // First sentence. We cannot bootstrap office further!
1394 OUString aMessage;
1395 OUStringBuffer aDiagnosticMessage( 100 );
1396
1397 OUString aErrorMsg;
1398
1399 if ( aBootstrapError == BE_UNO_SERVICEMANAGER )
1400 aErrorMsg = GetMsgString( STR_BOOTSTRAP_ERR_NO_SERVICE,
1401 OUString( RTL_CONSTASCII_USTRINGPARAM( "The service manager is not available." )) );
1402 else
1403 aErrorMsg = GetMsgString( STR_BOOTSTRAP_ERR_NO_CFG_SERVICE,
1404 OUString( RTL_CONSTASCII_USTRINGPARAM( "The configuration service is not available." )) );
1405
1406 aDiagnosticMessage.append( aErrorMsg );
1407 aDiagnosticMessage.appendAscii( "\n" );
1408
1409 // Due to the fact the we haven't a backup applicat.rdb file anymore it is not possible to
1410 // repair the installation with the setup executable besides the office executable. Now
1411 // we have to ask the user to start the setup on CD/installation directory manually!!
1412 OUString aStartSetupManually( GetMsgString(
1413 STR_ASK_START_SETUP_MANUALLY,
1414 OUString( RTL_CONSTASCII_USTRINGPARAM( "Start setup application to repair the installation from CD, or the folder containing the installation packages." )) ));
1415
1416 aDiagnosticMessage.append( aStartSetupManually );
1417 aMessage = MakeStartupErrorMessage( aDiagnosticMessage.makeStringAndClear() );
1418
1419 FatalError( aMessage);
1420 }
1421 else if ( aBootstrapError == BE_OFFICECONFIG_BROKEN )
1422 {
1423 OUString aMessage;
1424 OUStringBuffer aDiagnosticMessage( 100 );
1425 OUString aErrorMsg;
1426 aErrorMsg = GetMsgString( STR_CONFIG_ERR_ACCESS_GENERAL,
1427 OUString( RTL_CONSTASCII_USTRINGPARAM( "A general error occurred while accessing your central configuration." )) );
1428 aDiagnosticMessage.append( aErrorMsg );
1429 aMessage = MakeStartupErrorMessage( aDiagnosticMessage.makeStringAndClear() );
1430 FatalError(aMessage);
1431 }
1432 else if ( aBootstrapError == BE_USERINSTALL_FAILED )
1433 {
1434 OUString aMessage;
1435 OUStringBuffer aDiagnosticMessage( 100 );
1436 OUString aErrorMsg;
1437 aErrorMsg = GetMsgString( STR_BOOTSTRAP_ERR_INTERNAL,
1438 OUString( RTL_CONSTASCII_USTRINGPARAM( "User installation could not be completed" )) );
1439 aDiagnosticMessage.append( aErrorMsg );
1440 aMessage = MakeStartupErrorMessage( aDiagnosticMessage.makeStringAndClear() );
1441 FatalError(aMessage);
1442 }
1443 else if ( aBootstrapError == BE_LANGUAGE_MISSING )
1444 {
1445 OUString aMessage;
1446 OUStringBuffer aDiagnosticMessage( 100 );
1447 OUString aErrorMsg;
1448 aErrorMsg = GetMsgString(
1449 //@@@ FIXME: should use an own resource string => #i36213#
1450 STR_BOOTSTRAP_ERR_LANGUAGE_MISSING,
1451 OUString( RTL_CONSTASCII_USTRINGPARAM(
1452 "Language could not be determined." )) );
1453 aDiagnosticMessage.append( aErrorMsg );
1454 aMessage = MakeStartupErrorMessage(
1455 aDiagnosticMessage.makeStringAndClear() );
1456 FatalError(aMessage);
1457 }
1458 else if (( aBootstrapError == BE_USERINSTALL_NOTENOUGHDISKSPACE ) ||
1459 ( aBootstrapError == BE_USERINSTALL_NOWRITEACCESS ))
1460 {
1461 OUString aUserInstallationURL;
1462 OUString aUserInstallationPath;
1463 OUString aMessage;
1464 OUString aErrorMsg;
1465 OUStringBuffer aDiagnosticMessage( 100 );
1466
1467 utl::Bootstrap::locateUserInstallation( aUserInstallationURL );
1468
1469 if ( aBootstrapError == BE_USERINSTALL_NOTENOUGHDISKSPACE )
1470 aErrorMsg = GetMsgString(
1471 STR_BOOSTRAP_ERR_NOTENOUGHDISKSPACE,
1472 OUString( RTL_CONSTASCII_USTRINGPARAM(
1473 "User installation could not be completed due to insufficient free disk space." )) );
1474 else
1475 aErrorMsg = GetMsgString(
1476 STR_BOOSTRAP_ERR_NOACCESSRIGHTS,
1477 OUString( RTL_CONSTASCII_USTRINGPARAM(
1478 "User installation could not be processed due to missing access rights." )) );
1479
1480 osl::File::getSystemPathFromFileURL( aUserInstallationURL, aUserInstallationPath );
1481
1482 aDiagnosticMessage.append( aErrorMsg );
1483 aDiagnosticMessage.append( aUserInstallationPath );
1484 aMessage = MakeStartupErrorMessage(
1485 aDiagnosticMessage.makeStringAndClear() );
1486 FatalError(aMessage);
1487 }
1488
1489 return;
1490 }
1491
1492
retrieveCrashReporterState()1493 void Desktop::retrieveCrashReporterState()
1494 {
1495 static const ::rtl::OUString CFG_PACKAGE_RECOVERY = ::rtl::OUString::createFromAscii("org.openoffice.Office.Recovery/");
1496 static const ::rtl::OUString CFG_PATH_CRASHREPORTER = ::rtl::OUString::createFromAscii("CrashReporter" );
1497 static const ::rtl::OUString CFG_ENTRY_ENABLED = ::rtl::OUString::createFromAscii("Enabled" );
1498
1499 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
1500
1501 sal_Bool bEnabled( sal_True );
1502 if ( xSMGR.is() )
1503 {
1504 css::uno::Any aVal = ::comphelper::ConfigurationHelper::readDirectKey(
1505 xSMGR,
1506 CFG_PACKAGE_RECOVERY,
1507 CFG_PATH_CRASHREPORTER,
1508 CFG_ENTRY_ENABLED,
1509 ::comphelper::ConfigurationHelper::E_READONLY);
1510 aVal >>= bEnabled;
1511 }
1512 _bCrashReporterEnabled = bEnabled;
1513 }
1514
isUIOnSessionShutdownAllowed()1515 sal_Bool Desktop::isUIOnSessionShutdownAllowed()
1516 {
1517 static const ::rtl::OUString CFG_PACKAGE_RECOVERY = ::rtl::OUString::createFromAscii("org.openoffice.Office.Recovery/");
1518 static const ::rtl::OUString CFG_PATH_SESSION = ::rtl::OUString::createFromAscii("SessionShutdown" );
1519 static const ::rtl::OUString CFG_ENTRY_UIENABLED = ::rtl::OUString::createFromAscii("DocumentStoreUIEnabled" );
1520
1521 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
1522
1523 sal_Bool bResult = sal_False;
1524 if ( xSMGR.is() )
1525 {
1526 css::uno::Any aVal = ::comphelper::ConfigurationHelper::readDirectKey(
1527 xSMGR,
1528 CFG_PACKAGE_RECOVERY,
1529 CFG_PATH_SESSION,
1530 CFG_ENTRY_UIENABLED,
1531 ::comphelper::ConfigurationHelper::E_READONLY);
1532 aVal >>= bResult;
1533 }
1534
1535 return bResult;
1536 }
1537
1538 //-----------------------------------------------
1539 /** @short check if crash reporter feature is enabled or
1540 disabled.
1541 */
isCrashReporterEnabled()1542 sal_Bool Desktop::isCrashReporterEnabled()
1543 {
1544 return _bCrashReporterEnabled;
1545 }
1546
1547 //-----------------------------------------------
1548 /** @short check if recovery must be started or not.
1549
1550 @param bCrashed [boolean ... out!]
1551 the office crashed last times.
1552 But may be there are no recovery data.
1553 Useful to trigger the error report tool without
1554 showing the recovery UI.
1555
1556 @param bRecoveryDataExists [boolean ... out!]
1557 there exists some recovery data.
1558
1559 @param bSessionDataExists [boolean ... out!]
1560 there exists some session data.
1561 Because the user may be logged out last time from it's
1562 unix session...
1563 */
impl_checkRecoveryState(sal_Bool & bCrashed,sal_Bool & bRecoveryDataExists,sal_Bool & bSessionDataExists)1564 void impl_checkRecoveryState(sal_Bool& bCrashed ,
1565 sal_Bool& bRecoveryDataExists,
1566 sal_Bool& bSessionDataExists )
1567 {
1568 static const ::rtl::OUString SERVICENAME_RECOVERYCORE = ::rtl::OUString::createFromAscii("com.sun.star.frame.AutoRecovery");
1569 static const ::rtl::OUString PROP_CRASHED = ::rtl::OUString::createFromAscii("Crashed" );
1570 static const ::rtl::OUString PROP_EXISTSRECOVERY = ::rtl::OUString::createFromAscii("ExistsRecoveryData" );
1571 static const ::rtl::OUString PROP_EXISTSSESSION = ::rtl::OUString::createFromAscii("ExistsSessionData" );
1572 static const ::rtl::OUString CFG_PACKAGE_RECOVERY = ::rtl::OUString::createFromAscii("org.openoffice.Office.Recovery/");
1573 static const ::rtl::OUString CFG_PATH_RECOVERYINFO = ::rtl::OUString::createFromAscii("RecoveryInfo" );
1574
1575 bCrashed = sal_False;
1576 bRecoveryDataExists = sal_False;
1577 bSessionDataExists = sal_False;
1578
1579 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
1580 try
1581 {
1582 css::uno::Reference< css::beans::XPropertySet > xRecovery(
1583 xSMGR->createInstance(SERVICENAME_RECOVERYCORE),
1584 css::uno::UNO_QUERY_THROW);
1585
1586 xRecovery->getPropertyValue(PROP_CRASHED ) >>= bCrashed ;
1587 xRecovery->getPropertyValue(PROP_EXISTSRECOVERY) >>= bRecoveryDataExists;
1588 xRecovery->getPropertyValue(PROP_EXISTSSESSION ) >>= bSessionDataExists ;
1589 }
1590 catch(const css::uno::Exception&) {}
1591 }
1592
1593 //-----------------------------------------------
1594 /* @short start the recovery wizard.
1595
1596 @param bEmergencySave
1597 differs between EMERGENCY_SAVE and RECOVERY
1598 */
impl_callRecoveryUI(sal_Bool bEmergencySave,sal_Bool bCrashed,sal_Bool bExistsRecoveryData)1599 sal_Bool impl_callRecoveryUI(sal_Bool bEmergencySave ,
1600 sal_Bool bCrashed ,
1601 sal_Bool bExistsRecoveryData)
1602 {
1603 static ::rtl::OUString SERVICENAME_RECOVERYUI = ::rtl::OUString::createFromAscii("com.sun.star.comp.svx.RecoveryUI" );
1604 static ::rtl::OUString SERVICENAME_URLPARSER = ::rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" );
1605 static ::rtl::OUString COMMAND_EMERGENCYSAVE = ::rtl::OUString::createFromAscii("vnd.sun.star.autorecovery:/doEmergencySave");
1606 static ::rtl::OUString COMMAND_RECOVERY = ::rtl::OUString::createFromAscii("vnd.sun.star.autorecovery:/doAutoRecovery" );
1607 static ::rtl::OUString COMMAND_CRASHREPORT = ::rtl::OUString::createFromAscii("vnd.sun.star.autorecovery:/doCrashReport" );
1608
1609 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
1610
1611 css::uno::Reference< css::frame::XSynchronousDispatch > xRecoveryUI(
1612 xSMGR->createInstance(SERVICENAME_RECOVERYUI),
1613 css::uno::UNO_QUERY_THROW);
1614
1615 css::uno::Reference< css::util::XURLTransformer > xURLParser(
1616 xSMGR->createInstance(SERVICENAME_URLPARSER),
1617 css::uno::UNO_QUERY_THROW);
1618
1619 css::util::URL aURL;
1620 if (bEmergencySave)
1621 aURL.Complete = COMMAND_EMERGENCYSAVE;
1622 else
1623 {
1624 if (bExistsRecoveryData)
1625 aURL.Complete = COMMAND_RECOVERY;
1626 else
1627 if (bCrashed && Desktop::isCrashReporterEnabled() )
1628 aURL.Complete = COMMAND_CRASHREPORT;
1629 }
1630
1631 sal_Bool bRet = sal_False;
1632 if ( aURL.Complete.getLength() > 0 )
1633 {
1634 xURLParser->parseStrict(aURL);
1635
1636 css::uno::Any aRet = xRecoveryUI->dispatchWithReturnValue(aURL, css::uno::Sequence< css::beans::PropertyValue >());
1637 aRet >>= bRet;
1638 }
1639 return bRet;
1640 }
1641
1642 /*
1643 * Save all open documents so they will be reopened
1644 * the next time the application is started
1645 *
1646 * returns sal_True if at least one document could be saved...
1647 *
1648 */
1649
1650 sal_Bool Desktop::_bTasksSaved = sal_False;
1651
SaveTasks()1652 sal_Bool Desktop::SaveTasks()
1653 {
1654 return impl_callRecoveryUI(
1655 sal_True , // sal_True => force emergency save
1656 sal_False, // 2. and 3. param not used if 1. = true!
1657 sal_False);
1658 }
1659
1660 namespace {
1661
restartOnMac(bool passArguments)1662 void restartOnMac(bool passArguments) {
1663 #if defined MACOSX
1664 OfficeIPCThread::DisableOfficeIPCThread();
1665 rtl::OUString execUrl;
1666 OSL_VERIFY(osl_getExecutableFile(&execUrl.pData) == osl_Process_E_None);
1667 rtl::OUString execPath;
1668 rtl::OString execPath8;
1669 if ((osl::FileBase::getSystemPathFromFileURL(execUrl, execPath)
1670 != osl::FileBase::E_None) ||
1671 !execPath.convertToString(
1672 &execPath8, osl_getThreadTextEncoding(),
1673 (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
1674 RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
1675 {
1676 std::abort();
1677 }
1678 std::vector< rtl::OString > args;
1679 args.push_back(execPath8);
1680 bool wait = false;
1681 if (passArguments) {
1682 sal_uInt32 n = osl_getCommandArgCount();
1683 for (sal_uInt32 i = 0; i < n; ++i) {
1684 rtl::OUString arg;
1685 OSL_VERIFY(osl_getCommandArg(i, &arg.pData) == osl_Process_E_None);
1686 if (arg.matchAsciiL(RTL_CONSTASCII_STRINGPARAM("-accept="))) {
1687 wait = true;
1688 }
1689 rtl::OString arg8;
1690 if (!arg.convertToString(
1691 &arg8, osl_getThreadTextEncoding(),
1692 (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
1693 RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
1694 {
1695 std::abort();
1696 }
1697 args.push_back(arg8);
1698 }
1699 }
1700 std::vector< char const * > argPtrs;
1701 for (std::vector< rtl::OString >::iterator i(args.begin()); i != args.end();
1702 ++i)
1703 {
1704 argPtrs.push_back(i->getStr());
1705 }
1706 argPtrs.push_back(0);
1707 execv(execPath8.getStr(), const_cast< char ** >(&argPtrs[0]));
1708 if (errno == ENOTSUP) { // happens when multithreaded on OS X < 10.6
1709 pid_t pid = fork();
1710 if (pid == 0) {
1711 execv(execPath8.getStr(), const_cast< char ** >(&argPtrs[0]));
1712 } else if (pid > 0) {
1713 // Two simultaneously running soffice processes lead to two dock
1714 // icons, so avoid waiting here unless it must be assumed that the
1715 // process invoking soffice itself wants to wait for soffice to
1716 // finish:
1717 if (!wait) {
1718 return;
1719 }
1720 int stat;
1721 if (waitpid(pid, &stat, 0) == pid && WIFEXITED(stat)) {
1722 _exit(WEXITSTATUS(stat));
1723 }
1724 }
1725 }
1726 std::abort();
1727 #else
1728 (void) passArguments; // avoid warnings
1729 #endif
1730 }
1731
1732 }
1733
Exception(sal_uInt16 nError)1734 sal_uInt16 Desktop::Exception(sal_uInt16 nError)
1735 {
1736 // protect against recursive calls
1737 static sal_Bool bInException = sal_False;
1738
1739 sal_uInt16 nOldMode = Application::GetSystemWindowMode();
1740 Application::SetSystemWindowMode( nOldMode & ~SYSTEMWINDOW_MODE_NOAUTOMODE );
1741 Application::SetDefDialogParent( NULL );
1742
1743 if ( bInException )
1744 {
1745 String aDoubleExceptionString;
1746 Application::Abort( aDoubleExceptionString );
1747 }
1748
1749 bInException = sal_True;
1750 CommandLineArgs* pArgs = GetCommandLineArgs();
1751
1752 // save all modified documents ... if it's allowed doing so.
1753 sal_Bool bRestart = sal_False;
1754 sal_Bool bAllowRecoveryAndSessionManagement = (
1755 ( !pArgs->IsNoRestore() ) && // some use cases of office must work without recovery
1756 ( !pArgs->IsHeadless() ) &&
1757 ( !pArgs->IsServer() ) &&
1758 (( nError & EXC_MAJORTYPE ) != EXC_DISPLAY ) && // recovery can't work without UI ... but UI layer seems to be the reason for this crash
1759 ( Application::IsInExecute() ) // crashes during startup and shutdown should be ignored (they indicates a corrupt installation ...)
1760 );
1761 if ( bAllowRecoveryAndSessionManagement )
1762 bRestart = SaveTasks();
1763
1764 FlushConfiguration();
1765
1766 switch( nError & EXC_MAJORTYPE )
1767 {
1768 case EXC_RSCNOTLOADED:
1769 {
1770 String aResExceptionString;
1771 Application::Abort( aResExceptionString );
1772 break;
1773 }
1774
1775 case EXC_SYSOBJNOTCREATED:
1776 {
1777 String aSysResExceptionString;
1778 Application::Abort( aSysResExceptionString );
1779 break;
1780 }
1781
1782 default:
1783 {
1784 if (m_pLockfile != NULL) {
1785 m_pLockfile->clean();
1786 }
1787 if( bRestart )
1788 {
1789 OfficeIPCThread::DisableOfficeIPCThread();
1790 if( pSignalHandler )
1791 DELETEZ( pSignalHandler );
1792 restartOnMac(false);
1793 _exit( ExitHelper::E_CRASH_WITH_RESTART );
1794 }
1795 else
1796 {
1797 Application::Abort( String() );
1798 }
1799
1800 break;
1801 }
1802 }
1803
1804 OSL_ASSERT(false); // unreachable
1805 return 0;
1806 }
1807
AppEvent(const ApplicationEvent & rAppEvent)1808 void Desktop::AppEvent( const ApplicationEvent& rAppEvent )
1809 {
1810 HandleAppEvent( rAppEvent );
1811 }
1812
1813 struct ExecuteGlobals
1814 {
1815 Reference < css::document::XEventListener > xGlobalBroadcaster;
1816 sal_Bool bRestartRequested;
1817 sal_Bool bUseSystemFileDialog;
1818 std::auto_ptr<SvtLanguageOptions> pLanguageOptions;
1819 std::auto_ptr<SvtPathOptions> pPathOptions;
1820
ExecuteGlobalsdesktop::ExecuteGlobals1821 ExecuteGlobals()
1822 : bRestartRequested( sal_False )
1823 , bUseSystemFileDialog( sal_True )
1824 {}
1825 };
1826
1827 static ExecuteGlobals* pExecGlobals = NULL;
1828
Main()1829 void Desktop::Main()
1830 {
1831 pExecGlobals = new ExecuteGlobals();
1832
1833 RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::Main" );
1834
1835 // Remember current context object
1836 com::sun::star::uno::ContextLayer layer(
1837 com::sun::star::uno::getCurrentContext() );
1838
1839 BootstrapError eError = GetBootstrapError();
1840 if ( eError != BE_OK )
1841 {
1842 HandleBootstrapErrors( eError );
1843 return;
1844 }
1845
1846 BootstrapStatus eStatus = GetBootstrapStatus();
1847 if (eStatus == BS_TERMINATE) {
1848 return;
1849 }
1850
1851 // Detect desktop environment - need to do this as early as possible
1852 com::sun::star::uno::setCurrentContext(
1853 new DesktopContext( com::sun::star::uno::getCurrentContext() ) );
1854
1855 CommandLineArgs* pCmdLineArgs = GetCommandLineArgs();
1856
1857 // setup configuration error handling
1858 ConfigurationErrorHandler aConfigErrHandler;
1859 if (!ShouldSuppressUI(pCmdLineArgs))
1860 aConfigErrHandler.activate();
1861
1862 ResMgr::SetReadStringHook( ReplaceStringHookProc );
1863
1864 // Startup screen
1865 RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109) Desktop::Main { OpenSplashScreen" );
1866 OpenSplashScreen();
1867 RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109) Desktop::Main } OpenSplashScreen" );
1868
1869 {
1870 UserInstall::UserInstallError instErr_fin = UserInstall::finalize();
1871 if ( instErr_fin != UserInstall::E_None)
1872 {
1873 OSL_ENSURE(sal_False, "userinstall failed");
1874 if ( instErr_fin == UserInstall::E_NoDiskSpace )
1875 HandleBootstrapErrors( BE_USERINSTALL_NOTENOUGHDISKSPACE );
1876 else if ( instErr_fin == UserInstall::E_NoWriteAccess )
1877 HandleBootstrapErrors( BE_USERINSTALL_NOWRITEACCESS );
1878 else
1879 HandleBootstrapErrors( BE_USERINSTALL_FAILED );
1880 return;
1881 }
1882 // refresh path information
1883 utl::Bootstrap::reloadData();
1884 SetSplashScreenProgress(25);
1885 }
1886
1887 Reference< XMultiServiceFactory > xSMgr =
1888 ::comphelper::getProcessServiceFactory();
1889
1890 Reference< ::com::sun::star::task::XRestartManager > xRestartManager;
1891 int nAcquireCount( 0 );
1892 try
1893 {
1894 RegisterServices( xSMgr );
1895
1896 //SetSplashScreenProgress(15);
1897
1898 #ifndef UNX
1899 if ( pCmdLineArgs->IsHelp() ) {
1900 displayCmdlineHelp();
1901 return;
1902 }
1903 #endif
1904
1905 // check user installation directory for lockfile so we can be sure
1906 // there is no other instance using our data files from a remote host
1907 RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109) Desktop::Main -> Lockfile" );
1908 m_pLockfile = new Lockfile;
1909 if ( !pCmdLineArgs->IsHeadless() && !pCmdLineArgs->IsInvisible() &&
1910 !pCmdLineArgs->IsNoLockcheck() && !m_pLockfile->check( Lockfile_execWarning )) {
1911 // Lockfile exists, and user clicked 'no'
1912 return;
1913 }
1914 RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109) Desktop::Main <- Lockfile" );
1915
1916 // check if accessibility is enabled but not working and allow to quit
1917 RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ GetEnableATToolSupport" );
1918 if( Application::GetSettings().GetMiscSettings().GetEnableATToolSupport() )
1919 {
1920 sal_Bool bQuitApp (sal_False);
1921
1922 if( !InitAccessBridge( true, bQuitApp ) )
1923 if( bQuitApp )
1924 return;
1925 }
1926 RTL_LOGFILE_CONTEXT_TRACE( aLog, "} GetEnableATToolSupport" );
1927
1928 // terminate if requested...
1929 if( pCmdLineArgs->IsTerminateAfterInit() ) return;
1930
1931 // Read the common configuration items for optimization purpose
1932 if ( !InitializeConfiguration() ) return;
1933
1934 //SetSplashScreenProgress(20);
1935
1936 // set static variable to enabled/disable crash reporter
1937 retrieveCrashReporterState();
1938 const bool bCrashReporterEnabled = isCrashReporterEnabled();
1939 osl_setErrorReporting( !bCrashReporterEnabled );
1940
1941 // create title string
1942 sal_Bool bCheckOk = sal_False;
1943 ::com::sun::star::lang::Locale aLocale;
1944 const char* pMgrName = "ofa";
1945 ResMgr* pLabelResMgr = ResMgr::SearchCreateResMgr( pMgrName, aLocale );
1946 String aTitle = pLabelResMgr ? String( ResId( RID_APPTITLE, *pLabelResMgr ) ) : String();
1947 delete pLabelResMgr;
1948
1949 // Check for StarOffice/Suite specific extensions runs also with OpenOffice installation sets
1950 OUString aTitleString( aTitle );
1951 bCheckOk = CheckInstallation( aTitleString );
1952 if ( !bCheckOk )
1953 return;
1954 else
1955 aTitle = aTitleString;
1956
1957 #ifdef DBG_UTIL
1958 //include version ID in non product builds
1959 ::rtl::OUString aDefault;
1960 aTitle += DEFINE_CONST_UNICODE(" [");
1961 String aVerId( utl::Bootstrap::getBuildIdData( aDefault ));
1962 aTitle += aVerId;
1963 aTitle += ']';
1964 #endif
1965
1966 SetDisplayName( aTitle );
1967 RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ create SvtPathOptions and SvtLanguageOptions" );
1968 pExecGlobals->pPathOptions.reset( new SvtPathOptions);
1969 SetSplashScreenProgress(40);
1970 RTL_LOGFILE_CONTEXT_TRACE( aLog, "} create SvtPathOptions and SvtLanguageOptions" );
1971
1972 // Check special env variable #111015#
1973 std::vector< String > aUnrestrictedFolders;
1974 svt::getUnrestrictedFolders( aUnrestrictedFolders );
1975
1976 if ( aUnrestrictedFolders.size() > 0 )
1977 {
1978 // Set different working directory. The first entry is
1979 // the new work path.
1980 String aWorkPath = aUnrestrictedFolders[0];
1981 SvtPathOptions().SetWorkPath( aWorkPath );
1982 }
1983
1984 // create service for loading SFX (still needed in startup)
1985 pExecGlobals->xGlobalBroadcaster = Reference < css::document::XEventListener >
1986 ( xSMgr->createInstance(
1987 DEFINE_CONST_UNICODE( "com.sun.star.frame.GlobalEventBroadcaster" ) ), UNO_QUERY );
1988
1989 /* ensure existence of a default window that messages can be dispatched to
1990 This is for the benefit of testtool which uses PostUserEvent extensively
1991 and else can deadlock while creating this window from another tread while
1992 the main thread is not yet in the event loop.
1993 */
1994 Application::GetDefaultDevice();
1995
1996 // initialize test-tool library (if available)
1997 RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ tools::InitTestToolLib" );
1998 tools::InitTestToolLib();
1999 RTL_LOGFILE_CONTEXT_TRACE( aLog, "} tools::InitTestToolLib" );
2000
2001 // Check if bundled or shared extensions were added /removed
2002 // and process those extensions (has to be done before checking
2003 // the extension dependencies!
2004 SynchronizeExtensionRepositories();
2005 bool bAbort = CheckExtensionDependencies();
2006 if ( bAbort )
2007 return;
2008
2009 {
2010 ::comphelper::ComponentContext aContext( xSMgr );
2011 xRestartManager.set( aContext.getSingleton( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.OfficeRestartManager" ) ) ), UNO_QUERY );
2012 }
2013
2014 // check whether the shutdown is caused by restart
2015 pExecGlobals->bRestartRequested = ( xRestartManager.is() && xRestartManager->isRestartRequested( sal_True ) );
2016
2017 // First Start Wizard allowed ?
2018 if ( ! pCmdLineArgs->IsNoFirstStartWizard() && !pExecGlobals->bRestartRequested )
2019 {
2020 RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ FirstStartWizard" );
2021
2022 if (IsFirstStartWizardNeeded())
2023 {
2024 Reference< XJob > xFirstStartJob( xSMgr->createInstance(
2025 DEFINE_CONST_UNICODE( "com.sun.star.comp.desktop.FirstStart" ) ), UNO_QUERY );
2026 if (xFirstStartJob.is())
2027 {
2028 sal_Bool bDone = sal_False;
2029 Sequence< NamedValue > lArgs(2);
2030 lArgs[0].Name = ::rtl::OUString::createFromAscii("LicenseNeedsAcceptance");
2031 lArgs[0].Value <<= LicenseNeedsAcceptance();
2032 lArgs[1].Name = ::rtl::OUString::createFromAscii("LicensePath");
2033 lArgs[1].Value <<= GetLicensePath();
2034
2035 xFirstStartJob->execute(lArgs) >>= bDone;
2036 if ( !bDone )
2037 {
2038 doShutdown();
2039 return;
2040 }
2041 // mark first start as done
2042 FinishFirstStart();
2043 }
2044 }
2045
2046 RTL_LOGFILE_CONTEXT_TRACE( aLog, "} FirstStartWizard" );
2047 }
2048
2049 // process non-pre-registered extensions
2050 installBundledExtensionBlobs();
2051
2052 // keep a language options instance...
2053 pExecGlobals->pLanguageOptions.reset( new SvtLanguageOptions(sal_True));
2054
2055 if (pExecGlobals->xGlobalBroadcaster.is())
2056 {
2057 css::document::EventObject aEvent;
2058 aEvent.EventName = ::rtl::OUString::createFromAscii("OnStartApp");
2059 pExecGlobals->xGlobalBroadcaster->notifyEvent(aEvent);
2060 }
2061
2062 SetSplashScreenProgress(50);
2063
2064 // Backing Component
2065 sal_Bool bCrashed = sal_False;
2066 sal_Bool bExistsRecoveryData = sal_False;
2067 sal_Bool bExistsSessionData = sal_False;
2068
2069 RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ impl_checkRecoveryState" );
2070 impl_checkRecoveryState(bCrashed, bExistsRecoveryData, bExistsSessionData);
2071 RTL_LOGFILE_CONTEXT_TRACE( aLog, "} impl_checkRecoveryState" );
2072
2073 {
2074 ::comphelper::ComponentContext aContext( xSMgr );
2075 xRestartManager.set( aContext.getSingleton( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.OfficeRestartManager" ) ) ), UNO_QUERY );
2076 }
2077
2078 // check whether the shutdown is caused by restart
2079 pExecGlobals->bRestartRequested = ( xRestartManager.is() && xRestartManager->isRestartRequested( sal_True ) );
2080
2081 if ( pCmdLineArgs->IsHeadless() )
2082 {
2083 // Ensure that we use not the system file dialogs as
2084 // headless mode relies on Application::EnableHeadlessMode()
2085 // which does only work for VCL dialogs!!
2086 SvtMiscOptions aMiscOptions;
2087 pExecGlobals->bUseSystemFileDialog = aMiscOptions.UseSystemFileDialog();
2088 aMiscOptions.SetUseSystemFileDialog( sal_False );
2089 }
2090
2091 if ( !pExecGlobals->bRestartRequested )
2092 {
2093 if ((!pCmdLineArgs->IsNoDefault() &&
2094 !pCmdLineArgs->WantsToLoadDocument() &&
2095 !pCmdLineArgs->IsInvisible() &&
2096 !pCmdLineArgs->IsHeadless() &&
2097 !pCmdLineArgs->IsQuickstart()) &&
2098 (SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::E_SSTARTMODULE)) &&
2099 (!bExistsRecoveryData ) &&
2100 (!bExistsSessionData ) &&
2101 (!Application::AnyInput( INPUT_APPEVENT ) ))
2102 {
2103 RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ create BackingComponent" );
2104 Reference< XFrame > xDesktopFrame( xSMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ))), UNO_QUERY );
2105 if (xDesktopFrame.is())
2106 {
2107 Reference< XFrame > xBackingFrame;
2108 Reference< ::com::sun::star::awt::XWindow > xContainerWindow;
2109
2110 xBackingFrame = xDesktopFrame->findFrame(OUString( RTL_CONSTASCII_USTRINGPARAM( "_blank" )), 0);
2111 if (xBackingFrame.is())
2112 xContainerWindow = xBackingFrame->getContainerWindow();
2113 if (xContainerWindow.is())
2114 {
2115 // set the WB_EXT_DOCUMENT style. Normally, this is done by the TaskCreator service when a "_blank"
2116 // frame/window is created. Since we do not use the TaskCreator here, we need to mimic its behavior,
2117 // otherwise documents loaded into this frame will later on miss functionality depending on the style.
2118 Window* pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow );
2119 OSL_ENSURE( pContainerWindow, "Desktop::Main: no implementation access to the frame's container window!" );
2120 pContainerWindow->SetExtendedStyle( pContainerWindow->GetExtendedStyle() | WB_EXT_DOCUMENT );
2121
2122 SetSplashScreenProgress(75);
2123 Sequence< Any > lArgs(1);
2124 lArgs[0] <<= xContainerWindow;
2125
2126 Reference< XController > xBackingComp(
2127 xSMgr->createInstanceWithArguments(OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.StartModule") ), lArgs), UNO_QUERY);
2128 if (xBackingComp.is())
2129 {
2130 Reference< ::com::sun::star::awt::XWindow > xBackingWin(xBackingComp, UNO_QUERY);
2131 // Attention: You MUST(!) call setComponent() before you call attachFrame().
2132 // Because the backing component set the property "IsBackingMode" of the frame
2133 // to true inside attachFrame(). But setComponent() reset this state everytimes ...
2134 xBackingFrame->setComponent(xBackingWin, xBackingComp);
2135 SetSplashScreenProgress(100);
2136 xBackingComp->attachFrame(xBackingFrame);
2137 CloseSplashScreen();
2138 xContainerWindow->setVisible(sal_True);
2139 }
2140 }
2141 }
2142 RTL_LOGFILE_CONTEXT_TRACE( aLog, "} create BackingComponent" );
2143 }
2144 }
2145 }
2146 catch ( com::sun::star::lang::WrappedTargetException& wte )
2147 {
2148 com::sun::star::uno::Exception te;
2149 wte.TargetException >>= te;
2150 FatalError( MakeStartupConfigAccessErrorMessage(wte.Message + te.Message) );
2151 return;
2152 }
2153 catch ( com::sun::star::uno::Exception& e )
2154 {
2155 FatalError( MakeStartupErrorMessage(e.Message) );
2156 return;
2157 }
2158
2159 SvtFontSubstConfig().Apply();
2160
2161 SvtTabAppearanceCfg aAppearanceCfg;
2162 aAppearanceCfg.SetInitialized();
2163 aAppearanceCfg.SetApplicationDefaults( this );
2164 SvtAccessibilityOptions aOptions;
2165 aOptions.SetVCLSettings();
2166
2167 if ( !pExecGlobals->bRestartRequested )
2168 {
2169 Application::SetFilterHdl( LINK( this, Desktop, ImplInitFilterHdl ) );
2170 sal_Bool bTerminateRequested = sal_False;
2171
2172 // Preload function depends on an initialized sfx application!
2173 SetSplashScreenProgress(75);
2174
2175 // use system window dialogs
2176 Application::SetSystemWindowMode( SYSTEMWINDOW_MODE_DIALOG );
2177
2178 // SetSplashScreenProgress(80);
2179
2180 if ( !bTerminateRequested && !pCmdLineArgs->IsInvisible() &&
2181 !pCmdLineArgs->IsNoQuickstart() )
2182 InitializeQuickstartMode( xSMgr );
2183
2184 RTL_LOGFILE_CONTEXT( aLog2, "desktop (cd100003) createInstance com.sun.star.frame.Desktop" );
2185 try
2186 {
2187 Reference< XDesktop > xDesktop( xSMgr->createInstance(
2188 OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ))), UNO_QUERY );
2189 if ( xDesktop.is() )
2190 xDesktop->addTerminateListener( new OfficeIPCThreadController );
2191 SetSplashScreenProgress(100);
2192 }
2193 catch ( com::sun::star::uno::Exception& e )
2194 {
2195 FatalError( MakeStartupErrorMessage(e.Message) );
2196 return;
2197 }
2198
2199 // Post user event to startup first application component window
2200 // We have to send this OpenClients message short before execute() to
2201 // minimize the risk that this message overtakes type detection construction!!
2202 Application::PostUserEvent( LINK( this, Desktop, OpenClients_Impl ) );
2203
2204 // Post event to enable acceptors
2205 Application::PostUserEvent( LINK( this, Desktop, EnableAcceptors_Impl) );
2206
2207 // The configuration error handler currently is only for startup
2208 aConfigErrHandler.deactivate();
2209
2210 // Acquire solar mutex just before we enter our message loop
2211 if ( nAcquireCount )
2212 Application::AcquireSolarMutex( nAcquireCount );
2213
2214 // call Application::Execute to process messages in vcl message loop
2215 RTL_LOGFILE_PRODUCT_TRACE( "PERFORMANCE - enter Application::Execute()" );
2216
2217 try
2218 {
2219 // The JavaContext contains an interaction handler which is used when
2220 // the creation of a Java Virtual Machine fails
2221 com::sun::star::uno::ContextLayer layer2(
2222 new svt::JavaContext( com::sun::star::uno::getCurrentContext() ) );
2223
2224 // check whether the shutdown is caused by restart just before entering the Execute
2225 pExecGlobals->bRestartRequested = pExecGlobals->bRestartRequested || ( xRestartManager.is() && xRestartManager->isRestartRequested( sal_True ) );
2226
2227 if ( !pExecGlobals->bRestartRequested )
2228 {
2229 // if this run of the office is triggered by restart, some additional actions should be done
2230 DoRestartActionsIfNecessary( !pCmdLineArgs->IsInvisible() && !pCmdLineArgs->IsNoQuickstart() );
2231
2232 Execute();
2233 }
2234 }
2235 catch(const com::sun::star::document::CorruptedFilterConfigurationException& exFilterCfg)
2236 {
2237 OfficeIPCThread::SetDowning();
2238 FatalError( MakeStartupErrorMessage(exFilterCfg.Message) );
2239 }
2240 catch(const com::sun::star::configuration::CorruptedConfigurationException& exAnyCfg)
2241 {
2242 OfficeIPCThread::SetDowning();
2243 FatalError( MakeStartupErrorMessage(exAnyCfg.Message) );
2244 }
2245 catch( const ::com::sun::star::uno::Exception& exUNO)
2246 {
2247 OfficeIPCThread::SetDowning();
2248 FatalError( exUNO.Message);
2249 }
2250 catch( const std::exception& exSTD)
2251 {
2252 OfficeIPCThread::SetDowning();
2253 FatalError( OUString::createFromAscii( exSTD.what()));
2254 }
2255 catch( ...)
2256 {
2257 OfficeIPCThread::SetDowning();
2258 FatalError( OUString(RTL_CONSTASCII_USTRINGPARAM( "Caught Unknown Exception: Aborting!")));
2259 }
2260 }
2261 // CAUTION: you do not necessarily get here e.g. on the Mac.
2262 // please put all deinitialization code into doShutdown
2263 doShutdown();
2264 }
2265
doShutdown()2266 void Desktop::doShutdown()
2267 {
2268 if( ! pExecGlobals )
2269 return;
2270
2271 if ( pExecGlobals->bRestartRequested )
2272 SetRestartState();
2273
2274 if (pExecGlobals->xGlobalBroadcaster.is())
2275 {
2276 css::document::EventObject aEvent;
2277 aEvent.EventName = ::rtl::OUString::createFromAscii("OnCloseApp");
2278 pExecGlobals->xGlobalBroadcaster->notifyEvent(aEvent);
2279 }
2280
2281 delete pResMgr, pResMgr = NULL;
2282 // Restore old value
2283 CommandLineArgs* pCmdLineArgs = GetCommandLineArgs();
2284 if ( pCmdLineArgs->IsHeadless() )
2285 SvtMiscOptions().SetUseSystemFileDialog( pExecGlobals->bUseSystemFileDialog );
2286
2287 // remove temp directory
2288 RemoveTemporaryDirectory();
2289 FlushConfiguration();
2290 // The acceptors in the AcceptorMap must be released (in DeregisterServices)
2291 // with the solar mutex unlocked, to avoid deadlock:
2292 sal_uLong nAcquireCount = Application::ReleaseSolarMutex();
2293 DeregisterServices();
2294 Application::AcquireSolarMutex(nAcquireCount);
2295 tools::DeInitTestToolLib();
2296 // be sure that path/language options gets destroyed before
2297 // UCB is deinitialized
2298 RTL_LOGFILE_CONTEXT_TRACE( aLog, "-> dispose path/language options" );
2299 pExecGlobals->pLanguageOptions.reset( 0 );
2300 pExecGlobals->pPathOptions.reset( 0 );
2301 RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- dispose path/language options" );
2302
2303 RTL_LOGFILE_CONTEXT_TRACE( aLog, "-> deinit ucb" );
2304 ::ucbhelper::ContentBroker::deinitialize();
2305 RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- deinit ucb" );
2306
2307 sal_Bool bRR = pExecGlobals->bRestartRequested;
2308 delete pExecGlobals, pExecGlobals = NULL;
2309
2310 RTL_LOGFILE_CONTEXT_TRACE( aLog, "FINISHED WITH Destop::Main" );
2311 if ( bRR )
2312 {
2313 restartOnMac(true);
2314 // wouldn't the solution be more clean if SalMain returns the exit code to the system?
2315 _exit( ExitHelper::E_NORMAL_RESTART );
2316 }
2317 }
2318
IMPL_LINK(Desktop,ImplInitFilterHdl,ConvertData *,pData)2319 IMPL_LINK( Desktop, ImplInitFilterHdl, ConvertData*, pData )
2320 {
2321 return GraphicFilter::GetGraphicFilter()->GetFilterCallback().Call( pData );
2322 }
2323
InitializeConfiguration()2324 sal_Bool Desktop::InitializeConfiguration()
2325 {
2326 sal_Bool bOk = sal_False;
2327
2328 try
2329 {
2330 bOk = InitConfiguration();
2331 }
2332 catch( ::com::sun::star::lang::ServiceNotRegisteredException& )
2333 {
2334 this->HandleBootstrapErrors( Desktop::BE_UNO_SERVICE_CONFIG_MISSING );
2335 }
2336 catch( ::com::sun::star::configuration::MissingBootstrapFileException& e )
2337 {
2338 OUString aMsg( CreateErrorMsgString( utl::Bootstrap::MISSING_BOOTSTRAP_FILE,
2339 e.BootstrapFileURL ));
2340 HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_USER_INSTALL, aMsg );
2341 }
2342 catch( ::com::sun::star::configuration::InvalidBootstrapFileException& e )
2343 {
2344 OUString aMsg( CreateErrorMsgString( utl::Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY,
2345 e.BootstrapFileURL ));
2346 HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_BASE_INSTALL, aMsg );
2347 }
2348 catch( ::com::sun::star::configuration::InstallationIncompleteException& )
2349 {
2350 OUString aVersionFileURL;
2351 OUString aMsg;
2352 utl::Bootstrap::PathStatus aPathStatus = utl::Bootstrap::locateVersionFile( aVersionFileURL );
2353 if ( aPathStatus == utl::Bootstrap::PATH_EXISTS )
2354 aMsg = CreateErrorMsgString( utl::Bootstrap::MISSING_VERSION_FILE_ENTRY, aVersionFileURL );
2355 else
2356 aMsg = CreateErrorMsgString( utl::Bootstrap::MISSING_VERSION_FILE, aVersionFileURL );
2357
2358 HandleBootstrapPathErrors( ::utl::Bootstrap::MISSING_USER_INSTALL, aMsg );
2359 }
2360 catch ( com::sun::star::configuration::backend::BackendAccessException& exception)
2361 {
2362 // [cm122549] It is assumed in this case that the message
2363 // coming from InitConfiguration (in fact CreateApplicationConf...)
2364 // is suitable for display directly.
2365 FatalError( MakeStartupErrorMessage( exception.Message ) );
2366 }
2367 catch ( com::sun::star::configuration::backend::BackendSetupException& exception)
2368 {
2369 // [cm122549] It is assumed in this case that the message
2370 // coming from InitConfiguration (in fact CreateApplicationConf...)
2371 // is suitable for display directly.
2372 FatalError( MakeStartupErrorMessage( exception.Message ) );
2373 }
2374 catch ( ::com::sun::star::configuration::CannotLoadConfigurationException& )
2375 {
2376 OUString aMsg( CreateErrorMsgString( utl::Bootstrap::INVALID_BOOTSTRAP_DATA,
2377 OUString() ));
2378 HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_BASE_INSTALL, aMsg );
2379 }
2380 catch( ::com::sun::star::uno::Exception& )
2381 {
2382 OUString aMsg( CreateErrorMsgString( utl::Bootstrap::INVALID_BOOTSTRAP_DATA,
2383 OUString() ));
2384 HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_BASE_INSTALL, aMsg );
2385 }
2386
2387 return bOk;
2388 }
2389
FlushConfiguration()2390 void Desktop::FlushConfiguration()
2391 {
2392 Reference < XFlushable > xCFGFlush( ::utl::ConfigManager::GetConfigManager()->GetConfigurationProvider(), UNO_QUERY );
2393 if (xCFGFlush.is())
2394 {
2395 xCFGFlush->flush();
2396 }
2397 else
2398 {
2399 // because there is no method to flush the configuration data, we must dispose the ConfigManager
2400 Reference < XComponent > xCFGDispose( ::utl::ConfigManager::GetConfigManager()->GetConfigurationProvider(), UNO_QUERY );
2401 if (xCFGDispose.is())
2402 xCFGDispose->dispose();
2403 }
2404 }
2405
InitializeQuickstartMode(Reference<XMultiServiceFactory> & rSMgr)2406 sal_Bool Desktop::InitializeQuickstartMode( Reference< XMultiServiceFactory >& rSMgr )
2407 {
2408 try
2409 {
2410 // the shutdown icon sits in the systray and allows the user to keep
2411 // the office instance running for quicker restart
2412 // this will only be activated if -quickstart was specified on cmdline
2413 RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) createInstance com.sun.star.office.Quickstart" );
2414
2415 sal_Bool bQuickstart = GetCommandLineArgs()->IsQuickstart();
2416 if ( !bQuickstart )
2417 {
2418 SfxItemSet aOptSet( SFX_APP()->GetPool(), SID_ATTR_QUICKLAUNCHER, SID_ATTR_QUICKLAUNCHER );
2419 SFX_APP()->GetOptions(aOptSet);
2420 const SfxPoolItem* pItem;
2421 if ( SFX_ITEM_SET == aOptSet.GetItemState( SID_ATTR_QUICKLAUNCHER, sal_False, &pItem ) )
2422 bQuickstart = ((const SfxBoolItem*)pItem)->GetValue();
2423 }
2424
2425 Sequence< Any > aSeq( 1 );
2426 aSeq[0] <<= bQuickstart;
2427
2428 // Try to instanciate quickstart service. This service is not mandatory, so
2429 // do nothing if service is not available
2430
2431 // #i105753# the following if was invented for performance
2432 // unfortunately this broke the QUARTZ behavior which is to always run
2433 // in quickstart mode since Mac applications do not usually quit
2434 // when the last document closes
2435 #ifndef QUARTZ
2436 if ( bQuickstart )
2437 #endif
2438 {
2439 Reference < XComponent > xQuickstart( rSMgr->createInstanceWithArguments(
2440 DEFINE_CONST_UNICODE( "com.sun.star.office.Quickstart" ), aSeq ),
2441 UNO_QUERY );
2442 }
2443 return sal_True;
2444 }
2445 catch( ::com::sun::star::uno::Exception& )
2446 {
2447 return sal_False;
2448 }
2449 }
2450
SystemSettingsChanging(AllSettings & rSettings,Window *)2451 void Desktop::SystemSettingsChanging( AllSettings& rSettings, Window* )
2452 {
2453 if ( !SvtTabAppearanceCfg::IsInitialized () )
2454 return;
2455
2456 # define DRAGFULL_OPTION_ALL \
2457 ( DRAGFULL_OPTION_WINDOWMOVE | DRAGFULL_OPTION_WINDOWSIZE \
2458 | DRAGFULL_OPTION_OBJECTMOVE | DRAGFULL_OPTION_OBJECTSIZE \
2459 | DRAGFULL_OPTION_DOCKING | DRAGFULL_OPTION_SPLIT \
2460 | DRAGFULL_OPTION_SCROLL )
2461 # define DRAGFULL_OPTION_NONE ((sal_uInt32)~DRAGFULL_OPTION_ALL)
2462
2463 StyleSettings hStyleSettings = rSettings.GetStyleSettings();
2464 MouseSettings hMouseSettings = rSettings.GetMouseSettings();
2465
2466 sal_uInt32 nDragFullOptions = hStyleSettings.GetDragFullOptions();
2467
2468 SvtTabAppearanceCfg aAppearanceCfg;
2469 sal_uInt16 nGet = aAppearanceCfg.GetDragMode();
2470 switch ( nGet )
2471 {
2472 case DragFullWindow:
2473 nDragFullOptions |= DRAGFULL_OPTION_ALL;
2474 break;
2475 case DragFrame:
2476 nDragFullOptions &= DRAGFULL_OPTION_NONE;
2477 break;
2478 case DragSystemDep:
2479 default:
2480 break;
2481 }
2482
2483 sal_uInt32 nFollow = hMouseSettings.GetFollow();
2484 hMouseSettings.SetFollow( aAppearanceCfg.IsMenuMouseFollow() ? (nFollow|MOUSE_FOLLOW_MENU) : (nFollow&~MOUSE_FOLLOW_MENU));
2485 rSettings.SetMouseSettings(hMouseSettings);
2486
2487 sal_Bool bUseImagesInMenus = hStyleSettings.GetUseImagesInMenus();
2488
2489 SvtMenuOptions aMenuOpt;
2490 nGet = aMenuOpt.GetMenuIconsState();
2491 switch ( nGet )
2492 {
2493 case 0:
2494 bUseImagesInMenus = sal_False;
2495 break;
2496 case 1:
2497 bUseImagesInMenus = sal_True;
2498 break;
2499 case 2:
2500 default:
2501 break;
2502 }
2503 hStyleSettings.SetUseImagesInMenus(bUseImagesInMenus);
2504
2505 hStyleSettings.SetDragFullOptions( nDragFullOptions );
2506 rSettings.SetStyleSettings ( hStyleSettings );
2507 }
2508
2509 // ========================================================================
IMPL_LINK(Desktop,AsyncInitFirstRun,void *,EMPTYARG)2510 IMPL_LINK( Desktop, AsyncInitFirstRun, void*, EMPTYARG )
2511 {
2512 DoFirstRunInitializations();
2513 return 0L;
2514 }
2515
2516 // ========================================================================
2517
2518 class ExitTimer : public Timer
2519 {
2520 public:
ExitTimer()2521 ExitTimer()
2522 {
2523 SetTimeout(500);
2524 Start();
2525 }
Timeout()2526 virtual void Timeout()
2527 {
2528 exit(42);
2529 }
2530 };
2531
IMPL_LINK(Desktop,OpenClients_Impl,void *,EMPTYARG)2532 IMPL_LINK( Desktop, OpenClients_Impl, void*, EMPTYARG )
2533 {
2534 RTL_LOGFILE_PRODUCT_CONTEXT( aLog, "PERFORMANCE - DesktopOpenClients_Impl()" );
2535
2536 // #114963#
2537 // Enable IPC thread before OpenClients
2538 //
2539 // This is because it is possible for another client to connect during the OpenClients() call.
2540 // This can happen on Windows when document is printed (not opened) and another client wants to print (when printing multiple documents).
2541 // If the IPC thread is enabled after OpenClients, then the client will not be processed because the application will exit after printing. i.e OfficeIPCThread::AreRequestsPending() will always return false
2542 //
2543 // ALSO:
2544 //
2545 // Multiple clients may request simultaneous connections.
2546 // When this server closes down it attempts to recreate the pipe (in DisableOfficeIPCThread()).
2547 // It's possible that the client has a pending connection request.
2548 // When the IPC thread is not running, this connection locks (because maPipe.accept()) is never called
2549 OfficeIPCThread::SetReady();
2550 OpenClients();
2551
2552 // CloseStartupScreen();
2553 CloseSplashScreen();
2554 CheckFirstRun( );
2555 EnableOleAutomation();
2556
2557 if (getenv ("OOO_EXIT_POST_STARTUP"))
2558 new ExitTimer();
2559 return 0;
2560 }
2561
2562 // enable acceptors
IMPL_LINK(Desktop,EnableAcceptors_Impl,void *,EMPTYARG)2563 IMPL_LINK( Desktop, EnableAcceptors_Impl, void*, EMPTYARG )
2564 {
2565 enableAcceptors();
2566 return 0;
2567 }
2568
2569
2570 // Registers a COM class factory of the service manager with the Windows operating system.
EnableOleAutomation()2571 void Desktop::EnableOleAutomation()
2572 {
2573 RTL_LOGFILE_CONTEXT( aLog, "desktop (jl97489) ::Desktop::EnableOleAutomation" );
2574 #ifdef WNT
2575 Reference< XMultiServiceFactory > xSMgr= comphelper::getProcessServiceFactory();
2576 xSMgr->createInstance(DEFINE_CONST_UNICODE("com.sun.star.bridge.OleApplicationRegistration"));
2577 xSMgr->createInstance(DEFINE_CONST_UNICODE("com.sun.star.comp.ole.EmbedServer"));
2578 #endif
2579 }
2580
CheckOEM()2581 sal_Bool Desktop::CheckOEM()
2582 {
2583 Reference<XMultiServiceFactory> rFactory = ::comphelper::getProcessServiceFactory();
2584 Reference<XJob> rOemJob(rFactory->createInstance(
2585 OUString::createFromAscii("com.sun.star.office.OEMPreloadJob")),
2586 UNO_QUERY );
2587 Sequence<NamedValue> args;
2588 sal_Bool bResult = sal_False;
2589 if (rOemJob.is()) {
2590 Any aResult = rOemJob->execute(args);
2591 aResult >>= bResult;
2592 return bResult;
2593 } else {
2594 return sal_True;
2595 }
2596 }
2597
PreloadModuleData(CommandLineArgs * pArgs)2598 void Desktop::PreloadModuleData( CommandLineArgs* pArgs )
2599 {
2600 Reference< XMultiServiceFactory > rFactory = ::comphelper::getProcessServiceFactory();
2601
2602 Sequence < com::sun::star::beans::PropertyValue > args(1);
2603 args[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Hidden"));
2604 args[0].Value <<= sal_True;
2605 Reference < XComponentLoader > xLoader( ::comphelper::getProcessServiceFactory()->createInstance(
2606 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ), UNO_QUERY );
2607
2608 if ( !xLoader.is() )
2609 return;
2610
2611 if ( pArgs->IsWriter() )
2612 {
2613 try
2614 {
2615 Reference < ::com::sun::star::util::XCloseable > xDoc( xLoader->loadComponentFromURL( DEFINE_CONST_UNICODE("private:factory/swriter"),
2616 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_blank")), 0, args ), UNO_QUERY_THROW );
2617 xDoc->close( sal_False );
2618 }
2619 catch ( com::sun::star::uno::Exception& )
2620 {
2621 }
2622 }
2623 if ( pArgs->IsCalc() )
2624 {
2625 try
2626 {
2627 Reference < ::com::sun::star::util::XCloseable > xDoc( xLoader->loadComponentFromURL( DEFINE_CONST_UNICODE("private:factory/scalc"),
2628 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_blank")), 0, args ), UNO_QUERY_THROW );
2629 xDoc->close( sal_False );
2630 }
2631 catch ( com::sun::star::uno::Exception& )
2632 {
2633 }
2634 }
2635 if ( pArgs->IsDraw() )
2636 {
2637 try
2638 {
2639 Reference < ::com::sun::star::util::XCloseable > xDoc( xLoader->loadComponentFromURL( DEFINE_CONST_UNICODE("private:factory/sdraw"),
2640 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_blank")), 0, args ), UNO_QUERY_THROW );
2641 xDoc->close( sal_False );
2642 }
2643 catch ( com::sun::star::uno::Exception& )
2644 {
2645 }
2646 }
2647 if ( pArgs->IsImpress() )
2648 {
2649 try
2650 {
2651 Reference < ::com::sun::star::util::XCloseable > xDoc( xLoader->loadComponentFromURL( DEFINE_CONST_UNICODE("private:factory/simpress"),
2652 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_blank")), 0, args ), UNO_QUERY_THROW );
2653 xDoc->close( sal_False );
2654 }
2655 catch ( com::sun::star::uno::Exception& )
2656 {
2657 }
2658 }
2659 }
2660
PreloadConfigurationData()2661 void Desktop::PreloadConfigurationData()
2662 {
2663 Reference< XMultiServiceFactory > rFactory = ::comphelper::getProcessServiceFactory();
2664 Reference< XNameAccess > xNameAccess( rFactory->createInstance(
2665 DEFINE_CONST_UNICODE( "com.sun.star.frame.UICommandDescription" )), UNO_QUERY );
2666
2667 rtl::OUString aWriterDoc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.TextDocument" ));
2668 rtl::OUString aCalcDoc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.SpreadsheetDocument" ));
2669 rtl::OUString aDrawDoc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.DrawingDocument" ));
2670 rtl::OUString aImpressDoc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.PresentationDocument" ));
2671
2672 // preload commands configuration
2673 if ( xNameAccess.is() )
2674 {
2675 Any a;
2676 Reference< XNameAccess > xCmdAccess;
2677
2678 try
2679 {
2680 a = xNameAccess->getByName( aWriterDoc );
2681 a >>= xCmdAccess;
2682 if ( xCmdAccess.is() )
2683 {
2684 xCmdAccess->getByName( DEFINE_CONST_UNICODE( ".uno:BasicShapes" ));
2685 xCmdAccess->getByName( DEFINE_CONST_UNICODE( ".uno:EditGlossary" ));
2686 }
2687 }
2688 catch ( ::com::sun::star::uno::Exception& )
2689 {
2690 }
2691
2692 try
2693 {
2694 a = xNameAccess->getByName( aCalcDoc );
2695 a >>= xCmdAccess;
2696 if ( xCmdAccess.is() )
2697 xCmdAccess->getByName( DEFINE_CONST_UNICODE( ".uno:InsertObjectStarMath" ));
2698 }
2699 catch ( ::com::sun::star::uno::Exception& )
2700 {
2701 }
2702
2703 try
2704 {
2705 // draw and impress share the same configuration file (DrawImpressCommands.xcu)
2706 a = xNameAccess->getByName( aDrawDoc );
2707 a >>= xCmdAccess;
2708 if ( xCmdAccess.is() )
2709 xCmdAccess->getByName( DEFINE_CONST_UNICODE( ".uno:Polygon" ));
2710 }
2711 catch ( ::com::sun::star::uno::Exception& )
2712 {
2713 }
2714 }
2715
2716 // preload window state configuration
2717 xNameAccess = Reference< XNameAccess >( rFactory->createInstance(
2718 DEFINE_CONST_UNICODE( "com.sun.star.ui.WindowStateConfiguration" )), UNO_QUERY );
2719 if ( xNameAccess.is() )
2720 {
2721 Any a;
2722 Reference< XNameAccess > xWindowAccess;
2723 try
2724 {
2725 a = xNameAccess->getByName( aWriterDoc );
2726 a >>= xWindowAccess;
2727 if ( xWindowAccess.is() )
2728 xWindowAccess->getByName( DEFINE_CONST_UNICODE( "private:resource/toolbar/standardbar" ));
2729 }
2730 catch ( ::com::sun::star::uno::Exception& )
2731 {
2732 }
2733 try
2734 {
2735 a = xNameAccess->getByName( aCalcDoc );
2736 a >>= xWindowAccess;
2737 if ( xWindowAccess.is() )
2738 xWindowAccess->getByName( DEFINE_CONST_UNICODE( "private:resource/toolbar/standardbar" ));
2739 }
2740 catch ( ::com::sun::star::uno::Exception& )
2741 {
2742 }
2743 try
2744 {
2745 a = xNameAccess->getByName( aDrawDoc );
2746 a >>= xWindowAccess;
2747 if ( xWindowAccess.is() )
2748 xWindowAccess->getByName( DEFINE_CONST_UNICODE( "private:resource/toolbar/standardbar" ));
2749 }
2750 catch ( ::com::sun::star::uno::Exception& )
2751 {
2752 }
2753 try
2754 {
2755 a = xNameAccess->getByName( aImpressDoc );
2756 a >>= xWindowAccess;
2757 if ( xWindowAccess.is() )
2758 xWindowAccess->getByName( DEFINE_CONST_UNICODE( "private:resource/toolbar/standardbar" ));
2759 }
2760 catch ( ::com::sun::star::uno::Exception& )
2761 {
2762 }
2763 }
2764
2765 // preload user interface element factories
2766 Sequence< Sequence< css::beans::PropertyValue > > aSeqSeqPropValue;
2767 Reference< ::com::sun::star::ui::XUIElementFactoryRegistration > xUIElementFactory(
2768 rFactory->createInstance(
2769 DEFINE_CONST_UNICODE( "com.sun.star.ui.UIElementFactoryManager" )),
2770 UNO_QUERY );
2771 if ( xUIElementFactory.is() )
2772 {
2773 try
2774 {
2775 aSeqSeqPropValue = xUIElementFactory->getRegisteredFactories();
2776 }
2777 catch ( ::com::sun::star::uno::Exception& )
2778 {
2779 }
2780 }
2781
2782 // preload popup menu controller factories. As all controllers are in the same
2783 // configuration file they also get preloaded!
2784 Reference< ::com::sun::star::frame::XUIControllerRegistration > xPopupMenuControllerFactory(
2785 rFactory->createInstance(
2786 DEFINE_CONST_UNICODE( "com.sun.star.frame.PopupMenuControllerFactory" )),
2787 UNO_QUERY );
2788 if ( xPopupMenuControllerFactory.is() )
2789 {
2790 try
2791 {
2792 xPopupMenuControllerFactory->hasController(
2793 DEFINE_CONST_UNICODE( ".uno:CharFontName" ),
2794 OUString() );
2795 }
2796 catch ( ::com::sun::star::uno::Exception& )
2797 {
2798 }
2799 }
2800
2801 // preload filter configuration
2802 Sequence< OUString > aSeq;
2803 xNameAccess = Reference< XNameAccess >( rFactory->createInstance(
2804 DEFINE_CONST_UNICODE( "com.sun.star.document.FilterFactory" )), UNO_QUERY );
2805 if ( xNameAccess.is() )
2806 {
2807 try
2808 {
2809 aSeq = xNameAccess->getElementNames();
2810 }
2811 catch ( ::com::sun::star::uno::Exception& )
2812 {
2813 }
2814 }
2815
2816 // preload type detection configuration
2817 xNameAccess = Reference< XNameAccess >( rFactory->createInstance(
2818 DEFINE_CONST_UNICODE( "com.sun.star.document.TypeDetection" )), UNO_QUERY );
2819 if ( xNameAccess.is() )
2820 {
2821 try
2822 {
2823 aSeq = xNameAccess->getElementNames();
2824 }
2825 catch ( ::com::sun::star::uno::Exception& )
2826 {
2827 }
2828 }
2829
2830 static const OUString sConfigSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ) );
2831 static const OUString sAccessSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationAccess" ) );
2832
2833 // get configuration provider
2834 Reference< XMultiServiceFactory > xConfigProvider;
2835 xConfigProvider = Reference< XMultiServiceFactory > (
2836 rFactory->createInstance( sConfigSrvc ),UNO_QUERY );
2837
2838 if ( xConfigProvider.is() )
2839 {
2840 // preload writer configuration
2841 Sequence< Any > theArgs(1);
2842 theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.Writer/MailMergeWizard" );
2843 try
2844 {
2845 xNameAccess = Reference< XNameAccess >(
2846 xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
2847 }
2848 catch (::com::sun::star::uno::Exception& )
2849 {
2850 }
2851
2852 // WriterWeb
2853 theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.WriterWeb/Content" );
2854 try
2855 {
2856 xNameAccess = Reference< XNameAccess >(
2857 xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
2858 }
2859 catch (::com::sun::star::uno::Exception& )
2860 {
2861 }
2862
2863 // preload compatibility
2864 theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.Compatibility/WriterCompatibilityVersion" );
2865 try
2866 {
2867 xNameAccess = Reference< XNameAccess >(
2868 xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
2869 }
2870 catch (::com::sun::star::uno::Exception& )
2871 {
2872 }
2873
2874 // preload calc configuration
2875 theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.Calc/Content" );
2876 try
2877 {
2878 xNameAccess = Reference< XNameAccess >(
2879 xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
2880 }
2881 catch (::com::sun::star::uno::Exception& )
2882 {
2883 }
2884
2885 // preload impress configuration
2886 theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.UI.Effects/UserInterface" );
2887 try
2888 {
2889 xNameAccess = Reference< XNameAccess >(
2890 xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
2891 }
2892 catch (::com::sun::star::uno::Exception& )
2893 {
2894 }
2895
2896 theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.Impress/Layout" );
2897 try
2898 {
2899 xNameAccess = Reference< XNameAccess >(
2900 xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
2901 }
2902 catch (::com::sun::star::uno::Exception& )
2903 {
2904 }
2905
2906 // preload draw configuration
2907 theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.Draw/Layout" );
2908 try
2909 {
2910 xNameAccess = Reference< XNameAccess >(
2911 xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
2912 }
2913 catch (::com::sun::star::uno::Exception& )
2914 {
2915 }
2916
2917 // preload ui configuration
2918 theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.UI/FilterClassification" );
2919 try
2920 {
2921 xNameAccess = Reference< XNameAccess >(
2922 xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
2923 }
2924 catch (::com::sun::star::uno::Exception& )
2925 {
2926 }
2927
2928 // preload addons configuration
2929 theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.Addons/AddonUI" );
2930 try
2931 {
2932 xNameAccess = Reference< XNameAccess >(
2933 xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
2934 }
2935 catch (::com::sun::star::uno::Exception& )
2936 {
2937 }
2938 }
2939 }
2940
OpenClients()2941 void Desktop::OpenClients()
2942 {
2943
2944 // check if a document has been recovered - if there is one or if a document was loaded by cmdline, no default document
2945 // should be created
2946 Reference < XComponent > xFirst;
2947 sal_Bool bLoaded = sal_False;
2948
2949 CommandLineArgs* pArgs = GetCommandLineArgs();
2950 SvtInternalOptions aInternalOptions;
2951
2952 Reference<XMultiServiceFactory> rFactory = ::comphelper::getProcessServiceFactory();
2953
2954 if (!pArgs->IsQuickstart()) {
2955 sal_Bool bShowHelp = sal_False;
2956 ::rtl::OUStringBuffer aHelpURLBuffer;
2957 if (pArgs->IsHelpWriter()) {
2958 bShowHelp = sal_True;
2959 aHelpURLBuffer.appendAscii("vnd.sun.star.help://swriter/start");
2960 } else if (pArgs->IsHelpCalc()) {
2961 bShowHelp = sal_True;
2962 aHelpURLBuffer.appendAscii("vnd.sun.star.help://scalc/start");
2963 } else if (pArgs->IsHelpDraw()) {
2964 bShowHelp = sal_True;
2965 aHelpURLBuffer.appendAscii("vnd.sun.star.help://sdraw/start");
2966 } else if (pArgs->IsHelpImpress()) {
2967 bShowHelp = sal_True;
2968 aHelpURLBuffer.appendAscii("vnd.sun.star.help://simpress/start");
2969 } else if (pArgs->IsHelpBase()) {
2970 bShowHelp = sal_True;
2971 aHelpURLBuffer.appendAscii("vnd.sun.star.help://sdatabase/start");
2972 } else if (pArgs->IsHelpBasic()) {
2973 bShowHelp = sal_True;
2974 aHelpURLBuffer.appendAscii("vnd.sun.star.help://sbasic/start");
2975 } else if (pArgs->IsHelpMath()) {
2976 bShowHelp = sal_True;
2977 aHelpURLBuffer.appendAscii("vnd.sun.star.help://smath/start");
2978 }
2979 if (bShowHelp) {
2980 Help *pHelp = Application::GetHelp();
2981
2982 Any aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::LOCALE );
2983 rtl::OUString aTmp;
2984 aRet >>= aTmp;
2985 aHelpURLBuffer.appendAscii("?Language=");
2986 aHelpURLBuffer.append(aTmp);
2987 #if defined UNX
2988 aHelpURLBuffer.appendAscii("&System=UNX");
2989 #elif defined WNT
2990 aHelpURLBuffer.appendAscii("&System=WIN");
2991 #elif defined OS2
2992 aHelpURLBuffer.appendAscii("&System=OS2");
2993 #endif
2994 pHelp->Start(aHelpURLBuffer.makeStringAndClear(), NULL);
2995 return;
2996 }
2997 }
2998 else
2999 {
3000 OUString aIniName;
3001 ::vos::OStartupInfo aInfo;
3002
3003 aInfo.getExecutableFile( aIniName );
3004 sal_uInt32 lastIndex = aIniName.lastIndexOf('/');
3005 if ( lastIndex > 0 )
3006 {
3007 aIniName = aIniName.copy( 0, lastIndex+1 );
3008 aIniName += OUString( RTL_CONSTASCII_USTRINGPARAM( "perftune" ));
3009 #if defined(WNT) || defined(OS2)
3010 aIniName += OUString( RTL_CONSTASCII_USTRINGPARAM( ".ini" ));
3011 #else
3012 aIniName += OUString( RTL_CONSTASCII_USTRINGPARAM( "rc" ));
3013 #endif
3014 }
3015
3016 rtl::Bootstrap aPerfTuneIniFile( aIniName );
3017
3018 OUString aDefault( RTL_CONSTASCII_USTRINGPARAM( "0" ));
3019 OUString aPreloadData;
3020
3021 aPerfTuneIniFile.getFrom( OUString( RTL_CONSTASCII_USTRINGPARAM( "QuickstartPreloadConfiguration" )), aPreloadData, aDefault );
3022 if ( aPreloadData.equalsAscii( "1" ))
3023 {
3024 if ( pArgs->IsWriter() ||
3025 pArgs->IsCalc() ||
3026 pArgs->IsDraw() ||
3027 pArgs->IsImpress() )
3028 {
3029 PreloadModuleData( pArgs );
3030 }
3031
3032 PreloadConfigurationData();
3033 }
3034 }
3035
3036 // Disable AutoSave feature in case "-norestore" or a similare command line switch is set on the command line.
3037 // The reason behind: AutoSave/EmergencySave/AutoRecovery share the same data.
3038 // But the require that all documents, which are saved as backup should exists inside
3039 // memory. May be this mechanism will be inconsistent if the configuration exists ...
3040 // but no document inside memory corrspond to this data.
3041 // Furter it's not acceptable to recover such documents without any UI. It can
3042 // need some time, where the user won't see any results and wait for finishing the office startup ...
3043 sal_Bool bAllowRecoveryAndSessionManagement = (
3044 ( !pArgs->IsNoRestore() ) &&
3045 ( !pArgs->IsHeadless() ) &&
3046 ( !pArgs->IsServer() )
3047 );
3048
3049 if ( ! bAllowRecoveryAndSessionManagement )
3050 {
3051 try
3052 {
3053 Reference< XDispatch > xRecovery(
3054 ::comphelper::getProcessServiceFactory()->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.AutoRecovery")) ),
3055 ::com::sun::star::uno::UNO_QUERY_THROW );
3056
3057 Reference< XURLTransformer > xParser(
3058 ::comphelper::getProcessServiceFactory()->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer")) ),
3059 ::com::sun::star::uno::UNO_QUERY_THROW );
3060
3061 css::util::URL aCmd;
3062 aCmd.Complete = ::rtl::OUString::createFromAscii("vnd.sun.star.autorecovery:/disableRecovery");
3063 xParser->parseStrict(aCmd);
3064
3065 xRecovery->dispatch(aCmd, css::uno::Sequence< css::beans::PropertyValue >());
3066 }
3067 catch(const css::uno::Exception& e)
3068 {
3069 OUString aMessage = OUString::createFromAscii("Could not disable AutoRecovery.\n")
3070 + e.Message;
3071 OSL_ENSURE(sal_False, OUStringToOString(aMessage, RTL_TEXTENCODING_ASCII_US).getStr());
3072 }
3073 }
3074 else
3075 {
3076 sal_Bool bCrashed = sal_False;
3077 sal_Bool bExistsRecoveryData = sal_False;
3078 sal_Bool bExistsSessionData = sal_False;
3079
3080 impl_checkRecoveryState(bCrashed, bExistsRecoveryData, bExistsSessionData);
3081
3082 if ( !getenv ("OOO_DISABLE_RECOVERY") &&
3083 ( ! bLoaded ) &&
3084 (
3085 ( bExistsRecoveryData ) || // => crash with files => recovery
3086 ( bCrashed ) // => crash without files => error report
3087 )
3088 )
3089 {
3090 try
3091 {
3092 impl_callRecoveryUI(
3093 sal_False , // false => force recovery instead of emergency save
3094 bCrashed ,
3095 bExistsRecoveryData);
3096 /* TODO we can't be sure, that at least one document could be recovered here successfully
3097 So we set bLoaded=sal_True to suppress opening of the default document.
3098 But we should make it more safe. Otherwise we have an office without an UI ...
3099 ...
3100 Maybe we can check the desktop if some documents are existing there.
3101 */
3102 Reference< XFramesSupplier > xTasksSupplier(
3103 ::comphelper::getProcessServiceFactory()->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
3104 ::com::sun::star::uno::UNO_QUERY_THROW );
3105 Reference< XElementAccess > xList( xTasksSupplier->getFrames(), UNO_QUERY_THROW );
3106 if ( xList->hasElements() )
3107 bLoaded = sal_True;
3108 }
3109 catch(const css::uno::Exception& e)
3110 {
3111 OUString aMessage = OUString::createFromAscii("Error during recovery\n")
3112 + e.Message;
3113 OSL_ENSURE(sal_False, OUStringToOString(aMessage, RTL_TEXTENCODING_ASCII_US).getStr());
3114 }
3115 }
3116
3117 Reference< XInitialization > xSessionListener;
3118 try
3119 {
3120 xSessionListener = Reference< XInitialization >(::comphelper::getProcessServiceFactory()->createInstance(
3121 OUString::createFromAscii("com.sun.star.frame.SessionListener")), UNO_QUERY_THROW);
3122
3123 // specifies whether the UI-interaction on Session shutdown is allowed
3124 sal_Bool bAllowUI = isUIOnSessionShutdownAllowed();
3125 css::beans::NamedValue aProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AllowUserInteractionOnQuit" ) ),
3126 css::uno::makeAny( bAllowUI ) );
3127 css::uno::Sequence< css::uno::Any > aArgs( 1 );
3128 aArgs[0] <<= aProperty;
3129
3130 xSessionListener->initialize( aArgs );
3131 }
3132 catch(const com::sun::star::uno::Exception& e)
3133 {
3134 OUString aMessage = OUString::createFromAscii("Registration of session listener failed\n")
3135 + e.Message;
3136 OSL_ENSURE(sal_False, OUStringToOString(aMessage, RTL_TEXTENCODING_ASCII_US).getStr());
3137 }
3138
3139 if (
3140 ( ! bLoaded ) &&
3141 ( bExistsSessionData )
3142 )
3143 {
3144 // session management
3145 try
3146 {
3147 Reference< XSessionManagerListener > r(xSessionListener, UNO_QUERY_THROW);
3148 bLoaded = r->doRestore();
3149 }
3150 catch(const com::sun::star::uno::Exception& e)
3151 {
3152 OUString aMessage = OUString::createFromAscii("Error in session management\n")
3153 + e.Message;
3154 OSL_ENSURE(sal_False, OUStringToOString(aMessage, RTL_TEXTENCODING_ASCII_US).getStr());
3155 }
3156 }
3157 }
3158
3159 OfficeIPCThread::EnableRequests();
3160
3161 sal_Bool bShutdown( sal_False );
3162 if ( !pArgs->IsServer() )
3163 {
3164 ProcessDocumentsRequest aRequest(pArgs->getCwdUrl());
3165 aRequest.pcProcessed = NULL;
3166
3167 pArgs->GetOpenList( aRequest.aOpenList );
3168 pArgs->GetViewList( aRequest.aViewList );
3169 pArgs->GetStartList( aRequest.aStartList );
3170 pArgs->GetPrintList( aRequest.aPrintList );
3171 pArgs->GetPrintToList( aRequest.aPrintToList );
3172 pArgs->GetPrinterName( aRequest.aPrinterName );
3173 pArgs->GetForceOpenList( aRequest.aForceOpenList );
3174 pArgs->GetForceNewList( aRequest.aForceNewList );
3175
3176 if ( aRequest.aOpenList.getLength() > 0 ||
3177 aRequest.aViewList.getLength() > 0 ||
3178 aRequest.aStartList.getLength() > 0 ||
3179 aRequest.aPrintList.getLength() > 0 ||
3180 aRequest.aForceOpenList.getLength() > 0 ||
3181 aRequest.aForceNewList.getLength() > 0 ||
3182 ( aRequest.aPrintToList.getLength() > 0 && aRequest.aPrinterName.getLength() > 0 ))
3183 {
3184 bLoaded = sal_True;
3185
3186 if ( pArgs->HasModuleParam() )
3187 {
3188 SvtModuleOptions aOpt;
3189
3190 // Support command line parameters to start a module (as preselection)
3191 if ( pArgs->IsWriter() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
3192 aRequest.aModule = aOpt.GetFactoryName( SvtModuleOptions::E_WRITER );
3193 else if ( pArgs->IsCalc() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) )
3194 aRequest.aModule = aOpt.GetFactoryName( SvtModuleOptions::E_CALC );
3195 else if ( pArgs->IsImpress() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) )
3196 aRequest.aModule= aOpt.GetFactoryName( SvtModuleOptions::E_IMPRESS );
3197 else if ( pArgs->IsDraw() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) )
3198 aRequest.aModule= aOpt.GetFactoryName( SvtModuleOptions::E_DRAW );
3199 }
3200
3201 // check for printing disabled
3202 if( ( aRequest.aPrintList.getLength() || aRequest.aPrintToList.getLength() )
3203 && Application::GetSettings().GetMiscSettings().GetDisablePrinting() )
3204 {
3205 aRequest.aPrintList = rtl::OUString();
3206 aRequest.aPrintToList = rtl::OUString();
3207 ResMgr* pDtResMgr = GetDesktopResManager();
3208 if( pDtResMgr )
3209 {
3210 ErrorBox aBox( NULL, ResId( EBX_ERR_PRINTDISABLED, *pDtResMgr ) );
3211 aBox.Execute();
3212 }
3213 }
3214
3215 // Process request
3216 bShutdown = OfficeIPCThread::ExecuteCmdLineRequests( aRequest );
3217 }
3218 }
3219
3220 // Don't do anything if we have successfully called terminate at desktop
3221 if ( bShutdown )
3222 return;
3223
3224 // no default document if a document was loaded by recovery or by command line or if soffice is used as server
3225 Reference< XFramesSupplier > xTasksSupplier(
3226 ::comphelper::getProcessServiceFactory()->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
3227 ::com::sun::star::uno::UNO_QUERY_THROW );
3228 Reference< XElementAccess > xList( xTasksSupplier->getFrames(), UNO_QUERY_THROW );
3229 if ( xList->hasElements() || pArgs->IsServer() )
3230 return;
3231
3232 if ( pArgs->IsQuickstart() || pArgs->IsInvisible() || pArgs->IsBean() || Application::AnyInput( INPUT_APPEVENT ) )
3233 // soffice was started as tray icon ...
3234 return;
3235 {
3236 OpenDefault();
3237 }
3238 }
3239
OpenDefault()3240 void Desktop::OpenDefault()
3241 {
3242
3243 RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::OpenDefault" );
3244
3245 ::rtl::OUString aName;
3246 SvtModuleOptions aOpt;
3247
3248 CommandLineArgs* pArgs = GetCommandLineArgs();
3249 if ( pArgs->IsNoDefault() ) return;
3250 if ( pArgs->HasModuleParam() )
3251 {
3252 // Support new command line parameters to start a module
3253 if ( pArgs->IsWriter() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
3254 aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_WRITER );
3255 else if ( pArgs->IsCalc() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) )
3256 aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_CALC );
3257 else if ( pArgs->IsImpress() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) )
3258 aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_IMPRESS );
3259 else if ( pArgs->IsBase() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
3260 aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_DATABASE );
3261 else if ( pArgs->IsDraw() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) )
3262 aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_DRAW );
3263 else if ( pArgs->IsMath() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SMATH ) )
3264 aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_MATH );
3265 else if ( pArgs->IsGlobal() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
3266 aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_WRITERGLOBAL );
3267 else if ( pArgs->IsWeb() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
3268 aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_WRITERWEB );
3269 }
3270
3271 if ( !aName.getLength() )
3272 {
3273 // Old way to create a default document
3274 if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
3275 aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_WRITER );
3276 else if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) )
3277 aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_CALC );
3278 else if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) )
3279 aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_IMPRESS );
3280 else if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
3281 aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_DATABASE );
3282 else if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) )
3283 aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_DRAW );
3284 else
3285 return;
3286 }
3287
3288 ProcessDocumentsRequest aRequest(pArgs->getCwdUrl());
3289 aRequest.pcProcessed = NULL;
3290 aRequest.aOpenList = aName;
3291 OfficeIPCThread::ExecuteCmdLineRequests( aRequest );
3292 }
3293
3294
GetURL_Impl(const String & rName,boost::optional<rtl::OUString> const & cwdUrl)3295 String GetURL_Impl(
3296 const String& rName, boost::optional< rtl::OUString > const & cwdUrl )
3297 {
3298 // if rName is a vnd.sun.star.script URL do not attempt to parse it
3299 // as INetURLObj does not handle their URLs
3300 if (rName.CompareToAscii("vnd.sun.star.script" , 19) == COMPARE_EQUAL)
3301 {
3302 return rName;
3303 }
3304
3305 // don't touch file urls, those should already be in internal form
3306 // they won't get better here (#112849#)
3307 if (rName.CompareToAscii("file:" , 5) == COMPARE_EQUAL)
3308 {
3309 return rName;
3310 }
3311
3312 if ( rName.CompareToAscii("service:" , 8) == COMPARE_EQUAL )
3313 {
3314 return rName;
3315 }
3316
3317 // Add path seperator to these directory and make given URL (rName) absolute by using of current working directory
3318 // Attention: "setFianlSlash()" is necessary for calling "smartRel2Abs()"!!!
3319 // Otherwise last part will be ignored and wrong result will be returned!!!
3320 // "smartRel2Abs()" interpret given URL as file not as path. So he truncate last element to get the base path ...
3321 // But if we add a seperator - he doesn't do it anymore.
3322 INetURLObject aObj;
3323 if (cwdUrl) {
3324 aObj.SetURL(*cwdUrl);
3325 aObj.setFinalSlash();
3326 }
3327
3328 // Use the provided parameters for smartRel2Abs to support the usage of '%' in system paths.
3329 // Otherwise this char won't get encoded and we are not able to load such files later,
3330 // see #110156#
3331 bool bWasAbsolute;
3332 INetURLObject aURL = aObj.smartRel2Abs( rName, bWasAbsolute, false, INetURLObject::WAS_ENCODED,
3333 RTL_TEXTENCODING_UTF8, true );
3334 String aFileURL = aURL.GetMainURL(INetURLObject::NO_DECODE);
3335
3336 ::osl::FileStatus aStatus( FileStatusMask_FileURL );
3337 ::osl::DirectoryItem aItem;
3338 if( ::osl::FileBase::E_None == ::osl::DirectoryItem::get( aFileURL, aItem ) &&
3339 ::osl::FileBase::E_None == aItem.getFileStatus( aStatus ) )
3340 aFileURL = aStatus.getFileURL();
3341
3342 return aFileURL;
3343 }
3344
HandleAppEvent(const ApplicationEvent & rAppEvent)3345 void Desktop::HandleAppEvent( const ApplicationEvent& rAppEvent )
3346 {
3347 if ( rAppEvent.GetEvent() == "APPEAR" && !GetCommandLineArgs()->IsInvisible() )
3348 {
3349 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
3350
3351 // find active task - the active task is always a visible task
3352 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFramesSupplier >
3353 xDesktop( xSMGR->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
3354 ::com::sun::star::uno::UNO_QUERY );
3355 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xTask = xDesktop->getActiveFrame();
3356 if ( !xTask.is() )
3357 {
3358 // get any task if there is no active one
3359 ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess > xList( xDesktop->getFrames(), ::com::sun::star::uno::UNO_QUERY );
3360 if ( xList->getCount()>0 )
3361 xList->getByIndex(0) >>= xTask;
3362 }
3363
3364 if ( xTask.is() )
3365 {
3366 Reference< com::sun::star::awt::XTopWindow > xTop( xTask->getContainerWindow(), UNO_QUERY );
3367 xTop->toFront();
3368 }
3369 else
3370 {
3371 // no visible task that could be activated found
3372 Reference< XFrame > xBackingFrame;
3373 Reference< ::com::sun::star::awt::XWindow > xContainerWindow;
3374 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xDesktopFrame( xDesktop, UNO_QUERY );
3375
3376 xBackingFrame = xDesktopFrame->findFrame(OUString( RTL_CONSTASCII_USTRINGPARAM( "_blank" )), 0);
3377 if (xBackingFrame.is())
3378 xContainerWindow = xBackingFrame->getContainerWindow();
3379 if (xContainerWindow.is())
3380 {
3381 Sequence< Any > lArgs(1);
3382 lArgs[0] <<= xContainerWindow;
3383 Reference< XController > xBackingComp(
3384 xSMGR->createInstanceWithArguments(OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.StartModule") ), lArgs),
3385 UNO_QUERY);
3386 if (xBackingComp.is())
3387 {
3388 Reference< ::com::sun::star::awt::XWindow > xBackingWin(xBackingComp, UNO_QUERY);
3389 // Attention: You MUST(!) call setComponent() before you call attachFrame().
3390 // Because the backing component set the property "IsBackingMode" of the frame
3391 // to true inside attachFrame(). But setComponent() reset this state everytimes ...
3392 xBackingFrame->setComponent(xBackingWin, xBackingComp);
3393 xBackingComp->attachFrame(xBackingFrame);
3394 xContainerWindow->setVisible(sal_True);
3395
3396 Window* pCompWindow = VCLUnoHelper::GetWindow(xBackingFrame->getComponentWindow());
3397 if (pCompWindow)
3398 pCompWindow->Update();
3399 }
3400 }
3401 }
3402 }
3403 else if ( rAppEvent.GetEvent() == "QUICKSTART" && !GetCommandLineArgs()->IsInvisible() )
3404 {
3405 // If the office has been started the second time its command line arguments are sent through a pipe
3406 // connection to the first office. We want to reuse the quickstart option for the first office.
3407 // NOTICE: The quickstart service must be initialized inside the "main thread", so we use the
3408 // application events to do this (they are executed inside main thread)!!!
3409 // Don't start quickstart service if the user specified "-invisible" on the command line!
3410 sal_Bool bQuickstart( sal_True );
3411 Sequence< Any > aSeq( 1 );
3412 aSeq[0] <<= bQuickstart;
3413
3414 Reference < XInitialization > xQuickstart( ::comphelper::getProcessServiceFactory()->createInstance(
3415 DEFINE_CONST_UNICODE( "com.sun.star.office.Quickstart" )),
3416 UNO_QUERY );
3417 if ( xQuickstart.is() )
3418 xQuickstart->initialize( aSeq );
3419 }
3420 else if ( rAppEvent.GetEvent() == "ACCEPT" )
3421 {
3422 // every time an accept parameter is used we create an acceptor
3423 // with the corresponding accept-string
3424 OUString aAcceptString(rAppEvent.GetData().GetBuffer());
3425 createAcceptor(aAcceptString);
3426 }
3427 else if ( rAppEvent.GetEvent() == "UNACCEPT" )
3428 {
3429 // try to remove corresponding acceptor
3430 OUString aUnAcceptString(rAppEvent.GetData().GetBuffer());
3431 destroyAcceptor(aUnAcceptString);
3432 }
3433 else if ( rAppEvent.GetEvent() == "SaveDocuments" )
3434 {
3435 Desktop::_bTasksSaved = sal_False;
3436 Desktop::_bTasksSaved = SaveTasks();
3437 }
3438 else if ( rAppEvent.GetEvent() == "OPENHELPURL" )
3439 {
3440 // start help for a specific URL
3441 OUString aHelpURL(rAppEvent.GetData().GetBuffer());
3442 Help *pHelp = Application::GetHelp();
3443 pHelp->Start(aHelpURL, NULL);
3444 }
3445 else if ( rAppEvent.GetEvent() == APPEVENT_OPEN_STRING )
3446 {
3447 OUString aOpenURL(rAppEvent.GetData().GetBuffer());
3448
3449 CommandLineArgs* pCmdLine = GetCommandLineArgs();
3450 if ( !pCmdLine->IsInvisible() && !pCmdLine->IsTerminateAfterInit() )
3451 {
3452 ProcessDocumentsRequest* pDocsRequest = new ProcessDocumentsRequest(
3453 pCmdLine->getCwdUrl());
3454 pDocsRequest->aOpenList = aOpenURL;
3455 pDocsRequest->pcProcessed = NULL;
3456
3457 OfficeIPCThread::ExecuteCmdLineRequests( *pDocsRequest );
3458 delete pDocsRequest;
3459 }
3460 }
3461 else if ( rAppEvent.GetEvent() == APPEVENT_PRINT_STRING )
3462 {
3463 OUString aPrintURL(rAppEvent.GetData().GetBuffer());
3464
3465 CommandLineArgs* pCmdLine = GetCommandLineArgs();
3466 if ( !pCmdLine->IsInvisible() && !pCmdLine->IsTerminateAfterInit() )
3467 {
3468 ProcessDocumentsRequest* pDocsRequest = new ProcessDocumentsRequest(
3469 pCmdLine->getCwdUrl());
3470 pDocsRequest->aPrintList = aPrintURL;
3471 pDocsRequest->pcProcessed = NULL;
3472
3473 OfficeIPCThread::ExecuteCmdLineRequests( *pDocsRequest );
3474 delete pDocsRequest;
3475 }
3476 }
3477 #ifndef UNX
3478 else if ( rAppEvent.GetEvent() == "HELP" )
3479 {
3480 // in non unix version allow showing of cmdline help window
3481 displayCmdlineHelp();
3482 }
3483 #endif
3484 else if ( rAppEvent.GetEvent() == "SHOWDIALOG" )
3485 {
3486 // ignore all errors here. It's clicking a menu entry only ...
3487 // The user will try it again, in case nothing happens .-)
3488 try
3489 {
3490 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
3491
3492 com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider >
3493 xDesktop( xSMGR->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
3494 ::com::sun::star::uno::UNO_QUERY );
3495
3496 // check provider ... we know it's weak reference only
3497 if ( ! xDesktop.is())
3498 return;
3499
3500 css::uno::Reference< css::util::XURLTransformer > xParser(xSMGR->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer"))), css::uno::UNO_QUERY_THROW);
3501 css::util::URL aCommand;
3502 if( rAppEvent.GetData().EqualsAscii( "PREFERENCES" ) )
3503 aCommand.Complete = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:OptionsTreeDialog" ) );
3504 else if( rAppEvent.GetData().EqualsAscii( "ABOUT" ) )
3505 aCommand.Complete = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:About" ) );
3506 if( aCommand.Complete.getLength() )
3507 {
3508 xParser->parseStrict(aCommand);
3509
3510 css::uno::Reference< css::frame::XDispatch > xDispatch = xDesktop->queryDispatch(aCommand, rtl::OUString(), 0);
3511 if (xDispatch.is())
3512 xDispatch->dispatch(aCommand, css::uno::Sequence< css::beans::PropertyValue >());
3513 }
3514 }
3515 catch(const css::uno::Exception&)
3516 {}
3517 }
3518 else if( rAppEvent.GetEvent() == "PRIVATE:DOSHUTDOWN" )
3519 {
3520 Desktop* pD = dynamic_cast<Desktop*>(GetpApp());
3521 OSL_ENSURE( pD, "no desktop ?!?" );
3522 if( pD )
3523 pD->doShutdown();
3524 }
3525 }
3526
OpenSplashScreen()3527 void Desktop::OpenSplashScreen()
3528 {
3529 ::rtl::OUString aTmpString;
3530 CommandLineArgs* pCmdLine = GetCommandLineArgs();
3531 sal_Bool bVisible = sal_False;
3532 // Show intro only if this is normal start (e.g. no server, no quickstart, no printing )
3533 if ( !pCmdLine->IsInvisible() &&
3534 !pCmdLine->IsHeadless() &&
3535 !pCmdLine->IsQuickstart() &&
3536 !pCmdLine->IsMinimized() &&
3537 !pCmdLine->IsNoLogo() &&
3538 !pCmdLine->IsTerminateAfterInit() &&
3539 !pCmdLine->GetPrintList( aTmpString ) &&
3540 !pCmdLine->GetPrintToList( aTmpString ) )
3541 {
3542 // Determine application name from command line parameters
3543 OUString aAppName;
3544 if ( pCmdLine->IsWriter() )
3545 aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "writer" ));
3546 else if ( pCmdLine->IsCalc() )
3547 aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "calc" ));
3548 else if ( pCmdLine->IsDraw() )
3549 aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "draw" ));
3550 else if ( pCmdLine->IsImpress() )
3551 aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "impress" ));
3552 else if ( pCmdLine->IsBase() )
3553 aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "base" ));
3554 else if ( pCmdLine->IsGlobal() )
3555 aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "global" ));
3556 else if ( pCmdLine->IsMath() )
3557 aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "math" ));
3558 else if ( pCmdLine->IsWeb() )
3559 aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "web" ));
3560
3561 bVisible = sal_True;
3562 Sequence< Any > aSeq( 2 );
3563 aSeq[0] <<= bVisible;
3564 aSeq[1] <<= aAppName;
3565 m_rSplashScreen = Reference<XStatusIndicator>(
3566 comphelper::getProcessServiceFactory()->createInstanceWithArguments(
3567 OUString::createFromAscii("com.sun.star.office.SplashScreen"),
3568 aSeq), UNO_QUERY);
3569
3570 if(m_rSplashScreen.is())
3571 m_rSplashScreen->start(OUString::createFromAscii("SplashScreen"), 100);
3572 }
3573
3574 }
3575
SetSplashScreenProgress(sal_Int32 iProgress)3576 void Desktop::SetSplashScreenProgress(sal_Int32 iProgress)
3577 {
3578 if(m_rSplashScreen.is())
3579 {
3580 m_rSplashScreen->setValue(iProgress);
3581 }
3582 }
3583
SetSplashScreenText(const::rtl::OUString & rText)3584 void Desktop::SetSplashScreenText( const ::rtl::OUString& rText )
3585 {
3586 if( m_rSplashScreen.is() )
3587 {
3588 m_rSplashScreen->setText( rText );
3589 }
3590 }
3591
CloseSplashScreen()3592 void Desktop::CloseSplashScreen()
3593 {
3594 if(m_rSplashScreen.is())
3595 {
3596 m_rSplashScreen->end();
3597 m_rSplashScreen = NULL;
3598 }
3599 }
3600
3601 // ========================================================================
DoFirstRunInitializations()3602 void Desktop::DoFirstRunInitializations()
3603 {
3604 try
3605 {
3606 Reference< XJobExecutor > xExecutor( ::comphelper::getProcessServiceFactory()->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.task.JobExecutor" ) ), UNO_QUERY );
3607 if( xExecutor.is() )
3608 xExecutor->trigger( ::rtl::OUString::createFromAscii("onFirstRunInitialization") );
3609 }
3610 catch(const ::com::sun::star::uno::Exception&)
3611 {
3612 OSL_ENSURE( sal_False, "Desktop::DoFirstRunInitializations: caught an exception while trigger job executor ..." );
3613 }
3614 }
3615
3616 // ========================================================================
CheckFirstRun()3617 void Desktop::CheckFirstRun( )
3618 {
3619 const ::rtl::OUString sCommonMiscNodeName = ::rtl::OUString::createFromAscii( "/org.openoffice.Office.Common/Misc" );
3620 const ::rtl::OUString sFirstRunNodeName = ::rtl::OUString::createFromAscii( "FirstRun" );
3621
3622 // --------------------------------------------------------------------
3623 // check if this is the first office start
3624
3625 // for this, open the Common/Misc node where this info is stored
3626 ::utl::OConfigurationTreeRoot aCommonMisc = ::utl::OConfigurationTreeRoot::createWithServiceFactory(
3627 ::comphelper::getProcessServiceFactory( ),
3628 sCommonMiscNodeName,
3629 2,
3630 ::utl::OConfigurationTreeRoot::CM_UPDATABLE
3631 );
3632
3633 // read the flag
3634 OSL_ENSURE( aCommonMisc.isValid(), "Desktop::CheckFirstRun: could not open the config node needed!" );
3635 sal_Bool bIsFirstRun = sal_False;
3636 aCommonMisc.getNodeValue( sFirstRunNodeName ) >>= bIsFirstRun;
3637
3638 if ( !bIsFirstRun )
3639 // nothing to do ....
3640 return;
3641
3642 // --------------------------------------------------------------------
3643 // it is the first run
3644 // this has once been done using a vos timer. this could lead to problems when
3645 // the timer would trigger when the app is already going down again, since VCL would
3646 // no longer be available. Since the old handler would do a postUserEvent to the main
3647 // thread anyway, we can use a vcl timer here to prevent the race contition (#107197#)
3648 m_firstRunTimer.SetTimeout(3000); // 3 sec.
3649 m_firstRunTimer.SetTimeoutHdl(LINK(this, Desktop, AsyncInitFirstRun));
3650 m_firstRunTimer.Start();
3651
3652 // --------------------------------------------------------------------
3653 // reset the config flag
3654
3655 // set the value
3656 aCommonMisc.setNodeValue( sFirstRunNodeName, makeAny( (sal_Bool)sal_False ) );
3657 // commit the changes
3658 aCommonMisc.commit();
3659 }
3660
3661 }
3662