Version 4.2.0.1, tag libreoffice-4.2.0.1
[LibreOffice.git] / vcl / source / app / svdata.cxx
blobaa58484fb872effc2f4137a0fa10e8e7571dbfd3
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <string.h>
21 #include <boost/ptr_container/ptr_vector.hpp>
23 #include <comphelper/processfactory.hxx>
24 #include <comphelper/string.hxx>
25 #include <osl/mutex.hxx>
26 #include <rtl/process.h>
27 #include <tools/debug.hxx>
28 #include <tools/resary.hxx>
29 #include <tools/gen.hxx>
30 #include <unotools/fontcfg.hxx>
31 #include <cppuhelper/implbase1.hxx>
32 #include <uno/current_context.hxx>
34 #include "vcl/configsettings.hxx"
35 #include "vcl/svapp.hxx"
36 #include "vcl/wrkwin.hxx"
37 #include "vcl/msgbox.hxx"
38 #include "vcl/button.hxx"
39 #include "vcl/dockwin.hxx"
40 #include "salinst.hxx"
41 #include "salframe.hxx"
42 #include "svdata.hxx"
43 #include "window.h"
44 #include "salimestatus.hxx"
45 #include "salsys.hxx"
46 #include "svids.hrc"
48 #include "com/sun/star/accessibility/AccessBridge.hpp"
49 #include "com/sun/star/accessibility/MSAAService.hpp"
50 #include "com/sun/star/awt/XExtendedToolkit.hpp"
51 #include "com/sun/star/java/JavaNotConfiguredException.hpp"
52 #include "com/sun/star/java/JavaVMCreationFailureException.hpp"
53 #include "com/sun/star/java/MissingJavaRuntimeException.hpp"
54 #include "com/sun/star/java/JavaDisabledException.hpp"
56 #include "officecfg/Office/Common.hxx"
58 #include <stdio.h>
60 using namespace com::sun::star::uno;
61 using namespace com::sun::star::lang;
62 using namespace com::sun::star::awt;
64 // =======================================================================
66 namespace
68 struct private_aImplSVData :
69 public rtl::Static<ImplSVData, private_aImplSVData> {};
72 // static SV-Data
73 ImplSVData* pImplSVData = NULL;
75 SalSystem* ImplGetSalSystem()
77 ImplSVData* pSVData = ImplGetSVData();
78 if( ! pSVData->mpSalSystem )
79 pSVData->mpSalSystem = pSVData->mpDefInst->CreateSalSystem();
80 return pSVData->mpSalSystem;
84 static OUString ReplaceJavaErrorMessages( const OUString& rString )
86 return rString.replaceAll("%OK", Button::GetStandardText(BUTTON_OK)).
87 replaceAll("%IGNORE", Button::GetStandardText(BUTTON_IGNORE)).
88 replaceAll("%CANCEL", Button::GetStandardText(BUTTON_CANCEL));
91 // =======================================================================
93 void ImplInitSVData()
95 pImplSVData = &private_aImplSVData::get();
97 // init global instance data
98 memset( pImplSVData, 0, sizeof( ImplSVData ) );
99 pImplSVData->maHelpData.mbAutoHelpId = sal_True;
100 pImplSVData->maNWFData.maMenuBarHighlightTextColor = Color( COL_TRANSPARENT );
102 // mark default layout border as unitialized
103 pImplSVData->maAppData.mnDefaultLayoutBorder = -1;
106 // -----------------------------------------------------------------------
108 void ImplDeInitSVData()
110 ImplSVData* pSVData = ImplGetSVData();
112 // delete global instance data
113 if( pSVData->mpSettingsConfigItem )
114 delete pSVData->mpSettingsConfigItem;
116 if( pSVData->mpDockingManager )
117 delete pSVData->mpDockingManager;
119 if( pSVData->maGDIData.mpDefaultFontConfiguration )
120 delete pSVData->maGDIData.mpDefaultFontConfiguration;
121 if( pSVData->maGDIData.mpFontSubstConfiguration )
122 delete pSVData->maGDIData.mpFontSubstConfiguration;
124 if( pSVData->maCtrlData.mpFieldUnitStrings )
125 delete pSVData->maCtrlData.mpFieldUnitStrings, pSVData->maCtrlData.mpFieldUnitStrings = NULL;
126 if( pSVData->maCtrlData.mpCleanUnitStrings )
127 delete pSVData->maCtrlData.mpCleanUnitStrings, pSVData->maCtrlData.mpCleanUnitStrings = NULL;
128 if( pSVData->mpPaperNames )
129 delete pSVData->mpPaperNames, pSVData->mpPaperNames = NULL;
132 // -----------------------------------------------------------------------
134 void ImplDestroySVData()
136 pImplSVData = NULL;
139 // -----------------------------------------------------------------------
141 Window* ImplGetDefaultWindow()
143 ImplSVData* pSVData = ImplGetSVData();
144 if ( pSVData->maWinData.mpAppWin )
145 return pSVData->maWinData.mpAppWin;
147 // First test if we already have a default window.
148 // Don't only place a single if..else inside solar mutex lockframe
149 // because then we might have to wait for the solar mutex what is not necessary
150 // if we already have a default window.
152 if ( !pSVData->mpDefaultWin )
154 Application::GetSolarMutex().acquire();
156 // Test again because the thread who released the solar mutex could have called
157 // the same method
159 if ( !pSVData->mpDefaultWin && !pSVData->mbDeInit )
161 DBG_WARNING( "ImplGetDefaultWindow(): No AppWindow" );
162 pSVData->mpDefaultWin = new WorkWindow( 0, WB_DEFAULTWIN );
163 pSVData->mpDefaultWin->SetText( OUString( "VCL ImplGetDefaultWindow" ) );
165 Application::GetSolarMutex().release();
168 return pSVData->mpDefaultWin;
171 // -----------------------------------------------------------------------
173 ResMgr* ImplGetResMgr()
175 ImplSVData* pSVData = ImplGetSVData();
176 if ( !pSVData->mpResMgr )
178 LanguageTag aLocale( Application::GetSettings().GetUILanguageTag());
179 pSVData->mpResMgr = ResMgr::SearchCreateResMgr( "vcl", aLocale );
181 static bool bMessageOnce = false;
182 if( !pSVData->mpResMgr && ! bMessageOnce )
184 bMessageOnce = true;
185 const char* pMsg =
186 "Missing vcl resource. This indicates that files vital to localization are missing. "
187 "You might have a corrupt installation.";
188 fprintf( stderr, "%s\n", pMsg );
189 ErrorBox aBox( NULL, WB_OK | WB_DEF_OK, OUString( pMsg, strlen( pMsg ), RTL_TEXTENCODING_ASCII_US ) );
190 aBox.Execute();
193 return pSVData->mpResMgr;
196 ResId VclResId( sal_Int32 nId )
198 ResMgr* pMgr = ImplGetResMgr();
199 if( ! pMgr )
200 throw std::bad_alloc();
202 return ResId( nId, *pMgr );
205 FieldUnitStringList* ImplGetFieldUnits()
207 ImplSVData* pSVData = ImplGetSVData();
208 if( ! pSVData->maCtrlData.mpFieldUnitStrings )
210 ResMgr* pResMgr = ImplGetResMgr();
211 if( pResMgr )
213 ResStringArray aUnits( ResId (SV_FUNIT_STRINGS, *pResMgr) );
214 sal_uInt32 nUnits = aUnits.Count();
215 pSVData->maCtrlData.mpFieldUnitStrings = new FieldUnitStringList();
216 pSVData->maCtrlData.mpFieldUnitStrings->reserve( nUnits );
217 for( sal_uInt32 i = 0; i < nUnits; i++ )
219 std::pair< OUString, FieldUnit > aElement( aUnits.GetString(i), static_cast<FieldUnit>(aUnits.GetValue(i)) );
220 pSVData->maCtrlData.mpFieldUnitStrings->push_back( aElement );
224 return pSVData->maCtrlData.mpFieldUnitStrings;
227 FieldUnitStringList* ImplGetCleanedFieldUnits()
229 ImplSVData* pSVData = ImplGetSVData();
230 if( ! pSVData->maCtrlData.mpCleanUnitStrings )
232 FieldUnitStringList* pUnits = ImplGetFieldUnits();
233 if( pUnits )
235 size_t nUnits = pUnits->size();
236 pSVData->maCtrlData.mpCleanUnitStrings = new FieldUnitStringList();
237 pSVData->maCtrlData.mpCleanUnitStrings->reserve( nUnits );
238 for( size_t i = 0; i < nUnits; ++i )
240 OUString aUnit( (*pUnits)[i].first );
241 aUnit = comphelper::string::remove(aUnit, ' ');
242 aUnit = aUnit.toAsciiLowerCase();
243 std::pair< OUString, FieldUnit > aElement( aUnit, (*pUnits)[i].second );
244 pSVData->maCtrlData.mpCleanUnitStrings->push_back( aElement );
248 return pSVData->maCtrlData.mpCleanUnitStrings;
251 DockingManager* ImplGetDockingManager()
253 ImplSVData* pSVData = ImplGetSVData();
254 if ( !pSVData->mpDockingManager )
255 pSVData->mpDockingManager = new DockingManager();
257 return pSVData->mpDockingManager;
260 BlendFrameCache* ImplGetBlendFrameCache()
262 ImplSVData* pSVData = ImplGetSVData();
263 if ( !pSVData->mpBlendFrameCache)
264 pSVData->mpBlendFrameCache= new BlendFrameCache();
266 return pSVData->mpBlendFrameCache;
269 class AccessBridgeCurrentContext: public cppu::WeakImplHelper1< com::sun::star::uno::XCurrentContext >
271 public:
272 AccessBridgeCurrentContext(
273 const com::sun::star::uno::Reference< com::sun::star::uno::XCurrentContext > &context ) :
274 m_prevContext( context ) {}
276 // XCurrentContext
277 virtual com::sun::star::uno::Any SAL_CALL getValueByName( const OUString& Name )
278 throw (com::sun::star::uno::RuntimeException);
279 private:
280 com::sun::star::uno::Reference< com::sun::star::uno::XCurrentContext > m_prevContext;
283 com::sun::star::uno::Any AccessBridgeCurrentContext::getValueByName( const OUString & Name )
284 throw (com::sun::star::uno::RuntimeException)
286 com::sun::star::uno::Any ret;
287 if ( Name == "java-vm.interaction-handler" )
289 // Currently, for accessbility no interaction handler shall be offered.
290 // There may be introduced later on a handler using native toolkits
291 // jbu->obr: Instantiate here your interaction handler
293 else if( m_prevContext.is() )
295 ret = m_prevContext->getValueByName( Name );
297 return ret;
300 #ifdef _WIN32
301 bool HasAtHook();
302 #endif
304 bool ImplInitAccessBridge(bool bAllowCancel, bool &rCancelled)
306 rCancelled = false;
308 bool bErrorMessage = true;
310 // Note:
311 // if bAllowCancel is sal_True we were called from application startup
312 // where we will disable any Java errorboxes and show our own accessibility dialog if Java throws an exception
313 // if bAllowCancel is sal_False we were called from Tools->Options
314 // where we will see Java errorboxes, se we do not show our dialogs in addition to Java's
318 // No error messages when env var is set ..
319 static const char* pEnv = getenv("SAL_ACCESSIBILITY_ENABLED" );
320 if( pEnv && *pEnv )
322 bErrorMessage = false;
325 ImplSVData* pSVData = ImplGetSVData();
326 if( ! pSVData->mxAccessBridge.is() )
328 css::uno::Reference< XComponentContext > xContext(comphelper::getProcessComponentContext());
330 #ifdef _WIN32
331 bool bTryIAcc2 = ( officecfg::Office::Common::Misc::ExperimentalMode::get( xContext ) &&
332 !getenv ("SAL_DISABLE_IACCESSIBLE2") );
334 if ( bTryIAcc2 ) // Windows only really
336 if (!HasAtHook() && !getenv("SAL_FORCE_IACCESSIBLE2"))
338 SAL_INFO("vcl", "Apparently no running AT -> "
339 "not enabling IAccessible2 integration");
341 else
343 try {
344 pSVData->mxAccessBridge
345 = css::accessibility::MSAAService::create(xContext);
346 SAL_INFO("vcl", "got IAccessible2 bridge");
347 return true;
348 } catch (css::uno::DeploymentException & e) {
349 SAL_INFO(
350 "vcl",
351 "got no IAccessible2 bridge, \"" << e.Message
352 << "\", falling back to java");
356 else
357 SAL_INFO( "vcl", "IAccessible2 disabled, falling back to java" );
358 #endif
360 css::uno::Reference< XExtendedToolkit > xToolkit =
361 css::uno::Reference< XExtendedToolkit >(Application::GetVCLToolkit(), UNO_QUERY);
363 // Disable default java error messages on startup, because they were probably unreadable
364 // for a disabled user. Use native message boxes which are accessible without java support.
365 // No need to do this when activated by Tools-Options dialog ..
366 if( bAllowCancel )
368 // customize the java-not-available-interaction-handler entry within the
369 // current context when called at startup.
370 com::sun::star::uno::ContextLayer layer(
371 new AccessBridgeCurrentContext( com::sun::star::uno::getCurrentContext() ) );
373 pSVData->mxAccessBridge
374 = css::accessibility::AccessBridge::createWithToolkit(
375 xContext, xToolkit);
377 else
379 pSVData->mxAccessBridge
380 = css::accessibility::AccessBridge::createWithToolkit(
381 xContext, xToolkit);
385 return true;
387 catch (const ::com::sun::star::java::JavaNotConfiguredException&)
389 ResMgr *pResMgr = ImplGetResMgr();
390 if( bErrorMessage && bAllowCancel && pResMgr )
392 OUString aTitle(ResId(SV_ACCESSERROR_JAVA_NOT_CONFIGURED, *pResMgr).toString());
393 OUStringBuffer aMessage((ResId(SV_ACCESSERROR_JAVA_MSG, *pResMgr)).toString());
395 aMessage.append(' ').append(ResId(SV_ACCESSERROR_OK_CANCEL_MSG, *pResMgr).toString());
397 int ret = ImplGetSalSystem()->ShowNativeMessageBox(
398 aTitle,
399 ReplaceJavaErrorMessages(aMessage.makeStringAndClear()),
400 SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK_CANCEL,
401 SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL, true);
403 // Do not change the setting in case the user chooses to cancel
404 if( SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL == ret )
405 rCancelled = true;
408 return false;
410 catch (const ::com::sun::star::java::JavaVMCreationFailureException&)
412 ResMgr *pResMgr = ImplGetResMgr();
413 if( bErrorMessage && bAllowCancel && pResMgr )
415 OUString aTitle(ResId(SV_ACCESSERROR_FAULTY_JAVA, *pResMgr).toString());
416 OUStringBuffer aMessage(ResId(SV_ACCESSERROR_JAVA_MSG, *pResMgr).toString());
418 aMessage.append(' ').append(ResId(SV_ACCESSERROR_OK_CANCEL_MSG, *pResMgr).toString());
420 int ret = ImplGetSalSystem()->ShowNativeMessageBox(
421 aTitle,
422 ReplaceJavaErrorMessages(aMessage.makeStringAndClear()),
423 SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK_CANCEL,
424 SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL, true);
426 // Do not change the setting in case the user chooses to cancel
427 if( SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL == ret )
428 rCancelled = true;
431 return false;
433 catch (const ::com::sun::star::java::MissingJavaRuntimeException&)
435 ResMgr *pResMgr = ImplGetResMgr();
436 if( bErrorMessage && bAllowCancel && pResMgr )
438 OUString aTitle(ResId(SV_ACCESSERROR_MISSING_JAVA, *pResMgr).toString());
439 OUStringBuffer aMessage(ResId(SV_ACCESSERROR_JAVA_MSG, *pResMgr).toString());
441 aMessage.append(' ').append(ResId(SV_ACCESSERROR_OK_CANCEL_MSG, *pResMgr).toString());
443 int ret = ImplGetSalSystem()->ShowNativeMessageBox(
444 aTitle,
445 ReplaceJavaErrorMessages(aMessage.makeStringAndClear()),
446 SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK_CANCEL,
447 SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL, true);
449 // Do not change the setting in case the user chooses to cancel
450 if( SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL == ret )
451 rCancelled = true;
454 return false;
456 catch (const ::com::sun::star::java::JavaDisabledException&)
458 ResMgr *pResMgr = ImplGetResMgr();
459 if( bErrorMessage && bAllowCancel && pResMgr )
461 OUString aTitle(ResId(SV_ACCESSERROR_JAVA_DISABLED, *pResMgr).toString());
462 OUStringBuffer aMessage(ResId(SV_ACCESSERROR_JAVA_MSG, *pResMgr).toString());
464 aMessage.append(' ').append(ResId(SV_ACCESSERROR_OK_CANCEL_MSG, *pResMgr).toString());
466 int ret = ImplGetSalSystem()->ShowNativeMessageBox(
467 aTitle,
468 ReplaceJavaErrorMessages(aMessage.makeStringAndClear()),
469 SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK_CANCEL,
470 SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL, true);
472 // Do not change the setting in case the user chooses to cancel
473 if( SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL == ret )
474 rCancelled = true;
477 return false;
479 catch (const ::com::sun::star::uno::RuntimeException& e)
481 ResMgr *pResMgr = ImplGetResMgr();
482 if( bErrorMessage && pResMgr )
484 OUString aTitle;
485 OUStringBuffer aMessage(ResId(SV_ACCESSERROR_BRIDGE_MSG, *pResMgr).toString());
487 if( e.Message.startsWith("ClassNotFound") )
489 aTitle = ResId(SV_ACCESSERROR_MISSING_BRIDGE, *pResMgr).toString();
491 else if( e.Message.startsWith("NoSuchMethod") )
493 aTitle = ResId(SV_ACCESSERROR_WRONG_VERSION, *pResMgr).toString();
496 if (!aTitle.isEmpty())
498 if( bAllowCancel )
500 // Something went wrong initializing the Java AccessBridge (on Windows) during the
501 // startup. Since the office will be probably unusable for a disabled user, we offer
502 // to terminate directly.
503 aMessage.append(' ').append(ResId(SV_ACCESSERROR_OK_CANCEL_MSG, *pResMgr).toString());
505 int ret = ImplGetSalSystem()->ShowNativeMessageBox(
506 aTitle,
507 ReplaceJavaErrorMessages(aMessage.makeStringAndClear()),
508 SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK_CANCEL,
509 SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL, true);
511 // Do not change the setting in case the user chooses to cancel
512 if( SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL == ret )
513 rCancelled = sal_True;
515 else
517 // The user tried to activate accessibility support using Tools-Options dialog,
518 // so we don't offer to terminate here !
519 ImplGetSalSystem()->ShowNativeMessageBox(
520 aTitle,
521 ReplaceJavaErrorMessages(aMessage.makeStringAndClear()),
522 SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK,
523 SALSYSTEM_SHOWNATIVEMSGBOX_BTN_OK, true);
528 return false;
530 catch (...)
532 return false;
536 // -----------------------------------------------------------------------
538 Window* ImplFindWindow( const SalFrame* pFrame, ::Point& rSalFramePos )
540 ImplSVData* pSVData = ImplGetSVData();
541 Window* pFrameWindow = pSVData->maWinData.mpFirstFrame;
542 while ( pFrameWindow )
544 if ( pFrameWindow->ImplGetFrame() == pFrame )
546 Window* pWindow = pFrameWindow->ImplFindWindow( rSalFramePos );
547 if ( !pWindow )
548 pWindow = pFrameWindow->ImplGetWindow();
549 rSalFramePos = pWindow->ImplFrameToOutput( rSalFramePos );
550 return pWindow;
552 pFrameWindow = pFrameWindow->ImplGetFrameData()->mpNextFrame;
555 return NULL;
558 void LocaleConfigurationListener::ConfigurationChanged( utl::ConfigurationBroadcaster*, sal_uInt32 nHint )
560 AllSettings::LocaleSettingsChanged( nHint );
563 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */