update credits
[LibreOffice.git] / vcl / source / app / svdata.cxx
blob2a7bc93916dcf40adbcb7265b24edb6c2eac4359
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" // for Button::GetStandardText
39 #include "vcl/dockwin.hxx" // for DockingManager
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/awt/XExtendedToolkit.hpp"
50 #include "com/sun/star/java/JavaNotConfiguredException.hpp"
51 #include "com/sun/star/java/JavaVMCreationFailureException.hpp"
52 #include "com/sun/star/java/MissingJavaRuntimeException.hpp"
53 #include "com/sun/star/java/JavaDisabledException.hpp"
55 #include <stdio.h>
57 using namespace com::sun::star::uno;
58 using namespace com::sun::star::lang;
59 using namespace com::sun::star::awt;
61 // =======================================================================
63 namespace
65 struct private_aImplSVData :
66 public rtl::Static<ImplSVData, private_aImplSVData> {};
69 // static SV-Data
70 ImplSVData* pImplSVData = NULL;
72 SalSystem* ImplGetSalSystem()
74 ImplSVData* pSVData = ImplGetSVData();
75 if( ! pSVData->mpSalSystem )
76 pSVData->mpSalSystem = pSVData->mpDefInst->CreateSalSystem();
77 return pSVData->mpSalSystem;
81 static OUString ReplaceJavaErrorMessages( const OUString& rString )
83 return rString.replaceAll("%OK", Button::GetStandardText(BUTTON_OK)).
84 replaceAll("%IGNORE", Button::GetStandardText(BUTTON_IGNORE)).
85 replaceAll("%CANCEL", Button::GetStandardText(BUTTON_CANCEL));
88 // =======================================================================
90 void ImplInitSVData()
92 pImplSVData = &private_aImplSVData::get();
94 // init global instance data
95 memset( pImplSVData, 0, sizeof( ImplSVData ) );
96 pImplSVData->maHelpData.mbAutoHelpId = sal_True;
97 pImplSVData->maNWFData.maMenuBarHighlightTextColor = Color( COL_TRANSPARENT );
99 // mark default layout border as unitialized
100 pImplSVData->maAppData.mnDefaultLayoutBorder = -1;
103 // -----------------------------------------------------------------------
105 void ImplDeInitSVData()
107 ImplSVData* pSVData = ImplGetSVData();
109 // delete global instance data
110 if( pSVData->mpSettingsConfigItem )
111 delete pSVData->mpSettingsConfigItem;
113 if( pSVData->mpDockingManager )
114 delete pSVData->mpDockingManager;
116 if( pSVData->maGDIData.mpDefaultFontConfiguration )
117 delete pSVData->maGDIData.mpDefaultFontConfiguration;
118 if( pSVData->maGDIData.mpFontSubstConfiguration )
119 delete pSVData->maGDIData.mpFontSubstConfiguration;
121 if( pSVData->maCtrlData.mpFieldUnitStrings )
122 delete pSVData->maCtrlData.mpFieldUnitStrings, pSVData->maCtrlData.mpFieldUnitStrings = NULL;
123 if( pSVData->maCtrlData.mpCleanUnitStrings )
124 delete pSVData->maCtrlData.mpCleanUnitStrings, pSVData->maCtrlData.mpCleanUnitStrings = NULL;
125 if( pSVData->mpPaperNames )
126 delete pSVData->mpPaperNames, pSVData->mpPaperNames = NULL;
129 // -----------------------------------------------------------------------
131 void ImplDestroySVData()
133 pImplSVData = NULL;
136 // -----------------------------------------------------------------------
138 Window* ImplGetDefaultWindow()
140 ImplSVData* pSVData = ImplGetSVData();
141 if ( pSVData->maWinData.mpAppWin )
142 return pSVData->maWinData.mpAppWin;
144 // First test if we already have a default window.
145 // Don't only place a single if..else inside solar mutex lockframe
146 // because then we might have to wait for the solar mutex what is not necessary
147 // if we already have a default window.
149 if ( !pSVData->mpDefaultWin )
151 Application::GetSolarMutex().acquire();
153 // Test again because the thread who released the solar mutex could have called
154 // the same method
156 if ( !pSVData->mpDefaultWin && !pSVData->mbDeInit )
158 DBG_WARNING( "ImplGetDefaultWindow(): No AppWindow" );
159 pSVData->mpDefaultWin = new WorkWindow( 0, WB_DEFAULTWIN );
160 pSVData->mpDefaultWin->SetText( OUString( "VCL ImplGetDefaultWindow" ) );
162 Application::GetSolarMutex().release();
165 return pSVData->mpDefaultWin;
168 // -----------------------------------------------------------------------
170 #define VCL_CREATERESMGR_NAME( Name ) #Name
172 ResMgr* ImplGetResMgr()
174 ImplSVData* pSVData = ImplGetSVData();
175 if ( !pSVData->mpResMgr )
177 LanguageTag aLocale( Application::GetSettings().GetUILanguageTag());
178 pSVData->mpResMgr = ResMgr::SearchCreateResMgr( VCL_CREATERESMGR_NAME( vcl ), aLocale );
180 static bool bMessageOnce = false;
181 if( !pSVData->mpResMgr && ! bMessageOnce )
183 bMessageOnce = true;
184 const char* pMsg =
185 "Missing vcl resource. This indicates that files vital to localization are missing. "
186 "You might have a corrupt installation.";
187 fprintf( stderr, "%s\n", pMsg );
188 ErrorBox aBox( NULL, WB_OK | WB_DEF_OK, OUString( pMsg, strlen( pMsg ), RTL_TEXTENCODING_ASCII_US ) );
189 aBox.Execute();
192 return pSVData->mpResMgr;
195 ResId VclResId( sal_Int32 nId )
197 ResMgr* pMgr = ImplGetResMgr();
198 if( ! pMgr )
199 throw std::bad_alloc();
201 return ResId( nId, *pMgr );
204 FieldUnitStringList* ImplGetFieldUnits()
206 ImplSVData* pSVData = ImplGetSVData();
207 if( ! pSVData->maCtrlData.mpFieldUnitStrings )
209 ResMgr* pResMgr = ImplGetResMgr();
210 if( pResMgr )
212 ResStringArray aUnits( ResId (SV_FUNIT_STRINGS, *pResMgr) );
213 sal_uInt32 nUnits = aUnits.Count();
214 pSVData->maCtrlData.mpFieldUnitStrings = new FieldUnitStringList();
215 pSVData->maCtrlData.mpFieldUnitStrings->reserve( nUnits );
216 for( sal_uInt32 i = 0; i < nUnits; i++ )
218 std::pair< String, FieldUnit > aElement( aUnits.GetString(i), static_cast<FieldUnit>(aUnits.GetValue(i)) );
219 pSVData->maCtrlData.mpFieldUnitStrings->push_back( aElement );
223 return pSVData->maCtrlData.mpFieldUnitStrings;
226 FieldUnitStringList* ImplGetCleanedFieldUnits()
228 ImplSVData* pSVData = ImplGetSVData();
229 if( ! pSVData->maCtrlData.mpCleanUnitStrings )
231 FieldUnitStringList* pUnits = ImplGetFieldUnits();
232 if( pUnits )
234 size_t nUnits = pUnits->size();
235 pSVData->maCtrlData.mpCleanUnitStrings = new FieldUnitStringList();
236 pSVData->maCtrlData.mpCleanUnitStrings->reserve( nUnits );
237 for( size_t i = 0; i < nUnits; ++i )
239 OUString aUnit( (*pUnits)[i].first );
240 aUnit = comphelper::string::remove(aUnit, ' ');
241 aUnit = aUnit.toAsciiLowerCase();
242 std::pair< String, FieldUnit > aElement( aUnit, (*pUnits)[i].second );
243 pSVData->maCtrlData.mpCleanUnitStrings->push_back( aElement );
247 return pSVData->maCtrlData.mpCleanUnitStrings;
250 DockingManager* ImplGetDockingManager()
252 ImplSVData* pSVData = ImplGetSVData();
253 if ( !pSVData->mpDockingManager )
254 pSVData->mpDockingManager = new DockingManager();
256 return pSVData->mpDockingManager;
259 BlendFrameCache* ImplGetBlendFrameCache()
261 ImplSVData* pSVData = ImplGetSVData();
262 if ( !pSVData->mpBlendFrameCache)
263 pSVData->mpBlendFrameCache= new BlendFrameCache();
265 return pSVData->mpBlendFrameCache;
268 class AccessBridgeCurrentContext: public cppu::WeakImplHelper1< com::sun::star::uno::XCurrentContext >
270 public:
271 AccessBridgeCurrentContext(
272 const com::sun::star::uno::Reference< com::sun::star::uno::XCurrentContext > &context ) :
273 m_prevContext( context ) {}
275 // XCurrentContext
276 virtual com::sun::star::uno::Any SAL_CALL getValueByName( const OUString& Name )
277 throw (com::sun::star::uno::RuntimeException);
278 private:
279 com::sun::star::uno::Reference< com::sun::star::uno::XCurrentContext > m_prevContext;
282 com::sun::star::uno::Any AccessBridgeCurrentContext::getValueByName( const OUString & Name )
283 throw (com::sun::star::uno::RuntimeException)
285 com::sun::star::uno::Any ret;
286 if ( Name == "java-vm.interaction-handler" )
288 // Currently, for accessbility no interaction handler shall be offered.
289 // There may be introduced later on a handler using native toolkits
290 // jbu->obr: Instantiate here your interaction handler
292 else if( m_prevContext.is() )
294 ret = m_prevContext->getValueByName( Name );
296 return ret;
300 bool ImplInitAccessBridge(bool bAllowCancel, bool &rCancelled)
302 rCancelled = false;
304 bool bErrorMessage = true;
306 // Note:
307 // if bAllowCancel is sal_True we were called from application startup
308 // where we will disable any Java errorboxes and show our own accessibility dialog if Java throws an exception
309 // if bAllowCancel is sal_False we were called from Tools->Options
310 // where we will see Java errorboxes, se we do not show our dialogs in addition to Java's
314 // No error messages when env var is set ..
315 static const char* pEnv = getenv("SAL_ACCESSIBILITY_ENABLED" );
316 if( pEnv && *pEnv )
318 bErrorMessage = false;
321 ImplSVData* pSVData = ImplGetSVData();
322 if( ! pSVData->mxAccessBridge.is() )
324 css::uno::Reference< XComponentContext > xContext(comphelper::getProcessComponentContext());
326 css::uno::Reference< XExtendedToolkit > xToolkit =
327 css::uno::Reference< XExtendedToolkit >(Application::GetVCLToolkit(), UNO_QUERY);
329 // Disable default java error messages on startup, because they were probably unreadable
330 // for a disabled user. Use native message boxes which are accessible without java support.
331 // No need to do this when activated by Tools-Options dialog ..
332 if( bAllowCancel )
334 // customize the java-not-available-interaction-handler entry within the
335 // current context when called at startup.
336 com::sun::star::uno::ContextLayer layer(
337 new AccessBridgeCurrentContext( com::sun::star::uno::getCurrentContext() ) );
339 pSVData->mxAccessBridge
340 = css::accessibility::AccessBridge::createWithToolkit(
341 xContext, xToolkit);
343 else
345 pSVData->mxAccessBridge
346 = css::accessibility::AccessBridge::createWithToolkit(
347 xContext, xToolkit);
351 return true;
353 catch (const ::com::sun::star::java::JavaNotConfiguredException&)
355 ResMgr *pResMgr = ImplGetResMgr();
356 if( bErrorMessage && bAllowCancel && pResMgr )
358 OUString aTitle(ResId(SV_ACCESSERROR_JAVA_NOT_CONFIGURED, *pResMgr).toString());
359 OUStringBuffer aMessage((ResId(SV_ACCESSERROR_JAVA_MSG, *pResMgr)).toString());
361 aMessage.append(' ').append(ResId(SV_ACCESSERROR_OK_CANCEL_MSG, *pResMgr).toString());
363 int ret = ImplGetSalSystem()->ShowNativeMessageBox(
364 aTitle,
365 ReplaceJavaErrorMessages(aMessage.makeStringAndClear()),
366 SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK_CANCEL,
367 SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL, true);
369 // Do not change the setting in case the user chooses to cancel
370 if( SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL == ret )
371 rCancelled = true;
374 return false;
376 catch (const ::com::sun::star::java::JavaVMCreationFailureException&)
378 ResMgr *pResMgr = ImplGetResMgr();
379 if( bErrorMessage && bAllowCancel && pResMgr )
381 OUString aTitle(ResId(SV_ACCESSERROR_FAULTY_JAVA, *pResMgr).toString());
382 OUStringBuffer aMessage(ResId(SV_ACCESSERROR_JAVA_MSG, *pResMgr).toString());
384 aMessage.append(' ').append(ResId(SV_ACCESSERROR_OK_CANCEL_MSG, *pResMgr).toString());
386 int ret = ImplGetSalSystem()->ShowNativeMessageBox(
387 aTitle,
388 ReplaceJavaErrorMessages(aMessage.makeStringAndClear()),
389 SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK_CANCEL,
390 SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL, true);
392 // Do not change the setting in case the user chooses to cancel
393 if( SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL == ret )
394 rCancelled = true;
397 return false;
399 catch (const ::com::sun::star::java::MissingJavaRuntimeException&)
401 ResMgr *pResMgr = ImplGetResMgr();
402 if( bErrorMessage && bAllowCancel && pResMgr )
404 OUString aTitle(ResId(SV_ACCESSERROR_MISSING_JAVA, *pResMgr).toString());
405 OUStringBuffer aMessage(ResId(SV_ACCESSERROR_JAVA_MSG, *pResMgr).toString());
407 aMessage.append(' ').append(ResId(SV_ACCESSERROR_OK_CANCEL_MSG, *pResMgr).toString());
409 int ret = ImplGetSalSystem()->ShowNativeMessageBox(
410 aTitle,
411 ReplaceJavaErrorMessages(aMessage.makeStringAndClear()),
412 SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK_CANCEL,
413 SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL, true);
415 // Do not change the setting in case the user chooses to cancel
416 if( SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL == ret )
417 rCancelled = true;
420 return false;
422 catch (const ::com::sun::star::java::JavaDisabledException&)
424 ResMgr *pResMgr = ImplGetResMgr();
425 if( bErrorMessage && bAllowCancel && pResMgr )
427 OUString aTitle(ResId(SV_ACCESSERROR_JAVA_DISABLED, *pResMgr).toString());
428 OUStringBuffer aMessage(ResId(SV_ACCESSERROR_JAVA_MSG, *pResMgr).toString());
430 aMessage.append(' ').append(ResId(SV_ACCESSERROR_OK_CANCEL_MSG, *pResMgr).toString());
432 int ret = ImplGetSalSystem()->ShowNativeMessageBox(
433 aTitle,
434 ReplaceJavaErrorMessages(aMessage.makeStringAndClear()),
435 SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK_CANCEL,
436 SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL, true);
438 // Do not change the setting in case the user chooses to cancel
439 if( SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL == ret )
440 rCancelled = true;
443 return false;
445 catch (const ::com::sun::star::uno::RuntimeException& e)
447 ResMgr *pResMgr = ImplGetResMgr();
448 if( bErrorMessage && pResMgr )
450 OUString aTitle;
451 OUStringBuffer aMessage(ResId(SV_ACCESSERROR_BRIDGE_MSG, *pResMgr).toString());
453 if( e.Message.startsWith("ClassNotFound") )
455 aTitle = ResId(SV_ACCESSERROR_MISSING_BRIDGE, *pResMgr).toString();
457 else if( e.Message.startsWith("NoSuchMethod") )
459 aTitle = ResId(SV_ACCESSERROR_WRONG_VERSION, *pResMgr).toString();
462 if (!aTitle.isEmpty())
464 if( bAllowCancel )
466 // Something went wrong initializing the Java AccessBridge (on Windows) during the
467 // startup. Since the office will be probably unusable for a disabled user, we offer
468 // to terminate directly.
469 aMessage.append(' ').append(ResId(SV_ACCESSERROR_OK_CANCEL_MSG, *pResMgr).toString());
471 int ret = ImplGetSalSystem()->ShowNativeMessageBox(
472 aTitle,
473 ReplaceJavaErrorMessages(aMessage.makeStringAndClear()),
474 SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK_CANCEL,
475 SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL, true);
477 // Do not change the setting in case the user chooses to cancel
478 if( SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL == ret )
479 rCancelled = sal_True;
481 else
483 // The user tried to activate accessibility support using Tools-Options dialog,
484 // so we don't offer to terminate here !
485 ImplGetSalSystem()->ShowNativeMessageBox(
486 aTitle,
487 ReplaceJavaErrorMessages(aMessage.makeStringAndClear()),
488 SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK,
489 SALSYSTEM_SHOWNATIVEMSGBOX_BTN_OK, true);
494 return false;
496 catch (...)
498 return false;
502 // -----------------------------------------------------------------------
504 Window* ImplFindWindow( const SalFrame* pFrame, ::Point& rSalFramePos )
506 ImplSVData* pSVData = ImplGetSVData();
507 Window* pFrameWindow = pSVData->maWinData.mpFirstFrame;
508 while ( pFrameWindow )
510 if ( pFrameWindow->ImplGetFrame() == pFrame )
512 Window* pWindow = pFrameWindow->ImplFindWindow( rSalFramePos );
513 if ( !pWindow )
514 pWindow = pFrameWindow->ImplGetWindow();
515 rSalFramePos = pWindow->ImplFrameToOutput( rSalFramePos );
516 return pWindow;
518 pFrameWindow = pFrameWindow->ImplGetFrameData()->mpNextFrame;
521 return NULL;
524 void LocaleConfigurationListener::ConfigurationChanged( utl::ConfigurationBroadcaster*, sal_uInt32 nHint )
526 AllSettings::LocaleSettingsChanged( nHint );
529 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */